@intlayer/chokidar 8.6.2 → 8.6.4

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.
@@ -21,9 +21,9 @@ const generateFetchLoadContentModule = (format, relativePrefix, locales) => {
21
21
  const extension = format === "cjs" ? "cjs" : "mjs";
22
22
  const body = `const loadContent = (key) => {
23
23
  const dynContent = loadContentDyn(key);
24
- return {\n${sortedLocales.map((locale) => ` '${locale}': async () => {\n try {\n const res = await fetch(\`\${configuration.editor.liveSyncURL}/dictionaries/\${key}/${locale}\`);\n return await res.json();\n } catch {\n return dynContent['${locale}']();\n }\n }`).join(",\n")}\n };\n};\n`;
25
- if (format === "esm") return `import { configuration } from 'intlayer';\nimport { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\n\n${body}\nexport { loadContent };\n`;
26
- return `const { configuration } = require('intlayer');\nconst { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\n\n${body}\nmodule.exports = { loadContent };\n`;
24
+ return {\n${sortedLocales.map((locale) => ` '${locale}': async () => {\n try {\n const res = await fetch(\`\${editor.liveSyncURL}/dictionaries/\${key}/${locale}\`);\n return await res.json();\n } catch {\n return dynContent['${locale}']();\n }\n }`).join(",\n")}\n };\n};\n`;
25
+ if (format === "esm") return `import { editor } from 'intlayer';\nimport { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\n\n${body}\nexport { loadContent };\n`;
26
+ return `const { editor } = require('intlayer');\nconst { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\n\n${body}\nmodule.exports = { loadContent };\n`;
27
27
  };
28
28
  /**
29
29
  * Generates the content of a fetch dictionary entry point file.
@@ -1 +1 @@
1
- {"version":3,"file":"writeFetchDictionary.cjs","names":["OUTPUT_FORMAT","parallelize","writeFileIfChanged"],"sources":["../../../src/buildIntlayerDictionary/writeFetchDictionary.ts"],"sourcesContent":["import { mkdir } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { OUTPUT_FORMAT } from '@intlayer/config/defaultValues';\nimport { colorizePath } from '@intlayer/config/logger';\nimport { normalizePath } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { parallelize } from '../utils/parallelize';\nimport { writeFileIfChanged } from '../writeFileIfChanged';\nimport type { LocalizedDictionaryOutput } from './writeDynamicDictionary';\n\nconst LOAD_CONTENT_MODULE = '_loadjson';\n\n/**\n * Generates the content of the shared `loadContent` module for fetch dictionaries.\n * - `configuration` is imported at runtime from \"intlayer\" (liveSyncURL not baked in).\n * - Fallback delegates to the dynamic dictionary's `_loadjson` module.\n * - Locales are baked in so each entry is a static function referencing one locale.\n */\nexport const generateFetchLoadContentModule = (\n format: 'cjs' | 'esm',\n relativePrefix: string,\n locales: string[]\n): string => {\n const sortedLocales = [...locales].sort((a, b) =>\n String(a).localeCompare(String(b))\n );\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n\n const localeEntries = sortedLocales\n .map(\n (locale) =>\n ` '${locale}': async () => {\\n` +\n ` try {\\n` +\n ` const res = await fetch(\\`\\${configuration.editor.liveSyncURL}/dictionaries/\\${key}/${locale}\\`);\\n` +\n ` return await res.json();\\n` +\n ` } catch {\\n` +\n ` return dynContent['${locale}']();\\n` +\n ` }\\n` +\n ` }`\n )\n .join(',\\n');\n\n const body =\n `const loadContent = (key) => {\\n` +\n ` const dynContent = loadContentDyn(key);\\n` +\n ` return {\\n${localeEntries}\\n };\\n` +\n `};\\n`;\n\n if (format === 'esm') {\n return (\n `import { configuration } from 'intlayer';\\n` +\n `import { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `${body}\\nexport { loadContent };\\n`\n );\n }\n return (\n `const { configuration } = require('intlayer');\\n` +\n `const { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `${body}\\nmodule.exports = { loadContent };\\n`\n );\n};\n\n/**\n * Generates the content of a fetch dictionary entry point file.\n */\nexport const generateDictionaryEntryPoint = (\n key: string,\n format: 'cjs' | 'esm' = 'esm'\n): string => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n if (format === 'esm') {\n return (\n `import { loadContent } from './${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `const content = loadContent('${key}');\\n\\n` +\n `export default content;\\n`\n );\n }\n return (\n `const { loadContent } = require('./${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `module.exports = loadContent('${key}');\\n`\n );\n};\n\n/**\n * Write the localized dictionaries to the dictionariesDir\n * @param mergedDictionaries - The merged dictionaries\n * @param configuration - The configuration\n * @returns The final dictionaries\n *\n * @example\n * ```ts\n * const unmergedDictionaries = await writeUnmergedDictionaries(dictionaries);\n * const finalDictionaries = await writeFinalDictionaries(unmergedDictionaries);\n * console.log(finalDictionaries);\n *\n * // .intlayer/fetch_dictionary/home.mjs\n * // .intlayer/fetch_dictionary/home.cjs\n * ```\n */\nexport const writeFetchDictionary = async (\n dynamicDictionaries: LocalizedDictionaryOutput,\n configuration: IntlayerConfig,\n formats: ('cjs' | 'esm')[] = OUTPUT_FORMAT\n): Promise<LocalizedDictionaryOutput> => {\n const { fetchDictionariesDir, dynamicDictionariesDir } = configuration.system;\n const { locales } = configuration.internationalization;\n\n // Compute relative path from fetch dir (where _loadjson lives) to dynamic dir\n let relativePrefix = normalizePath(\n relative(fetchDictionariesDir, dynamicDictionariesDir)\n );\n if (!relativePrefix.startsWith('.')) {\n relativePrefix = `./${relativePrefix}`;\n }\n\n await mkdir(resolve(fetchDictionariesDir), { recursive: true });\n\n // Write the shared loadContent module once per format\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`),\n generateFetchLoadContentModule(format, relativePrefix, locales)\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`))}:`,\n err\n );\n });\n });\n\n const resultDictionariesPaths: LocalizedDictionaryOutput = {};\n\n // Write entry points for each dictionary in parallel\n await parallelize(Object.entries(dynamicDictionaries), async ([key]) => {\n if (key === 'undefined') return;\n\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n const content = generateDictionaryEntryPoint(key, format);\n\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${key}.${extension}`),\n content\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${key}.${extension}`))}:`,\n err\n );\n });\n });\n });\n\n return resultDictionariesPaths;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAM,sBAAsB;;;;;;;AAQ5B,MAAa,kCACX,QACA,gBACA,YACW;CACX,MAAM,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,MAC1C,OAAO,EAAE,CAAC,cAAc,OAAO,EAAE,CAAC,CACnC;CACD,MAAM,YAAY,WAAW,QAAQ,QAAQ;CAgB7C,MAAM,OACJ;;cAfoB,cACnB,KACE,WACC,MAAM,OAAO,yHAEgF,OAAO,gFAGxE,OAAO,mBAGtC,CACA,KAAK,MAAM,CAKiB;AAG/B,KAAI,WAAW,MACb,QACE,6FACkD,eAAe,GAAG,oBAAoB,GAAG,UAAU,QAClG,KAAK;AAGZ,QACE,oGACoD,eAAe,GAAG,oBAAoB,GAAG,UAAU,SACpG,KAAK;;;;;AAOZ,MAAa,gCACX,KACA,SAAwB,UACb;CACX,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,KAAI,WAAW,MACb,QACE,kCAAkC,oBAAoB,GAAG,UAAU,qCACnC,IAAI;AAIxC,QACE,sCAAsC,oBAAoB,GAAG,UAAU,uCACtC,IAAI;;;;;;;;;;;;;;;;;;AAoBzC,MAAa,uBAAuB,OAClC,qBACA,eACA,UAA6BA,iDACU;CACvC,MAAM,EAAE,sBAAsB,2BAA2B,cAAc;CACvE,MAAM,EAAE,YAAY,cAAc;CAGlC,IAAI,mFACO,sBAAsB,uBAAuB,CACvD;AACD,KAAI,CAAC,eAAe,WAAW,IAAI,CACjC,kBAAiB,KAAK;AAGxB,0DAAoB,qBAAqB,EAAE,EAAE,WAAW,MAAM,CAAC;AAG/D,OAAMC,sCAAY,SAAS,OAAO,WAAW;EAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,QAAMC,qEACI,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,EACpE,+BAA+B,QAAQ,gBAAgB,QAAQ,CAChE,CAAC,OAAO,QAAQ;AACf,WAAQ,MACN,yFAA6C,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,CAAC,CAAC,IAC3G,IACD;IACD;GACF;CAEF,MAAM,0BAAqD,EAAE;AAG7D,OAAMD,sCAAY,OAAO,QAAQ,oBAAoB,EAAE,OAAO,CAAC,SAAS;AACtE,MAAI,QAAQ,YAAa;AAEzB,QAAMA,sCAAY,SAAS,OAAO,WAAW;GAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;GAC7C,MAAM,UAAU,6BAA6B,KAAK,OAAO;AAEzD,SAAMC,qEACI,sBAAsB,GAAG,IAAI,GAAG,YAAY,EACpD,QACD,CAAC,OAAO,QAAQ;AACf,YAAQ,MACN,yFAA6C,sBAAsB,GAAG,IAAI,GAAG,YAAY,CAAC,CAAC,IAC3F,IACD;KACD;IACF;GACF;AAEF,QAAO"}
1
+ {"version":3,"file":"writeFetchDictionary.cjs","names":["OUTPUT_FORMAT","parallelize","writeFileIfChanged"],"sources":["../../../src/buildIntlayerDictionary/writeFetchDictionary.ts"],"sourcesContent":["import { mkdir } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { OUTPUT_FORMAT } from '@intlayer/config/defaultValues';\nimport { colorizePath } from '@intlayer/config/logger';\nimport { normalizePath } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { parallelize } from '../utils/parallelize';\nimport { writeFileIfChanged } from '../writeFileIfChanged';\nimport type { LocalizedDictionaryOutput } from './writeDynamicDictionary';\n\nconst LOAD_CONTENT_MODULE = '_loadjson';\n\n/**\n * Generates the content of the shared `loadContent` module for fetch dictionaries.\n * - `configuration` is imported at runtime from \"intlayer\" (liveSyncURL not baked in).\n * - Fallback delegates to the dynamic dictionary's `_loadjson` module.\n * - Locales are baked in so each entry is a static function referencing one locale.\n */\nexport const generateFetchLoadContentModule = (\n format: 'cjs' | 'esm',\n relativePrefix: string,\n locales: string[]\n): string => {\n const sortedLocales = [...locales].sort((a, b) =>\n String(a).localeCompare(String(b))\n );\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n\n const localeEntries = sortedLocales\n .map(\n (locale) =>\n ` '${locale}': async () => {\\n` +\n ` try {\\n` +\n ` const res = await fetch(\\`\\${editor.liveSyncURL}/dictionaries/\\${key}/${locale}\\`);\\n` +\n ` return await res.json();\\n` +\n ` } catch {\\n` +\n ` return dynContent['${locale}']();\\n` +\n ` }\\n` +\n ` }`\n )\n .join(',\\n');\n\n const body =\n `const loadContent = (key) => {\\n` +\n ` const dynContent = loadContentDyn(key);\\n` +\n ` return {\\n${localeEntries}\\n };\\n` +\n `};\\n`;\n\n if (format === 'esm') {\n return (\n `import { editor } from 'intlayer';\\n` +\n `import { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `${body}\\nexport { loadContent };\\n`\n );\n }\n return (\n `const { editor } = require('intlayer');\\n` +\n `const { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `${body}\\nmodule.exports = { loadContent };\\n`\n );\n};\n\n/**\n * Generates the content of a fetch dictionary entry point file.\n */\nexport const generateDictionaryEntryPoint = (\n key: string,\n format: 'cjs' | 'esm' = 'esm'\n): string => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n if (format === 'esm') {\n return (\n `import { loadContent } from './${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `const content = loadContent('${key}');\\n\\n` +\n `export default content;\\n`\n );\n }\n return (\n `const { loadContent } = require('./${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `module.exports = loadContent('${key}');\\n`\n );\n};\n\n/**\n * Write the localized dictionaries to the dictionariesDir\n * @param mergedDictionaries - The merged dictionaries\n * @param configuration - The configuration\n * @returns The final dictionaries\n *\n * @example\n * ```ts\n * const unmergedDictionaries = await writeUnmergedDictionaries(dictionaries);\n * const finalDictionaries = await writeFinalDictionaries(unmergedDictionaries);\n * console.log(finalDictionaries);\n *\n * // .intlayer/fetch_dictionary/home.mjs\n * // .intlayer/fetch_dictionary/home.cjs\n * ```\n */\nexport const writeFetchDictionary = async (\n dynamicDictionaries: LocalizedDictionaryOutput,\n configuration: IntlayerConfig,\n formats: ('cjs' | 'esm')[] = OUTPUT_FORMAT\n): Promise<LocalizedDictionaryOutput> => {\n const { fetchDictionariesDir, dynamicDictionariesDir } = configuration.system;\n const { locales } = configuration.internationalization;\n\n // Compute relative path from fetch dir (where _loadjson lives) to dynamic dir\n let relativePrefix = normalizePath(\n relative(fetchDictionariesDir, dynamicDictionariesDir)\n );\n if (!relativePrefix.startsWith('.')) {\n relativePrefix = `./${relativePrefix}`;\n }\n\n await mkdir(resolve(fetchDictionariesDir), { recursive: true });\n\n // Write the shared loadContent module once per format\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`),\n generateFetchLoadContentModule(format, relativePrefix, locales)\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`))}:`,\n err\n );\n });\n });\n\n const resultDictionariesPaths: LocalizedDictionaryOutput = {};\n\n // Write entry points for each dictionary in parallel\n await parallelize(Object.entries(dynamicDictionaries), async ([key]) => {\n if (key === 'undefined') return;\n\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n const content = generateDictionaryEntryPoint(key, format);\n\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${key}.${extension}`),\n content\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${key}.${extension}`))}:`,\n err\n );\n });\n });\n });\n\n return resultDictionariesPaths;\n};\n"],"mappings":";;;;;;;;;;;AAUA,MAAM,sBAAsB;;;;;;;AAQ5B,MAAa,kCACX,QACA,gBACA,YACW;CACX,MAAM,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,MAC1C,OAAO,EAAE,CAAC,cAAc,OAAO,EAAE,CAAC,CACnC;CACD,MAAM,YAAY,WAAW,QAAQ,QAAQ;CAgB7C,MAAM,OACJ;;cAfoB,cACnB,KACE,WACC,MAAM,OAAO,2GAEkE,OAAO,gFAG1D,OAAO,mBAGtC,CACA,KAAK,MAAM,CAKiB;AAG/B,KAAI,WAAW,MACb,QACE,sFACkD,eAAe,GAAG,oBAAoB,GAAG,UAAU,QAClG,KAAK;AAGZ,QACE,6FACoD,eAAe,GAAG,oBAAoB,GAAG,UAAU,SACpG,KAAK;;;;;AAOZ,MAAa,gCACX,KACA,SAAwB,UACb;CACX,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,KAAI,WAAW,MACb,QACE,kCAAkC,oBAAoB,GAAG,UAAU,qCACnC,IAAI;AAIxC,QACE,sCAAsC,oBAAoB,GAAG,UAAU,uCACtC,IAAI;;;;;;;;;;;;;;;;;;AAoBzC,MAAa,uBAAuB,OAClC,qBACA,eACA,UAA6BA,iDACU;CACvC,MAAM,EAAE,sBAAsB,2BAA2B,cAAc;CACvE,MAAM,EAAE,YAAY,cAAc;CAGlC,IAAI,mFACO,sBAAsB,uBAAuB,CACvD;AACD,KAAI,CAAC,eAAe,WAAW,IAAI,CACjC,kBAAiB,KAAK;AAGxB,0DAAoB,qBAAqB,EAAE,EAAE,WAAW,MAAM,CAAC;AAG/D,OAAMC,sCAAY,SAAS,OAAO,WAAW;EAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,QAAMC,qEACI,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,EACpE,+BAA+B,QAAQ,gBAAgB,QAAQ,CAChE,CAAC,OAAO,QAAQ;AACf,WAAQ,MACN,yFAA6C,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,CAAC,CAAC,IAC3G,IACD;IACD;GACF;CAEF,MAAM,0BAAqD,EAAE;AAG7D,OAAMD,sCAAY,OAAO,QAAQ,oBAAoB,EAAE,OAAO,CAAC,SAAS;AACtE,MAAI,QAAQ,YAAa;AAEzB,QAAMA,sCAAY,SAAS,OAAO,WAAW;GAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;GAC7C,MAAM,UAAU,6BAA6B,KAAK,OAAO;AAEzD,SAAMC,qEACI,sBAAsB,GAAG,IAAI,GAAG,YAAY,EACpD,QACD,CAAC,OAAO,QAAQ;AACf,YAAQ,MACN,yFAA6C,sBAAsB,GAAG,IAAI,GAAG,YAAY,CAAC,CAAC,IAC3F,IACD;KACD;IACF;GACF;AAEF,QAAO"}
@@ -6,14 +6,13 @@ let node_fs = require("node:fs");
6
6
  let simple_git = require("simple-git");
7
7
  simple_git = require_runtime.__toESM(simple_git);
8
8
  let _intlayer_config_built = require("@intlayer/config/built");
9
- _intlayer_config_built = require_runtime.__toESM(_intlayer_config_built);
10
9
 
11
10
  //#region src/listGitFiles.ts
12
11
  const getGitRootDir = async () => {
13
12
  try {
14
13
  return (await (0, simple_git.default)().revparse(["--show-toplevel"])).trim();
15
14
  } catch (error) {
16
- (0, _intlayer_config_logger.getAppLogger)(_intlayer_config_built.default)(`Error getting git root directory: ${error}`, { level: "error" });
15
+ (0, _intlayer_config_logger.getAppLogger)({ log: _intlayer_config_built.log })(`Error getting git root directory: ${error}`, { level: "error" });
17
16
  return null;
18
17
  }
19
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"listGitFiles.cjs","names":["configuration"],"sources":["../../src/listGitFiles.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport configuration from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport simpleGit from 'simple-git';\n\nexport type DiffMode = 'gitDiff' | 'uncommitted' | 'unpushed' | 'untracked';\n\nconst getGitRootDir = async (): Promise<string | null> => {\n try {\n const git = simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (error) {\n const appLogger = getAppLogger(configuration);\n appLogger(`Error getting git root directory: ${error}`, {\n level: 'error',\n });\n return null;\n }\n};\n\nexport type ListGitFilesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n absolute?: boolean;\n};\n\nexport const listGitFiles = async ({\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n absolute = true,\n}: ListGitFilesOptions) => {\n try {\n const git = simpleGit();\n const diff: Set<string> = new Set();\n\n if (mode.includes('untracked')) {\n const status = await git.status();\n status.not_added.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('uncommitted')) {\n // Get uncommitted changes\n const uncommittedDiff = await git.diff(['--name-only', 'HEAD']);\n\n const uncommittedFiles = uncommittedDiff.split('\\n').filter(Boolean);\n\n uncommittedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('unpushed')) {\n // Get unpushed commits\n const unpushedDiff = await git.diff(['--name-only', '@{push}...HEAD']);\n\n const unpushedFiles = unpushedDiff.split('\\n').filter(Boolean);\n\n unpushedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('gitDiff')) {\n // Get the base branch (usually main/master) from CI environment\n\n await git.fetch(baseRef);\n\n const diffBranch = await git.diff([\n '--name-only',\n `${baseRef}...${currentRef}`,\n ]);\n\n const gitDiffFiles = diffBranch.split('\\n').filter(Boolean);\n\n gitDiffFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (absolute) {\n const gitRootDir = await getGitRootDir();\n if (!gitRootDir) {\n return [];\n }\n return Array.from(diff).map((file) => join(gitRootDir, file));\n }\n\n return Array.from(diff);\n } catch (error) {\n console.warn('Failed to get changes list:', error);\n }\n};\n\nexport type ListGitLinesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n};\n\nexport const listGitLines = async (\n filePath: string,\n {\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n }: ListGitLinesOptions\n): Promise<number[]> => {\n const git = simpleGit();\n // We collect **line numbers** (1-based) that were modified/added by the diff.\n // Using a Set ensures uniqueness when the same line is reported by several modes.\n const changedLines: Set<number> = new Set();\n\n /**\n * Extracts line numbers from a diff generated with `--unified=0`.\n * Each hunk header looks like: @@ -<oldStart>,<oldCount> +<newStart>,<newCount> @@\n * We consider both the \"+\" (new) side for additions and the \"-\" (old) side for deletions.\n * For deletions, we add the line before and after the deletion point in the current file.\n */\n const collectLinesFromDiff = (diffOutput: string) => {\n const hunkRegex = /@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/g;\n let match: RegExpExecArray | null;\n\n // biome-ignore lint/suspicious/noAssignInExpressions: Used in while loop condition\n while ((match = hunkRegex.exec(diffOutput)) !== null) {\n const oldCount = match[2] ? Number(match[2]) : 1;\n const newStart = Number(match[3]);\n const newCount = match[4] ? Number(match[4]) : 1;\n\n // Handle additions/modifications (+ side)\n if (newCount > 0) {\n for (let i = 0; i < newCount; i++) {\n changedLines.add(newStart + i);\n }\n }\n\n // Handle deletions (- side)\n if (oldCount > 0 && newCount === 0) {\n // For deletions, add the line before and after the deletion point\n // The deletion point in the new file is at newStart\n if (newStart > 1) {\n changedLines.add(newStart - 1); // Line before deletion\n }\n changedLines.add(newStart); // Line after deletion (if it exists)\n }\n }\n };\n\n // 1. Handle untracked files – when a file is untracked its entire content is new.\n if (mode.includes('untracked')) {\n const status = await git.status();\n const isUntracked = status.not_added.includes(filePath);\n if (isUntracked) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n content.split('\\n').forEach((_, idx) => {\n changedLines.add(idx + 1);\n });\n } catch {\n // ignore read errors – file may have been deleted, etc.\n }\n }\n }\n\n // 2. Uncommitted changes (working tree vs HEAD)\n if (mode.includes('uncommitted')) {\n const diffOutput = await git.diff(['--unified=0', 'HEAD', '--', filePath]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 3. Unpushed commits – compare local branch to its upstream\n if (mode.includes('unpushed')) {\n const diffOutput = await git.diff([\n '--unified=0',\n '@{push}...HEAD',\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 4. Regular git diff between baseRef and currentRef (e.g., CI pull-request diff)\n if (mode.includes('gitDiff')) {\n await git.fetch(baseRef);\n const diffOutput = await git.diff([\n '--unified=0',\n `${baseRef}...${currentRef}`,\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // Return the list sorted for convenience\n return Array.from(changedLines).sort((a, b) => a - b);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"listGitFiles.cjs","names":[],"sources":["../../src/listGitFiles.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { log } from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport simpleGit from 'simple-git';\n\nexport type DiffMode = 'gitDiff' | 'uncommitted' | 'unpushed' | 'untracked';\n\nconst getGitRootDir = async (): Promise<string | null> => {\n try {\n const git = simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (error) {\n const appLogger = getAppLogger({ log });\n appLogger(`Error getting git root directory: ${error}`, {\n level: 'error',\n });\n return null;\n }\n};\n\nexport type ListGitFilesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n absolute?: boolean;\n};\n\nexport const listGitFiles = async ({\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n absolute = true,\n}: ListGitFilesOptions) => {\n try {\n const git = simpleGit();\n const diff: Set<string> = new Set();\n\n if (mode.includes('untracked')) {\n const status = await git.status();\n status.not_added.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('uncommitted')) {\n // Get uncommitted changes\n const uncommittedDiff = await git.diff(['--name-only', 'HEAD']);\n\n const uncommittedFiles = uncommittedDiff.split('\\n').filter(Boolean);\n\n uncommittedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('unpushed')) {\n // Get unpushed commits\n const unpushedDiff = await git.diff(['--name-only', '@{push}...HEAD']);\n\n const unpushedFiles = unpushedDiff.split('\\n').filter(Boolean);\n\n unpushedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('gitDiff')) {\n // Get the base branch (usually main/master) from CI environment\n\n await git.fetch(baseRef);\n\n const diffBranch = await git.diff([\n '--name-only',\n `${baseRef}...${currentRef}`,\n ]);\n\n const gitDiffFiles = diffBranch.split('\\n').filter(Boolean);\n\n gitDiffFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (absolute) {\n const gitRootDir = await getGitRootDir();\n if (!gitRootDir) {\n return [];\n }\n return Array.from(diff).map((file) => join(gitRootDir, file));\n }\n\n return Array.from(diff);\n } catch (error) {\n console.warn('Failed to get changes list:', error);\n }\n};\n\nexport type ListGitLinesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n};\n\nexport const listGitLines = async (\n filePath: string,\n {\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n }: ListGitLinesOptions\n): Promise<number[]> => {\n const git = simpleGit();\n // We collect **line numbers** (1-based) that were modified/added by the diff.\n // Using a Set ensures uniqueness when the same line is reported by several modes.\n const changedLines: Set<number> = new Set();\n\n /**\n * Extracts line numbers from a diff generated with `--unified=0`.\n * Each hunk header looks like: @@ -<oldStart>,<oldCount> +<newStart>,<newCount> @@\n * We consider both the \"+\" (new) side for additions and the \"-\" (old) side for deletions.\n * For deletions, we add the line before and after the deletion point in the current file.\n */\n const collectLinesFromDiff = (diffOutput: string) => {\n const hunkRegex = /@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/g;\n let match: RegExpExecArray | null;\n\n // biome-ignore lint/suspicious/noAssignInExpressions: Used in while loop condition\n while ((match = hunkRegex.exec(diffOutput)) !== null) {\n const oldCount = match[2] ? Number(match[2]) : 1;\n const newStart = Number(match[3]);\n const newCount = match[4] ? Number(match[4]) : 1;\n\n // Handle additions/modifications (+ side)\n if (newCount > 0) {\n for (let i = 0; i < newCount; i++) {\n changedLines.add(newStart + i);\n }\n }\n\n // Handle deletions (- side)\n if (oldCount > 0 && newCount === 0) {\n // For deletions, add the line before and after the deletion point\n // The deletion point in the new file is at newStart\n if (newStart > 1) {\n changedLines.add(newStart - 1); // Line before deletion\n }\n changedLines.add(newStart); // Line after deletion (if it exists)\n }\n }\n };\n\n // 1. Handle untracked files – when a file is untracked its entire content is new.\n if (mode.includes('untracked')) {\n const status = await git.status();\n const isUntracked = status.not_added.includes(filePath);\n if (isUntracked) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n content.split('\\n').forEach((_, idx) => {\n changedLines.add(idx + 1);\n });\n } catch {\n // ignore read errors – file may have been deleted, etc.\n }\n }\n }\n\n // 2. Uncommitted changes (working tree vs HEAD)\n if (mode.includes('uncommitted')) {\n const diffOutput = await git.diff(['--unified=0', 'HEAD', '--', filePath]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 3. Unpushed commits – compare local branch to its upstream\n if (mode.includes('unpushed')) {\n const diffOutput = await git.diff([\n '--unified=0',\n '@{push}...HEAD',\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 4. Regular git diff between baseRef and currentRef (e.g., CI pull-request diff)\n if (mode.includes('gitDiff')) {\n await git.fetch(baseRef);\n const diffOutput = await git.diff([\n '--unified=0',\n `${baseRef}...${currentRef}`,\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // Return the list sorted for convenience\n return Array.from(changedLines).sort((a, b) => a - b);\n};\n"],"mappings":"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"}
@@ -24,7 +24,7 @@ var DictionariesLogger = class {
24
24
  pluginDone = 0;
25
25
  pluginError;
26
26
  constructor() {
27
- this.prefix = (0, _intlayer_config_logger.getPrefix)(_intlayer_config_built.default?.log?.prefix) ?? "";
27
+ this.prefix = (0, _intlayer_config_logger.getPrefix)(_intlayer_config_built.default.log?.prefix) ?? "";
28
28
  }
29
29
  setExpectRemote(expect) {
30
30
  this.expectRemote = expect;
@@ -1 +1 @@
1
- {"version":3,"file":"log.cjs","names":["spinnerFrames","configuration","ANSIColors","v","x"],"sources":["../../../src/loadDictionaries/log.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n colorize,\n getPrefix,\n spinnerFrames,\n v,\n x,\n} from '@intlayer/config/logger';\nimport { extractErrorMessage } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport class DictionariesLogger {\n private statuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private spinnerIndex = 0;\n private renderedLines = 0;\n private readonly spinnerFrames = spinnerFrames;\n private isFinished = false;\n private readonly prefix: string;\n private lastRenderedState: string = '';\n private remoteCheckInProgress = false;\n private expectRemote = false;\n private remoteError: string | undefined;\n private pluginTotal = 0;\n private pluginDone = 0;\n private pluginError: string | undefined;\n\n constructor() {\n this.prefix = getPrefix(configuration?.log?.prefix) ?? '';\n }\n\n setExpectRemote(expect: boolean) {\n this.expectRemote = expect;\n }\n\n startRemoteCheck() {\n if (this.isFinished) return;\n this.remoteCheckInProgress = true;\n this.startSpinner();\n this.render();\n }\n\n stopRemoteCheck() {\n this.remoteCheckInProgress = false;\n }\n\n update(newStatuses: DictionariesStatus[]) {\n if (this.isFinished) return;\n for (const status of newStatuses) {\n const index = this.statuses.findIndex(\n (s) =>\n s.dictionaryKey === status.dictionaryKey && s.type === status.type\n );\n if (index >= 0) {\n this.statuses[index] = status;\n } else {\n this.statuses.push(status);\n }\n }\n\n // If we expect remote fetch later, avoid rendering a local-only line first\n const { remoteTotal } = this.computeProgress();\n if (this.expectRemote && !this.remoteCheckInProgress && remoteTotal === 0) {\n // Do not start spinner or render yet; wait until remote check starts\n return;\n }\n\n this.startSpinner();\n this.render();\n }\n\n finish() {\n this.isFinished = true;\n this.stopSpinner();\n // Render final state and keep it visible\n this.render();\n }\n\n private startSpinner() {\n if (this.spinnerTimer || this.isFinished) return;\n this.spinnerTimer = setInterval(() => {\n this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n this.render();\n }, 100);\n }\n\n private stopSpinner() {\n if (!this.spinnerTimer) return;\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n\n public setRemoteError = (error?: Error) => {\n this.remoteError = extractErrorMessage(error);\n // Avoid rendering a transient remote-only line while the remote check flag is still true\n // Ensure local + remote are rendered together after a failure\n this.stopRemoteCheck();\n this.render();\n };\n\n setPluginTotal(total: number) {\n if (this.isFinished) return;\n this.pluginTotal = total;\n if (total > 0) {\n this.startSpinner();\n }\n this.render();\n }\n\n setPluginDone(done: number) {\n if (this.isFinished) return;\n this.pluginDone = done;\n this.render();\n }\n\n setPluginError(error?: Error) {\n if (this.isFinished) return;\n this.pluginError = extractErrorMessage(error);\n this.render();\n }\n\n private render() {\n const {\n localTotal,\n localDone,\n remoteTotal,\n remoteDone,\n pluginTotal,\n pluginDone,\n } = this.computeProgress();\n\n const frame = this.spinnerFrames[this.spinnerIndex];\n const clock = colorize(frame, ANSIColors.BLUE);\n const lines: string[] = [];\n\n const isLocalDone = localDone === localTotal;\n const isRemoteDone = remoteDone === remoteTotal;\n const isPluginDone = pluginDone === pluginTotal;\n\n const suppressLocalWhileCheckingRemote =\n this.expectRemote && this.remoteCheckInProgress && remoteTotal === 0;\n\n if (!suppressLocalWhileCheckingRemote) {\n if (isLocalDone) {\n lines.push(\n `${this.prefix} ${v} Local content: ${colorize(`${localDone}`, ANSIColors.GREEN)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Local content: ${colorize(`${localDone}`, ANSIColors.BLUE)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Single remote line: show error, check, or progress counts\n if (remoteTotal > 0 || this.remoteCheckInProgress || this.remoteError) {\n if (this.remoteError) {\n lines.push(\n `${this.prefix} ${x} Remote content: ${colorize(\n this.remoteError,\n ANSIColors.RED\n )}`\n );\n } else if (remoteTotal === 0) {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize('Check server', ANSIColors.BLUE)}`\n );\n } else if (isRemoteDone) {\n lines.push(\n `${this.prefix} ${v} Remote content: ${colorize(`${remoteDone}`, ANSIColors.GREEN)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize(`${remoteDone}`, ANSIColors.BLUE)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Plugin line: show error or progress counts\n if (pluginTotal > 0 || this.pluginError) {\n if (this.pluginError) {\n lines.push(\n `${this.prefix} ${x} Plugin content: ${colorize(\n this.pluginError,\n ANSIColors.RED\n )}`\n );\n } else if (isPluginDone) {\n lines.push(\n `${this.prefix} ${v} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.GREEN)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.BLUE)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Check if the state has changed to avoid duplicate rendering\n const currentState = lines.join('\\n');\n if (currentState === this.lastRenderedState) {\n return;\n }\n this.lastRenderedState = currentState;\n\n if (this.renderedLines > 0) {\n process.stdout.write(`\\x1b[${this.renderedLines}F`);\n }\n\n const totalLinesToClear = Math.max(this.renderedLines, lines.length);\n for (let i = 0; i < totalLinesToClear; i++) {\n process.stdout.write('\\x1b[2K');\n const line = lines[i];\n if (line !== undefined) {\n process.stdout.write(line);\n }\n process.stdout.write('\\n');\n }\n\n this.renderedLines = lines.length;\n }\n\n private computeProgress() {\n const localKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'local')\n .map((s) => s.dictionaryKey)\n );\n\n const localDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'local' && (s.status === 'built' || s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n const remoteKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'remote')\n .map((s) => s.dictionaryKey)\n );\n\n const remoteDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'remote' &&\n (s.status === 'fetched' ||\n s.status === 'imported' ||\n s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n return {\n localTotal: localKeys.size,\n localDone: localDoneKeys.size,\n remoteTotal: remoteKeys.size,\n remoteDone: remoteDoneKeys.size,\n pluginTotal: this.pluginTotal,\n pluginDone: this.pluginDone,\n } as const;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"log.cjs","names":["spinnerFrames","defaultConfiguration","ANSIColors","v","x"],"sources":["../../../src/loadDictionaries/log.ts"],"sourcesContent":["import { default as defaultConfiguration } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n colorize,\n getPrefix,\n spinnerFrames,\n v,\n x,\n} from '@intlayer/config/logger';\nimport { extractErrorMessage } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport class DictionariesLogger {\n private statuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private spinnerIndex = 0;\n private renderedLines = 0;\n private readonly spinnerFrames = spinnerFrames;\n private isFinished = false;\n private readonly prefix: string;\n private lastRenderedState: string = '';\n private remoteCheckInProgress = false;\n private expectRemote = false;\n private remoteError: string | undefined;\n private pluginTotal = 0;\n private pluginDone = 0;\n private pluginError: string | undefined;\n\n constructor() {\n this.prefix = getPrefix(defaultConfiguration.log?.prefix) ?? '';\n }\n\n setExpectRemote(expect: boolean) {\n this.expectRemote = expect;\n }\n\n startRemoteCheck() {\n if (this.isFinished) return;\n this.remoteCheckInProgress = true;\n this.startSpinner();\n this.render();\n }\n\n stopRemoteCheck() {\n this.remoteCheckInProgress = false;\n }\n\n update(newStatuses: DictionariesStatus[]) {\n if (this.isFinished) return;\n for (const status of newStatuses) {\n const index = this.statuses.findIndex(\n (s) =>\n s.dictionaryKey === status.dictionaryKey && s.type === status.type\n );\n if (index >= 0) {\n this.statuses[index] = status;\n } else {\n this.statuses.push(status);\n }\n }\n\n // If we expect remote fetch later, avoid rendering a local-only line first\n const { remoteTotal } = this.computeProgress();\n if (this.expectRemote && !this.remoteCheckInProgress && remoteTotal === 0) {\n // Do not start spinner or render yet; wait until remote check starts\n return;\n }\n\n this.startSpinner();\n this.render();\n }\n\n finish() {\n this.isFinished = true;\n this.stopSpinner();\n // Render final state and keep it visible\n this.render();\n }\n\n private startSpinner() {\n if (this.spinnerTimer || this.isFinished) return;\n this.spinnerTimer = setInterval(() => {\n this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n this.render();\n }, 100);\n }\n\n private stopSpinner() {\n if (!this.spinnerTimer) return;\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n\n public setRemoteError = (error?: Error) => {\n this.remoteError = extractErrorMessage(error);\n // Avoid rendering a transient remote-only line while the remote check flag is still true\n // Ensure local + remote are rendered together after a failure\n this.stopRemoteCheck();\n this.render();\n };\n\n setPluginTotal(total: number) {\n if (this.isFinished) return;\n this.pluginTotal = total;\n if (total > 0) {\n this.startSpinner();\n }\n this.render();\n }\n\n setPluginDone(done: number) {\n if (this.isFinished) return;\n this.pluginDone = done;\n this.render();\n }\n\n setPluginError(error?: Error) {\n if (this.isFinished) return;\n this.pluginError = extractErrorMessage(error);\n this.render();\n }\n\n private render() {\n const {\n localTotal,\n localDone,\n remoteTotal,\n remoteDone,\n pluginTotal,\n pluginDone,\n } = this.computeProgress();\n\n const frame = this.spinnerFrames[this.spinnerIndex];\n const clock = colorize(frame, ANSIColors.BLUE);\n const lines: string[] = [];\n\n const isLocalDone = localDone === localTotal;\n const isRemoteDone = remoteDone === remoteTotal;\n const isPluginDone = pluginDone === pluginTotal;\n\n const suppressLocalWhileCheckingRemote =\n this.expectRemote && this.remoteCheckInProgress && remoteTotal === 0;\n\n if (!suppressLocalWhileCheckingRemote) {\n if (isLocalDone) {\n lines.push(\n `${this.prefix} ${v} Local content: ${colorize(`${localDone}`, ANSIColors.GREEN)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Local content: ${colorize(`${localDone}`, ANSIColors.BLUE)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Single remote line: show error, check, or progress counts\n if (remoteTotal > 0 || this.remoteCheckInProgress || this.remoteError) {\n if (this.remoteError) {\n lines.push(\n `${this.prefix} ${x} Remote content: ${colorize(\n this.remoteError,\n ANSIColors.RED\n )}`\n );\n } else if (remoteTotal === 0) {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize('Check server', ANSIColors.BLUE)}`\n );\n } else if (isRemoteDone) {\n lines.push(\n `${this.prefix} ${v} Remote content: ${colorize(`${remoteDone}`, ANSIColors.GREEN)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize(`${remoteDone}`, ANSIColors.BLUE)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Plugin line: show error or progress counts\n if (pluginTotal > 0 || this.pluginError) {\n if (this.pluginError) {\n lines.push(\n `${this.prefix} ${x} Plugin content: ${colorize(\n this.pluginError,\n ANSIColors.RED\n )}`\n );\n } else if (isPluginDone) {\n lines.push(\n `${this.prefix} ${v} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.GREEN)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.BLUE)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Check if the state has changed to avoid duplicate rendering\n const currentState = lines.join('\\n');\n if (currentState === this.lastRenderedState) {\n return;\n }\n this.lastRenderedState = currentState;\n\n if (this.renderedLines > 0) {\n process.stdout.write(`\\x1b[${this.renderedLines}F`);\n }\n\n const totalLinesToClear = Math.max(this.renderedLines, lines.length);\n for (let i = 0; i < totalLinesToClear; i++) {\n process.stdout.write('\\x1b[2K');\n const line = lines[i];\n if (line !== undefined) {\n process.stdout.write(line);\n }\n process.stdout.write('\\n');\n }\n\n this.renderedLines = lines.length;\n }\n\n private computeProgress() {\n const localKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'local')\n .map((s) => s.dictionaryKey)\n );\n\n const localDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'local' && (s.status === 'built' || s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n const remoteKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'remote')\n .map((s) => s.dictionaryKey)\n );\n\n const remoteDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'remote' &&\n (s.status === 'fetched' ||\n s.status === 'imported' ||\n s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n return {\n localTotal: localKeys.size,\n localDone: localDoneKeys.size,\n remoteTotal: remoteKeys.size,\n remoteDone: remoteDoneKeys.size,\n pluginTotal: this.pluginTotal,\n pluginDone: this.pluginDone,\n } as const;\n }\n}\n"],"mappings":"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"}
@@ -5,12 +5,11 @@ let _intlayer_config_logger = require("@intlayer/config/logger");
5
5
  let _intlayer_config_colors = require("@intlayer/config/colors");
6
6
  _intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
7
7
  let _intlayer_config_built = require("@intlayer/config/built");
8
- _intlayer_config_built = require_runtime.__toESM(_intlayer_config_built);
9
8
  let _intlayer_core_localization = require("@intlayer/core/localization");
10
9
  let _intlayer_types_locales = require("@intlayer/types/locales");
11
10
 
12
11
  //#region src/utils/formatter.ts
13
- const formatPath = (path, color) => [path].flat().map((path) => path.startsWith("/") ? (0, node_path.relative)(_intlayer_config_built.default.system.baseDir, path) : path).map((relativePath) => color === false ? relativePath : (0, _intlayer_config_logger.colorizePath)(relativePath, color)).join(`, `);
12
+ const formatPath = (path, color) => [path].flat().map((path) => path.startsWith("/") ? (0, node_path.relative)(_intlayer_config_built.system.baseDir, path) : path).map((relativePath) => color === false ? relativePath : (0, _intlayer_config_logger.colorizePath)(relativePath, color)).join(`, `);
14
13
  const formatLocale = (locale, color = _intlayer_config_colors.GREEN) => [locale].flat().map((locale) => `${(0, _intlayer_core_localization.getLocaleName)(locale, _intlayer_types_locales.ENGLISH)} (${locale})`).map((text) => color === false ? text : (0, _intlayer_config_logger.colorize)(text, color)).join(`, `);
15
14
 
16
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.cjs","names":["configuration","ANSIColors","ENGLISH"],"sources":["../../../src/utils/formatter.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport configuration from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n type ANSIColorsType,\n colorize,\n colorizePath,\n} from '@intlayer/config/logger';\nimport { getLocaleName } from '@intlayer/core/localization';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\nexport const formatPath = (\n path: string | string[],\n color?: ANSIColorsType | false\n) =>\n [path]\n .flat()\n .map((path) =>\n path.startsWith('/') ? relative(configuration.system.baseDir, path) : path\n )\n .map((relativePath) =>\n color === false ? relativePath : colorizePath(relativePath, color)\n )\n .join(`, `);\n\nexport const formatLocale = (\n locale: LocalesValues | LocalesValues[],\n color: ANSIColorsType | false = ANSIColors.GREEN\n) =>\n [locale]\n .flat()\n .map((locale) => `${getLocaleName(locale, ENGLISH)} (${locale})`)\n .map((text) => (color === false ? text : colorize(text, color)))\n .join(`, `);\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,cACX,MACA,UAEA,CAAC,KAAK,CACH,MAAM,CACN,KAAK,SACJ,KAAK,WAAW,IAAI,2BAAYA,+BAAc,OAAO,SAAS,KAAK,GAAG,KACvE,CACA,KAAK,iBACJ,UAAU,QAAQ,yDAA4B,cAAc,MAAM,CACnE,CACA,KAAK,KAAK;AAEf,MAAa,gBACX,QACA,QAAgCC,wBAAW,UAE3C,CAAC,OAAO,CACL,MAAM,CACN,KAAK,WAAW,kDAAiB,QAAQC,gCAAQ,CAAC,IAAI,OAAO,GAAG,CAChE,KAAK,SAAU,UAAU,QAAQ,6CAAgB,MAAM,MAAM,CAAE,CAC/D,KAAK,KAAK"}
1
+ {"version":3,"file":"formatter.cjs","names":["system","ANSIColors","ENGLISH"],"sources":["../../../src/utils/formatter.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { system } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n type ANSIColorsType,\n colorize,\n colorizePath,\n} from '@intlayer/config/logger';\nimport { getLocaleName } from '@intlayer/core/localization';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\nexport const formatPath = (\n path: string | string[],\n color?: ANSIColorsType | false\n) =>\n [path]\n .flat()\n .map((path) =>\n path.startsWith('/') ? relative(system.baseDir, path) : path\n )\n .map((relativePath) =>\n color === false ? relativePath : colorizePath(relativePath, color)\n )\n .join(`, `);\n\nexport const formatLocale = (\n locale: LocalesValues | LocalesValues[],\n color: ANSIColorsType | false = ANSIColors.GREEN\n) =>\n [locale]\n .flat()\n .map((locale) => `${getLocaleName(locale, ENGLISH)} (${locale})`)\n .map((text) => (color === false ? text : colorize(text, color)))\n .join(`, `);\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,cACX,MACA,UAEA,CAAC,KAAK,CACH,MAAM,CACN,KAAK,SACJ,KAAK,WAAW,IAAI,2BAAYA,8BAAO,SAAS,KAAK,GAAG,KACzD,CACA,KAAK,iBACJ,UAAU,QAAQ,yDAA4B,cAAc,MAAM,CACnE,CACA,KAAK,KAAK;AAEf,MAAa,gBACX,QACA,QAAgCC,wBAAW,UAE3C,CAAC,OAAO,CACL,MAAM,CACN,KAAK,WAAW,kDAAiB,QAAQC,gCAAQ,CAAC,IAAI,OAAO,GAAG,CAChE,KAAK,SAAU,UAAU,QAAQ,6CAAgB,MAAM,MAAM,CAAE,CAC/D,KAAK,KAAK"}
@@ -25,6 +25,7 @@ exports.assembleJSON = require_utils_chunkJSON.assembleJSON;
25
25
  exports.autoDecorateContent = require_utils_autoDecorateContent.autoDecorateContent;
26
26
  exports.buildComponentFilesList = require_utils_buildComponentFilesList.buildComponentFilesList;
27
27
  exports.chunkJSON = require_utils_chunkJSON.chunkJSON;
28
+ exports.excludeObjectFormat = require_utils_reduceObjectFormat.excludeObjectFormat;
28
29
  exports.formatLocale = require_utils_formatter.formatLocale;
29
30
  exports.formatPath = require_utils_formatter.formatPath;
30
31
  exports.getChunk = require_utils_getChunk.getChunk;
@@ -26,7 +26,45 @@ const reduceObjectFormat = (source, format) => {
26
26
  }
27
27
  return source;
28
28
  };
29
+ /**
30
+ * Returns the subset of source whose keys are NOT present in the format object.
31
+ * Inverse of reduceObjectFormat.
32
+ *
33
+ * Null values in source are always included as explicit fallback markers
34
+ * (they signal "use default locale" at render time).
35
+ *
36
+ * Examples:
37
+ * excludeObjectFormat({ a: 1, b: 2 }, { b: 0 }) => { a: 1 }
38
+ * excludeObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { y: 2 } }
39
+ * excludeObjectFormat({ a: null, b: 2 }, { b: 0 }) => { a: null }
40
+ */
41
+ const excludeObjectFormat = (source, format) => {
42
+ if (source === null) return null;
43
+ if (format === void 0 || format === null) return source;
44
+ if (typeof source === "object" && !Array.isArray(source) && typeof format === "object" && !Array.isArray(format)) {
45
+ const result = {};
46
+ let hasContent = false;
47
+ for (const key of Object.keys(source)) {
48
+ const excluded = excludeObjectFormat(source[key], format[key]);
49
+ if (excluded !== void 0) {
50
+ result[key] = excluded;
51
+ hasContent = true;
52
+ }
53
+ }
54
+ return hasContent ? result : void 0;
55
+ }
56
+ if (Array.isArray(source)) {
57
+ const formatArr = Array.isArray(format) ? format : [];
58
+ const result = [];
59
+ for (let i = 0; i < source.length; i++) {
60
+ const excluded = excludeObjectFormat(source[i], formatArr[i]);
61
+ if (excluded !== void 0) result.push(excluded);
62
+ }
63
+ return result.length > 0 ? result : void 0;
64
+ }
65
+ };
29
66
 
30
67
  //#endregion
68
+ exports.excludeObjectFormat = excludeObjectFormat;
31
69
  exports.reduceObjectFormat = reduceObjectFormat;
32
70
  //# sourceMappingURL=reduceObjectFormat.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"reduceObjectFormat.cjs","names":[],"sources":["../../../src/utils/reduceObjectFormat.ts"],"sourcesContent":["type Primitive = string | number | boolean | null | undefined;\n\ntype Recursive = Primitive | { [key: string]: Recursive } | Array<Recursive>;\n\n/**\n * Reduce an object to only the shape provided by a format object.\n * Values are always taken from the source object; the format is used only for structure.\n *\n * Examples:\n * reduceObjectFormat({ a: 1, b: 2 }, { a: 0 }) => { a: 1 }\n * reduceObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { x: 1 } }\n */\nexport const reduceObjectFormat = (\n source: Recursive,\n format: Recursive\n): Recursive => {\n // If the format is an array, reduce each element by its counterpart in source\n if (Array.isArray(format)) {\n const sourceArray = Array.isArray(source) ? source : [];\n return format.map((formatItem, index) =>\n reduceObjectFormat(sourceArray[index], formatItem)\n );\n }\n\n // If the format is an object (and not null), pick matching keys and recurse\n if (typeof format === 'object' && format !== null) {\n const result: Record<string, Recursive> = {};\n const sourceObject =\n typeof source === 'object' && source !== null && !Array.isArray(source)\n ? (source as Record<string, Recursive>)\n : ({} as Record<string, Recursive>);\n\n for (const key of Object.keys(format)) {\n const nextSource = sourceObject[key];\n const nextFormat = (format as Record<string, Recursive>)[key];\n result[key] = reduceObjectFormat(nextSource, nextFormat);\n }\n return result;\n }\n\n // For primitives in the format, simply return the source value (can be undefined)\n return source as Primitive;\n};\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,sBACX,QACA,WACc;AAEd,KAAI,MAAM,QAAQ,OAAO,EAAE;EACzB,MAAM,cAAc,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;AACvD,SAAO,OAAO,KAAK,YAAY,UAC7B,mBAAmB,YAAY,QAAQ,WAAW,CACnD;;AAIH,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,SAAoC,EAAE;EAC5C,MAAM,eACJ,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,OAAO,GAClE,SACA,EAAE;AAET,OAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;GACrC,MAAM,aAAa,aAAa;GAChC,MAAM,aAAc,OAAqC;AACzD,UAAO,OAAO,mBAAmB,YAAY,WAAW;;AAE1D,SAAO;;AAIT,QAAO"}
1
+ {"version":3,"file":"reduceObjectFormat.cjs","names":[],"sources":["../../../src/utils/reduceObjectFormat.ts"],"sourcesContent":["export type Primitive = string | number | boolean | null | undefined;\n\nexport type Recursive =\n | Primitive\n | { [key: string]: Recursive }\n | Array<Recursive>;\n\n/**\n * Reduce an object to only the shape provided by a format object.\n * Values are always taken from the source object; the format is used only for structure.\n *\n * Examples:\n * reduceObjectFormat({ a: 1, b: 2 }, { a: 0 }) => { a: 1 }\n * reduceObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { x: 1 } }\n */\nexport const reduceObjectFormat = (\n source: Recursive,\n format: Recursive\n): Recursive => {\n // If the format is an array, reduce each element by its counterpart in source\n if (Array.isArray(format)) {\n const sourceArray = Array.isArray(source) ? source : [];\n return format.map((formatItem, index) =>\n reduceObjectFormat(sourceArray[index], formatItem)\n );\n }\n\n // If the format is an object (and not null), pick matching keys and recurse\n if (typeof format === 'object' && format !== null) {\n const result: Record<string, Recursive> = {};\n const sourceObject =\n typeof source === 'object' && source !== null && !Array.isArray(source)\n ? (source as Record<string, Recursive>)\n : ({} as Record<string, Recursive>);\n\n for (const key of Object.keys(format)) {\n const nextSource = sourceObject[key];\n const nextFormat = (format as Record<string, Recursive>)[key];\n result[key] = reduceObjectFormat(nextSource, nextFormat);\n }\n return result;\n }\n\n // For primitives in the format, simply return the source value (can be undefined)\n return source as Primitive;\n};\n\n/**\n * Returns the subset of source whose keys are NOT present in the format object.\n * Inverse of reduceObjectFormat.\n *\n * Null values in source are always included as explicit fallback markers\n * (they signal \"use default locale\" at render time).\n *\n * Examples:\n * excludeObjectFormat({ a: 1, b: 2 }, { b: 0 }) => { a: 1 }\n * excludeObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { y: 2 } }\n * excludeObjectFormat({ a: null, b: 2 }, { b: 0 }) => { a: null }\n */\nexport const excludeObjectFormat = (\n source: Recursive,\n format: Recursive\n): Recursive | undefined => {\n // null in source = explicit fallback marker → always include\n if (source === null) return null;\n\n // No format means nothing is translated yet → include all source\n if (format === undefined || format === null) return source;\n\n // Both plain objects → recurse key-by-key\n if (\n typeof source === 'object' &&\n !Array.isArray(source) &&\n typeof format === 'object' &&\n !Array.isArray(format)\n ) {\n const result: Record<string, Recursive> = {};\n let hasContent = false;\n\n for (const key of Object.keys(source as Record<string, Recursive>)) {\n const excluded = excludeObjectFormat(\n (source as Record<string, Recursive>)[key],\n (format as Record<string, Recursive>)[key]\n );\n if (excluded !== undefined) {\n result[key] = excluded;\n hasContent = true;\n }\n }\n\n return hasContent ? result : undefined;\n }\n\n // Arrays → recurse by index\n if (Array.isArray(source)) {\n const formatArr = Array.isArray(format) ? format : [];\n const result: Recursive[] = [];\n\n for (let i = 0; i < source.length; i++) {\n const excluded = excludeObjectFormat(source[i], formatArr[i]);\n if (excluded !== undefined) {\n result.push(excluded);\n }\n }\n\n return result.length > 0 ? result : undefined;\n }\n\n // Primitive in source and format has a value → already translated → exclude\n return undefined;\n};\n"],"mappings":";;;;;;;;;;;AAeA,MAAa,sBACX,QACA,WACc;AAEd,KAAI,MAAM,QAAQ,OAAO,EAAE;EACzB,MAAM,cAAc,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;AACvD,SAAO,OAAO,KAAK,YAAY,UAC7B,mBAAmB,YAAY,QAAQ,WAAW,CACnD;;AAIH,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,SAAoC,EAAE;EAC5C,MAAM,eACJ,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,OAAO,GAClE,SACA,EAAE;AAET,OAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;GACrC,MAAM,aAAa,aAAa;GAChC,MAAM,aAAc,OAAqC;AACzD,UAAO,OAAO,mBAAmB,YAAY,WAAW;;AAE1D,SAAO;;AAIT,QAAO;;;;;;;;;;;;;;AAeT,MAAa,uBACX,QACA,WAC0B;AAE1B,KAAI,WAAW,KAAM,QAAO;AAG5B,KAAI,WAAW,UAAa,WAAW,KAAM,QAAO;AAGpD,KACE,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,OAAO,IACtB,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,OAAO,EACtB;EACA,MAAM,SAAoC,EAAE;EAC5C,IAAI,aAAa;AAEjB,OAAK,MAAM,OAAO,OAAO,KAAK,OAAoC,EAAE;GAClE,MAAM,WAAW,oBACd,OAAqC,MACrC,OAAqC,KACvC;AACD,OAAI,aAAa,QAAW;AAC1B,WAAO,OAAO;AACd,iBAAa;;;AAIjB,SAAO,aAAa,SAAS;;AAI/B,KAAI,MAAM,QAAQ,OAAO,EAAE;EACzB,MAAM,YAAY,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;EACrD,MAAM,SAAsB,EAAE;AAE9B,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,WAAW,oBAAoB,OAAO,IAAI,UAAU,GAAG;AAC7D,OAAI,aAAa,OACf,QAAO,KAAK,SAAS;;AAIzB,SAAO,OAAO,SAAS,IAAI,SAAS"}
@@ -19,9 +19,9 @@ const generateFetchLoadContentModule = (format, relativePrefix, locales) => {
19
19
  const extension = format === "cjs" ? "cjs" : "mjs";
20
20
  const body = `const loadContent = (key) => {
21
21
  const dynContent = loadContentDyn(key);
22
- return {\n${sortedLocales.map((locale) => ` '${locale}': async () => {\n try {\n const res = await fetch(\`\${configuration.editor.liveSyncURL}/dictionaries/\${key}/${locale}\`);\n return await res.json();\n } catch {\n return dynContent['${locale}']();\n }\n }`).join(",\n")}\n };\n};\n`;
23
- if (format === "esm") return `import { configuration } from 'intlayer';\nimport { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\n\n${body}\nexport { loadContent };\n`;
24
- return `const { configuration } = require('intlayer');\nconst { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\n\n${body}\nmodule.exports = { loadContent };\n`;
22
+ return {\n${sortedLocales.map((locale) => ` '${locale}': async () => {\n try {\n const res = await fetch(\`\${editor.liveSyncURL}/dictionaries/\${key}/${locale}\`);\n return await res.json();\n } catch {\n return dynContent['${locale}']();\n }\n }`).join(",\n")}\n };\n};\n`;
23
+ if (format === "esm") return `import { editor } from 'intlayer';\nimport { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\n\n${body}\nexport { loadContent };\n`;
24
+ return `const { editor } = require('intlayer');\nconst { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\n\n${body}\nmodule.exports = { loadContent };\n`;
25
25
  };
26
26
  /**
27
27
  * Generates the content of a fetch dictionary entry point file.
@@ -1 +1 @@
1
- {"version":3,"file":"writeFetchDictionary.mjs","names":[],"sources":["../../../src/buildIntlayerDictionary/writeFetchDictionary.ts"],"sourcesContent":["import { mkdir } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { OUTPUT_FORMAT } from '@intlayer/config/defaultValues';\nimport { colorizePath } from '@intlayer/config/logger';\nimport { normalizePath } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { parallelize } from '../utils/parallelize';\nimport { writeFileIfChanged } from '../writeFileIfChanged';\nimport type { LocalizedDictionaryOutput } from './writeDynamicDictionary';\n\nconst LOAD_CONTENT_MODULE = '_loadjson';\n\n/**\n * Generates the content of the shared `loadContent` module for fetch dictionaries.\n * - `configuration` is imported at runtime from \"intlayer\" (liveSyncURL not baked in).\n * - Fallback delegates to the dynamic dictionary's `_loadjson` module.\n * - Locales are baked in so each entry is a static function referencing one locale.\n */\nexport const generateFetchLoadContentModule = (\n format: 'cjs' | 'esm',\n relativePrefix: string,\n locales: string[]\n): string => {\n const sortedLocales = [...locales].sort((a, b) =>\n String(a).localeCompare(String(b))\n );\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n\n const localeEntries = sortedLocales\n .map(\n (locale) =>\n ` '${locale}': async () => {\\n` +\n ` try {\\n` +\n ` const res = await fetch(\\`\\${configuration.editor.liveSyncURL}/dictionaries/\\${key}/${locale}\\`);\\n` +\n ` return await res.json();\\n` +\n ` } catch {\\n` +\n ` return dynContent['${locale}']();\\n` +\n ` }\\n` +\n ` }`\n )\n .join(',\\n');\n\n const body =\n `const loadContent = (key) => {\\n` +\n ` const dynContent = loadContentDyn(key);\\n` +\n ` return {\\n${localeEntries}\\n };\\n` +\n `};\\n`;\n\n if (format === 'esm') {\n return (\n `import { configuration } from 'intlayer';\\n` +\n `import { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `${body}\\nexport { loadContent };\\n`\n );\n }\n return (\n `const { configuration } = require('intlayer');\\n` +\n `const { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `${body}\\nmodule.exports = { loadContent };\\n`\n );\n};\n\n/**\n * Generates the content of a fetch dictionary entry point file.\n */\nexport const generateDictionaryEntryPoint = (\n key: string,\n format: 'cjs' | 'esm' = 'esm'\n): string => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n if (format === 'esm') {\n return (\n `import { loadContent } from './${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `const content = loadContent('${key}');\\n\\n` +\n `export default content;\\n`\n );\n }\n return (\n `const { loadContent } = require('./${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `module.exports = loadContent('${key}');\\n`\n );\n};\n\n/**\n * Write the localized dictionaries to the dictionariesDir\n * @param mergedDictionaries - The merged dictionaries\n * @param configuration - The configuration\n * @returns The final dictionaries\n *\n * @example\n * ```ts\n * const unmergedDictionaries = await writeUnmergedDictionaries(dictionaries);\n * const finalDictionaries = await writeFinalDictionaries(unmergedDictionaries);\n * console.log(finalDictionaries);\n *\n * // .intlayer/fetch_dictionary/home.mjs\n * // .intlayer/fetch_dictionary/home.cjs\n * ```\n */\nexport const writeFetchDictionary = async (\n dynamicDictionaries: LocalizedDictionaryOutput,\n configuration: IntlayerConfig,\n formats: ('cjs' | 'esm')[] = OUTPUT_FORMAT\n): Promise<LocalizedDictionaryOutput> => {\n const { fetchDictionariesDir, dynamicDictionariesDir } = configuration.system;\n const { locales } = configuration.internationalization;\n\n // Compute relative path from fetch dir (where _loadjson lives) to dynamic dir\n let relativePrefix = normalizePath(\n relative(fetchDictionariesDir, dynamicDictionariesDir)\n );\n if (!relativePrefix.startsWith('.')) {\n relativePrefix = `./${relativePrefix}`;\n }\n\n await mkdir(resolve(fetchDictionariesDir), { recursive: true });\n\n // Write the shared loadContent module once per format\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`),\n generateFetchLoadContentModule(format, relativePrefix, locales)\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`))}:`,\n err\n );\n });\n });\n\n const resultDictionariesPaths: LocalizedDictionaryOutput = {};\n\n // Write entry points for each dictionary in parallel\n await parallelize(Object.entries(dynamicDictionaries), async ([key]) => {\n if (key === 'undefined') return;\n\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n const content = generateDictionaryEntryPoint(key, format);\n\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${key}.${extension}`),\n content\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${key}.${extension}`))}:`,\n err\n );\n });\n });\n });\n\n return resultDictionariesPaths;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAM,sBAAsB;;;;;;;AAQ5B,MAAa,kCACX,QACA,gBACA,YACW;CACX,MAAM,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,MAC1C,OAAO,EAAE,CAAC,cAAc,OAAO,EAAE,CAAC,CACnC;CACD,MAAM,YAAY,WAAW,QAAQ,QAAQ;CAgB7C,MAAM,OACJ;;cAfoB,cACnB,KACE,WACC,MAAM,OAAO,yHAEgF,OAAO,gFAGxE,OAAO,mBAGtC,CACA,KAAK,MAAM,CAKiB;AAG/B,KAAI,WAAW,MACb,QACE,6FACkD,eAAe,GAAG,oBAAoB,GAAG,UAAU,QAClG,KAAK;AAGZ,QACE,oGACoD,eAAe,GAAG,oBAAoB,GAAG,UAAU,SACpG,KAAK;;;;;AAOZ,MAAa,gCACX,KACA,SAAwB,UACb;CACX,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,KAAI,WAAW,MACb,QACE,kCAAkC,oBAAoB,GAAG,UAAU,qCACnC,IAAI;AAIxC,QACE,sCAAsC,oBAAoB,GAAG,UAAU,uCACtC,IAAI;;;;;;;;;;;;;;;;;;AAoBzC,MAAa,uBAAuB,OAClC,qBACA,eACA,UAA6B,kBACU;CACvC,MAAM,EAAE,sBAAsB,2BAA2B,cAAc;CACvE,MAAM,EAAE,YAAY,cAAc;CAGlC,IAAI,iBAAiB,cACnB,SAAS,sBAAsB,uBAAuB,CACvD;AACD,KAAI,CAAC,eAAe,WAAW,IAAI,CACjC,kBAAiB,KAAK;AAGxB,OAAM,MAAM,QAAQ,qBAAqB,EAAE,EAAE,WAAW,MAAM,CAAC;AAG/D,OAAM,YAAY,SAAS,OAAO,WAAW;EAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,QAAM,mBACJ,QAAQ,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,EACpE,+BAA+B,QAAQ,gBAAgB,QAAQ,CAChE,CAAC,OAAO,QAAQ;AACf,WAAQ,MACN,wBAAwB,aAAa,QAAQ,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,CAAC,CAAC,IAC3G,IACD;IACD;GACF;CAEF,MAAM,0BAAqD,EAAE;AAG7D,OAAM,YAAY,OAAO,QAAQ,oBAAoB,EAAE,OAAO,CAAC,SAAS;AACtE,MAAI,QAAQ,YAAa;AAEzB,QAAM,YAAY,SAAS,OAAO,WAAW;GAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;GAC7C,MAAM,UAAU,6BAA6B,KAAK,OAAO;AAEzD,SAAM,mBACJ,QAAQ,sBAAsB,GAAG,IAAI,GAAG,YAAY,EACpD,QACD,CAAC,OAAO,QAAQ;AACf,YAAQ,MACN,wBAAwB,aAAa,QAAQ,sBAAsB,GAAG,IAAI,GAAG,YAAY,CAAC,CAAC,IAC3F,IACD;KACD;IACF;GACF;AAEF,QAAO"}
1
+ {"version":3,"file":"writeFetchDictionary.mjs","names":[],"sources":["../../../src/buildIntlayerDictionary/writeFetchDictionary.ts"],"sourcesContent":["import { mkdir } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { OUTPUT_FORMAT } from '@intlayer/config/defaultValues';\nimport { colorizePath } from '@intlayer/config/logger';\nimport { normalizePath } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { parallelize } from '../utils/parallelize';\nimport { writeFileIfChanged } from '../writeFileIfChanged';\nimport type { LocalizedDictionaryOutput } from './writeDynamicDictionary';\n\nconst LOAD_CONTENT_MODULE = '_loadjson';\n\n/**\n * Generates the content of the shared `loadContent` module for fetch dictionaries.\n * - `configuration` is imported at runtime from \"intlayer\" (liveSyncURL not baked in).\n * - Fallback delegates to the dynamic dictionary's `_loadjson` module.\n * - Locales are baked in so each entry is a static function referencing one locale.\n */\nexport const generateFetchLoadContentModule = (\n format: 'cjs' | 'esm',\n relativePrefix: string,\n locales: string[]\n): string => {\n const sortedLocales = [...locales].sort((a, b) =>\n String(a).localeCompare(String(b))\n );\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n\n const localeEntries = sortedLocales\n .map(\n (locale) =>\n ` '${locale}': async () => {\\n` +\n ` try {\\n` +\n ` const res = await fetch(\\`\\${editor.liveSyncURL}/dictionaries/\\${key}/${locale}\\`);\\n` +\n ` return await res.json();\\n` +\n ` } catch {\\n` +\n ` return dynContent['${locale}']();\\n` +\n ` }\\n` +\n ` }`\n )\n .join(',\\n');\n\n const body =\n `const loadContent = (key) => {\\n` +\n ` const dynContent = loadContentDyn(key);\\n` +\n ` return {\\n${localeEntries}\\n };\\n` +\n `};\\n`;\n\n if (format === 'esm') {\n return (\n `import { editor } from 'intlayer';\\n` +\n `import { loadContent as loadContentDyn } from '${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `${body}\\nexport { loadContent };\\n`\n );\n }\n return (\n `const { editor } = require('intlayer');\\n` +\n `const { loadContent: loadContentDyn } = require('${relativePrefix}/${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `${body}\\nmodule.exports = { loadContent };\\n`\n );\n};\n\n/**\n * Generates the content of a fetch dictionary entry point file.\n */\nexport const generateDictionaryEntryPoint = (\n key: string,\n format: 'cjs' | 'esm' = 'esm'\n): string => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n if (format === 'esm') {\n return (\n `import { loadContent } from './${LOAD_CONTENT_MODULE}.${extension}';\\n\\n` +\n `const content = loadContent('${key}');\\n\\n` +\n `export default content;\\n`\n );\n }\n return (\n `const { loadContent } = require('./${LOAD_CONTENT_MODULE}.${extension}');\\n\\n` +\n `module.exports = loadContent('${key}');\\n`\n );\n};\n\n/**\n * Write the localized dictionaries to the dictionariesDir\n * @param mergedDictionaries - The merged dictionaries\n * @param configuration - The configuration\n * @returns The final dictionaries\n *\n * @example\n * ```ts\n * const unmergedDictionaries = await writeUnmergedDictionaries(dictionaries);\n * const finalDictionaries = await writeFinalDictionaries(unmergedDictionaries);\n * console.log(finalDictionaries);\n *\n * // .intlayer/fetch_dictionary/home.mjs\n * // .intlayer/fetch_dictionary/home.cjs\n * ```\n */\nexport const writeFetchDictionary = async (\n dynamicDictionaries: LocalizedDictionaryOutput,\n configuration: IntlayerConfig,\n formats: ('cjs' | 'esm')[] = OUTPUT_FORMAT\n): Promise<LocalizedDictionaryOutput> => {\n const { fetchDictionariesDir, dynamicDictionariesDir } = configuration.system;\n const { locales } = configuration.internationalization;\n\n // Compute relative path from fetch dir (where _loadjson lives) to dynamic dir\n let relativePrefix = normalizePath(\n relative(fetchDictionariesDir, dynamicDictionariesDir)\n );\n if (!relativePrefix.startsWith('.')) {\n relativePrefix = `./${relativePrefix}`;\n }\n\n await mkdir(resolve(fetchDictionariesDir), { recursive: true });\n\n // Write the shared loadContent module once per format\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`),\n generateFetchLoadContentModule(format, relativePrefix, locales)\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${LOAD_CONTENT_MODULE}.${extension}`))}:`,\n err\n );\n });\n });\n\n const resultDictionariesPaths: LocalizedDictionaryOutput = {};\n\n // Write entry points for each dictionary in parallel\n await parallelize(Object.entries(dynamicDictionaries), async ([key]) => {\n if (key === 'undefined') return;\n\n await parallelize(formats, async (format) => {\n const extension = format === 'cjs' ? 'cjs' : 'mjs';\n const content = generateDictionaryEntryPoint(key, format);\n\n await writeFileIfChanged(\n resolve(fetchDictionariesDir, `${key}.${extension}`),\n content\n ).catch((err) => {\n console.error(\n `Error creating fetch ${colorizePath(resolve(fetchDictionariesDir, `${key}.${extension}`))}:`,\n err\n );\n });\n });\n });\n\n return resultDictionariesPaths;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAM,sBAAsB;;;;;;;AAQ5B,MAAa,kCACX,QACA,gBACA,YACW;CACX,MAAM,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,MAC1C,OAAO,EAAE,CAAC,cAAc,OAAO,EAAE,CAAC,CACnC;CACD,MAAM,YAAY,WAAW,QAAQ,QAAQ;CAgB7C,MAAM,OACJ;;cAfoB,cACnB,KACE,WACC,MAAM,OAAO,2GAEkE,OAAO,gFAG1D,OAAO,mBAGtC,CACA,KAAK,MAAM,CAKiB;AAG/B,KAAI,WAAW,MACb,QACE,sFACkD,eAAe,GAAG,oBAAoB,GAAG,UAAU,QAClG,KAAK;AAGZ,QACE,6FACoD,eAAe,GAAG,oBAAoB,GAAG,UAAU,SACpG,KAAK;;;;;AAOZ,MAAa,gCACX,KACA,SAAwB,UACb;CACX,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,KAAI,WAAW,MACb,QACE,kCAAkC,oBAAoB,GAAG,UAAU,qCACnC,IAAI;AAIxC,QACE,sCAAsC,oBAAoB,GAAG,UAAU,uCACtC,IAAI;;;;;;;;;;;;;;;;;;AAoBzC,MAAa,uBAAuB,OAClC,qBACA,eACA,UAA6B,kBACU;CACvC,MAAM,EAAE,sBAAsB,2BAA2B,cAAc;CACvE,MAAM,EAAE,YAAY,cAAc;CAGlC,IAAI,iBAAiB,cACnB,SAAS,sBAAsB,uBAAuB,CACvD;AACD,KAAI,CAAC,eAAe,WAAW,IAAI,CACjC,kBAAiB,KAAK;AAGxB,OAAM,MAAM,QAAQ,qBAAqB,EAAE,EAAE,WAAW,MAAM,CAAC;AAG/D,OAAM,YAAY,SAAS,OAAO,WAAW;EAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;AAC7C,QAAM,mBACJ,QAAQ,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,EACpE,+BAA+B,QAAQ,gBAAgB,QAAQ,CAChE,CAAC,OAAO,QAAQ;AACf,WAAQ,MACN,wBAAwB,aAAa,QAAQ,sBAAsB,GAAG,oBAAoB,GAAG,YAAY,CAAC,CAAC,IAC3G,IACD;IACD;GACF;CAEF,MAAM,0BAAqD,EAAE;AAG7D,OAAM,YAAY,OAAO,QAAQ,oBAAoB,EAAE,OAAO,CAAC,SAAS;AACtE,MAAI,QAAQ,YAAa;AAEzB,QAAM,YAAY,SAAS,OAAO,WAAW;GAC3C,MAAM,YAAY,WAAW,QAAQ,QAAQ;GAC7C,MAAM,UAAU,6BAA6B,KAAK,OAAO;AAEzD,SAAM,mBACJ,QAAQ,sBAAsB,GAAG,IAAI,GAAG,YAAY,EACpD,QACD,CAAC,OAAO,QAAQ;AACf,YAAQ,MACN,wBAAwB,aAAa,QAAQ,sBAAsB,GAAG,IAAI,GAAG,YAAY,CAAC,CAAC,IAC3F,IACD;KACD;IACF;GACF;AAEF,QAAO"}
@@ -2,14 +2,14 @@ import { join } from "node:path";
2
2
  import { getAppLogger } from "@intlayer/config/logger";
3
3
  import { readFileSync } from "node:fs";
4
4
  import simpleGit from "simple-git";
5
- import configuration from "@intlayer/config/built";
5
+ import { log } from "@intlayer/config/built";
6
6
 
7
7
  //#region src/listGitFiles.ts
8
8
  const getGitRootDir = async () => {
9
9
  try {
10
10
  return (await simpleGit().revparse(["--show-toplevel"])).trim();
11
11
  } catch (error) {
12
- getAppLogger(configuration)(`Error getting git root directory: ${error}`, { level: "error" });
12
+ getAppLogger({ log })(`Error getting git root directory: ${error}`, { level: "error" });
13
13
  return null;
14
14
  }
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"listGitFiles.mjs","names":[],"sources":["../../src/listGitFiles.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport configuration from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport simpleGit from 'simple-git';\n\nexport type DiffMode = 'gitDiff' | 'uncommitted' | 'unpushed' | 'untracked';\n\nconst getGitRootDir = async (): Promise<string | null> => {\n try {\n const git = simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (error) {\n const appLogger = getAppLogger(configuration);\n appLogger(`Error getting git root directory: ${error}`, {\n level: 'error',\n });\n return null;\n }\n};\n\nexport type ListGitFilesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n absolute?: boolean;\n};\n\nexport const listGitFiles = async ({\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n absolute = true,\n}: ListGitFilesOptions) => {\n try {\n const git = simpleGit();\n const diff: Set<string> = new Set();\n\n if (mode.includes('untracked')) {\n const status = await git.status();\n status.not_added.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('uncommitted')) {\n // Get uncommitted changes\n const uncommittedDiff = await git.diff(['--name-only', 'HEAD']);\n\n const uncommittedFiles = uncommittedDiff.split('\\n').filter(Boolean);\n\n uncommittedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('unpushed')) {\n // Get unpushed commits\n const unpushedDiff = await git.diff(['--name-only', '@{push}...HEAD']);\n\n const unpushedFiles = unpushedDiff.split('\\n').filter(Boolean);\n\n unpushedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('gitDiff')) {\n // Get the base branch (usually main/master) from CI environment\n\n await git.fetch(baseRef);\n\n const diffBranch = await git.diff([\n '--name-only',\n `${baseRef}...${currentRef}`,\n ]);\n\n const gitDiffFiles = diffBranch.split('\\n').filter(Boolean);\n\n gitDiffFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (absolute) {\n const gitRootDir = await getGitRootDir();\n if (!gitRootDir) {\n return [];\n }\n return Array.from(diff).map((file) => join(gitRootDir, file));\n }\n\n return Array.from(diff);\n } catch (error) {\n console.warn('Failed to get changes list:', error);\n }\n};\n\nexport type ListGitLinesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n};\n\nexport const listGitLines = async (\n filePath: string,\n {\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n }: ListGitLinesOptions\n): Promise<number[]> => {\n const git = simpleGit();\n // We collect **line numbers** (1-based) that were modified/added by the diff.\n // Using a Set ensures uniqueness when the same line is reported by several modes.\n const changedLines: Set<number> = new Set();\n\n /**\n * Extracts line numbers from a diff generated with `--unified=0`.\n * Each hunk header looks like: @@ -<oldStart>,<oldCount> +<newStart>,<newCount> @@\n * We consider both the \"+\" (new) side for additions and the \"-\" (old) side for deletions.\n * For deletions, we add the line before and after the deletion point in the current file.\n */\n const collectLinesFromDiff = (diffOutput: string) => {\n const hunkRegex = /@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/g;\n let match: RegExpExecArray | null;\n\n // biome-ignore lint/suspicious/noAssignInExpressions: Used in while loop condition\n while ((match = hunkRegex.exec(diffOutput)) !== null) {\n const oldCount = match[2] ? Number(match[2]) : 1;\n const newStart = Number(match[3]);\n const newCount = match[4] ? Number(match[4]) : 1;\n\n // Handle additions/modifications (+ side)\n if (newCount > 0) {\n for (let i = 0; i < newCount; i++) {\n changedLines.add(newStart + i);\n }\n }\n\n // Handle deletions (- side)\n if (oldCount > 0 && newCount === 0) {\n // For deletions, add the line before and after the deletion point\n // The deletion point in the new file is at newStart\n if (newStart > 1) {\n changedLines.add(newStart - 1); // Line before deletion\n }\n changedLines.add(newStart); // Line after deletion (if it exists)\n }\n }\n };\n\n // 1. Handle untracked files – when a file is untracked its entire content is new.\n if (mode.includes('untracked')) {\n const status = await git.status();\n const isUntracked = status.not_added.includes(filePath);\n if (isUntracked) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n content.split('\\n').forEach((_, idx) => {\n changedLines.add(idx + 1);\n });\n } catch {\n // ignore read errors – file may have been deleted, etc.\n }\n }\n }\n\n // 2. Uncommitted changes (working tree vs HEAD)\n if (mode.includes('uncommitted')) {\n const diffOutput = await git.diff(['--unified=0', 'HEAD', '--', filePath]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 3. Unpushed commits – compare local branch to its upstream\n if (mode.includes('unpushed')) {\n const diffOutput = await git.diff([\n '--unified=0',\n '@{push}...HEAD',\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 4. Regular git diff between baseRef and currentRef (e.g., CI pull-request diff)\n if (mode.includes('gitDiff')) {\n await git.fetch(baseRef);\n const diffOutput = await git.diff([\n '--unified=0',\n `${baseRef}...${currentRef}`,\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // Return the list sorted for convenience\n return Array.from(changedLines).sort((a, b) => a - b);\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"listGitFiles.mjs","names":[],"sources":["../../src/listGitFiles.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { log } from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport simpleGit from 'simple-git';\n\nexport type DiffMode = 'gitDiff' | 'uncommitted' | 'unpushed' | 'untracked';\n\nconst getGitRootDir = async (): Promise<string | null> => {\n try {\n const git = simpleGit();\n const rootDir = await git.revparse(['--show-toplevel']);\n return rootDir.trim();\n } catch (error) {\n const appLogger = getAppLogger({ log });\n appLogger(`Error getting git root directory: ${error}`, {\n level: 'error',\n });\n return null;\n }\n};\n\nexport type ListGitFilesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n absolute?: boolean;\n};\n\nexport const listGitFiles = async ({\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n absolute = true,\n}: ListGitFilesOptions) => {\n try {\n const git = simpleGit();\n const diff: Set<string> = new Set();\n\n if (mode.includes('untracked')) {\n const status = await git.status();\n status.not_added.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('uncommitted')) {\n // Get uncommitted changes\n const uncommittedDiff = await git.diff(['--name-only', 'HEAD']);\n\n const uncommittedFiles = uncommittedDiff.split('\\n').filter(Boolean);\n\n uncommittedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('unpushed')) {\n // Get unpushed commits\n const unpushedDiff = await git.diff(['--name-only', '@{push}...HEAD']);\n\n const unpushedFiles = unpushedDiff.split('\\n').filter(Boolean);\n\n unpushedFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (mode.includes('gitDiff')) {\n // Get the base branch (usually main/master) from CI environment\n\n await git.fetch(baseRef);\n\n const diffBranch = await git.diff([\n '--name-only',\n `${baseRef}...${currentRef}`,\n ]);\n\n const gitDiffFiles = diffBranch.split('\\n').filter(Boolean);\n\n gitDiffFiles.forEach((file) => {\n diff.add(file);\n });\n }\n\n if (absolute) {\n const gitRootDir = await getGitRootDir();\n if (!gitRootDir) {\n return [];\n }\n return Array.from(diff).map((file) => join(gitRootDir, file));\n }\n\n return Array.from(diff);\n } catch (error) {\n console.warn('Failed to get changes list:', error);\n }\n};\n\nexport type ListGitLinesOptions = {\n mode: DiffMode[];\n baseRef?: string;\n currentRef?: string;\n};\n\nexport const listGitLines = async (\n filePath: string,\n {\n mode,\n baseRef = 'origin/main',\n currentRef = 'HEAD', // HEAD points to the current branch's latest commit\n }: ListGitLinesOptions\n): Promise<number[]> => {\n const git = simpleGit();\n // We collect **line numbers** (1-based) that were modified/added by the diff.\n // Using a Set ensures uniqueness when the same line is reported by several modes.\n const changedLines: Set<number> = new Set();\n\n /**\n * Extracts line numbers from a diff generated with `--unified=0`.\n * Each hunk header looks like: @@ -<oldStart>,<oldCount> +<newStart>,<newCount> @@\n * We consider both the \"+\" (new) side for additions and the \"-\" (old) side for deletions.\n * For deletions, we add the line before and after the deletion point in the current file.\n */\n const collectLinesFromDiff = (diffOutput: string) => {\n const hunkRegex = /@@ -(\\d+)(?:,(\\d+))? \\+(\\d+)(?:,(\\d+))? @@/g;\n let match: RegExpExecArray | null;\n\n // biome-ignore lint/suspicious/noAssignInExpressions: Used in while loop condition\n while ((match = hunkRegex.exec(diffOutput)) !== null) {\n const oldCount = match[2] ? Number(match[2]) : 1;\n const newStart = Number(match[3]);\n const newCount = match[4] ? Number(match[4]) : 1;\n\n // Handle additions/modifications (+ side)\n if (newCount > 0) {\n for (let i = 0; i < newCount; i++) {\n changedLines.add(newStart + i);\n }\n }\n\n // Handle deletions (- side)\n if (oldCount > 0 && newCount === 0) {\n // For deletions, add the line before and after the deletion point\n // The deletion point in the new file is at newStart\n if (newStart > 1) {\n changedLines.add(newStart - 1); // Line before deletion\n }\n changedLines.add(newStart); // Line after deletion (if it exists)\n }\n }\n };\n\n // 1. Handle untracked files – when a file is untracked its entire content is new.\n if (mode.includes('untracked')) {\n const status = await git.status();\n const isUntracked = status.not_added.includes(filePath);\n if (isUntracked) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n content.split('\\n').forEach((_, idx) => {\n changedLines.add(idx + 1);\n });\n } catch {\n // ignore read errors – file may have been deleted, etc.\n }\n }\n }\n\n // 2. Uncommitted changes (working tree vs HEAD)\n if (mode.includes('uncommitted')) {\n const diffOutput = await git.diff(['--unified=0', 'HEAD', '--', filePath]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 3. Unpushed commits – compare local branch to its upstream\n if (mode.includes('unpushed')) {\n const diffOutput = await git.diff([\n '--unified=0',\n '@{push}...HEAD',\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // 4. Regular git diff between baseRef and currentRef (e.g., CI pull-request diff)\n if (mode.includes('gitDiff')) {\n await git.fetch(baseRef);\n const diffOutput = await git.diff([\n '--unified=0',\n `${baseRef}...${currentRef}`,\n '--',\n filePath,\n ]);\n collectLinesFromDiff(diffOutput);\n }\n\n // Return the list sorted for convenience\n return Array.from(changedLines).sort((a, b) => a - b);\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { colorize, getPrefix, spinnerFrames, v, x } from "@intlayer/config/logger";
2
2
  import { extractErrorMessage } from "@intlayer/config/utils";
3
3
  import * as ANSIColors from "@intlayer/config/colors";
4
- import configuration from "@intlayer/config/built";
4
+ import defaultConfiguration from "@intlayer/config/built";
5
5
 
6
6
  //#region src/loadDictionaries/log.ts
7
7
  var DictionariesLogger = class {
@@ -20,7 +20,7 @@ var DictionariesLogger = class {
20
20
  pluginDone = 0;
21
21
  pluginError;
22
22
  constructor() {
23
- this.prefix = getPrefix(configuration?.log?.prefix) ?? "";
23
+ this.prefix = getPrefix(defaultConfiguration.log?.prefix) ?? "";
24
24
  }
25
25
  setExpectRemote(expect) {
26
26
  this.expectRemote = expect;
@@ -1 +1 @@
1
- {"version":3,"file":"log.mjs","names":[],"sources":["../../../src/loadDictionaries/log.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n colorize,\n getPrefix,\n spinnerFrames,\n v,\n x,\n} from '@intlayer/config/logger';\nimport { extractErrorMessage } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport class DictionariesLogger {\n private statuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private spinnerIndex = 0;\n private renderedLines = 0;\n private readonly spinnerFrames = spinnerFrames;\n private isFinished = false;\n private readonly prefix: string;\n private lastRenderedState: string = '';\n private remoteCheckInProgress = false;\n private expectRemote = false;\n private remoteError: string | undefined;\n private pluginTotal = 0;\n private pluginDone = 0;\n private pluginError: string | undefined;\n\n constructor() {\n this.prefix = getPrefix(configuration?.log?.prefix) ?? '';\n }\n\n setExpectRemote(expect: boolean) {\n this.expectRemote = expect;\n }\n\n startRemoteCheck() {\n if (this.isFinished) return;\n this.remoteCheckInProgress = true;\n this.startSpinner();\n this.render();\n }\n\n stopRemoteCheck() {\n this.remoteCheckInProgress = false;\n }\n\n update(newStatuses: DictionariesStatus[]) {\n if (this.isFinished) return;\n for (const status of newStatuses) {\n const index = this.statuses.findIndex(\n (s) =>\n s.dictionaryKey === status.dictionaryKey && s.type === status.type\n );\n if (index >= 0) {\n this.statuses[index] = status;\n } else {\n this.statuses.push(status);\n }\n }\n\n // If we expect remote fetch later, avoid rendering a local-only line first\n const { remoteTotal } = this.computeProgress();\n if (this.expectRemote && !this.remoteCheckInProgress && remoteTotal === 0) {\n // Do not start spinner or render yet; wait until remote check starts\n return;\n }\n\n this.startSpinner();\n this.render();\n }\n\n finish() {\n this.isFinished = true;\n this.stopSpinner();\n // Render final state and keep it visible\n this.render();\n }\n\n private startSpinner() {\n if (this.spinnerTimer || this.isFinished) return;\n this.spinnerTimer = setInterval(() => {\n this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n this.render();\n }, 100);\n }\n\n private stopSpinner() {\n if (!this.spinnerTimer) return;\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n\n public setRemoteError = (error?: Error) => {\n this.remoteError = extractErrorMessage(error);\n // Avoid rendering a transient remote-only line while the remote check flag is still true\n // Ensure local + remote are rendered together after a failure\n this.stopRemoteCheck();\n this.render();\n };\n\n setPluginTotal(total: number) {\n if (this.isFinished) return;\n this.pluginTotal = total;\n if (total > 0) {\n this.startSpinner();\n }\n this.render();\n }\n\n setPluginDone(done: number) {\n if (this.isFinished) return;\n this.pluginDone = done;\n this.render();\n }\n\n setPluginError(error?: Error) {\n if (this.isFinished) return;\n this.pluginError = extractErrorMessage(error);\n this.render();\n }\n\n private render() {\n const {\n localTotal,\n localDone,\n remoteTotal,\n remoteDone,\n pluginTotal,\n pluginDone,\n } = this.computeProgress();\n\n const frame = this.spinnerFrames[this.spinnerIndex];\n const clock = colorize(frame, ANSIColors.BLUE);\n const lines: string[] = [];\n\n const isLocalDone = localDone === localTotal;\n const isRemoteDone = remoteDone === remoteTotal;\n const isPluginDone = pluginDone === pluginTotal;\n\n const suppressLocalWhileCheckingRemote =\n this.expectRemote && this.remoteCheckInProgress && remoteTotal === 0;\n\n if (!suppressLocalWhileCheckingRemote) {\n if (isLocalDone) {\n lines.push(\n `${this.prefix} ${v} Local content: ${colorize(`${localDone}`, ANSIColors.GREEN)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Local content: ${colorize(`${localDone}`, ANSIColors.BLUE)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Single remote line: show error, check, or progress counts\n if (remoteTotal > 0 || this.remoteCheckInProgress || this.remoteError) {\n if (this.remoteError) {\n lines.push(\n `${this.prefix} ${x} Remote content: ${colorize(\n this.remoteError,\n ANSIColors.RED\n )}`\n );\n } else if (remoteTotal === 0) {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize('Check server', ANSIColors.BLUE)}`\n );\n } else if (isRemoteDone) {\n lines.push(\n `${this.prefix} ${v} Remote content: ${colorize(`${remoteDone}`, ANSIColors.GREEN)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize(`${remoteDone}`, ANSIColors.BLUE)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Plugin line: show error or progress counts\n if (pluginTotal > 0 || this.pluginError) {\n if (this.pluginError) {\n lines.push(\n `${this.prefix} ${x} Plugin content: ${colorize(\n this.pluginError,\n ANSIColors.RED\n )}`\n );\n } else if (isPluginDone) {\n lines.push(\n `${this.prefix} ${v} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.GREEN)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.BLUE)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Check if the state has changed to avoid duplicate rendering\n const currentState = lines.join('\\n');\n if (currentState === this.lastRenderedState) {\n return;\n }\n this.lastRenderedState = currentState;\n\n if (this.renderedLines > 0) {\n process.stdout.write(`\\x1b[${this.renderedLines}F`);\n }\n\n const totalLinesToClear = Math.max(this.renderedLines, lines.length);\n for (let i = 0; i < totalLinesToClear; i++) {\n process.stdout.write('\\x1b[2K');\n const line = lines[i];\n if (line !== undefined) {\n process.stdout.write(line);\n }\n process.stdout.write('\\n');\n }\n\n this.renderedLines = lines.length;\n }\n\n private computeProgress() {\n const localKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'local')\n .map((s) => s.dictionaryKey)\n );\n\n const localDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'local' && (s.status === 'built' || s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n const remoteKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'remote')\n .map((s) => s.dictionaryKey)\n );\n\n const remoteDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'remote' &&\n (s.status === 'fetched' ||\n s.status === 'imported' ||\n s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n return {\n localTotal: localKeys.size,\n localDone: localDoneKeys.size,\n remoteTotal: remoteKeys.size,\n remoteDone: remoteDoneKeys.size,\n pluginTotal: this.pluginTotal,\n pluginDone: this.pluginDone,\n } as const;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"log.mjs","names":[],"sources":["../../../src/loadDictionaries/log.ts"],"sourcesContent":["import { default as defaultConfiguration } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n colorize,\n getPrefix,\n spinnerFrames,\n v,\n x,\n} from '@intlayer/config/logger';\nimport { extractErrorMessage } from '@intlayer/config/utils';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport class DictionariesLogger {\n private statuses: DictionariesStatus[] = [];\n private spinnerTimer: NodeJS.Timeout | null = null;\n private spinnerIndex = 0;\n private renderedLines = 0;\n private readonly spinnerFrames = spinnerFrames;\n private isFinished = false;\n private readonly prefix: string;\n private lastRenderedState: string = '';\n private remoteCheckInProgress = false;\n private expectRemote = false;\n private remoteError: string | undefined;\n private pluginTotal = 0;\n private pluginDone = 0;\n private pluginError: string | undefined;\n\n constructor() {\n this.prefix = getPrefix(defaultConfiguration.log?.prefix) ?? '';\n }\n\n setExpectRemote(expect: boolean) {\n this.expectRemote = expect;\n }\n\n startRemoteCheck() {\n if (this.isFinished) return;\n this.remoteCheckInProgress = true;\n this.startSpinner();\n this.render();\n }\n\n stopRemoteCheck() {\n this.remoteCheckInProgress = false;\n }\n\n update(newStatuses: DictionariesStatus[]) {\n if (this.isFinished) return;\n for (const status of newStatuses) {\n const index = this.statuses.findIndex(\n (s) =>\n s.dictionaryKey === status.dictionaryKey && s.type === status.type\n );\n if (index >= 0) {\n this.statuses[index] = status;\n } else {\n this.statuses.push(status);\n }\n }\n\n // If we expect remote fetch later, avoid rendering a local-only line first\n const { remoteTotal } = this.computeProgress();\n if (this.expectRemote && !this.remoteCheckInProgress && remoteTotal === 0) {\n // Do not start spinner or render yet; wait until remote check starts\n return;\n }\n\n this.startSpinner();\n this.render();\n }\n\n finish() {\n this.isFinished = true;\n this.stopSpinner();\n // Render final state and keep it visible\n this.render();\n }\n\n private startSpinner() {\n if (this.spinnerTimer || this.isFinished) return;\n this.spinnerTimer = setInterval(() => {\n this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n this.render();\n }, 100);\n }\n\n private stopSpinner() {\n if (!this.spinnerTimer) return;\n clearInterval(this.spinnerTimer);\n this.spinnerTimer = null;\n }\n\n public setRemoteError = (error?: Error) => {\n this.remoteError = extractErrorMessage(error);\n // Avoid rendering a transient remote-only line while the remote check flag is still true\n // Ensure local + remote are rendered together after a failure\n this.stopRemoteCheck();\n this.render();\n };\n\n setPluginTotal(total: number) {\n if (this.isFinished) return;\n this.pluginTotal = total;\n if (total > 0) {\n this.startSpinner();\n }\n this.render();\n }\n\n setPluginDone(done: number) {\n if (this.isFinished) return;\n this.pluginDone = done;\n this.render();\n }\n\n setPluginError(error?: Error) {\n if (this.isFinished) return;\n this.pluginError = extractErrorMessage(error);\n this.render();\n }\n\n private render() {\n const {\n localTotal,\n localDone,\n remoteTotal,\n remoteDone,\n pluginTotal,\n pluginDone,\n } = this.computeProgress();\n\n const frame = this.spinnerFrames[this.spinnerIndex];\n const clock = colorize(frame, ANSIColors.BLUE);\n const lines: string[] = [];\n\n const isLocalDone = localDone === localTotal;\n const isRemoteDone = remoteDone === remoteTotal;\n const isPluginDone = pluginDone === pluginTotal;\n\n const suppressLocalWhileCheckingRemote =\n this.expectRemote && this.remoteCheckInProgress && remoteTotal === 0;\n\n if (!suppressLocalWhileCheckingRemote) {\n if (isLocalDone) {\n lines.push(\n `${this.prefix} ${v} Local content: ${colorize(`${localDone}`, ANSIColors.GREEN)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Local content: ${colorize(`${localDone}`, ANSIColors.BLUE)}${colorize(`/${localTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Single remote line: show error, check, or progress counts\n if (remoteTotal > 0 || this.remoteCheckInProgress || this.remoteError) {\n if (this.remoteError) {\n lines.push(\n `${this.prefix} ${x} Remote content: ${colorize(\n this.remoteError,\n ANSIColors.RED\n )}`\n );\n } else if (remoteTotal === 0) {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize('Check server', ANSIColors.BLUE)}`\n );\n } else if (isRemoteDone) {\n lines.push(\n `${this.prefix} ${v} Remote content: ${colorize(`${remoteDone}`, ANSIColors.GREEN)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Remote content: ${colorize(`${remoteDone}`, ANSIColors.BLUE)}${colorize(`/${remoteTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Plugin line: show error or progress counts\n if (pluginTotal > 0 || this.pluginError) {\n if (this.pluginError) {\n lines.push(\n `${this.prefix} ${x} Plugin content: ${colorize(\n this.pluginError,\n ANSIColors.RED\n )}`\n );\n } else if (isPluginDone) {\n lines.push(\n `${this.prefix} ${v} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.GREEN)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n } else {\n lines.push(\n `${this.prefix} ${clock} Plugin content: ${colorize(`${pluginDone}`, ANSIColors.BLUE)}${colorize(`/${pluginTotal}`, ANSIColors.GREY)}`\n );\n }\n }\n\n // Check if the state has changed to avoid duplicate rendering\n const currentState = lines.join('\\n');\n if (currentState === this.lastRenderedState) {\n return;\n }\n this.lastRenderedState = currentState;\n\n if (this.renderedLines > 0) {\n process.stdout.write(`\\x1b[${this.renderedLines}F`);\n }\n\n const totalLinesToClear = Math.max(this.renderedLines, lines.length);\n for (let i = 0; i < totalLinesToClear; i++) {\n process.stdout.write('\\x1b[2K');\n const line = lines[i];\n if (line !== undefined) {\n process.stdout.write(line);\n }\n process.stdout.write('\\n');\n }\n\n this.renderedLines = lines.length;\n }\n\n private computeProgress() {\n const localKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'local')\n .map((s) => s.dictionaryKey)\n );\n\n const localDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'local' && (s.status === 'built' || s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n const remoteKeys = new Set(\n this.statuses\n .filter((s) => s.type === 'remote')\n .map((s) => s.dictionaryKey)\n );\n\n const remoteDoneKeys = new Set(\n this.statuses\n .filter(\n (s) =>\n s.type === 'remote' &&\n (s.status === 'fetched' ||\n s.status === 'imported' ||\n s.status === 'error')\n )\n .map((s) => s.dictionaryKey)\n );\n\n return {\n localTotal: localKeys.size,\n localDone: localDoneKeys.size,\n remoteTotal: remoteKeys.size,\n remoteDone: remoteDoneKeys.size,\n pluginTotal: this.pluginTotal,\n pluginDone: this.pluginDone,\n } as const;\n }\n}\n"],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  import { relative } from "node:path";
2
2
  import { colorize, colorizePath } from "@intlayer/config/logger";
3
3
  import * as ANSIColors from "@intlayer/config/colors";
4
- import configuration from "@intlayer/config/built";
4
+ import { system } from "@intlayer/config/built";
5
5
  import { getLocaleName } from "@intlayer/core/localization";
6
6
  import { ENGLISH } from "@intlayer/types/locales";
7
7
 
8
8
  //#region src/utils/formatter.ts
9
- const formatPath = (path, color) => [path].flat().map((path) => path.startsWith("/") ? relative(configuration.system.baseDir, path) : path).map((relativePath) => color === false ? relativePath : colorizePath(relativePath, color)).join(`, `);
9
+ const formatPath = (path, color) => [path].flat().map((path) => path.startsWith("/") ? relative(system.baseDir, path) : path).map((relativePath) => color === false ? relativePath : colorizePath(relativePath, color)).join(`, `);
10
10
  const formatLocale = (locale, color = ANSIColors.GREEN) => [locale].flat().map((locale) => `${getLocaleName(locale, ENGLISH)} (${locale})`).map((text) => color === false ? text : colorize(text, color)).join(`, `);
11
11
 
12
12
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.mjs","names":[],"sources":["../../../src/utils/formatter.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport configuration from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n type ANSIColorsType,\n colorize,\n colorizePath,\n} from '@intlayer/config/logger';\nimport { getLocaleName } from '@intlayer/core/localization';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\nexport const formatPath = (\n path: string | string[],\n color?: ANSIColorsType | false\n) =>\n [path]\n .flat()\n .map((path) =>\n path.startsWith('/') ? relative(configuration.system.baseDir, path) : path\n )\n .map((relativePath) =>\n color === false ? relativePath : colorizePath(relativePath, color)\n )\n .join(`, `);\n\nexport const formatLocale = (\n locale: LocalesValues | LocalesValues[],\n color: ANSIColorsType | false = ANSIColors.GREEN\n) =>\n [locale]\n .flat()\n .map((locale) => `${getLocaleName(locale, ENGLISH)} (${locale})`)\n .map((text) => (color === false ? text : colorize(text, color)))\n .join(`, `);\n"],"mappings":";;;;;;;;AAYA,MAAa,cACX,MACA,UAEA,CAAC,KAAK,CACH,MAAM,CACN,KAAK,SACJ,KAAK,WAAW,IAAI,GAAG,SAAS,cAAc,OAAO,SAAS,KAAK,GAAG,KACvE,CACA,KAAK,iBACJ,UAAU,QAAQ,eAAe,aAAa,cAAc,MAAM,CACnE,CACA,KAAK,KAAK;AAEf,MAAa,gBACX,QACA,QAAgC,WAAW,UAE3C,CAAC,OAAO,CACL,MAAM,CACN,KAAK,WAAW,GAAG,cAAc,QAAQ,QAAQ,CAAC,IAAI,OAAO,GAAG,CAChE,KAAK,SAAU,UAAU,QAAQ,OAAO,SAAS,MAAM,MAAM,CAAE,CAC/D,KAAK,KAAK"}
1
+ {"version":3,"file":"formatter.mjs","names":[],"sources":["../../../src/utils/formatter.ts"],"sourcesContent":["import { relative } from 'node:path';\nimport { system } from '@intlayer/config/built';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport {\n type ANSIColorsType,\n colorize,\n colorizePath,\n} from '@intlayer/config/logger';\nimport { getLocaleName } from '@intlayer/core/localization';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\nexport const formatPath = (\n path: string | string[],\n color?: ANSIColorsType | false\n) =>\n [path]\n .flat()\n .map((path) =>\n path.startsWith('/') ? relative(system.baseDir, path) : path\n )\n .map((relativePath) =>\n color === false ? relativePath : colorizePath(relativePath, color)\n )\n .join(`, `);\n\nexport const formatLocale = (\n locale: LocalesValues | LocalesValues[],\n color: ANSIColorsType | false = ANSIColors.GREEN\n) =>\n [locale]\n .flat()\n .map((locale) => `${getLocaleName(locale, ENGLISH)} (${locale})`)\n .map((text) => (color === false ? text : colorize(text, color)))\n .join(`, `);\n"],"mappings":";;;;;;;;AAYA,MAAa,cACX,MACA,UAEA,CAAC,KAAK,CACH,MAAM,CACN,KAAK,SACJ,KAAK,WAAW,IAAI,GAAG,SAAS,OAAO,SAAS,KAAK,GAAG,KACzD,CACA,KAAK,iBACJ,UAAU,QAAQ,eAAe,aAAa,cAAc,MAAM,CACnE,CACA,KAAK,KAAK;AAEf,MAAa,gBACX,QACA,QAAgC,WAAW,UAE3C,CAAC,OAAO,CACL,MAAM,CACN,KAAK,WAAW,GAAG,cAAc,QAAQ,QAAQ,CAAC,IAAI,OAAO,GAAG,CAChE,KAAK,SAAU,UAAU,QAAQ,OAAO,SAAS,MAAM,MAAM,CAAE,CAC/D,KAAK,KAAK"}
@@ -11,7 +11,7 @@ import { getContentExtension } from "./getContentExtension.mjs";
11
11
  import { getExtensionFromFormat, getFormatFromExtension } from "./getFormatFromExtension.mjs";
12
12
  import { mergeChunks } from "./mergeChunks.mjs";
13
13
  import { getGlobalLimiter, getTaskLimiter, parallelizeGlobal } from "./parallelizeGlobal.mjs";
14
- import { reduceObjectFormat } from "./reduceObjectFormat.mjs";
14
+ import { excludeObjectFormat, reduceObjectFormat } from "./reduceObjectFormat.mjs";
15
15
  import { resolveObjectPromises } from "./resolveObjectPromises.mjs";
16
16
  import { resolveRelativePath } from "./resolveRelativePath.mjs";
17
17
  import { runOnce } from "./runOnce.mjs";
@@ -19,4 +19,4 @@ import { runParallel } from "./runParallel/index.mjs";
19
19
  import { sortAlphabetically } from "./sortAlphabetically.mjs";
20
20
  import { verifyIdenticObjectFormat } from "./verifyIdenticObjectFormat.mjs";
21
21
 
22
- export { Queue, assembleJSON, autoDecorateContent, buildComponentFilesList, chunkJSON, formatLocale, formatPath, getChunk, getContentExtension, getExtensionFromFormat, getFormatFromExtension, getGlobalLimiter, getPathHash, getTaskLimiter, mergeChunks, pLimit, parallelize, parallelizeGlobal, reconstructFromSingleChunk, reduceObjectFormat, resolveObjectPromises, resolveRelativePath, runOnce, runParallel, sortAlphabetically, splitTextByLines, verifyIdenticObjectFormat };
22
+ export { Queue, assembleJSON, autoDecorateContent, buildComponentFilesList, chunkJSON, excludeObjectFormat, formatLocale, formatPath, getChunk, getContentExtension, getExtensionFromFormat, getFormatFromExtension, getGlobalLimiter, getPathHash, getTaskLimiter, mergeChunks, pLimit, parallelize, parallelizeGlobal, reconstructFromSingleChunk, reduceObjectFormat, resolveObjectPromises, resolveRelativePath, runOnce, runParallel, sortAlphabetically, splitTextByLines, verifyIdenticObjectFormat };
@@ -24,7 +24,44 @@ const reduceObjectFormat = (source, format) => {
24
24
  }
25
25
  return source;
26
26
  };
27
+ /**
28
+ * Returns the subset of source whose keys are NOT present in the format object.
29
+ * Inverse of reduceObjectFormat.
30
+ *
31
+ * Null values in source are always included as explicit fallback markers
32
+ * (they signal "use default locale" at render time).
33
+ *
34
+ * Examples:
35
+ * excludeObjectFormat({ a: 1, b: 2 }, { b: 0 }) => { a: 1 }
36
+ * excludeObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { y: 2 } }
37
+ * excludeObjectFormat({ a: null, b: 2 }, { b: 0 }) => { a: null }
38
+ */
39
+ const excludeObjectFormat = (source, format) => {
40
+ if (source === null) return null;
41
+ if (format === void 0 || format === null) return source;
42
+ if (typeof source === "object" && !Array.isArray(source) && typeof format === "object" && !Array.isArray(format)) {
43
+ const result = {};
44
+ let hasContent = false;
45
+ for (const key of Object.keys(source)) {
46
+ const excluded = excludeObjectFormat(source[key], format[key]);
47
+ if (excluded !== void 0) {
48
+ result[key] = excluded;
49
+ hasContent = true;
50
+ }
51
+ }
52
+ return hasContent ? result : void 0;
53
+ }
54
+ if (Array.isArray(source)) {
55
+ const formatArr = Array.isArray(format) ? format : [];
56
+ const result = [];
57
+ for (let i = 0; i < source.length; i++) {
58
+ const excluded = excludeObjectFormat(source[i], formatArr[i]);
59
+ if (excluded !== void 0) result.push(excluded);
60
+ }
61
+ return result.length > 0 ? result : void 0;
62
+ }
63
+ };
27
64
 
28
65
  //#endregion
29
- export { reduceObjectFormat };
66
+ export { excludeObjectFormat, reduceObjectFormat };
30
67
  //# sourceMappingURL=reduceObjectFormat.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"reduceObjectFormat.mjs","names":[],"sources":["../../../src/utils/reduceObjectFormat.ts"],"sourcesContent":["type Primitive = string | number | boolean | null | undefined;\n\ntype Recursive = Primitive | { [key: string]: Recursive } | Array<Recursive>;\n\n/**\n * Reduce an object to only the shape provided by a format object.\n * Values are always taken from the source object; the format is used only for structure.\n *\n * Examples:\n * reduceObjectFormat({ a: 1, b: 2 }, { a: 0 }) => { a: 1 }\n * reduceObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { x: 1 } }\n */\nexport const reduceObjectFormat = (\n source: Recursive,\n format: Recursive\n): Recursive => {\n // If the format is an array, reduce each element by its counterpart in source\n if (Array.isArray(format)) {\n const sourceArray = Array.isArray(source) ? source : [];\n return format.map((formatItem, index) =>\n reduceObjectFormat(sourceArray[index], formatItem)\n );\n }\n\n // If the format is an object (and not null), pick matching keys and recurse\n if (typeof format === 'object' && format !== null) {\n const result: Record<string, Recursive> = {};\n const sourceObject =\n typeof source === 'object' && source !== null && !Array.isArray(source)\n ? (source as Record<string, Recursive>)\n : ({} as Record<string, Recursive>);\n\n for (const key of Object.keys(format)) {\n const nextSource = sourceObject[key];\n const nextFormat = (format as Record<string, Recursive>)[key];\n result[key] = reduceObjectFormat(nextSource, nextFormat);\n }\n return result;\n }\n\n // For primitives in the format, simply return the source value (can be undefined)\n return source as Primitive;\n};\n"],"mappings":";;;;;;;;;AAYA,MAAa,sBACX,QACA,WACc;AAEd,KAAI,MAAM,QAAQ,OAAO,EAAE;EACzB,MAAM,cAAc,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;AACvD,SAAO,OAAO,KAAK,YAAY,UAC7B,mBAAmB,YAAY,QAAQ,WAAW,CACnD;;AAIH,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,SAAoC,EAAE;EAC5C,MAAM,eACJ,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,OAAO,GAClE,SACA,EAAE;AAET,OAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;GACrC,MAAM,aAAa,aAAa;GAChC,MAAM,aAAc,OAAqC;AACzD,UAAO,OAAO,mBAAmB,YAAY,WAAW;;AAE1D,SAAO;;AAIT,QAAO"}
1
+ {"version":3,"file":"reduceObjectFormat.mjs","names":[],"sources":["../../../src/utils/reduceObjectFormat.ts"],"sourcesContent":["export type Primitive = string | number | boolean | null | undefined;\n\nexport type Recursive =\n | Primitive\n | { [key: string]: Recursive }\n | Array<Recursive>;\n\n/**\n * Reduce an object to only the shape provided by a format object.\n * Values are always taken from the source object; the format is used only for structure.\n *\n * Examples:\n * reduceObjectFormat({ a: 1, b: 2 }, { a: 0 }) => { a: 1 }\n * reduceObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { x: 1 } }\n */\nexport const reduceObjectFormat = (\n source: Recursive,\n format: Recursive\n): Recursive => {\n // If the format is an array, reduce each element by its counterpart in source\n if (Array.isArray(format)) {\n const sourceArray = Array.isArray(source) ? source : [];\n return format.map((formatItem, index) =>\n reduceObjectFormat(sourceArray[index], formatItem)\n );\n }\n\n // If the format is an object (and not null), pick matching keys and recurse\n if (typeof format === 'object' && format !== null) {\n const result: Record<string, Recursive> = {};\n const sourceObject =\n typeof source === 'object' && source !== null && !Array.isArray(source)\n ? (source as Record<string, Recursive>)\n : ({} as Record<string, Recursive>);\n\n for (const key of Object.keys(format)) {\n const nextSource = sourceObject[key];\n const nextFormat = (format as Record<string, Recursive>)[key];\n result[key] = reduceObjectFormat(nextSource, nextFormat);\n }\n return result;\n }\n\n // For primitives in the format, simply return the source value (can be undefined)\n return source as Primitive;\n};\n\n/**\n * Returns the subset of source whose keys are NOT present in the format object.\n * Inverse of reduceObjectFormat.\n *\n * Null values in source are always included as explicit fallback markers\n * (they signal \"use default locale\" at render time).\n *\n * Examples:\n * excludeObjectFormat({ a: 1, b: 2 }, { b: 0 }) => { a: 1 }\n * excludeObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { y: 2 } }\n * excludeObjectFormat({ a: null, b: 2 }, { b: 0 }) => { a: null }\n */\nexport const excludeObjectFormat = (\n source: Recursive,\n format: Recursive\n): Recursive | undefined => {\n // null in source = explicit fallback marker → always include\n if (source === null) return null;\n\n // No format means nothing is translated yet → include all source\n if (format === undefined || format === null) return source;\n\n // Both plain objects → recurse key-by-key\n if (\n typeof source === 'object' &&\n !Array.isArray(source) &&\n typeof format === 'object' &&\n !Array.isArray(format)\n ) {\n const result: Record<string, Recursive> = {};\n let hasContent = false;\n\n for (const key of Object.keys(source as Record<string, Recursive>)) {\n const excluded = excludeObjectFormat(\n (source as Record<string, Recursive>)[key],\n (format as Record<string, Recursive>)[key]\n );\n if (excluded !== undefined) {\n result[key] = excluded;\n hasContent = true;\n }\n }\n\n return hasContent ? result : undefined;\n }\n\n // Arrays → recurse by index\n if (Array.isArray(source)) {\n const formatArr = Array.isArray(format) ? format : [];\n const result: Recursive[] = [];\n\n for (let i = 0; i < source.length; i++) {\n const excluded = excludeObjectFormat(source[i], formatArr[i]);\n if (excluded !== undefined) {\n result.push(excluded);\n }\n }\n\n return result.length > 0 ? result : undefined;\n }\n\n // Primitive in source and format has a value → already translated → exclude\n return undefined;\n};\n"],"mappings":";;;;;;;;;AAeA,MAAa,sBACX,QACA,WACc;AAEd,KAAI,MAAM,QAAQ,OAAO,EAAE;EACzB,MAAM,cAAc,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;AACvD,SAAO,OAAO,KAAK,YAAY,UAC7B,mBAAmB,YAAY,QAAQ,WAAW,CACnD;;AAIH,KAAI,OAAO,WAAW,YAAY,WAAW,MAAM;EACjD,MAAM,SAAoC,EAAE;EAC5C,MAAM,eACJ,OAAO,WAAW,YAAY,WAAW,QAAQ,CAAC,MAAM,QAAQ,OAAO,GAClE,SACA,EAAE;AAET,OAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;GACrC,MAAM,aAAa,aAAa;GAChC,MAAM,aAAc,OAAqC;AACzD,UAAO,OAAO,mBAAmB,YAAY,WAAW;;AAE1D,SAAO;;AAIT,QAAO;;;;;;;;;;;;;;AAeT,MAAa,uBACX,QACA,WAC0B;AAE1B,KAAI,WAAW,KAAM,QAAO;AAG5B,KAAI,WAAW,UAAa,WAAW,KAAM,QAAO;AAGpD,KACE,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,OAAO,IACtB,OAAO,WAAW,YAClB,CAAC,MAAM,QAAQ,OAAO,EACtB;EACA,MAAM,SAAoC,EAAE;EAC5C,IAAI,aAAa;AAEjB,OAAK,MAAM,OAAO,OAAO,KAAK,OAAoC,EAAE;GAClE,MAAM,WAAW,oBACd,OAAqC,MACrC,OAAqC,KACvC;AACD,OAAI,aAAa,QAAW;AAC1B,WAAO,OAAO;AACd,iBAAa;;;AAIjB,SAAO,aAAa,SAAS;;AAI/B,KAAI,MAAM,QAAQ,OAAO,EAAE;EACzB,MAAM,YAAY,MAAM,QAAQ,OAAO,GAAG,SAAS,EAAE;EACrD,MAAM,SAAsB,EAAE;AAE9B,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,WAAW,oBAAoB,OAAO,IAAI,UAAU,GAAG;AAC7D,OAAI,aAAa,OACf,QAAO,KAAK,SAAS;;AAIzB,SAAO,OAAO,SAAS,IAAI,SAAS"}
@@ -10,7 +10,7 @@ import { mergeChunks } from "./mergeChunks.js";
10
10
  import { parallelize } from "./parallelize.js";
11
11
  import { Queue, pLimit } from "./pLimit.js";
12
12
  import { getGlobalLimiter, getTaskLimiter, parallelizeGlobal } from "./parallelizeGlobal.js";
13
- import { reduceObjectFormat } from "./reduceObjectFormat.js";
13
+ import { Primitive, Recursive, excludeObjectFormat, reduceObjectFormat } from "./reduceObjectFormat.js";
14
14
  import { resolveObjectPromises } from "./resolveObjectPromises.js";
15
15
  import { resolveRelativePath } from "./resolveRelativePath.js";
16
16
  import { runOnce } from "./runOnce.js";
@@ -18,4 +18,4 @@ import { ParallelHandle, runParallel } from "./runParallel/index.js";
18
18
  import { sortAlphabetically } from "./sortAlphabetically.js";
19
19
  import { splitTextByLines } from "./splitTextByLine.js";
20
20
  import { verifyIdenticObjectFormat } from "./verifyIdenticObjectFormat.js";
21
- export { Extension, Format, JSONObject, JsonChunk, ParallelHandle, Queue, assembleJSON, autoDecorateContent, buildComponentFilesList, chunkJSON, formatLocale, formatPath, getChunk, getContentExtension, getExtensionFromFormat, getFormatFromExtension, getGlobalLimiter, getPathHash, getTaskLimiter, mergeChunks, pLimit, parallelize, parallelizeGlobal, reconstructFromSingleChunk, reduceObjectFormat, resolveObjectPromises, resolveRelativePath, runOnce, runParallel, sortAlphabetically, splitTextByLines, verifyIdenticObjectFormat };
21
+ export { Extension, Format, JSONObject, JsonChunk, ParallelHandle, Primitive, Queue, Recursive, assembleJSON, autoDecorateContent, buildComponentFilesList, chunkJSON, excludeObjectFormat, formatLocale, formatPath, getChunk, getContentExtension, getExtensionFromFormat, getFormatFromExtension, getGlobalLimiter, getPathHash, getTaskLimiter, mergeChunks, pLimit, parallelize, parallelizeGlobal, reconstructFromSingleChunk, reduceObjectFormat, resolveObjectPromises, resolveRelativePath, runOnce, runParallel, sortAlphabetically, splitTextByLines, verifyIdenticObjectFormat };
@@ -12,6 +12,19 @@ type Recursive = Primitive | {
12
12
  * reduceObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { x: 1 } }
13
13
  */
14
14
  declare const reduceObjectFormat: (source: Recursive, format: Recursive) => Recursive;
15
+ /**
16
+ * Returns the subset of source whose keys are NOT present in the format object.
17
+ * Inverse of reduceObjectFormat.
18
+ *
19
+ * Null values in source are always included as explicit fallback markers
20
+ * (they signal "use default locale" at render time).
21
+ *
22
+ * Examples:
23
+ * excludeObjectFormat({ a: 1, b: 2 }, { b: 0 }) => { a: 1 }
24
+ * excludeObjectFormat({ a: { x: 1, y: 2 } }, { a: { x: 0 } }) => { a: { y: 2 } }
25
+ * excludeObjectFormat({ a: null, b: 2 }, { b: 0 }) => { a: null }
26
+ */
27
+ declare const excludeObjectFormat: (source: Recursive, format: Recursive) => Recursive | undefined;
15
28
  //#endregion
16
- export { reduceObjectFormat };
29
+ export { Primitive, Recursive, excludeObjectFormat, reduceObjectFormat };
17
30
  //# sourceMappingURL=reduceObjectFormat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reduceObjectFormat.d.ts","names":[],"sources":["../../../src/utils/reduceObjectFormat.ts"],"mappings":";KAAK,SAAA;AAAA,KAEA,SAAA,GAAY,SAAA;EAAA,CAAe,GAAA,WAAc,SAAA;AAAA,IAAc,KAAA,CAAM,SAAA;;;AAFpD;;;;;;cAYD,kBAAA,GACX,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,SAAA,KACP,SAAA"}
1
+ {"version":3,"file":"reduceObjectFormat.d.ts","names":[],"sources":["../../../src/utils/reduceObjectFormat.ts"],"mappings":";KAAY,SAAA;AAAA,KAEA,SAAA,GACR,SAAA;EAAA,CACG,GAAA,WAAc,SAAA;AAAA,IACjB,KAAA,CAAM,SAAA;;;AAHV;;;;;;cAaa,kBAAA,GACX,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,SAAA,KACP,SAAA;;;;;;;;;;AAHH;;;cA4Ca,mBAAA,GACX,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,SAAA,KACP,SAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/chokidar",
3
- "version": "8.6.2",
3
+ "version": "8.6.4",
4
4
  "private": false,
5
5
  "description": "Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.",
6
6
  "keywords": [
@@ -109,13 +109,13 @@
109
109
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
110
110
  },
111
111
  "dependencies": {
112
- "@intlayer/api": "8.6.2",
113
- "@intlayer/config": "8.6.2",
114
- "@intlayer/core": "8.6.2",
115
- "@intlayer/dictionaries-entry": "8.6.2",
116
- "@intlayer/remote-dictionaries-entry": "8.6.2",
117
- "@intlayer/types": "8.6.2",
118
- "@intlayer/unmerged-dictionaries-entry": "8.6.2",
112
+ "@intlayer/api": "8.6.4",
113
+ "@intlayer/config": "8.6.4",
114
+ "@intlayer/core": "8.6.4",
115
+ "@intlayer/dictionaries-entry": "8.6.4",
116
+ "@intlayer/remote-dictionaries-entry": "8.6.4",
117
+ "@intlayer/types": "8.6.4",
118
+ "@intlayer/unmerged-dictionaries-entry": "8.6.4",
119
119
  "chokidar": "3.6.0",
120
120
  "defu": "6.1.4",
121
121
  "fast-glob": "3.3.3",