unoffical wafrn mirror
wafrn.net
atproto
social-network
activitypub
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}