11import { exec } from 'child_process' ;
22import { existsSync } from 'fs' ;
3- import { appendFile , cp , mkdir , readFile , writeFile } from 'fs/promises' ;
3+ import { appendFile , cp , mkdir , readdir , readFile , writeFile } from 'fs/promises' ;
44import path from 'path' ;
5+ import { fileURLToPath } from 'url' ;
56
67import { svelte } from '@sveltejs/vite-plugin-svelte' ;
78import { isObject } from '@sveltia/utils/object' ;
@@ -26,6 +27,14 @@ const MAIN_TYPE_PATH = 'package/main.d.ts';
2627 * Path to the generated public type declaration file.
2728 */
2829const PUBLIC_TYPE_PATH = 'package/types/public.d.ts' ;
30+ /**
31+ * Path to the app’s locale files.
32+ */
33+ const APP_LOCALES_DIR = 'src/lib/locales' ;
34+ /**
35+ * Path to the generated locale files.
36+ */
37+ const OUTPUT_LOCALES_DIR = 'package/locales' ;
2938
3039/**
3140 * Recursively squash multiline strings in a parsed YAML object into single lines.
@@ -109,7 +118,7 @@ const copyPackageFiles = () => ({
109118 devDependencies : Object . fromEntries (
110119 DEV_DEPENDENCIES . map ( ( key ) => [ key , dependencies [ key ] ?? devDependencies [ key ] ] ) ,
111120 ) ,
112- files : [ 'dist' , 'schema' , 'services' , 'types' , 'main.d.ts' ] ,
121+ files : [ 'dist' , 'locales' , ' schema', 'services' , 'types' , 'main.d.ts' ] ,
113122 main : './dist/sveltia-cms.mjs' ,
114123 module : './dist/sveltia-cms.mjs' ,
115124 exports : {
@@ -216,7 +225,54 @@ const generateSchema = async () => {
216225} ;
217226
218227/**
219- * Generate extra files such as TypeScript type declaration and JSON schema.
228+ * Read a YAML file and parse it, stripping comments and squashing multiline strings, just like the
229+ * {@link yamlToJS} plugin does for imported YAML files.
230+ * @param {string } filePath Path to the YAML file.
231+ * @returns {Promise<Record<string, any>> } Parsed object.
232+ */
233+ const parseYAMLFile = async ( filePath ) =>
234+ /** @type {Record<string, any> } */ ( squashStrings ( parseYAML ( await readFile ( filePath , 'utf-8' ) ) ) ) ;
235+
236+ /**
237+ * Generate JSON locale files from the YAML sources. The Sveltia CMS strings are merged with the
238+ * Sveltia UI strings, the latter being prefixed with `_sui`, in the same way as `initAppLocale`
239+ * does at runtime. These files are published so that developers can look up the string keys, for
240+ * example to override some strings with the `i18n` option.
241+ * @see https://unpkg.com/@sveltia/cms/locales/en-US.json - Our published locale file
242+ */
243+ const generateLocales = async ( ) => {
244+ // Resolve the path to the locale files bundled with the `@sveltia/ui` package
245+ const uiLocalesDir = path . resolve (
246+ path . dirname ( fileURLToPath ( import . meta. resolve ( '@sveltia/ui' ) ) ) ,
247+ 'locales' ,
248+ ) ;
249+
250+ const locales = ( await readdir ( APP_LOCALES_DIR ) )
251+ . filter ( ( name ) => name . endsWith ( '.yaml' ) )
252+ . map ( ( name ) => path . basename ( name , '.yaml' ) ) ;
253+
254+ await mkdir ( OUTPUT_LOCALES_DIR , { recursive : true } ) ;
255+
256+ await Promise . all (
257+ locales . map ( async ( locale ) => {
258+ const uiLocalePath = path . resolve ( uiLocalesDir , `${ locale } .yaml` ) ;
259+
260+ const [ appStrings , componentStrings ] = await Promise . all ( [
261+ parseYAMLFile ( path . resolve ( APP_LOCALES_DIR , `${ locale } .yaml` ) ) ,
262+ // Sveltia UI may not have the locale yet
263+ existsSync ( uiLocalePath ) ? parseYAMLFile ( uiLocalePath ) : { } ,
264+ ] ) ;
265+
266+ await writeFile (
267+ path . resolve ( OUTPUT_LOCALES_DIR , `${ locale } .json` ) ,
268+ JSON . stringify ( { ...appStrings , _sui : componentStrings } ) . concat ( '\n' ) ,
269+ ) ;
270+ } ) ,
271+ ) ;
272+ } ;
273+
274+ /**
275+ * Generate extra files such as TypeScript type declaration, JSON schema and JSON locales.
220276 * @returns {import('vite').Plugin } Vite plugin.
221277 */
222278const generateExtraFiles = ( ) => ( {
@@ -229,6 +285,7 @@ const generateExtraFiles = () => ({
229285 handler : async ( ) => {
230286 await generateTypes ( ) ;
231287 await generateSchema ( ) ;
288+ await generateLocales ( ) ;
232289 } ,
233290 } ,
234291} ) ;
0 commit comments