1import Minipass from 'minipass'; 2import path from 'path'; 3import { ReadEntry } from 'tar'; 4 5export function sanitizedName(name: string) { 6 return name 7 .replace(/[\W_]+/g, '') 8 .normalize('NFD') 9 .replace(/[\u0300-\u036f]/g, ''); 10} 11 12class Transformer extends Minipass { 13 data: string; 14 15 constructor(private name: string) { 16 super(); 17 this.data = ''; 18 } 19 write(data: string) { 20 this.data += data; 21 return true; 22 } 23 end() { 24 const replaced = this.data 25 .replace(/Hello App Display Name/g, this.name) 26 .replace(/HelloWorld/g, sanitizedName(this.name)) 27 .replace(/helloworld/g, sanitizedName(this.name.toLowerCase())); 28 super.write(replaced); 29 return super.end(); 30 } 31} 32 33export function createEntryResolver(name: string) { 34 return (entry: ReadEntry) => { 35 if (name) { 36 // Rewrite paths for bare workflow 37 entry.path = entry.path 38 .replace( 39 /HelloWorld/g, 40 entry.path.includes('android') ? sanitizedName(name.toLowerCase()) : sanitizedName(name) 41 ) 42 .replace(/helloworld/g, sanitizedName(name).toLowerCase()); 43 } 44 if (entry.type && /^file$/i.test(entry.type) && path.basename(entry.path) === 'gitignore') { 45 // Rename `gitignore` because npm ignores files named `.gitignore` when publishing. 46 // See: https://github.com/npm/npm/issues/1862 47 entry.path = entry.path.replace(/gitignore$/, '.gitignore'); 48 } 49 }; 50} 51 52export function createFileTransform(name: string) { 53 return (entry: ReadEntry) => { 54 // Binary files, don't process these (avoid decoding as utf8) 55 if ( 56 ![ 57 '.png', 58 '.jpg', 59 '.jpeg', 60 '.gif', 61 '.webp', 62 '.psd', 63 '.tiff', 64 '.svg', 65 '.jar', 66 '.keystore', 67 // Font files 68 '.otf', 69 '.ttf', 70 ].includes(path.extname(entry.path)) && 71 name 72 ) { 73 return new Transformer(name); 74 } 75 return undefined; 76 }; 77} 78