unoffical wafrn mirror wafrn.net
atproto social-network activitypub
at angular21 95 lines 2.7 kB view raw
1import fs from 'fs' 2 3/** 4 * Options for patchObjects() 5 */ 6type PatchOptions = { placeholderTransformer: (value: string) => string } 7 8const defaultOptions: PatchOptions = { 9 placeholderTransformer: (value) => '[FIXME] Patched value: ' + value 10} 11 12/** 13 * Recursively patch entries from {from} to {to} with given options 14 */ 15function patchEntries(from: Object, to: Object, options: PatchOptions) { 16 const fromEntries = Object.entries(from) 17 const toEntries = Object.entries(to) 18 19 for (let i = 0; i < fromEntries.length; i++) { 20 const fromKey = fromEntries[i][0] 21 const fromValue = fromEntries[i][1] 22 23 const missingKey = fromKey !== toEntries.at(i)?.at(0) 24 25 if (typeof fromValue === 'object') { 26 if (missingKey) { 27 toEntries.splice(i, 0, [fromKey, {}]) 28 } 29 30 toEntries[i][1] = patchEntries(fromValue, toEntries[i][1], options) 31 } else if (missingKey) { 32 toEntries.splice(i, 0, [fromKey, options.placeholderTransformer(fromValue)]) 33 } 34 } 35 return Object.fromEntries(toEntries) 36} 37 38// 39// CLI usage 40// 41 42// Prevent foot guns, hopefully 43function cleanPath(path: string) { 44 return path.trim().replaceAll(/^\./g, '').replaceAll('/', '') 45} 46 47// Options you may want to modify for your own instance 48const cliOpts = { 49 folderPath: 'src/assets/i18n/', // set to work from packages/frontend 50 defaultLang: 'en.json' 51} 52 53const isScript = require.main === module 54if (isScript) main() 55 56function main(): void { 57 const args = process.argv.slice(2) 58 59 if (args.length === 0) { 60 console.warn('Not enough arguments given') 61 return 62 } 63 64 // One argument, patch default language on to given language 65 if (args.length === 1) { 66 patchFile(cliOpts.defaultLang, cleanPath(args[0])) 67 } else if (args.length === 2) { 68 // Two arguments, patch first to second 69 patchFile(cleanPath(args[0]), cleanPath(args[1])) 70 } else { 71 console.warn('Command not recognized') 72 return 73 } 74 75 console.log("Patch complete! Now run 'npm run frontend:translations:format' and continue your translations") 76} 77 78function patchFile(sourceFileName: string, patchFileName: string): void { 79 const sourceFile = cliOpts.folderPath + sourceFileName 80 const patchFile = cliOpts.folderPath + patchFileName 81 if (!fs.existsSync(patchFile)) { 82 console.log("File to patch did not exist, creating file", patchFile); 83 fs.copyFileSync(sourceFile, patchFile) 84 } 85 86 console.log('Patching', sourceFile, 'to', patchFile) 87 88 const defaultLang = <Object>require(sourceFile) 89 const patchLang = <Object>require(patchFile) 90 91 const combinedOpts = Object.assign(defaultOptions, {}) 92 const patched = patchEntries(defaultLang, patchLang, combinedOpts) 93 94 fs.writeFileSync(patchFile, JSON.stringify(patched)) 95}