@@ -4,6 +4,9 @@ import type { Options } from 'prettier';
44import { format } from 'prettier' ;
55import options from '../.prettierrc.cjs' ;
66import type { LocaleDefinition } from '../src' ;
7+ import { DEFINITIONS } from '../src/definitions' ;
8+
9+ // Constants
710
811const pathRoot = resolve ( __dirname , '..' ) ;
912const pathLocale = resolve ( pathRoot , 'src' , 'locale' ) ;
@@ -16,36 +19,58 @@ const pathDocsApiLocalization = resolve(
1619 'localization.md'
1720) ;
1821
19- const scriptCommand = 'pnpm run generate:locales' ;
2022const prettierTsOptions : Options = { ...options , parser : 'typescript' } ;
2123const prettierMdOptions : Options = { ...options , parser : 'markdown' } ;
2224
23- const locales = readdirSync ( pathLocales ) ;
24- locales . splice ( locales . indexOf ( 'index.ts' ) , 1 ) ;
25-
26- let localeIndexImports = "import type { LocaleDefinition } from '..';\n" ;
27- let localeIndexType = 'export type KnownLocale =\n' ;
28- let localeIndexLocales = 'const locales: KnownLocales = {\n' ;
29-
30- let localizationLocales = '| Locale | Name |\n| :--- | :--- |\n' ;
25+ const scriptCommand = 'pnpm run generate:locales' ;
3126
3227const autoGeneratedCommentHeader = `/*
3328 * This file is automatically generated.
3429 * Run '${ scriptCommand } ' to update.
3530 */` ;
3631
37- for ( const locale of locales ) {
38- // eslint-disable-next-line @typescript-eslint/no-var-requires
39- const localeDef : LocaleDefinition = require ( '../src/locales/' +
40- locale ) . default ;
41- const localeTitle = localeDef . title ;
32+ // Helper functions
4233
43- localeIndexImports += `import ${ locale } from './${ locale } ';\n` ;
44- localeIndexType += ` | '${ locale } '\n` ;
45- localeIndexLocales += ` ${ locale } ,\n` ;
46- localizationLocales += `| ${ locale } | ${ localeTitle } |\n` ;
34+ function removeIndexTs ( files : string [ ] ) : string [ ] {
35+ const index = files . indexOf ( 'index.ts' ) ;
36+ if ( index !== - 1 ) {
37+ files . splice ( index , 1 ) ;
38+ }
39+ return files ;
40+ }
4741
48- // src/locale/<locale>.ts
42+ function removeTsSuffix ( files : string [ ] ) : string [ ] {
43+ return files . map ( ( file ) => file . replace ( '.ts' , '' ) ) ;
44+ }
45+
46+ function escapeImport ( module : string ) : string {
47+ if ( module === 'name' ) {
48+ return 'name_' ;
49+ } else if ( module === 'type' ) {
50+ return 'type_' ;
51+ } else {
52+ return module ;
53+ }
54+ }
55+
56+ function escapeField ( module : string ) : string {
57+ if ( module === 'name' ) {
58+ return 'name: name_' ;
59+ } else if ( module === 'type' ) {
60+ return 'type: type_' ;
61+ } else {
62+ return module ;
63+ }
64+ }
65+
66+ function containsAll ( checked ?: string [ ] , expected ?: string [ ] ) : boolean {
67+ if ( typeof expected === 'undefined' || typeof checked === 'undefined' ) {
68+ return true ;
69+ }
70+ return expected . every ( ( c ) => checked . includes ( c ) ) ;
71+ }
72+
73+ function generateLocaleFile ( locale : string ) {
4974 let content = `
5075 ${ autoGeneratedCommentHeader }
5176
@@ -69,6 +94,106 @@ for (const locale of locales) {
6994 writeFileSync ( resolve ( pathLocale , locale + '.ts' ) , content ) ;
7095}
7196
97+ function generateLocalesIndexFile (
98+ path : string ,
99+ name : string ,
100+ type : string ,
101+ depth : number ,
102+ extra : string = '' ,
103+ expected ?: string [ ]
104+ ) {
105+ let modules = readdirSync ( path ) ;
106+ modules = removeIndexTs ( modules ) ;
107+ modules = removeTsSuffix ( modules ) ;
108+ const importType = type ;
109+ if ( ! containsAll ( modules , expected ) ) {
110+ type = `Partial<${ type } >` ;
111+ }
112+ let fieldType = '' ;
113+ let asType = '' ;
114+ if ( ! containsAll ( expected , modules ) ) {
115+ asType = ` as ${ type } ` ;
116+ } else {
117+ fieldType = `: ${ type } ` ;
118+ }
119+ let content = `${ autoGeneratedCommentHeader }
120+ import type { ${ importType } } from '..${ '/..' . repeat ( depth ) } ';
121+ ${ modules
122+ . map ( ( module ) => `import ${ escapeImport ( module ) } from './${ module } ';` )
123+ . join ( '\n' ) }
124+
125+ const ${ name } ${ fieldType } = {
126+ ${ extra }
127+ ${ modules . map ( ( module ) => `${ escapeField ( module ) } ,` ) . join ( '\n' ) }
128+ }${ asType } ;
129+
130+ export default ${ name } ;
131+ ` ;
132+ content = format ( content , prettierTsOptions ) ;
133+ writeFileSync ( resolve ( path , 'index.ts' ) , content ) ;
134+ }
135+
136+ // Start of actual logic
137+
138+ const locales = readdirSync ( pathLocales ) ;
139+ removeIndexTs ( locales ) ;
140+
141+ let localeIndexImports = "import type { LocaleDefinition } from '..';\n" ;
142+ let localeIndexType = 'export type KnownLocale =\n' ;
143+ let localeIndexLocales = 'const locales: KnownLocales = {\n' ;
144+
145+ let localizationLocales = '| Locale | Name |\n| :--- | :--- |\n' ;
146+
147+ for ( const locale of locales ) {
148+ // eslint-disable-next-line @typescript-eslint/no-var-requires
149+ const localeDef : LocaleDefinition = require ( '../src/locales/' +
150+ locale ) . default ;
151+ const localeTitle = localeDef . title ;
152+ const localeSeparator = localeDef . separator ;
153+
154+ localeIndexImports += `import ${ locale } from './${ locale } ';\n` ;
155+ localeIndexType += ` | '${ locale } '\n` ;
156+ localeIndexLocales += ` ${ locale } ,\n` ;
157+ localizationLocales += `| ${ locale } | ${ localeTitle } |\n` ;
158+
159+ // src/locale/<locale>.ts
160+ generateLocaleFile ( locale ) ;
161+
162+ // src/locales/<locale>/index.ts
163+ const pathModules = resolve ( pathLocales , locale ) ;
164+ generateLocalesIndexFile (
165+ pathModules ,
166+ locale ,
167+ 'LocaleDefinition' ,
168+ 1 ,
169+ `title: '${ localeTitle } ',` +
170+ ( localeSeparator ? `\nseparator: '${ localeSeparator } ',` : '' ) ,
171+ undefined
172+ ) ;
173+
174+ let modules = readdirSync ( pathModules ) ;
175+ modules = removeIndexTs ( modules ) ;
176+ modules = removeTsSuffix ( modules ) ;
177+ for ( const module of modules ) {
178+ // src/locales/<locale>/<module>/index.ts
179+ const pathModule = resolve ( pathModules , module ) ;
180+ const moduleFiles : string [ ] = DEFINITIONS [ module ] ;
181+ if ( typeof moduleFiles === 'undefined' ) {
182+ continue ;
183+ }
184+ generateLocalesIndexFile (
185+ pathModule ,
186+ module ,
187+ `${ module . replace ( / ( ^ | _ ) ( [ a - z ] ) / g, ( s ) =>
188+ s . replace ( '_' , '' ) . toUpperCase ( )
189+ ) } Definitions`,
190+ 2 ,
191+ '' ,
192+ moduleFiles
193+ ) ;
194+ }
195+ }
196+
72197// src/locales/index.ts
73198
74199let indexContent = `
@@ -86,7 +211,6 @@ let indexContent = `
86211 ` ;
87212
88213indexContent = format ( indexContent , prettierTsOptions ) ;
89-
90214writeFileSync ( pathLocalesIndex , indexContent ) ;
91215
92216// docs/api/localization.md
0 commit comments