[READ-ONLY] One Calendar is a privacy-first calendar web app built with Next.js. It has modern security features, including e2ee, password-protected sharing, and self-destructing share links 馃搮
calendar.xyehr.cn
nextjs
1.6 kB
50 lines
1import { promises as fs } from 'node:fs'
2import path from 'node:path'
3import { fileURLToPath } from 'node:url'
4
5const __filename = fileURLToPath(import.meta.url)
6const __dirname = path.dirname(__filename)
7const projectRoot = path.resolve(__dirname, '..')
8const localesDir = path.join(projectRoot, 'locales')
9const outputFile = path.join(projectRoot, 'lib', 'locales.ts')
10
11const toIdentifier = (value) =>
12 `locale${value.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase()).replace(/^[a-z]/, (chr) => chr.toUpperCase())}`
13
14const run = async () => {
15 const localeFiles = (await fs.readdir(localesDir))
16 .filter((file) => file.endsWith('.json'))
17 .sort((a, b) => a.localeCompare(b))
18
19 if (localeFiles.length === 0) {
20 throw new Error('No locale json files found in /locales')
21 }
22
23 const imports = localeFiles
24 .map((file) => {
25 const lang = file.replace(/\.json$/, '')
26 const identifier = toIdentifier(lang)
27 return `import ${identifier} from "@/locales/${file}"`
28 })
29 .join('\n')
30
31 const entries = localeFiles
32 .map((file) => {
33 const lang = file.replace(/\.json$/, '')
34 const identifier = toIdentifier(lang)
35 return ` "${lang}": ${identifier},`
36 })
37 .join('\n')
38
39 const content = `${imports}\n\nexport const translations = {\n${entries}\n} as const\n\nexport type Language = keyof typeof translations\n`
40
41 await fs.writeFile(outputFile, content, 'utf8')
42 console.log(
43 `Generated ${path.relative(projectRoot, outputFile)} with ${localeFiles.length} locale(s).`,
44 )
45}
46
47run().catch((error) => {
48 console.error(error)
49 process.exit(1)
50})