@intlayer/engine 9.5.12 → 9.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/installSkills/skills/cli.md +28 -1
- package/dist/assets/installSkills/skills/compat.md +1 -1
- package/dist/assets/installSkills/skills/dev-tools.md +8 -6
- package/dist/cjs/build.cjs +12 -2
- package/dist/cjs/buildIntlayerDictionary/buildIntlayerDictionary.cjs +12 -11
- package/dist/cjs/buildIntlayerDictionary/buildIntlayerDictionary.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/index.cjs +4 -1
- package/dist/cjs/buildIntlayerDictionary/rebuildUnmergedDictionaries.cjs +23 -0
- package/dist/cjs/buildIntlayerDictionary/rebuildUnmergedDictionaries.cjs.map +1 -0
- package/dist/cjs/cli.cjs +12 -0
- package/dist/cjs/fetchDistantDictionaries.cjs.map +1 -1
- package/dist/cjs/handleAdditionalContentDeclarationFile.cjs +1 -1
- package/dist/cjs/handleContentDeclarationFileChange.cjs +1 -1
- package/dist/cjs/handleUnlinkedContentDeclarationFile.cjs +1 -1
- package/dist/cjs/init/cms.cjs +18 -0
- package/dist/cjs/init/cms.cjs.map +1 -1
- package/dist/cjs/init/index.cjs +23 -10
- package/dist/cjs/init/index.cjs.map +1 -1
- package/dist/cjs/init/utils/configManipulation.cjs +28 -0
- package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
- package/dist/cjs/init/utils/contentLayout.cjs +61 -0
- package/dist/cjs/init/utils/contentLayout.cjs.map +1 -0
- package/dist/cjs/init/utils/index.cjs +1 -0
- package/dist/cjs/init/utils/packageManager.cjs +1 -1
- package/dist/cjs/init/utils/packageManager.cjs.map +1 -1
- package/dist/cjs/installMCP/installMCP.cjs +35 -25
- package/dist/cjs/installMCP/installMCP.cjs.map +1 -1
- package/dist/cjs/installSkills/index.cjs +26 -1
- package/dist/cjs/installSkills/index.cjs.map +1 -1
- package/dist/cjs/listDictionariesPath.cjs +2 -5
- package/dist/cjs/listDictionariesPath.cjs.map +1 -1
- package/dist/cjs/listGitFiles.cjs +3 -5
- package/dist/cjs/listGitFiles.cjs.map +1 -1
- package/dist/cjs/listProjects.cjs +1 -2
- package/dist/cjs/listProjects.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/index.cjs +1 -1
- package/dist/cjs/loadDictionaries/loadDictionaries.cjs +1 -1
- package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs.map +1 -1
- package/dist/cjs/utils/buildComponentFilesList.cjs +18 -30
- package/dist/cjs/utils/buildComponentFilesList.cjs.map +1 -1
- package/dist/cjs/utils/chunkJSON.cjs +1 -1
- package/dist/cjs/utils/chunkJSON.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +2 -0
- package/dist/cjs/utils/isDirectoryExcluded.cjs +36 -0
- package/dist/cjs/utils/isDirectoryExcluded.cjs.map +1 -0
- package/dist/cjs/watcher.cjs +5 -2
- package/dist/cjs/watcher.cjs.map +1 -1
- package/dist/cjs/writeConfiguration/index.cjs +23 -0
- package/dist/cjs/writeConfiguration/index.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/index.cjs +6 -0
- package/dist/cjs/writeContentDeclaration/processContentDeclarationContent.cjs +20 -13
- package/dist/cjs/writeContentDeclaration/processContentDeclarationContent.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/renderContentDeclaration.cjs +213 -0
- package/dist/cjs/writeContentDeclaration/renderContentDeclaration.cjs.map +1 -0
- package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs +5 -51
- package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs +2 -31
- package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs +2 -8
- package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs.map +1 -1
- package/dist/esm/build.mjs +7 -5
- package/dist/esm/buildIntlayerDictionary/buildIntlayerDictionary.mjs +12 -12
- package/dist/esm/buildIntlayerDictionary/buildIntlayerDictionary.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/index.mjs +3 -2
- package/dist/esm/buildIntlayerDictionary/rebuildUnmergedDictionaries.mjs +22 -0
- package/dist/esm/buildIntlayerDictionary/rebuildUnmergedDictionaries.mjs.map +1 -0
- package/dist/esm/cli.mjs +5 -3
- package/dist/esm/fetchDistantDictionaries.mjs.map +1 -1
- package/dist/esm/handleAdditionalContentDeclarationFile.mjs +1 -1
- package/dist/esm/handleContentDeclarationFileChange.mjs +1 -1
- package/dist/esm/handleUnlinkedContentDeclarationFile.mjs +1 -1
- package/dist/esm/init/cms.mjs +19 -2
- package/dist/esm/init/cms.mjs.map +1 -1
- package/dist/esm/init/index.mjs +24 -11
- package/dist/esm/init/index.mjs.map +1 -1
- package/dist/esm/init/utils/configManipulation.mjs +28 -1
- package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
- package/dist/esm/init/utils/contentLayout.mjs +58 -0
- package/dist/esm/init/utils/contentLayout.mjs.map +1 -0
- package/dist/esm/init/utils/index.mjs +2 -2
- package/dist/esm/init/utils/packageManager.mjs +1 -1
- package/dist/esm/init/utils/packageManager.mjs.map +1 -1
- package/dist/esm/installMCP/installMCP.mjs +35 -25
- package/dist/esm/installMCP/installMCP.mjs.map +1 -1
- package/dist/esm/installSkills/index.mjs +27 -3
- package/dist/esm/installSkills/index.mjs.map +1 -1
- package/dist/esm/listDictionariesPath.mjs +2 -5
- package/dist/esm/listDictionariesPath.mjs.map +1 -1
- package/dist/esm/listGitFiles.mjs +1 -1
- package/dist/esm/listGitFiles.mjs.map +1 -1
- package/dist/esm/listProjects.mjs +1 -1
- package/dist/esm/listProjects.mjs.map +1 -1
- package/dist/esm/loadDictionaries/index.mjs +1 -1
- package/dist/esm/loadDictionaries/loadDictionaries.mjs +1 -1
- package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs.map +1 -1
- package/dist/esm/utils/buildComponentFilesList.mjs +19 -31
- package/dist/esm/utils/buildComponentFilesList.mjs.map +1 -1
- package/dist/esm/utils/chunkJSON.mjs +1 -1
- package/dist/esm/utils/chunkJSON.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +2 -1
- package/dist/esm/utils/isDirectoryExcluded.mjs +35 -0
- package/dist/esm/utils/isDirectoryExcluded.mjs.map +1 -0
- package/dist/esm/utils/runParallel/pidTree.mjs +3 -3
- package/dist/esm/utils/runParallel/pidTree.mjs.map +1 -1
- package/dist/esm/utils/runParallel/ps.mjs +2 -2
- package/dist/esm/utils/runParallel/ps.mjs.map +1 -1
- package/dist/esm/utils/runParallel/wmic.mjs +2 -2
- package/dist/esm/utils/runParallel/wmic.mjs.map +1 -1
- package/dist/esm/watcher.mjs +5 -2
- package/dist/esm/watcher.mjs.map +1 -1
- package/dist/esm/writeConfiguration/index.mjs +23 -1
- package/dist/esm/writeConfiguration/index.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/index.mjs +2 -1
- package/dist/esm/writeContentDeclaration/processContentDeclarationContent.mjs +20 -13
- package/dist/esm/writeContentDeclaration/processContentDeclarationContent.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/renderContentDeclaration.mjs +208 -0
- package/dist/esm/writeContentDeclaration/renderContentDeclaration.mjs.map +1 -0
- package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs +5 -51
- package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs +2 -31
- package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeYamlFile.mjs +2 -8
- package/dist/esm/writeContentDeclaration/writeYamlFile.mjs.map +1 -1
- package/dist/types/build.d.ts +5 -3
- package/dist/types/buildIntlayerDictionary/buildIntlayerDictionary.d.ts +6 -0
- package/dist/types/buildIntlayerDictionary/buildIntlayerDictionary.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/index.d.ts +3 -2
- package/dist/types/buildIntlayerDictionary/rebuildUnmergedDictionaries.d.ts +14 -0
- package/dist/types/buildIntlayerDictionary/rebuildUnmergedDictionaries.d.ts.map +1 -0
- package/dist/types/cli.d.ts +6 -4
- package/dist/types/fetchDistantDictionaries.d.ts +1 -1
- package/dist/types/fetchDistantDictionaries.d.ts.map +1 -1
- package/dist/types/init/cms.d.ts +6 -0
- package/dist/types/init/cms.d.ts.map +1 -1
- package/dist/types/init/index.d.ts +15 -14
- package/dist/types/init/index.d.ts.map +1 -1
- package/dist/types/init/utils/configManipulation.d.ts +8 -0
- package/dist/types/init/utils/configManipulation.d.ts.map +1 -1
- package/dist/types/init/utils/contentLayout.d.ts +42 -0
- package/dist/types/init/utils/contentLayout.d.ts.map +1 -0
- package/dist/types/init/utils/index.d.ts +2 -2
- package/dist/types/init/utils/packageManager.d.ts +9 -3
- package/dist/types/init/utils/packageManager.d.ts.map +1 -1
- package/dist/types/installMCP/installMCP.d.ts +4 -0
- package/dist/types/installMCP/installMCP.d.ts.map +1 -1
- package/dist/types/installSkills/index.d.ts +6 -0
- package/dist/types/installSkills/index.d.ts.map +1 -1
- package/dist/types/listDictionariesPath.d.ts +1 -1
- package/dist/types/listDictionariesPath.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadRemoteDictionaries.d.ts +1 -1
- package/dist/types/loadDictionaries/loadRemoteDictionaries.d.ts.map +1 -1
- package/dist/types/utils/buildComponentFilesList.d.ts +6 -6
- package/dist/types/utils/buildComponentFilesList.d.ts.map +1 -1
- package/dist/types/utils/chunkJSON.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +2 -1
- package/dist/types/utils/isDirectoryExcluded.d.ts +15 -0
- package/dist/types/utils/isDirectoryExcluded.d.ts.map +1 -0
- package/dist/types/watcher.d.ts.map +1 -1
- package/dist/types/writeConfiguration/index.d.ts +13 -0
- package/dist/types/writeConfiguration/index.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/index.d.ts +2 -1
- package/dist/types/writeContentDeclaration/processContentDeclarationContent.d.ts +8 -2
- package/dist/types/writeContentDeclaration/processContentDeclarationContent.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/renderContentDeclaration.d.ts +61 -0
- package/dist/types/writeContentDeclaration/renderContentDeclaration.d.ts.map +1 -0
- package/dist/types/writeContentDeclaration/writeContentDeclaration.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/writeMarkdownFile.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/writeYamlFile.d.ts.map +1 -1
- package/package.json +18 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeContentDeclaration.cjs","names":["processContentDeclarationContent","getPerLocaleDictionary","getFilteredLocalesDictionary","extname","getFormatFromExtension","COMPILER_NO_METADATA","join","readDictionariesFromDisk","isDeepStrictEqual","resolve","dirname","mkdir","writeMarkdownFile","writeYamlFile","existsSync","readFile","transformJSONFile","basename","writeFile","rename","rm","detectFormatCommand","writeJSFile"],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { COMPILER_NO_METADATA } from '@intlayer/config/defaultValues';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\nimport { writeMarkdownFile } from './writeMarkdownFile';\nimport { writeYamlFile } from './writeYamlFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n // Build result from the original dictionary so that extra user-defined fields\n // (e.g. custom frontmatter in markdown files) are preserved.\n // Strip internal-only fields that must never appear in persisted output.\n const INTERNAL_FIELDS = new Set([\n '$schema',\n 'filePath',\n 'localId',\n 'localIds',\n 'projectIds',\n ]);\n\n const preservedFields = Object.fromEntries(\n Object.entries(dictionary as Record<string, unknown>).filter(\n ([k]) => !INTERNAL_FIELDS.has(k)\n )\n );\n\n let result: Dictionary = {\n ...preservedFields,\n content,\n } as Dictionary;\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { system, compiler } = configuration;\n const { baseDir } = system;\n\n const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.system.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(configuration.system.baseDir, dictionary.filePath);\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n noMetadata?: boolean\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n\n if (extension === '.md' || extension === '.mdx') {\n await writeMarkdownFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n if (extension === '.yaml' || extension === '.yml') {\n await writeYamlFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n // Handle JSON, JSONC, and JSON5 via the AST transformer\n if (['.json', '.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(\n fileContent,\n dictionary,\n noMetadata\n );\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n return;\n }\n\n const knownJsExtensions = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n ]);\n\n if (!knownJsExtensions.has(extension)) {\n // Unknown extension (e.g. .po managed by a plugin) — skip; the plugin\n // owns this file format and writeJSFile / prettier would corrupt it.\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"writeContentDeclaration.cjs","names":["COMPILER_NO_METADATA","join","readDictionariesFromDisk","formatContentDeclaration","isDeepStrictEqual","resolve","dirname","mkdir","extname","writeMarkdownFile","writeYamlFile","existsSync","readFile","transformJSONFile","basename","writeFile","rename","rm","detectFormatCommand","writeJSFile"],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { COMPILER_NO_METADATA } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { formatContentDeclaration } from './renderContentDeclaration';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\nimport { writeMarkdownFile } from './writeMarkdownFile';\nimport { writeYamlFile } from './writeYamlFile';\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { system, compiler } = configuration;\n const { baseDir } = system;\n\n const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n { configuration, localeList }\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.system.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(configuration.system.baseDir, dictionary.filePath);\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n noMetadata?: boolean\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n\n if (extension === '.md' || extension === '.mdx') {\n await writeMarkdownFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n if (extension === '.yaml' || extension === '.yml') {\n await writeYamlFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n // Handle JSON, JSONC, and JSON5 via the AST transformer\n if (['.json', '.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(\n fileContent,\n dictionary,\n noMetadata\n );\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n return;\n }\n\n const knownJsExtensions = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n ]);\n\n if (!knownJsExtensions.has(extension)) {\n // Unknown extension (e.g. .po managed by a plugin) — skip; the plugin\n // owns this file format and writeJSFile / prettier would corrupt it.\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
|
|
@@ -1,42 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_detectFormatCommand = require('../detectFormatCommand.cjs');
|
|
3
|
+
const require_writeContentDeclaration_renderContentDeclaration = require('./renderContentDeclaration.cjs');
|
|
3
4
|
let node_path = require("node:path");
|
|
4
|
-
let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
let node_child_process = require("node:child_process");
|
|
7
7
|
|
|
8
8
|
//#region src/writeContentDeclaration/writeMarkdownFile.ts
|
|
9
|
-
const stringifyYamlFrontmatter = (fields) => Object.entries(fields).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => {
|
|
10
|
-
if (Array.isArray(value)) return `${key}:\n${value.map((item) => ` - ${JSON.stringify(item)}`).join("\n")}`;
|
|
11
|
-
if (typeof value === "string" && (value.includes(":") || value.includes("\n") || value.includes("#"))) return `${key}: ${JSON.stringify(value)}`;
|
|
12
|
-
return `${key}: ${value}`;
|
|
13
|
-
}).join("\n");
|
|
14
|
-
const getMarkdownBody = (content) => {
|
|
15
|
-
const lines = content.split(/\r?\n/);
|
|
16
|
-
const firstNonEmptyIndex = lines.findIndex((line) => line.trim() !== "");
|
|
17
|
-
if (firstNonEmptyIndex === -1 || lines[firstNonEmptyIndex]?.trim() !== "---") return content;
|
|
18
|
-
let endIndex = -1;
|
|
19
|
-
for (let i = firstNonEmptyIndex + 1; i < lines.length; i++) if (lines[i]?.trim() === "---") {
|
|
20
|
-
endIndex = i;
|
|
21
|
-
break;
|
|
22
|
-
}
|
|
23
|
-
if (endIndex === -1) return content;
|
|
24
|
-
return lines.slice(endIndex + 1).join("\n").trimStart();
|
|
25
|
-
};
|
|
26
|
-
const EXCLUDED_FRONTMATTER_KEYS = /* @__PURE__ */ new Set([
|
|
27
|
-
"content",
|
|
28
|
-
"$schema",
|
|
29
|
-
"filePath",
|
|
30
|
-
"localId",
|
|
31
|
-
"localIds",
|
|
32
|
-
"projectIds"
|
|
33
|
-
]);
|
|
34
9
|
const writeMarkdownFile = async (absoluteFilePath, dictionary, configuration) => {
|
|
35
|
-
const
|
|
36
|
-
const markdownRaw = typeof content === "object" && content?.nodeType === _intlayer_types_nodeType.MARKDOWN ? content[_intlayer_types_nodeType.MARKDOWN] ?? "" : "";
|
|
37
|
-
const markdownBody = getMarkdownBody(markdownRaw);
|
|
38
|
-
const frontmatterFields = Object.fromEntries(Object.entries(dictionary).filter(([k, v]) => !EXCLUDED_FRONTMATTER_KEYS.has(k) && v !== void 0));
|
|
39
|
-
const fileContent = `---\n${stringifyYamlFrontmatter(frontmatterFields)}\n---\n\n${markdownBody}`;
|
|
10
|
+
const fileContent = require_writeContentDeclaration_renderContentDeclaration.renderMarkdownContentDeclaration(dictionary);
|
|
40
11
|
const dir = (0, node_path.dirname)(absoluteFilePath);
|
|
41
12
|
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
|
|
42
13
|
const tempDir = configuration.system?.tempDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeMarkdownFile.cjs","names":["
|
|
1
|
+
{"version":3,"file":"writeMarkdownFile.cjs","names":["renderMarkdownContentDeclaration","dirname","mkdir","basename","join","writeFile","rename","rm","detectFormatCommand"],"sources":["../../../src/writeContentDeclaration/writeMarkdownFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport { renderMarkdownContentDeclaration } from './renderContentDeclaration';\n\nexport const writeMarkdownFile = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const fileContent = renderMarkdownContentDeclaration(dictionary);\n\n const dir = dirname(absoluteFilePath);\n await mkdir(dir, { recursive: true });\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) await mkdir(tempDir, { recursive: true });\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n\n try {\n await writeFile(tempPath, fileContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":";;;;;;;;AAQA,MAAa,oBAAoB,OAC/B,kBACA,YACA,kBACkB;CAClB,MAAM,cAAcA,0FAAiC,UAAU;CAE/D,MAAM,UAAMC,mBAAQ,gBAAgB;CACpC,UAAMC,wBAAM,KAAK,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,QAAQ;CACtC,IAAI,SAAS,UAAMA,wBAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CAErD,MAAM,eAAe,OAAGC,oBAAS,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;CACxG,MAAM,WAAW,cACbC,gBAAK,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;CAE3B,IAAI;EACF,UAAMC,4BAAU,UAAU,aAAa,OAAO;EAC9C,UAAMC,yBAAO,UAAU,gBAAgB;CACzC,SAAS,OAAO;EACd,IAAI;GACF,UAAMC,qBAAG,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAER;EACA,MAAM;CACR;CAEA,MAAM,gBAAgBC,gDAAoB,aAAa;CACvD,IAAI,eACF,IAAI;EACF,iCAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;GAC5D,OAAO;GACP,KAAK,cAAc,OAAO;EAC5B,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;AAEJ"}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_detectFormatCommand = require('../detectFormatCommand.cjs');
|
|
3
|
+
const require_writeContentDeclaration_renderContentDeclaration = require('./renderContentDeclaration.cjs');
|
|
3
4
|
let node_path = require("node:path");
|
|
4
5
|
let node_fs_promises = require("node:fs/promises");
|
|
5
6
|
let node_child_process = require("node:child_process");
|
|
6
|
-
let _intlayer_core_utils = require("@intlayer/core/utils");
|
|
7
7
|
|
|
8
8
|
//#region src/writeContentDeclaration/writeYamlFile.ts
|
|
9
|
-
const EXCLUDED_YAML_KEYS = /* @__PURE__ */ new Set([
|
|
10
|
-
"$schema",
|
|
11
|
-
"id",
|
|
12
|
-
"filePath"
|
|
13
|
-
]);
|
|
14
9
|
const writeYamlFile = async (absoluteFilePath, dictionary, configuration) => {
|
|
15
|
-
const
|
|
16
|
-
const fileContent = (0, _intlayer_core_utils.stringifyYaml)(filtered);
|
|
10
|
+
const fileContent = require_writeContentDeclaration_renderContentDeclaration.renderYamlContentDeclaration(dictionary);
|
|
17
11
|
const dir = (0, node_path.dirname)(absoluteFilePath);
|
|
18
12
|
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
|
|
19
13
|
const tempDir = configuration.system?.tempDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeYamlFile.cjs","names":["
|
|
1
|
+
{"version":3,"file":"writeYamlFile.cjs","names":["renderYamlContentDeclaration","dirname","mkdir","basename","join","writeFile","rename","rm","detectFormatCommand"],"sources":["../../../src/writeContentDeclaration/writeYamlFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport { renderYamlContentDeclaration } from './renderContentDeclaration';\n\nexport const writeYamlFile = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const fileContent = renderYamlContentDeclaration(dictionary);\n\n const dir = dirname(absoluteFilePath);\n await mkdir(dir, { recursive: true });\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) await mkdir(tempDir, { recursive: true });\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n\n try {\n await writeFile(tempPath, fileContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":";;;;;;;;AAQA,MAAa,gBAAgB,OAC3B,kBACA,YACA,kBACkB;CAClB,MAAM,cAAcA,sFAA6B,UAAU;CAE3D,MAAM,UAAMC,mBAAQ,gBAAgB;CACpC,UAAMC,wBAAM,KAAK,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,QAAQ;CACtC,IAAI,SAAS,UAAMA,wBAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CAErD,MAAM,eAAe,OAAGC,oBAAS,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE;CACxG,MAAM,WAAW,cACbC,gBAAK,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;CAE3B,IAAI;EACF,UAAMC,4BAAU,UAAU,aAAa,OAAO;EAC9C,UAAMC,yBAAO,UAAU,gBAAgB;CACzC,SAAS,OAAO;EACd,IAAI;GACF,UAAMC,qBAAG,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAER;EACA,MAAM;CACR;CAEA,MAAM,gBAAgBC,gDAAoB,aAAa;CACvD,IAAI,eACF,IAAI;EACF,iCAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;GAC5D,OAAO;GACP,KAAK,cAAc,OAAO;EAC5B,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;AAEJ"}
|
package/dist/esm/build.mjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { readDictionariesFromDisk } from "./utils/readDictionariesFromDisk.mjs";
|
|
2
|
-
import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
|
|
2
|
+
import { addStoredSiblingDictionaries, buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
|
|
3
3
|
import { processContentDeclaration } from "./buildIntlayerDictionary/processContentDeclaration.mjs";
|
|
4
|
+
import { ensureIntlayerBundle, formatLocalDictionaries, loadContentDeclaration, loadContentDeclarations } from "./loadDictionaries/loadContentDeclaration.mjs";
|
|
5
|
+
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
6
|
+
import { rebuildUnmergedDictionaries } from "./buildIntlayerDictionary/rebuildUnmergedDictionaries.mjs";
|
|
4
7
|
import { cleanOutputDir } from "./cleanOutputDir.mjs";
|
|
5
8
|
import { generateDictionaryListContent } from "./createDictionaryEntryPoint/generateDictionaryListContent.mjs";
|
|
6
9
|
import { getBuiltDictionariesPath } from "./createDictionaryEntryPoint/getBuiltDictionariesPath.mjs";
|
|
@@ -12,16 +15,15 @@ import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createD
|
|
|
12
15
|
import { createModuleAugmentation, formatDomains, formatRewriteRules, getTypeName } from "./createType/createModuleAugmentation.mjs";
|
|
13
16
|
import { createTypes, generateTypeScriptType } from "./createType/createType.mjs";
|
|
14
17
|
import { formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput } from "./formatDictionary.mjs";
|
|
15
|
-
import { ensureIntlayerBundle, formatLocalDictionaries, loadContentDeclaration, loadContentDeclarations } from "./loadDictionaries/loadContentDeclaration.mjs";
|
|
16
18
|
import { formatDistantDictionaries, loadRemoteDictionaries } from "./loadDictionaries/loadRemoteDictionaries.mjs";
|
|
17
19
|
import { loadDictionaries } from "./loadDictionaries/loadDictionaries.mjs";
|
|
18
|
-
import {
|
|
19
|
-
import { isCachedConfigurationUpToDate, writeConfiguration } from "./writeConfiguration/index.mjs";
|
|
20
|
+
import { isCachedConfigurationUpToDate, overrideBuiltEditorConfiguration, writeConfiguration } from "./writeConfiguration/index.mjs";
|
|
20
21
|
import { prepareIntlayer } from "./prepareIntlayer.mjs";
|
|
21
22
|
import { INTLAYER_WATCH_ENV_VAR, getIsDevWatcherCommand, getIsServerDevelopment, prepareIntlayerServer } from "./prepareIntlayerServer.mjs";
|
|
22
23
|
import { detectExportedComponentName } from "./writeContentDeclaration/detectExportedComponentName.mjs";
|
|
23
24
|
import { transformJSFile } from "./writeContentDeclaration/transformJSFile.mjs";
|
|
25
|
+
import { formatContentDeclaration, isRenderableContentDeclarationPath, renderContentDeclaration, renderMarkdownContentDeclaration, renderYamlContentDeclaration } from "./writeContentDeclaration/renderContentDeclaration.mjs";
|
|
24
26
|
import { writeJSFile } from "./writeContentDeclaration/writeJSFile.mjs";
|
|
25
27
|
import { writeContentDeclaration } from "./writeContentDeclaration/writeContentDeclaration.mjs";
|
|
26
28
|
|
|
27
|
-
export { INTLAYER_WATCH_ENV_VAR, buildDictionary, cleanOutputDir, createDictionaryEntryPoint, createModuleAugmentation, createTypes, detectExportedComponentName, ensureIntlayerBundle, formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput, formatDistantDictionaries, formatDomains, formatLocalDictionaries, formatRewriteRules, generateDictionaryListContent, generateTypeScriptType, getBuiltDictionariesPath, getBuiltDynamicDictionariesPath, getBuiltFetchDictionariesPath, getBuiltRemoteDictionariesPath, getBuiltUnmergedDictionariesPath, getIsDevWatcherCommand, getIsServerDevelopment, getTypeName, isCachedConfigurationUpToDate, loadContentDeclaration, loadContentDeclarations, loadDictionaries, loadLocalDictionaries, loadRemoteDictionaries, prepareIntlayer, prepareIntlayerServer, processContentDeclaration, readDictionariesFromDisk, transformJSFile, writeConfiguration, writeContentDeclaration, writeJSFile };
|
|
29
|
+
export { INTLAYER_WATCH_ENV_VAR, addStoredSiblingDictionaries, buildDictionary, cleanOutputDir, createDictionaryEntryPoint, createModuleAugmentation, createTypes, detectExportedComponentName, ensureIntlayerBundle, formatContentDeclaration, formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput, formatDistantDictionaries, formatDomains, formatLocalDictionaries, formatRewriteRules, generateDictionaryListContent, generateTypeScriptType, getBuiltDictionariesPath, getBuiltDynamicDictionariesPath, getBuiltFetchDictionariesPath, getBuiltRemoteDictionariesPath, getBuiltUnmergedDictionariesPath, getIsDevWatcherCommand, getIsServerDevelopment, getTypeName, isCachedConfigurationUpToDate, isRenderableContentDeclarationPath, loadContentDeclaration, loadContentDeclarations, loadDictionaries, loadLocalDictionaries, loadRemoteDictionaries, overrideBuiltEditorConfiguration, prepareIntlayer, prepareIntlayerServer, processContentDeclaration, readDictionariesFromDisk, rebuildUnmergedDictionaries, renderContentDeclaration, renderMarkdownContentDeclaration, renderYamlContentDeclaration, transformJSFile, writeConfiguration, writeContentDeclaration, writeJSFile };
|
|
@@ -15,6 +15,16 @@ const defaultOptions = {
|
|
|
15
15
|
env: "dev"
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
|
+
* Appends the already-built declarations sharing a key with
|
|
19
|
+
* `localDictionaries` (other `localId`), so a partial rebuild does not drop
|
|
20
|
+
* the declarations coming from other content files.
|
|
21
|
+
*/
|
|
22
|
+
const addStoredSiblingDictionaries = (localDictionaries, configuration) => {
|
|
23
|
+
const storedUnmergedDictionaries = readDictionariesFromDisk(configuration.system.unmergedDictionariesDir);
|
|
24
|
+
const siblingDictionaries = localDictionaries.flatMap((localDictionary) => (storedUnmergedDictionaries[localDictionary.key] ?? []).filter((storedDictionary) => storedDictionary.localId !== localDictionary.localId));
|
|
25
|
+
return [...localDictionaries, ...siblingDictionaries];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
18
28
|
* This function transpile the bundled code to to make dictionaries as JSON files
|
|
19
29
|
*/
|
|
20
30
|
const buildDictionary = async (localDictionariesEntries, configuration, options) => {
|
|
@@ -23,17 +33,7 @@ const buildDictionary = async (localDictionariesEntries, configuration, options)
|
|
|
23
33
|
...defaultOptions,
|
|
24
34
|
...options
|
|
25
35
|
};
|
|
26
|
-
const unmergedDictionariesToUpdate = [...localDictionariesEntries];
|
|
27
|
-
if (importOtherDictionaries) {
|
|
28
|
-
const prevUnmergedDictionaries = readDictionariesFromDisk(configuration.system.unmergedDictionariesDir);
|
|
29
|
-
for (const dictionaryToWrite of localDictionariesEntries) {
|
|
30
|
-
const allPrebuiltUnmergedDictionaries = prevUnmergedDictionaries[dictionaryToWrite.key];
|
|
31
|
-
if (allPrebuiltUnmergedDictionaries?.length > 0) {
|
|
32
|
-
const otherUnmergedDictionaries = allPrebuiltUnmergedDictionaries?.filter((unmergedDictionary) => unmergedDictionary.localId !== dictionaryToWrite.localId);
|
|
33
|
-
unmergedDictionariesToUpdate.push(...otherUnmergedDictionaries ?? []);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
36
|
+
const unmergedDictionariesToUpdate = importOtherDictionaries ? addStoredSiblingDictionaries(localDictionariesEntries, configuration) : [...localDictionariesEntries];
|
|
37
37
|
const unmergedDictionaries = await writeUnmergedDictionaries(unmergedDictionariesToUpdate, configuration, env);
|
|
38
38
|
const mergedDictionaries = await writeMergedDictionaries(unmergedDictionaries, configuration);
|
|
39
39
|
const nestedDictionaryGraph = getNestedDictionaryGraph(Object.values(readDictionariesFromDisk(configuration.system.dictionariesDir)));
|
|
@@ -86,5 +86,5 @@ const buildDictionary = async (localDictionariesEntries, configuration, options)
|
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
//#endregion
|
|
89
|
-
export { buildDictionary };
|
|
89
|
+
export { addStoredSiblingDictionaries, buildDictionary };
|
|
90
90
|
//# sourceMappingURL=buildIntlayerDictionary.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildIntlayerDictionary.mjs","names":[],"sources":["../../../src/buildIntlayerDictionary/buildIntlayerDictionary.ts"],"sourcesContent":["import { IMPORT_MODE, OUTPUT_FORMAT } from '@intlayer/config/defaultValues';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport {\n getNestedDictionaryGraph,\n isQualifiedDictionaryGroup,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport {\n type LocalizedDictionaryOutput,\n type QualifiedMergedDictionaryOutput,\n writeDynamicDictionary,\n writeDynamicQualifiedDictionaries,\n} from './writeDynamicDictionary';\nimport { writeFetchDictionary } from './writeFetchDictionary';\nimport {\n type PlainMergedDictionaryOutput,\n writeMergedDictionaries,\n} from './writeMergedDictionary';\nimport { writeNestedDictionaries } from './writeNestedDictionary';\nimport { writeUnmergedDictionaries } from './writeUnmergedDictionary';\n\nexport type BuildDictionariesOptions = Partial<{\n formats: typeof OUTPUT_FORMAT;\n importOtherDictionaries: boolean;\n env: 'prod' | 'dev';\n}>;\n\nconst defaultOptions = {\n formats: OUTPUT_FORMAT,\n importOtherDictionaries: true,\n env: 'dev',\n} as const satisfies BuildDictionariesOptions;\n\n/**\n * This function transpile the bundled code to to make dictionaries as JSON files\n */\nexport const buildDictionary = async (\n localDictionariesEntries: Dictionary[],\n configuration: IntlayerConfig,\n options?: BuildDictionariesOptions\n) => {\n const importMode =\n configuration?.build?.importMode ??\n configuration?.dictionary?.importMode ??\n IMPORT_MODE;\n\n const { importOtherDictionaries, env, formats } = {\n ...defaultOptions,\n ...options,\n };\n\n
|
|
1
|
+
{"version":3,"file":"buildIntlayerDictionary.mjs","names":[],"sources":["../../../src/buildIntlayerDictionary/buildIntlayerDictionary.ts"],"sourcesContent":["import { IMPORT_MODE, OUTPUT_FORMAT } from '@intlayer/config/defaultValues';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport {\n getNestedDictionaryGraph,\n isQualifiedDictionaryGroup,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport {\n type LocalizedDictionaryOutput,\n type QualifiedMergedDictionaryOutput,\n writeDynamicDictionary,\n writeDynamicQualifiedDictionaries,\n} from './writeDynamicDictionary';\nimport { writeFetchDictionary } from './writeFetchDictionary';\nimport {\n type PlainMergedDictionaryOutput,\n writeMergedDictionaries,\n} from './writeMergedDictionary';\nimport { writeNestedDictionaries } from './writeNestedDictionary';\nimport { writeUnmergedDictionaries } from './writeUnmergedDictionary';\n\nexport type BuildDictionariesOptions = Partial<{\n formats: typeof OUTPUT_FORMAT;\n importOtherDictionaries: boolean;\n env: 'prod' | 'dev';\n}>;\n\nconst defaultOptions = {\n formats: OUTPUT_FORMAT,\n importOtherDictionaries: true,\n env: 'dev',\n} as const satisfies BuildDictionariesOptions;\n\n/**\n * Appends the already-built declarations sharing a key with\n * `localDictionaries` (other `localId`), so a partial rebuild does not drop\n * the declarations coming from other content files.\n */\nexport const addStoredSiblingDictionaries = (\n localDictionaries: Dictionary[],\n configuration: IntlayerConfig\n): Dictionary[] => {\n const storedUnmergedDictionaries: Record<string, Dictionary[]> =\n readDictionariesFromDisk(configuration.system.unmergedDictionariesDir);\n\n const siblingDictionaries = localDictionaries.flatMap((localDictionary) =>\n (storedUnmergedDictionaries[localDictionary.key] ?? []).filter(\n (storedDictionary) => storedDictionary.localId !== localDictionary.localId\n )\n );\n\n return [...localDictionaries, ...siblingDictionaries];\n};\n\n/**\n * This function transpile the bundled code to to make dictionaries as JSON files\n */\nexport const buildDictionary = async (\n localDictionariesEntries: Dictionary[],\n configuration: IntlayerConfig,\n options?: BuildDictionariesOptions\n) => {\n const importMode =\n configuration?.build?.importMode ??\n configuration?.dictionary?.importMode ??\n IMPORT_MODE;\n\n const { importOtherDictionaries, env, formats } = {\n ...defaultOptions,\n ...options,\n };\n\n // Reinsert other dictionaries with the same key to avoid merging errors\n const unmergedDictionariesToUpdate: Dictionary[] = importOtherDictionaries\n ? addStoredSiblingDictionaries(localDictionariesEntries, configuration)\n : [...localDictionariesEntries];\n\n const unmergedDictionaries = await writeUnmergedDictionaries(\n unmergedDictionariesToUpdate,\n configuration,\n env\n );\n\n const mergedDictionaries = await writeMergedDictionaries(\n unmergedDictionaries,\n configuration\n );\n\n // `nest()` dependency graph, read back from disk so it stays complete on\n // incremental rebuilds where only a subset of dictionaries was regenerated.\n // Every artifact kind attaches its dependencies, letting `getNesting` resolve\n // them locally instead of through the registry the optimizer strips.\n const nestedDictionaryGraph = getNestedDictionaryGraph(\n Object.values(\n readDictionariesFromDisk<Record<string, Dictionary>>(\n configuration.system.dictionariesDir\n )\n )\n );\n\n await writeNestedDictionaries(nestedDictionaryGraph, configuration, formats);\n\n const dictionariesToBuildDynamic: PlainMergedDictionaryOutput = {};\n const qualifiedDictionariesToBuildDynamic: QualifiedMergedDictionaryOutput =\n {};\n const keysToBuildFetch = new Set<string>();\n\n for (const [key, mergedResult] of Object.entries(mergedDictionaries)) {\n const dictionary = mergedResult.dictionary;\n\n if (isQualifiedDictionaryGroup(dictionary)) {\n // Collections / variants resolve their qualifier at\n // runtime from a selector. Static mode keeps every entry in one JSON;\n // dynamic mode splits them into one chunk per (locale, qualifierId).\n const entryMode = dictionary.importMode ?? importMode;\n\n if (entryMode === 'dynamic') {\n qualifiedDictionariesToBuildDynamic[key] = {\n dictionaryPath: mergedResult.dictionaryPath,\n dictionary,\n };\n } else if (entryMode === 'fetch') {\n const appLogger = getAppLogger(configuration);\n appLogger(\n `Dictionary ${colorizeKey(key)} uses 'fetch' import mode with (${dictionary.qualifierTypes.join(', ')}) entries — fetch mode is not qualifier-aware yet, falling back to static import.`,\n { level: 'warn' }\n );\n }\n\n continue;\n }\n\n const mode = dictionary.importMode ?? importMode;\n\n if (mode === 'dynamic' || mode === 'fetch') {\n dictionariesToBuildDynamic[key] = {\n dictionaryPath: mergedResult.dictionaryPath,\n dictionary,\n };\n }\n\n if (mode === 'fetch') {\n keysToBuildFetch.add(key);\n }\n }\n\n // A lazily loaded dictionary resolves its `nest()` references from chunks\n // loaded by the same loader, so its nest targets need dynamic artifacts of\n // their own — whatever import mode they declare for their own call sites.\n for (const consumerKey of Object.keys(dictionariesToBuildDynamic)) {\n for (const nestedKey of nestedDictionaryGraph.get(consumerKey) ?? []) {\n if (dictionariesToBuildDynamic[nestedKey]) continue;\n\n const nestedResult = mergedDictionaries[nestedKey];\n if (\n !nestedResult ||\n isQualifiedDictionaryGroup(nestedResult.dictionary)\n ) {\n continue;\n }\n\n dictionariesToBuildDynamic[nestedKey] = {\n dictionaryPath: nestedResult.dictionaryPath,\n dictionary: nestedResult.dictionary,\n };\n }\n }\n\n let dynamicDictionaries: LocalizedDictionaryOutput | null = null;\n\n if (Object.keys(dictionariesToBuildDynamic).length > 0) {\n dynamicDictionaries = await writeDynamicDictionary(\n dictionariesToBuildDynamic,\n configuration,\n formats,\n nestedDictionaryGraph\n );\n }\n\n if (Object.keys(qualifiedDictionariesToBuildDynamic).length > 0) {\n await writeDynamicQualifiedDictionaries(\n qualifiedDictionariesToBuildDynamic,\n configuration,\n formats\n );\n }\n\n let fetchDictionaries: LocalizedDictionaryOutput | null = null;\n\n if (dynamicDictionaries && keysToBuildFetch.size > 0) {\n const dictionariesToBuildFetch: LocalizedDictionaryOutput = {};\n\n for (const key of keysToBuildFetch) {\n if (dynamicDictionaries[key]) {\n dictionariesToBuildFetch[key] = dynamicDictionaries[key];\n }\n }\n\n if (Object.keys(dictionariesToBuildFetch).length > 0) {\n fetchDictionaries = await writeFetchDictionary(\n dictionariesToBuildFetch,\n configuration,\n formats,\n nestedDictionaryGraph\n );\n }\n }\n\n return {\n unmergedDictionaries,\n mergedDictionaries,\n dynamicDictionaries,\n fetchDictionaries,\n };\n};\n"],"mappings":";;;;;;;;;;;AA6BA,MAAM,iBAAiB;CACrB,SAAS;CACT,yBAAyB;CACzB,KAAK;AACP;;;;;;AAOA,MAAa,gCACX,mBACA,kBACiB;CACjB,MAAM,6BACJ,yBAAyB,cAAc,OAAO,uBAAuB;CAEvE,MAAM,sBAAsB,kBAAkB,SAAS,qBACpD,2BAA2B,gBAAgB,QAAQ,CAAC,EAAC,CAAE,QACrD,qBAAqB,iBAAiB,YAAY,gBAAgB,OACrE,CACF;CAEA,OAAO,CAAC,GAAG,mBAAmB,GAAG,mBAAmB;AACtD;;;;AAKA,MAAa,kBAAkB,OAC7B,0BACA,eACA,YACG;CACH,MAAM,aACJ,eAAe,OAAO,cACtB,eAAe,YAAY,cAC3B;CAEF,MAAM,EAAE,yBAAyB,KAAK,YAAY;EAChD,GAAG;EACH,GAAG;CACL;CAGA,MAAM,+BAA6C,0BAC/C,6BAA6B,0BAA0B,aAAa,IACpE,CAAC,GAAG,wBAAwB;CAEhC,MAAM,uBAAuB,MAAM,0BACjC,8BACA,eACA,GACF;CAEA,MAAM,qBAAqB,MAAM,wBAC/B,sBACA,aACF;CAMA,MAAM,wBAAwB,yBAC5B,OAAO,OACL,yBACE,cAAc,OAAO,eACvB,CACF,CACF;CAEA,MAAM,wBAAwB,uBAAuB,eAAe,OAAO;CAE3E,MAAM,6BAA0D,CAAC;CACjE,MAAM,sCACJ,CAAC;CACH,MAAM,mCAAmB,IAAI,IAAY;CAEzC,KAAK,MAAM,CAAC,KAAK,iBAAiB,OAAO,QAAQ,kBAAkB,GAAG;EACpE,MAAM,aAAa,aAAa;EAEhC,IAAI,2BAA2B,UAAU,GAAG;GAI1C,MAAM,YAAY,WAAW,cAAc;GAE3C,IAAI,cAAc,WAChB,oCAAoC,OAAO;IACzC,gBAAgB,aAAa;IAC7B;GACF;QACK,IAAI,cAAc,SAEvB,AADkB,aAAa,aACvB,CAAC,CACP,cAAc,YAAY,GAAG,EAAE,kCAAkC,WAAW,eAAe,KAAK,IAAI,EAAE,oFACtG,EAAE,OAAO,OAAO,CAClB;GAGF;EACF;EAEA,MAAM,OAAO,WAAW,cAAc;EAEtC,IAAI,SAAS,aAAa,SAAS,SACjC,2BAA2B,OAAO;GAChC,gBAAgB,aAAa;GAC7B;EACF;EAGF,IAAI,SAAS,SACX,iBAAiB,IAAI,GAAG;CAE5B;CAKA,KAAK,MAAM,eAAe,OAAO,KAAK,0BAA0B,GAC9D,KAAK,MAAM,aAAa,sBAAsB,IAAI,WAAW,KAAK,CAAC,GAAG;EACpE,IAAI,2BAA2B,YAAY;EAE3C,MAAM,eAAe,mBAAmB;EACxC,IACE,CAAC,gBACD,2BAA2B,aAAa,UAAU,GAElD;EAGF,2BAA2B,aAAa;GACtC,gBAAgB,aAAa;GAC7B,YAAY,aAAa;EAC3B;CACF;CAGF,IAAI,sBAAwD;CAE5D,IAAI,OAAO,KAAK,0BAA0B,CAAC,CAAC,SAAS,GACnD,sBAAsB,MAAM,uBAC1B,4BACA,eACA,SACA,qBACF;CAGF,IAAI,OAAO,KAAK,mCAAmC,CAAC,CAAC,SAAS,GAC5D,MAAM,kCACJ,qCACA,eACA,OACF;CAGF,IAAI,oBAAsD;CAE1D,IAAI,uBAAuB,iBAAiB,OAAO,GAAG;EACpD,MAAM,2BAAsD,CAAC;EAE7D,KAAK,MAAM,OAAO,kBAChB,IAAI,oBAAoB,MACtB,yBAAyB,OAAO,oBAAoB;EAIxD,IAAI,OAAO,KAAK,wBAAwB,CAAC,CAAC,SAAS,GACjD,oBAAoB,MAAM,qBACxB,0BACA,eACA,SACA,qBACF;CAEJ;CAEA,OAAO;EACL;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { buildDictionary } from "./buildIntlayerDictionary.mjs";
|
|
1
|
+
import { addStoredSiblingDictionaries, buildDictionary } from "./buildIntlayerDictionary.mjs";
|
|
2
2
|
import { processContentDeclaration } from "./processContentDeclaration.mjs";
|
|
3
|
+
import { rebuildUnmergedDictionaries } from "./rebuildUnmergedDictionaries.mjs";
|
|
3
4
|
|
|
4
|
-
export { buildDictionary, processContentDeclaration };
|
|
5
|
+
export { addStoredSiblingDictionaries, buildDictionary, processContentDeclaration, rebuildUnmergedDictionaries };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { writeUnmergedDictionaries } from "./writeUnmergedDictionary.mjs";
|
|
2
|
+
import { addStoredSiblingDictionaries } from "./buildIntlayerDictionary.mjs";
|
|
3
|
+
import { loadLocalDictionaries } from "../loadDictionaries/loadLocalDictionaries.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/buildIntlayerDictionary/rebuildUnmergedDictionaries.ts
|
|
6
|
+
/**
|
|
7
|
+
* Reloads a content declaration file and rewrites only the unmerged
|
|
8
|
+
* dictionaries of its keys. Used by the editor server right after writing a
|
|
9
|
+
* source file, so the next read reflects the write without waiting for the
|
|
10
|
+
* app watcher (which still owns the merged / dynamic / type outputs).
|
|
11
|
+
*
|
|
12
|
+
* @returns The reloaded declarations of the file.
|
|
13
|
+
*/
|
|
14
|
+
const rebuildUnmergedDictionaries = async (contentDeclarationPath, configuration) => {
|
|
15
|
+
const localDictionaries = await loadLocalDictionaries(contentDeclarationPath, configuration);
|
|
16
|
+
await writeUnmergedDictionaries(addStoredSiblingDictionaries(localDictionaries, configuration), configuration, "dev");
|
|
17
|
+
return localDictionaries;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { rebuildUnmergedDictionaries };
|
|
22
|
+
//# sourceMappingURL=rebuildUnmergedDictionaries.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuildUnmergedDictionaries.mjs","names":[],"sources":["../../../src/buildIntlayerDictionary/rebuildUnmergedDictionaries.ts"],"sourcesContent":["import type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { loadLocalDictionaries } from '../loadDictionaries/loadLocalDictionaries';\nimport { addStoredSiblingDictionaries } from './buildIntlayerDictionary';\nimport { writeUnmergedDictionaries } from './writeUnmergedDictionary';\n\n/**\n * Reloads a content declaration file and rewrites only the unmerged\n * dictionaries of its keys. Used by the editor server right after writing a\n * source file, so the next read reflects the write without waiting for the\n * app watcher (which still owns the merged / dynamic / type outputs).\n *\n * @returns The reloaded declarations of the file.\n */\nexport const rebuildUnmergedDictionaries = async (\n contentDeclarationPath: string,\n configuration: IntlayerConfig\n): Promise<Dictionary[]> => {\n const localDictionaries = await loadLocalDictionaries(\n contentDeclarationPath,\n configuration\n );\n\n await writeUnmergedDictionaries(\n addStoredSiblingDictionaries(localDictionaries, configuration),\n configuration,\n 'dev'\n );\n\n return localDictionaries;\n};\n"],"mappings":";;;;;;;;;;;;;AAcA,MAAa,8BAA8B,OACzC,wBACA,kBAC0B;CAC1B,MAAM,oBAAoB,MAAM,sBAC9B,wBACA,aACF;CAEA,MAAM,0BACJ,6BAA6B,mBAAmB,aAAa,GAC7D,eACA,KACF;CAEA,OAAO;AACT"}
|
package/dist/esm/cli.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { listDictionaries, listDictionariesWithStats } from "./listDictionariesP
|
|
|
4
4
|
import { prepareIntlayer } from "./prepareIntlayer.mjs";
|
|
5
5
|
import { detectExportedComponentName } from "./writeContentDeclaration/detectExportedComponentName.mjs";
|
|
6
6
|
import { transformJSFile } from "./writeContentDeclaration/transformJSFile.mjs";
|
|
7
|
+
import { formatContentDeclaration, isRenderableContentDeclarationPath, renderContentDeclaration, renderMarkdownContentDeclaration, renderYamlContentDeclaration } from "./writeContentDeclaration/renderContentDeclaration.mjs";
|
|
7
8
|
import { getContentDeclarationFileTemplate } from "./getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs";
|
|
8
9
|
import { writeJSFile } from "./writeContentDeclaration/writeJSFile.mjs";
|
|
9
10
|
import { writeContentDeclaration } from "./writeContentDeclaration/writeContentDeclaration.mjs";
|
|
@@ -14,10 +15,11 @@ import { COMPAT_I18N_LIBRARIES, detectCompatI18nLibraries, detectPackageManager,
|
|
|
14
15
|
import { NEXT_INTLAYER_BABEL_CONFIG_CONTENT } from "./init/utils/nextCompilerBabel.mjs";
|
|
15
16
|
import { hasUrlRoutingFramework } from "./init/utils/urlRoutingFramework.mjs";
|
|
16
17
|
import { upgradeIntlayerPackages } from "./init/upgradeIntlayerPackages.mjs";
|
|
18
|
+
import { CATALOG_MESSAGE_FORMATS, CONTENT_FORMATS_BY_LAYOUT, getContentLayoutSetup } from "./init/utils/contentLayout.mjs";
|
|
17
19
|
import { getDefaultApplicationURL, initIntlayer, logInitSuccessMessage } from "./init/index.mjs";
|
|
18
20
|
import { installLSP } from "./installLSP.mjs";
|
|
19
|
-
import { PLATFORMS, PLATFORMS_METADATA, SKILLS, SKILLS_METADATA, getInitialSkills, installSkills } from "./installSkills/index.mjs";
|
|
20
|
-
import { installMCP } from "./installMCP/installMCP.mjs";
|
|
21
|
+
import { PLATFORMS, PLATFORMS_METADATA, SKILLS, SKILLS_METADATA, detectPlatform, getInitialSkills, installSkills } from "./installSkills/index.mjs";
|
|
22
|
+
import { MCP_TRANSPORTS, installMCP } from "./installMCP/installMCP.mjs";
|
|
21
23
|
import { listGitFiles, listGitLines } from "./listGitFiles.mjs";
|
|
22
24
|
|
|
23
|
-
export { COMPAT_I18N_LIBRARIES, DocumentationRouter, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, SKILLS, SKILLS_METADATA, detectCompatI18nLibraries, detectExportedComponentName, detectFormatCommand, detectPackageManager, enableEditorInConfig, findLockFileDir, getContentDeclarationFileTemplate, getDefaultApplicationURL, getDocumentationUrl, getGitRootDir, getInitialSkills, hasLintTooling, hasUrlRoutingFramework, initIntlayer, installLSP, installMCP, installPackages, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, logInitSuccessMessage, prepareIntlayer, setupCmsCredentials, transformJSFile, upgradeIntlayerPackages, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
|
|
25
|
+
export { CATALOG_MESSAGE_FORMATS, COMPAT_I18N_LIBRARIES, CONTENT_FORMATS_BY_LAYOUT, DocumentationRouter, MCP_TRANSPORTS, NEXT_INTLAYER_BABEL_CONFIG_CONTENT, PLATFORMS, PLATFORMS_METADATA, SKILLS, SKILLS_METADATA, detectCompatI18nLibraries, detectExportedComponentName, detectFormatCommand, detectPackageManager, detectPlatform, enableEditorInConfig, findLockFileDir, formatContentDeclaration, getContentDeclarationFileTemplate, getContentLayoutSetup, getDefaultApplicationURL, getDocumentationUrl, getGitRootDir, getInitialSkills, hasLintTooling, hasUrlRoutingFramework, initIntlayer, installLSP, installMCP, installPackages, installSkills, isRenderableContentDeclarationPath, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, logConfigDetails, logInitSuccessMessage, prepareIntlayer, renderContentDeclaration, renderMarkdownContentDeclaration, renderYamlContentDeclaration, setupCmsCredentials, transformJSFile, upgradeIntlayerPackages, writeCmsCredentialsToEnv, writeContentDeclaration, writeJSFile };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchDistantDictionaries.mjs","names":[],"sources":["../../src/fetchDistantDictionaries.ts"],"sourcesContent":["import { createIntlayerCMS } from '@intlayer/api';\nimport { dictionaryEndpoint } from '@intlayer/api/dictionary';\n// @ts-ignore @intlayer/backend is not build yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { getAppLogger, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { retryManager } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { chunkArray } from './utils/chunkArray';\nimport { parallelize } from './utils/parallelize';\n\n/**\n * Number of dictionaries requested per HTTP call. Must stay under the batch\n * limit enforced by the backend (`MAX_DICTIONARY_KEYS_PER_REQUEST`).\n */\nconst DEFAULT_DICTIONARIES_PER_REQUEST = 3;\n\n/** Number of batch requests kept in flight at the same time. */\nconst DEFAULT_PARALLEL_REQUESTS = 5;\n\n/** Number of retries performed on a failing batch request. */\nconst DEFAULT_MAX_RETRY = 2;\n\n/** Delay between two attempts of a failing batch request, in milliseconds. */\nconst DEFAULT_RETRY_DELAY = 250;\n\n/** HTTP statuses worth another attempt despite being client errors. */\nconst RETRYABLE_CLIENT_ERROR_STATUSES = new Set([408, 425, 429]);\n\n/**\n * A request is worth retrying when it failed for a reason another attempt could\n * fix: a network error (no status at all) or a server-side / throttling status.\n * Replaying a `404` or a `401` only multiplies the noise.\n */\nconst isRetryableError = (error: unknown): boolean => {\n const status = (error as { status?: number })?.status;\n\n if (typeof status !== 'number') return true;\n\n if (status >= 500) return true;\n\n return RETRYABLE_CLIENT_ERROR_STATUSES.has(status);\n};\n\n/**\n * A backend that predates the batch endpoint routes `/dictionary/by-keys` to\n * its `/dictionary/:dictionaryKey` handler, which answers `404` - either as an\n * unknown dictionary or as an unknown route. Both mean the same thing here:\n * this backend cannot serve batches, so fall back to one request per key.\n */\nconst isBatchEndpointUnsupported = (error: unknown): boolean =>\n (error as { status?: number })?.status === 404;\n\ntype FetchDistantDictionariesOptions = {\n dictionaryKeys: string[];\n newDictionariesPath?: string;\n logPrefix?: string;\n /**\n * Number of dictionaries fetched by a single request.\n * @default 3\n */\n dictionariesPerRequest?: number;\n /**\n * Number of requests kept in flight at the same time.\n * @default 5\n */\n parallelRequests?: number;\n /**\n * Number of retries performed when a batch request fails.\n * @default 2\n */\n maxRetry?: number;\n /**\n * Delay between two attempts of a failing batch request, in milliseconds.\n * @default 250\n */\n retryDelay?: number;\n};\n\n/**\n * Fetch distant dictionaries and update the logger with their statuses.\n *\n * Keys are grouped into batches fetched by a single request each, and those\n * requests are kept in flight together — by default 5 concurrent requests of 3\n * dictionaries, so 15 dictionaries travel at any given time. A slot is refilled\n * as soon as its request settles, so no batch waits for the whole wave.\n * Failing requests are retried before their keys are reported as errors.\n */\nexport const fetchDistantDictionaries = async (\n options: FetchDistantDictionariesOptions,\n onStatusUpdate?: (status: DictionariesStatus[]) => void\n): Promise<DictionaryAPI[]> => {\n const config = getConfiguration();\n const appLogger = getAppLogger(config);\n try {\n const dictionary = dictionaryEndpoint(createIntlayerCMS(config));\n\n const {\n dictionariesPerRequest = DEFAULT_DICTIONARIES_PER_REQUEST,\n parallelRequests = DEFAULT_PARALLEL_REQUESTS,\n maxRetry = DEFAULT_MAX_RETRY,\n retryDelay = DEFAULT_RETRY_DELAY,\n } = options;\n\n // A same key can be listed twice when several qualified dictionaries share\n // it - one request per key is enough to retrieve all of its siblings.\n const distantDictionariesKeys = [...new Set(options.dictionaryKeys)];\n\n if (distantDictionariesKeys.length === 0) return [];\n\n const batches = chunkArray(distantDictionariesKeys, dictionariesPerRequest);\n\n // Flipped once for the whole run as soon as a backend proves unable to\n // serve batches, so the remaining batches skip the doomed request.\n let isBatchEndpointSupported = true;\n let hasLoggedBatchFallback = false;\n\n /**\n * Fetch each key of a batch with its own request. Used against backends\n * without the batch endpoint. A key missing on the remote only discards\n * itself, never its neighbours.\n */\n const requestDictionariesOneByOne = async (\n batchKeys: string[]\n ): Promise<DictionaryAPI[]> => {\n const results = await parallelize(\n batchKeys,\n async (dictionaryKey) => {\n try {\n const getDictionaryResult =\n await dictionary.getDictionary(dictionaryKey);\n\n return getDictionaryResult.data;\n } catch (_error) {\n return undefined;\n }\n },\n batchKeys.length\n );\n\n return results.filter(\n (distantDictionary): distantDictionary is DictionaryAPI =>\n distantDictionary !== undefined\n );\n };\n\n /**\n * Request one batch of dictionaries, retrying the whole request when it\n * fails for a transient reason - a batch carries several dictionaries, so\n * a network hiccup would otherwise discard all of them at once.\n */\n const requestBatch = retryManager(\n async (batchKeys: string[]): Promise<DictionaryAPI[]> => {\n if (isBatchEndpointSupported) {\n try {\n const getDictionariesResult =\n await dictionary.getDictionariesByKeys(batchKeys);\n\n return getDictionariesResult.data ?? [];\n } catch (error) {\n if (!isBatchEndpointUnsupported(error)) throw error;\n\n isBatchEndpointSupported = false;\n\n if (!hasLoggedBatchFallback) {\n hasLoggedBatchFallback = true;\n appLogger(\n 'This backend does not provide the batch dictionary endpoint - falling back to one request per dictionary.',\n { level: 'warn' }\n );\n }\n }\n }\n\n return await requestDictionariesOneByOne(batchKeys);\n },\n {\n maxRetry,\n delay: retryDelay,\n shouldRetry: isRetryableError,\n onError: ({ error, attempt }) =>\n appLogger(\n `Retrying distant dictionaries request (attempt ${attempt + 1}/${maxRetry}): ${error}`,\n { level: 'warn' }\n ),\n }\n );\n\n /**\n * Fetch one batch of dictionaries within a single request, and report the\n * resulting status of every key it contains.\n */\n const processBatch = async (\n batchKeys: string[]\n ): Promise<DictionaryAPI[]> => {\n onStatusUpdate?.(\n batchKeys.map((dictionaryKey) => ({\n dictionaryKey,\n type: 'remote',\n status: 'fetching',\n }))\n );\n\n try {\n const distantDictionaries = await requestBatch(batchKeys);\n\n const fetchedKeys = new Set(\n distantDictionaries.map(\n (distantDictionary: DictionaryAPI) => distantDictionary.key\n )\n );\n\n onStatusUpdate?.(\n batchKeys.map(\n (dictionaryKey): DictionariesStatus =>\n fetchedKeys.has(dictionaryKey)\n ? {\n dictionaryKey,\n type: 'remote',\n status: 'fetched',\n }\n : {\n dictionaryKey,\n type: 'remote',\n status: 'error',\n error: `Dictionary ${dictionaryKey} not found on remote`,\n }\n )\n );\n\n return distantDictionaries;\n } catch (error) {\n onStatusUpdate?.(\n batchKeys.map((dictionaryKey) => ({\n dictionaryKey,\n type: 'remote',\n status: 'error',\n error: `Error fetching dictionary ${dictionaryKey}: ${error}`,\n }))\n );\n return [];\n }\n };\n\n const batchResults = await parallelize(\n batches,\n processBatch,\n parallelRequests\n );\n\n return batchResults.flat();\n } catch (_error) {\n appLogger(`${x} Failed to fetch distant dictionaries`, { level: 'error' });\n return [];\n }\n};\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAM,mCAAmC;;AAGzC,MAAM,4BAA4B;;AAGlC,MAAM,oBAAoB;;AAG1B,MAAM,sBAAsB;;AAG5B,MAAM,kDAAkC,IAAI,IAAI;CAAC;CAAK;CAAK;AAAG,CAAC;;;;;;AAO/D,MAAM,oBAAoB,UAA4B;CACpD,MAAM,SAAU,OAA+B;CAE/C,IAAI,OAAO,WAAW,UAAU,OAAO;CAEvC,IAAI,UAAU,KAAK,OAAO;CAE1B,OAAO,gCAAgC,IAAI,MAAM;AACnD;;;;;;;AAQA,MAAM,8BAA8B,UACjC,OAA+B,WAAW;;;;;;;;;;AAqC7C,MAAa,2BAA2B,OACtC,SACA,mBAC6B;CAC7B,MAAM,SAAS,iBAAiB;CAChC,MAAM,YAAY,aAAa,MAAM;CACrC,IAAI;EACF,MAAM,aAAa,mBAAmB,kBAAkB,MAAM,CAAC;EAE/D,MAAM,EACJ,yBAAyB,kCACzB,mBAAmB,2BACnB,WAAW,mBACX,aAAa,wBACX;EAIJ,MAAM,0BAA0B,CAAC,GAAG,IAAI,IAAI,QAAQ,cAAc,CAAC;EAEnE,IAAI,wBAAwB,WAAW,GAAG,OAAO,CAAC;EAElD,MAAM,UAAU,WAAW,yBAAyB,sBAAsB;EAI1E,IAAI,2BAA2B;EAC/B,IAAI,yBAAyB;;;;;;EAO7B,MAAM,8BAA8B,OAClC,cAC6B;GAgB7B,QAAO,MAfe,YACpB,WACA,OAAO,kBAAkB;IACvB,IAAI;KAIF,QAAO,MAFC,WAAW,cAAc,aAAa,EAEpB,CAAC;IAC7B,SAAS,QAAQ;KACf;IACF;GACF,GACA,UAAU,MACZ,EAEc,CAAC,QACZ,sBACC,sBAAsB,MAC1B;EACF;;;;;;EAOA,MAAM,eAAe,aACnB,OAAO,cAAkD;GACvD,IAAI,0BACF,IAAI;IAIF,QAAO,MAFC,WAAW,sBAAsB,SAAS,EAEtB,CAAC,QAAQ,CAAC;GACxC,SAAS,OAAO;IACd,IAAI,CAAC,2BAA2B,KAAK,GAAG,MAAM;IAE9C,2BAA2B;IAE3B,IAAI,CAAC,wBAAwB;KAC3B,yBAAyB;KACzB,UACE,6GACA,EAAE,OAAO,OAAO,CAClB;IACF;GACF;GAGF,OAAO,MAAM,4BAA4B,SAAS;EACpD,GACA;GACE;GACA,OAAO;GACP,aAAa;GACb,UAAU,EAAE,OAAO,cACjB,UACE,kDAAkD,UAAU,EAAE,GAAG,SAAS,KAAK,SAC/E,EAAE,OAAO,OAAO,CAClB;EACJ,CACF;;;;;EAMA,MAAM,eAAe,OACnB,cAC6B;GAC7B,iBACE,UAAU,KAAK,mBAAmB;IAChC;IACA,MAAM;IACN,QAAQ;GACV,EAAE,CACJ;GAEA,IAAI;IACF,MAAM,sBAAsB,MAAM,aAAa,SAAS;IAExD,MAAM,cAAc,IAAI,IACtB,oBAAoB,KACjB,sBAAqC,kBAAkB,GAC1D,CACF;IAEA,iBACE,UAAU,KACP,kBACC,YAAY,IAAI,aAAa,IACzB;KACE;KACA,MAAM;KACN,QAAQ;IACV,IACA;KACE;KACA,MAAM;KACN,QAAQ;KACR,OAAO,cAAc,cAAc;IACrC,CACR,CACF;IAEA,OAAO;GACT,SAAS,OAAO;IACd,iBACE,UAAU,KAAK,mBAAmB;KAChC;KACA,MAAM;KACN,QAAQ;KACR,OAAO,6BAA6B,cAAc,IAAI;IACxD,EAAE,CACJ;IACA,OAAO,CAAC;GACV;EACF;EAQA,QAAO,MANoB,YACzB,SACA,cACA,gBACF,EAEmB,CAAC,KAAK;CAC3B,SAAS,QAAQ;EACf,UAAU,GAAG,EAAE,wCAAwC,EAAE,OAAO,QAAQ,CAAC;EACzE,OAAO,CAAC;CACV;AACF"}
|
|
1
|
+
{"version":3,"file":"fetchDistantDictionaries.mjs","names":[],"sources":["../../src/fetchDistantDictionaries.ts"],"sourcesContent":["import { createIntlayerCMS, type DictionaryAPI } from '@intlayer/api';\nimport { dictionaryEndpoint } from '@intlayer/api/dictionary';\nimport { getAppLogger, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { retryManager } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { chunkArray } from './utils/chunkArray';\nimport { parallelize } from './utils/parallelize';\n\n/**\n * Number of dictionaries requested per HTTP call. Must stay under the batch\n * limit enforced by the backend (`MAX_DICTIONARY_KEYS_PER_REQUEST`).\n */\nconst DEFAULT_DICTIONARIES_PER_REQUEST = 3;\n\n/** Number of batch requests kept in flight at the same time. */\nconst DEFAULT_PARALLEL_REQUESTS = 5;\n\n/** Number of retries performed on a failing batch request. */\nconst DEFAULT_MAX_RETRY = 2;\n\n/** Delay between two attempts of a failing batch request, in milliseconds. */\nconst DEFAULT_RETRY_DELAY = 250;\n\n/** HTTP statuses worth another attempt despite being client errors. */\nconst RETRYABLE_CLIENT_ERROR_STATUSES = new Set([408, 425, 429]);\n\n/**\n * A request is worth retrying when it failed for a reason another attempt could\n * fix: a network error (no status at all) or a server-side / throttling status.\n * Replaying a `404` or a `401` only multiplies the noise.\n */\nconst isRetryableError = (error: unknown): boolean => {\n const status = (error as { status?: number })?.status;\n\n if (typeof status !== 'number') return true;\n\n if (status >= 500) return true;\n\n return RETRYABLE_CLIENT_ERROR_STATUSES.has(status);\n};\n\n/**\n * A backend that predates the batch endpoint routes `/dictionary/by-keys` to\n * its `/dictionary/:dictionaryKey` handler, which answers `404` - either as an\n * unknown dictionary or as an unknown route. Both mean the same thing here:\n * this backend cannot serve batches, so fall back to one request per key.\n */\nconst isBatchEndpointUnsupported = (error: unknown): boolean =>\n (error as { status?: number })?.status === 404;\n\ntype FetchDistantDictionariesOptions = {\n dictionaryKeys: string[];\n newDictionariesPath?: string;\n logPrefix?: string;\n /**\n * Number of dictionaries fetched by a single request.\n * @default 3\n */\n dictionariesPerRequest?: number;\n /**\n * Number of requests kept in flight at the same time.\n * @default 5\n */\n parallelRequests?: number;\n /**\n * Number of retries performed when a batch request fails.\n * @default 2\n */\n maxRetry?: number;\n /**\n * Delay between two attempts of a failing batch request, in milliseconds.\n * @default 250\n */\n retryDelay?: number;\n};\n\n/**\n * Fetch distant dictionaries and update the logger with their statuses.\n *\n * Keys are grouped into batches fetched by a single request each, and those\n * requests are kept in flight together — by default 5 concurrent requests of 3\n * dictionaries, so 15 dictionaries travel at any given time. A slot is refilled\n * as soon as its request settles, so no batch waits for the whole wave.\n * Failing requests are retried before their keys are reported as errors.\n */\nexport const fetchDistantDictionaries = async (\n options: FetchDistantDictionariesOptions,\n onStatusUpdate?: (status: DictionariesStatus[]) => void\n): Promise<DictionaryAPI[]> => {\n const config = getConfiguration();\n const appLogger = getAppLogger(config);\n try {\n const dictionary = dictionaryEndpoint(createIntlayerCMS(config));\n\n const {\n dictionariesPerRequest = DEFAULT_DICTIONARIES_PER_REQUEST,\n parallelRequests = DEFAULT_PARALLEL_REQUESTS,\n maxRetry = DEFAULT_MAX_RETRY,\n retryDelay = DEFAULT_RETRY_DELAY,\n } = options;\n\n // A same key can be listed twice when several qualified dictionaries share\n // it - one request per key is enough to retrieve all of its siblings.\n const distantDictionariesKeys = [...new Set(options.dictionaryKeys)];\n\n if (distantDictionariesKeys.length === 0) return [];\n\n const batches = chunkArray(distantDictionariesKeys, dictionariesPerRequest);\n\n // Flipped once for the whole run as soon as a backend proves unable to\n // serve batches, so the remaining batches skip the doomed request.\n let isBatchEndpointSupported = true;\n let hasLoggedBatchFallback = false;\n\n /**\n * Fetch each key of a batch with its own request. Used against backends\n * without the batch endpoint. A key missing on the remote only discards\n * itself, never its neighbours.\n */\n const requestDictionariesOneByOne = async (\n batchKeys: string[]\n ): Promise<DictionaryAPI[]> => {\n const results = await parallelize(\n batchKeys,\n async (dictionaryKey) => {\n try {\n const getDictionaryResult =\n await dictionary.getDictionary(dictionaryKey);\n\n return getDictionaryResult.data;\n } catch (_error) {\n return undefined;\n }\n },\n batchKeys.length\n );\n\n return results.filter(\n (distantDictionary): distantDictionary is DictionaryAPI =>\n distantDictionary !== undefined\n );\n };\n\n /**\n * Request one batch of dictionaries, retrying the whole request when it\n * fails for a transient reason - a batch carries several dictionaries, so\n * a network hiccup would otherwise discard all of them at once.\n */\n const requestBatch = retryManager(\n async (batchKeys: string[]): Promise<DictionaryAPI[]> => {\n if (isBatchEndpointSupported) {\n try {\n const getDictionariesResult =\n await dictionary.getDictionariesByKeys(batchKeys);\n\n return getDictionariesResult.data ?? [];\n } catch (error) {\n if (!isBatchEndpointUnsupported(error)) throw error;\n\n isBatchEndpointSupported = false;\n\n if (!hasLoggedBatchFallback) {\n hasLoggedBatchFallback = true;\n appLogger(\n 'This backend does not provide the batch dictionary endpoint - falling back to one request per dictionary.',\n { level: 'warn' }\n );\n }\n }\n }\n\n return await requestDictionariesOneByOne(batchKeys);\n },\n {\n maxRetry,\n delay: retryDelay,\n shouldRetry: isRetryableError,\n onError: ({ error, attempt }) =>\n appLogger(\n `Retrying distant dictionaries request (attempt ${attempt + 1}/${maxRetry}): ${error}`,\n { level: 'warn' }\n ),\n }\n );\n\n /**\n * Fetch one batch of dictionaries within a single request, and report the\n * resulting status of every key it contains.\n */\n const processBatch = async (\n batchKeys: string[]\n ): Promise<DictionaryAPI[]> => {\n onStatusUpdate?.(\n batchKeys.map((dictionaryKey) => ({\n dictionaryKey,\n type: 'remote',\n status: 'fetching',\n }))\n );\n\n try {\n const distantDictionaries = await requestBatch(batchKeys);\n\n const fetchedKeys = new Set(\n distantDictionaries.map(\n (distantDictionary: DictionaryAPI) => distantDictionary.key\n )\n );\n\n onStatusUpdate?.(\n batchKeys.map(\n (dictionaryKey): DictionariesStatus =>\n fetchedKeys.has(dictionaryKey)\n ? {\n dictionaryKey,\n type: 'remote',\n status: 'fetched',\n }\n : {\n dictionaryKey,\n type: 'remote',\n status: 'error',\n error: `Dictionary ${dictionaryKey} not found on remote`,\n }\n )\n );\n\n return distantDictionaries;\n } catch (error) {\n onStatusUpdate?.(\n batchKeys.map((dictionaryKey) => ({\n dictionaryKey,\n type: 'remote',\n status: 'error',\n error: `Error fetching dictionary ${dictionaryKey}: ${error}`,\n }))\n );\n return [];\n }\n };\n\n const batchResults = await parallelize(\n batches,\n processBatch,\n parallelRequests\n );\n\n return batchResults.flat();\n } catch (_error) {\n appLogger(`${x} Failed to fetch distant dictionaries`, { level: 'error' });\n return [];\n }\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAM,mCAAmC;;AAGzC,MAAM,4BAA4B;;AAGlC,MAAM,oBAAoB;;AAG1B,MAAM,sBAAsB;;AAG5B,MAAM,kDAAkC,IAAI,IAAI;CAAC;CAAK;CAAK;AAAG,CAAC;;;;;;AAO/D,MAAM,oBAAoB,UAA4B;CACpD,MAAM,SAAU,OAA+B;CAE/C,IAAI,OAAO,WAAW,UAAU,OAAO;CAEvC,IAAI,UAAU,KAAK,OAAO;CAE1B,OAAO,gCAAgC,IAAI,MAAM;AACnD;;;;;;;AAQA,MAAM,8BAA8B,UACjC,OAA+B,WAAW;;;;;;;;;;AAqC7C,MAAa,2BAA2B,OACtC,SACA,mBAC6B;CAC7B,MAAM,SAAS,iBAAiB;CAChC,MAAM,YAAY,aAAa,MAAM;CACrC,IAAI;EACF,MAAM,aAAa,mBAAmB,kBAAkB,MAAM,CAAC;EAE/D,MAAM,EACJ,yBAAyB,kCACzB,mBAAmB,2BACnB,WAAW,mBACX,aAAa,wBACX;EAIJ,MAAM,0BAA0B,CAAC,GAAG,IAAI,IAAI,QAAQ,cAAc,CAAC;EAEnE,IAAI,wBAAwB,WAAW,GAAG,OAAO,CAAC;EAElD,MAAM,UAAU,WAAW,yBAAyB,sBAAsB;EAI1E,IAAI,2BAA2B;EAC/B,IAAI,yBAAyB;;;;;;EAO7B,MAAM,8BAA8B,OAClC,cAC6B;GAgB7B,QAAO,MAfe,YACpB,WACA,OAAO,kBAAkB;IACvB,IAAI;KAIF,QAAO,MAFC,WAAW,cAAc,aAAa,EAEpB,CAAC;IAC7B,SAAS,QAAQ;KACf;IACF;GACF,GACA,UAAU,MACZ,EAEc,CAAC,QACZ,sBACC,sBAAsB,MAC1B;EACF;;;;;;EAOA,MAAM,eAAe,aACnB,OAAO,cAAkD;GACvD,IAAI,0BACF,IAAI;IAIF,QAAO,MAFC,WAAW,sBAAsB,SAAS,EAEtB,CAAC,QAAQ,CAAC;GACxC,SAAS,OAAO;IACd,IAAI,CAAC,2BAA2B,KAAK,GAAG,MAAM;IAE9C,2BAA2B;IAE3B,IAAI,CAAC,wBAAwB;KAC3B,yBAAyB;KACzB,UACE,6GACA,EAAE,OAAO,OAAO,CAClB;IACF;GACF;GAGF,OAAO,MAAM,4BAA4B,SAAS;EACpD,GACA;GACE;GACA,OAAO;GACP,aAAa;GACb,UAAU,EAAE,OAAO,cACjB,UACE,kDAAkD,UAAU,EAAE,GAAG,SAAS,KAAK,SAC/E,EAAE,OAAO,OAAO,CAClB;EACJ,CACF;;;;;EAMA,MAAM,eAAe,OACnB,cAC6B;GAC7B,iBACE,UAAU,KAAK,mBAAmB;IAChC;IACA,MAAM;IACN,QAAQ;GACV,EAAE,CACJ;GAEA,IAAI;IACF,MAAM,sBAAsB,MAAM,aAAa,SAAS;IAExD,MAAM,cAAc,IAAI,IACtB,oBAAoB,KACjB,sBAAqC,kBAAkB,GAC1D,CACF;IAEA,iBACE,UAAU,KACP,kBACC,YAAY,IAAI,aAAa,IACzB;KACE;KACA,MAAM;KACN,QAAQ;IACV,IACA;KACE;KACA,MAAM;KACN,QAAQ;KACR,OAAO,cAAc,cAAc;IACrC,CACR,CACF;IAEA,OAAO;GACT,SAAS,OAAO;IACd,iBACE,UAAU,KAAK,mBAAmB;KAChC;KACA,MAAM;KACN,QAAQ;KACR,OAAO,6BAA6B,cAAc,IAAI;IACxD,EAAE,CACJ;IACA,OAAO,CAAC;GACV;EACF;EAQA,QAAO,MANoB,YACzB,SACA,cACA,gBACF,EAEmB,CAAC,KAAK;CAC3B,SAAS,QAAQ;EACf,UAAU,GAAG,EAAE,wCAAwC,EAAE,OAAO,QAAQ,CAAC;EACzE,OAAO,CAAC;CACV;AACF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { formatPath } from "./utils/formatter.mjs";
|
|
2
2
|
import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
|
|
3
|
+
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
3
4
|
import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
|
|
4
5
|
import { createModuleAugmentation } from "./createType/createModuleAugmentation.mjs";
|
|
5
6
|
import { createTypes } from "./createType/createType.mjs";
|
|
6
|
-
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
7
7
|
import { getAppLogger } from "@intlayer/config/logger";
|
|
8
8
|
|
|
9
9
|
//#region src/handleAdditionalContentDeclarationFile.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { formatPath } from "./utils/formatter.mjs";
|
|
2
2
|
import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
|
|
3
|
+
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
3
4
|
import { getBuiltDictionariesPath } from "./createDictionaryEntryPoint/getBuiltDictionariesPath.mjs";
|
|
4
5
|
import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
|
|
5
6
|
import { createModuleAugmentation } from "./createType/createModuleAugmentation.mjs";
|
|
6
7
|
import { createTypes } from "./createType/createType.mjs";
|
|
7
|
-
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
8
8
|
import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
import { getAppLogger } from "@intlayer/config/logger";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { formatPath } from "./utils/formatter.mjs";
|
|
2
2
|
import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
|
|
3
|
+
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
3
4
|
import { createModuleAugmentation } from "./createType/createModuleAugmentation.mjs";
|
|
4
5
|
import { createTypes } from "./createType/createType.mjs";
|
|
5
|
-
import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
|
|
6
6
|
import { listDictionaries } from "./listDictionariesPath.mjs";
|
|
7
7
|
import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
|
|
8
8
|
import { normalize } from "node:path";
|
package/dist/esm/init/cms.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { enableIntlayerEditorConfig, setIntlayerConfigCompilerOutput, setIntlayerConfigEnableProxy, setIntlayerConfigRoutingMode, setIntlayerConfigRoutingStorageOnly } from "./utils/configManipulation.mjs";
|
|
1
|
+
import { enableIntlayerEditorConfig, setIntlayerConfigCompilerOutput, setIntlayerConfigDictionaryLocale, setIntlayerConfigEnableProxy, setIntlayerConfigRoutingMode, setIntlayerConfigRoutingStorageOnly } from "./utils/configManipulation.mjs";
|
|
2
2
|
import { exists, readFileFromRoot, writeFileToRoot } from "./utils/fileSystem.mjs";
|
|
3
3
|
import * as ANSIColors from "@intlayer/config/colors";
|
|
4
4
|
import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
|
|
@@ -167,6 +167,23 @@ const setCompilerOutputInConfig = async (rootDir, outputTemplate) => {
|
|
|
167
167
|
return configFile;
|
|
168
168
|
};
|
|
169
169
|
/**
|
|
170
|
+
* Sets `dictionary.locale` to the default locale in the project's Intlayer
|
|
171
|
+
* configuration file. Returns the config file that was updated, or `undefined`
|
|
172
|
+
* when none was found.
|
|
173
|
+
*/
|
|
174
|
+
const setDictionaryLocaleInConfig = async (rootDir) => {
|
|
175
|
+
const configFile = await findIntlayerConfigFile(rootDir);
|
|
176
|
+
if (!configFile) return void 0;
|
|
177
|
+
const extension = configFile.split(".").pop();
|
|
178
|
+
const content = await readFileFromRoot(rootDir, configFile);
|
|
179
|
+
const updatedContent = setIntlayerConfigDictionaryLocale(content, extension);
|
|
180
|
+
if (updatedContent !== content) {
|
|
181
|
+
await writeFileToRoot(rootDir, configFile, updatedContent);
|
|
182
|
+
logger(`${v} Set ${colorize("dictionary.locale", ANSIColors.GREY_LIGHT)} to the default locale in ${colorizePath(configFile)}`);
|
|
183
|
+
}
|
|
184
|
+
return configFile;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
170
187
|
* Completes the CMS setup once credentials are received from the login flow:
|
|
171
188
|
* writes them to the environment file and enables the editor in the Intlayer
|
|
172
189
|
* configuration file.
|
|
@@ -177,5 +194,5 @@ const setupCmsCredentials = async (rootDir, credentials) => {
|
|
|
177
194
|
};
|
|
178
195
|
|
|
179
196
|
//#endregion
|
|
180
|
-
export { INTLAYER_CONFIG_FILE_CANDIDATES, enableEditorInConfig, findEnvFile, setCompilerOutputInConfig, setEnableProxyInConfig, setRoutingModeInConfig, setRoutingStorageOnlyInConfig, setupCmsCredentials, writeCmsCredentialsToEnv };
|
|
197
|
+
export { INTLAYER_CONFIG_FILE_CANDIDATES, enableEditorInConfig, findEnvFile, setCompilerOutputInConfig, setDictionaryLocaleInConfig, setEnableProxyInConfig, setRoutingModeInConfig, setRoutingStorageOnlyInConfig, setupCmsCredentials, writeCmsCredentialsToEnv };
|
|
181
198
|
//# sourceMappingURL=cms.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms.mjs","names":[],"sources":["../../../src/init/cms.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport fg from 'fast-glob';\nimport {\n enableIntlayerEditorConfig,\n type RoutingMode,\n setIntlayerConfigCompilerOutput,\n setIntlayerConfigEnableProxy,\n setIntlayerConfigRoutingMode,\n setIntlayerConfigRoutingStorageOnly,\n} from './utils/configManipulation';\nimport { exists, readFileFromRoot, writeFileToRoot } from './utils/fileSystem';\n\n/**\n * Intlayer configuration file candidates, ordered by the precedence used when\n * resolving which file to mutate.\n */\nexport const INTLAYER_CONFIG_FILE_CANDIDATES = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n 'intlayer.config.json',\n] as const;\n\n/**\n * Environment files searched (most-preferred first) when persisting the CMS\n * credentials. The first existing match is reused; otherwise a `.env` file is\n * created at the project root.\n */\nconst ENV_FILE_CANDIDATES = ['.env', '.env.local', '.env.development'] as const;\n\n/** Credentials returned by the CMS login flow (access key pair). */\nexport type CmsCredentials = {\n clientId: string;\n clientSecret: string;\n};\n\n/**\n * Resolves the first existing Intlayer configuration file at the project root,\n * or `undefined` when none is present.\n */\nconst findIntlayerConfigFile = async (\n rootDir: string\n): Promise<(typeof INTLAYER_CONFIG_FILE_CANDIDATES)[number] | undefined> => {\n for (const candidate of INTLAYER_CONFIG_FILE_CANDIDATES) {\n if (await exists(rootDir, candidate)) {\n return candidate;\n }\n }\n\n return undefined;\n};\n\n/**\n * Locates the environment file the CMS credentials should be written to. Uses\n * `fast-glob` to detect an existing dotenv file at the project root, preferring\n * a plain `.env`; falls back to `.env` (to be created) when none exist.\n */\nexport const findEnvFile = async (rootDir: string): Promise<string> => {\n const matches = await fg([...ENV_FILE_CANDIDATES], {\n cwd: rootDir,\n dot: true,\n deep: 1,\n onlyFiles: true,\n });\n\n return (\n ENV_FILE_CANDIDATES.find((candidate) => matches.includes(candidate)) ??\n '.env'\n );\n};\n\n/**\n * Inserts or updates a `KEY=value` line in dotenv file content. An existing\n * assignment of the same key is replaced in place; otherwise the line is\n * appended with a trailing newline.\n */\nconst upsertEnvVariable = (\n content: string,\n key: string,\n value: string\n): string => {\n const line = `${key}=${value}`;\n const keyMatcher = new RegExp(`^${key}=.*$`, 'm');\n\n if (keyMatcher.test(content)) {\n return content.replace(keyMatcher, line);\n }\n\n const needsLeadingNewline = content.length > 0 && !content.endsWith('\\n');\n\n return `${content}${needsLeadingNewline ? '\\n' : ''}${line}\\n`;\n};\n\n/**\n * Persists the CMS access-key credentials to the project's environment file as\n * `INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`. The target file is detected\n * with {@link findEnvFile} and created when missing. Returns the relative path\n * of the file that was written.\n */\nexport const writeCmsCredentialsToEnv = async (\n rootDir: string,\n { clientId, clientSecret }: CmsCredentials\n): Promise<string> => {\n const envFile = await findEnvFile(rootDir);\n\n let content = '';\n if (await exists(rootDir, envFile)) {\n content = await readFileFromRoot(rootDir, envFile);\n }\n\n let updatedContent = content;\n updatedContent = upsertEnvVariable(\n updatedContent,\n 'INTLAYER_CLIENT_ID',\n clientId\n );\n updatedContent = upsertEnvVariable(\n updatedContent,\n 'INTLAYER_CLIENT_SECRET',\n clientSecret\n );\n\n await writeFileToRoot(rootDir, envFile, updatedContent);\n logger(\n `${v} Saved Intlayer CMS credentials to ${colorizePath(envFile)} (${colorize('INTLAYER_CLIENT_ID', ANSIColors.GREY_LIGHT)}, ${colorize('INTLAYER_CLIENT_SECRET', ANSIColors.GREY_LIGHT)})`\n );\n\n return envFile;\n};\n\n/**\n * Enables the Intlayer visual editor in the project's configuration file:\n * flips `editor.enabled` to `true` and wires `clientId` / `clientSecret` to the\n * matching environment variables. JSON configs cannot reference `process.env`,\n * so they are skipped with a warning. Returns the config file that was updated,\n * or `undefined` when no editable config was found.\n */\nexport const enableEditorInConfig = async (\n rootDir: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) {\n logger(\n `${x} Could not find an Intlayer configuration file to enable the editor.`,\n { level: 'warn' }\n );\n return undefined;\n }\n\n const extension = configFile.split('.').pop()!;\n\n if (extension === 'json') {\n logger(\n `${x} ${colorizePath(configFile)} is a JSON config and cannot reference environment variables. Enable the editor and set clientId/clientSecret manually.`,\n { level: 'warn' }\n );\n return undefined;\n }\n\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = enableIntlayerEditorConfig(content);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(`${v} Enabled the Intlayer editor in ${colorizePath(configFile)}`);\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already has the Intlayer editor enabled`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `routing.mode` in the project's Intlayer configuration file. Returns the\n * config file that was updated, or `undefined` when none was found.\n */\nexport const setRoutingModeInConfig = async (\n rootDir: string,\n mode: RoutingMode\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigRoutingMode(content, extension, mode);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`routing.mode = '${mode}'`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `routing.enableProxy` in the project's Intlayer configuration file.\n * Returns the config file that was updated, or `undefined` when none was found.\n */\nexport const setEnableProxyInConfig = async (\n rootDir: string,\n enableProxy: boolean\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigEnableProxy(\n content,\n extension,\n enableProxy\n );\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`routing.enableProxy = ${enableProxy}`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Reduces `routing` in the project's Intlayer configuration file to its\n * `storage` entry. Returns the config file that was updated, or `undefined`\n * when none was found.\n */\nexport const setRoutingStorageOnlyInConfig = async (\n rootDir: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigRoutingStorageOnly(\n content,\n extension\n );\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Kept only ${colorize('routing.storage', ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)} (no URL routing in this project)`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `compiler.output` in the project's Intlayer configuration file to the\n * given `{{variable}}` path template. Returns the config file that was updated,\n * or `undefined` when none was found.\n */\nexport const setCompilerOutputInConfig = async (\n rootDir: string,\n outputTemplate: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigCompilerOutput(\n content,\n extension,\n outputTemplate\n );\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`compiler.output = '${outputTemplate}'`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Completes the CMS setup once credentials are received from the login flow:\n * writes them to the environment file and enables the editor in the Intlayer\n * configuration file.\n */\nexport const setupCmsCredentials = async (\n rootDir: string,\n credentials: CmsCredentials\n): Promise<void> => {\n await writeCmsCredentialsToEnv(rootDir, credentials);\n await enableEditorInConfig(rootDir);\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cms.mjs","names":[],"sources":["../../../src/init/cms.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, logger, v, x } from '@intlayer/config/logger';\nimport fg from 'fast-glob';\nimport {\n enableIntlayerEditorConfig,\n type RoutingMode,\n setIntlayerConfigCompilerOutput,\n setIntlayerConfigDictionaryLocale,\n setIntlayerConfigEnableProxy,\n setIntlayerConfigRoutingMode,\n setIntlayerConfigRoutingStorageOnly,\n} from './utils/configManipulation';\nimport { exists, readFileFromRoot, writeFileToRoot } from './utils/fileSystem';\n\n/**\n * Intlayer configuration file candidates, ordered by the precedence used when\n * resolving which file to mutate.\n */\nexport const INTLAYER_CONFIG_FILE_CANDIDATES = [\n 'intlayer.config.ts',\n 'intlayer.config.mjs',\n 'intlayer.config.js',\n 'intlayer.config.cjs',\n 'intlayer.config.json',\n] as const;\n\n/**\n * Environment files searched (most-preferred first) when persisting the CMS\n * credentials. The first existing match is reused; otherwise a `.env` file is\n * created at the project root.\n */\nconst ENV_FILE_CANDIDATES = ['.env', '.env.local', '.env.development'] as const;\n\n/** Credentials returned by the CMS login flow (access key pair). */\nexport type CmsCredentials = {\n clientId: string;\n clientSecret: string;\n};\n\n/**\n * Resolves the first existing Intlayer configuration file at the project root,\n * or `undefined` when none is present.\n */\nconst findIntlayerConfigFile = async (\n rootDir: string\n): Promise<(typeof INTLAYER_CONFIG_FILE_CANDIDATES)[number] | undefined> => {\n for (const candidate of INTLAYER_CONFIG_FILE_CANDIDATES) {\n if (await exists(rootDir, candidate)) {\n return candidate;\n }\n }\n\n return undefined;\n};\n\n/**\n * Locates the environment file the CMS credentials should be written to. Uses\n * `fast-glob` to detect an existing dotenv file at the project root, preferring\n * a plain `.env`; falls back to `.env` (to be created) when none exist.\n */\nexport const findEnvFile = async (rootDir: string): Promise<string> => {\n const matches = await fg([...ENV_FILE_CANDIDATES], {\n cwd: rootDir,\n dot: true,\n deep: 1,\n onlyFiles: true,\n });\n\n return (\n ENV_FILE_CANDIDATES.find((candidate) => matches.includes(candidate)) ??\n '.env'\n );\n};\n\n/**\n * Inserts or updates a `KEY=value` line in dotenv file content. An existing\n * assignment of the same key is replaced in place; otherwise the line is\n * appended with a trailing newline.\n */\nconst upsertEnvVariable = (\n content: string,\n key: string,\n value: string\n): string => {\n const line = `${key}=${value}`;\n const keyMatcher = new RegExp(`^${key}=.*$`, 'm');\n\n if (keyMatcher.test(content)) {\n return content.replace(keyMatcher, line);\n }\n\n const needsLeadingNewline = content.length > 0 && !content.endsWith('\\n');\n\n return `${content}${needsLeadingNewline ? '\\n' : ''}${line}\\n`;\n};\n\n/**\n * Persists the CMS access-key credentials to the project's environment file as\n * `INTLAYER_CLIENT_ID` / `INTLAYER_CLIENT_SECRET`. The target file is detected\n * with {@link findEnvFile} and created when missing. Returns the relative path\n * of the file that was written.\n */\nexport const writeCmsCredentialsToEnv = async (\n rootDir: string,\n { clientId, clientSecret }: CmsCredentials\n): Promise<string> => {\n const envFile = await findEnvFile(rootDir);\n\n let content = '';\n if (await exists(rootDir, envFile)) {\n content = await readFileFromRoot(rootDir, envFile);\n }\n\n let updatedContent = content;\n updatedContent = upsertEnvVariable(\n updatedContent,\n 'INTLAYER_CLIENT_ID',\n clientId\n );\n updatedContent = upsertEnvVariable(\n updatedContent,\n 'INTLAYER_CLIENT_SECRET',\n clientSecret\n );\n\n await writeFileToRoot(rootDir, envFile, updatedContent);\n logger(\n `${v} Saved Intlayer CMS credentials to ${colorizePath(envFile)} (${colorize('INTLAYER_CLIENT_ID', ANSIColors.GREY_LIGHT)}, ${colorize('INTLAYER_CLIENT_SECRET', ANSIColors.GREY_LIGHT)})`\n );\n\n return envFile;\n};\n\n/**\n * Enables the Intlayer visual editor in the project's configuration file:\n * flips `editor.enabled` to `true` and wires `clientId` / `clientSecret` to the\n * matching environment variables. JSON configs cannot reference `process.env`,\n * so they are skipped with a warning. Returns the config file that was updated,\n * or `undefined` when no editable config was found.\n */\nexport const enableEditorInConfig = async (\n rootDir: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) {\n logger(\n `${x} Could not find an Intlayer configuration file to enable the editor.`,\n { level: 'warn' }\n );\n return undefined;\n }\n\n const extension = configFile.split('.').pop()!;\n\n if (extension === 'json') {\n logger(\n `${x} ${colorizePath(configFile)} is a JSON config and cannot reference environment variables. Enable the editor and set clientId/clientSecret manually.`,\n { level: 'warn' }\n );\n return undefined;\n }\n\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = enableIntlayerEditorConfig(content);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(`${v} Enabled the Intlayer editor in ${colorizePath(configFile)}`);\n } else {\n logger(\n `${v} ${colorizePath(configFile)} already has the Intlayer editor enabled`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `routing.mode` in the project's Intlayer configuration file. Returns the\n * config file that was updated, or `undefined` when none was found.\n */\nexport const setRoutingModeInConfig = async (\n rootDir: string,\n mode: RoutingMode\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigRoutingMode(content, extension, mode);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`routing.mode = '${mode}'`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `routing.enableProxy` in the project's Intlayer configuration file.\n * Returns the config file that was updated, or `undefined` when none was found.\n */\nexport const setEnableProxyInConfig = async (\n rootDir: string,\n enableProxy: boolean\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigEnableProxy(\n content,\n extension,\n enableProxy\n );\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`routing.enableProxy = ${enableProxy}`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Reduces `routing` in the project's Intlayer configuration file to its\n * `storage` entry. Returns the config file that was updated, or `undefined`\n * when none was found.\n */\nexport const setRoutingStorageOnlyInConfig = async (\n rootDir: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigRoutingStorageOnly(\n content,\n extension\n );\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Kept only ${colorize('routing.storage', ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)} (no URL routing in this project)`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `compiler.output` in the project's Intlayer configuration file to the\n * given `{{variable}}` path template. Returns the config file that was updated,\n * or `undefined` when none was found.\n */\nexport const setCompilerOutputInConfig = async (\n rootDir: string,\n outputTemplate: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigCompilerOutput(\n content,\n extension,\n outputTemplate\n );\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize(`compiler.output = '${outputTemplate}'`, ANSIColors.GREY_LIGHT)} in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Sets `dictionary.locale` to the default locale in the project's Intlayer\n * configuration file. Returns the config file that was updated, or `undefined`\n * when none was found.\n */\nexport const setDictionaryLocaleInConfig = async (\n rootDir: string\n): Promise<string | undefined> => {\n const configFile = await findIntlayerConfigFile(rootDir);\n\n if (!configFile) return undefined;\n\n const extension = configFile.split('.').pop()!;\n const content = await readFileFromRoot(rootDir, configFile);\n const updatedContent = setIntlayerConfigDictionaryLocale(content, extension);\n\n if (updatedContent !== content) {\n await writeFileToRoot(rootDir, configFile, updatedContent);\n logger(\n `${v} Set ${colorize('dictionary.locale', ANSIColors.GREY_LIGHT)} to the default locale in ${colorizePath(configFile)}`\n );\n }\n\n return configFile;\n};\n\n/**\n * Completes the CMS setup once credentials are received from the login flow:\n * writes them to the environment file and enables the editor in the Intlayer\n * configuration file.\n */\nexport const setupCmsCredentials = async (\n rootDir: string,\n credentials: CmsCredentials\n): Promise<void> => {\n await writeCmsCredentialsToEnv(rootDir, credentials);\n await enableEditorInConfig(rootDir);\n};\n"],"mappings":"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"}
|