@intlayer/engine 9.5.2 → 9.5.4-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +9 -9
  2. package/dist/assets/initConfig/templates/cjs.txt +0 -4
  3. package/dist/assets/initConfig/templates/json.txt +0 -4
  4. package/dist/assets/initConfig/templates/mjs.txt +0 -4
  5. package/dist/assets/initConfig/templates/ts.txt +0 -4
  6. package/dist/cjs/_virtual/_utils_asset.cjs +1 -1
  7. package/dist/cjs/build.cjs +2 -2
  8. package/dist/cjs/cleanOutputDir.cjs +1 -1
  9. package/dist/cjs/cleanRemovedContentDeclaration.cjs +37 -20
  10. package/dist/cjs/cleanRemovedContentDeclaration.cjs.map +1 -1
  11. package/dist/cjs/cli.cjs +2 -2
  12. package/dist/cjs/createDictionaryEntryPoint/getBuiltDictionariesPath.cjs +2 -2
  13. package/dist/cjs/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.cjs +2 -2
  14. package/dist/cjs/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.cjs +2 -2
  15. package/dist/cjs/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.cjs +2 -2
  16. package/dist/cjs/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.cjs +2 -2
  17. package/dist/cjs/createType/createModuleAugmentation.cjs +2 -2
  18. package/dist/cjs/docReview/index.cjs +4 -4
  19. package/dist/cjs/docReview/pipeline.cjs +2 -2
  20. package/dist/cjs/docReview/reviewReport.cjs +1 -1
  21. package/dist/cjs/filterInvalidDictionaries.cjs +1 -1
  22. package/dist/cjs/handleAdditionalContentDeclarationFile.cjs +1 -1
  23. package/dist/cjs/handleContentDeclarationFileChange.cjs +4 -4
  24. package/dist/cjs/handleContentDeclarationFileMoved.cjs +1 -1
  25. package/dist/cjs/handleUnlinkedContentDeclarationFile.cjs +1 -1
  26. package/dist/cjs/init/cms.cjs +2 -2
  27. package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs +1 -1
  28. package/dist/cjs/init/frameworkSetup/tanstackStart/index.cjs +1 -1
  29. package/dist/cjs/init/index.cjs +2 -2
  30. package/dist/cjs/init/utils/fileSystem.cjs +1 -1
  31. package/dist/cjs/init/utils/githubActions.cjs +1 -1
  32. package/dist/cjs/init/utils/nextCompilerBabel.cjs +1 -1
  33. package/dist/cjs/init/utils/packageManager.cjs +1 -1
  34. package/dist/cjs/installLSP.cjs +1 -1
  35. package/dist/cjs/installMCP/installMCP.cjs +1 -1
  36. package/dist/cjs/installSkills/index.cjs +1 -1
  37. package/dist/cjs/listDictionariesPath.cjs +1 -1
  38. package/dist/cjs/listGitFiles.cjs +2 -2
  39. package/dist/cjs/listProjects.cjs +1 -1
  40. package/dist/cjs/loadDictionaries/getIntlayerBundle.cjs +1 -1
  41. package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs +1 -1
  42. package/dist/cjs/loadDictionaries/loadDictionaries.cjs +1 -1
  43. package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs +2 -2
  44. package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs.map +1 -1
  45. package/dist/cjs/loadDictionaries/log.cjs +2 -2
  46. package/dist/cjs/logConfigDetails.cjs +3 -3
  47. package/dist/cjs/logConfigDetails.cjs.map +1 -1
  48. package/dist/cjs/prepareIntlayer.cjs +3 -3
  49. package/dist/cjs/scan/index.cjs +1 -1
  50. package/dist/cjs/scan/scanWebsite.cjs +2 -2
  51. package/dist/cjs/syncPluginKit/createFileAdapter.cjs +1 -1
  52. package/dist/cjs/utils/autoDecorateContent.cjs +5 -5
  53. package/dist/cjs/utils/autoDecorateContent.cjs.map +1 -1
  54. package/dist/cjs/utils/buildComponentFilesList.cjs +2 -2
  55. package/dist/cjs/utils/contentWatcherLock.cjs +2 -2
  56. package/dist/cjs/utils/formatter.cjs +1 -1
  57. package/dist/cjs/utils/readDictionariesFromDisk.cjs +1 -1
  58. package/dist/cjs/utils/runOnce.cjs +1 -1
  59. package/dist/cjs/utils/runParallel/pidTree.cjs +1 -1
  60. package/dist/cjs/utils/withFileLock.cjs +1 -1
  61. package/dist/cjs/watcher.cjs +5 -5
  62. package/dist/cjs/writeContentDeclaration/processContentDeclarationContent.cjs +1 -1
  63. package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs +1 -1
  64. package/dist/cjs/writeContentDeclaration/writeJSFile.cjs +1 -1
  65. package/dist/cjs/writeFileIfChanged.cjs +1 -1
  66. package/dist/esm/_virtual/_utils_asset.mjs +1 -1
  67. package/dist/esm/build.mjs +2 -2
  68. package/dist/esm/cleanOutputDir.mjs +1 -1
  69. package/dist/esm/cleanRemovedContentDeclaration.mjs +37 -20
  70. package/dist/esm/cleanRemovedContentDeclaration.mjs.map +1 -1
  71. package/dist/esm/cli.mjs +2 -2
  72. package/dist/esm/createDictionaryEntryPoint/getBuiltDictionariesPath.mjs +2 -2
  73. package/dist/esm/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.mjs +2 -2
  74. package/dist/esm/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.mjs +2 -2
  75. package/dist/esm/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.mjs +2 -2
  76. package/dist/esm/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.mjs +2 -2
  77. package/dist/esm/createType/createModuleAugmentation.mjs +1 -1
  78. package/dist/esm/docReview/index.mjs +4 -4
  79. package/dist/esm/docReview/pipeline.mjs +2 -2
  80. package/dist/esm/docReview/reviewReport.mjs +1 -1
  81. package/dist/esm/filterInvalidDictionaries.mjs +1 -1
  82. package/dist/esm/handleAdditionalContentDeclarationFile.mjs +1 -1
  83. package/dist/esm/handleContentDeclarationFileChange.mjs +4 -4
  84. package/dist/esm/handleContentDeclarationFileMoved.mjs +1 -1
  85. package/dist/esm/handleUnlinkedContentDeclarationFile.mjs +1 -1
  86. package/dist/esm/init/cms.mjs +1 -1
  87. package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs +1 -1
  88. package/dist/esm/init/frameworkSetup/tanstackStart/index.mjs +1 -1
  89. package/dist/esm/init/index.mjs +1 -1
  90. package/dist/esm/init/utils/fileSystem.mjs +1 -1
  91. package/dist/esm/init/utils/githubActions.mjs +1 -1
  92. package/dist/esm/init/utils/nextCompilerBabel.mjs +1 -1
  93. package/dist/esm/init/utils/packageManager.mjs +1 -1
  94. package/dist/esm/installLSP.mjs +1 -1
  95. package/dist/esm/installMCP/installMCP.mjs +1 -1
  96. package/dist/esm/installSkills/index.mjs +1 -1
  97. package/dist/esm/listDictionariesPath.mjs +1 -1
  98. package/dist/esm/listGitFiles.mjs +2 -2
  99. package/dist/esm/listProjects.mjs +1 -1
  100. package/dist/esm/loadDictionaries/getIntlayerBundle.mjs +1 -1
  101. package/dist/esm/loadDictionaries/loadContentDeclaration.mjs +1 -1
  102. package/dist/esm/loadDictionaries/loadDictionaries.mjs +1 -1
  103. package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs +1 -1
  104. package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs.map +1 -1
  105. package/dist/esm/loadDictionaries/log.mjs +1 -1
  106. package/dist/esm/logConfigDetails.mjs +3 -3
  107. package/dist/esm/logConfigDetails.mjs.map +1 -1
  108. package/dist/esm/prepareIntlayer.mjs +2 -2
  109. package/dist/esm/scan/index.mjs +1 -1
  110. package/dist/esm/scan/scanWebsite.mjs +2 -2
  111. package/dist/esm/syncPluginKit/createFileAdapter.mjs +1 -1
  112. package/dist/esm/utils/autoDecorateContent.mjs +5 -5
  113. package/dist/esm/utils/autoDecorateContent.mjs.map +1 -1
  114. package/dist/esm/utils/buildComponentFilesList.mjs +1 -1
  115. package/dist/esm/utils/contentWatcherLock.mjs +2 -2
  116. package/dist/esm/utils/formatter.mjs +1 -1
  117. package/dist/esm/utils/readDictionariesFromDisk.mjs +1 -1
  118. package/dist/esm/utils/runOnce.mjs +1 -1
  119. package/dist/esm/utils/runParallel/pidTree.mjs +1 -1
  120. package/dist/esm/utils/withFileLock.mjs +1 -1
  121. package/dist/esm/watcher.mjs +4 -4
  122. package/dist/esm/writeContentDeclaration/processContentDeclarationContent.mjs +1 -1
  123. package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs +1 -1
  124. package/dist/esm/writeContentDeclaration/writeJSFile.mjs +1 -1
  125. package/dist/esm/writeFileIfChanged.mjs +1 -1
  126. package/dist/types/cleanRemovedContentDeclaration.d.ts.map +1 -1
  127. package/dist/types/formatDictionary.d.ts +2 -3
  128. package/dist/types/formatDictionary.d.ts.map +1 -1
  129. package/dist/types/logConfigDetails.d.ts.map +1 -1
  130. package/dist/types/utils/autoDecorateContent.d.ts.map +1 -1
  131. package/package.json +10 -11
  132. package/dist/types/intlayer/dist/types/index.d.ts +0 -14
@@ -1,6 +1,6 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { rm } from "node:fs/promises";
2
3
  import { getAppLogger } from "@intlayer/config/logger";
3
- import { existsSync } from "node:fs";
4
4
 
5
5
  //#region src/cleanOutputDir.ts
6
6
  const cleanOutputDir = async (configuration) => {
@@ -1,13 +1,33 @@
1
- import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
2
1
  import { readDictionariesFromDisk } from "./utils/readDictionariesFromDisk.mjs";
3
2
  import { writeJsonIfChanged } from "./writeJsonIfChanged.mjs";
3
+ import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
4
4
  import { readFile, rm } from "node:fs/promises";
5
5
  import { join, normalize, relative } from "node:path";
6
- import { normalizePath } from "@intlayer/config/client";
7
6
  import { colorizeKey, colorizePath, getAppLogger } from "@intlayer/config/logger";
8
7
  import fg from "fast-glob";
8
+ import { normalizePath } from "@intlayer/config/client";
9
9
 
10
10
  //#region src/cleanRemovedContentDeclaration.ts
11
+ /**
12
+ * Grace period before bundler-graph artifacts (JSON, dynamic chunks) are
13
+ * deleted, so a bundler rebuild started from the previous entry point can
14
+ * still resolve them.
15
+ */
16
+ const ARTIFACT_REMOVAL_DELAY_MS = 3e3;
17
+ /**
18
+ * Source ids of a merged dictionary. A dictionary built from a single source
19
+ * is written as-is, so it carries `localId` rather than `localIds`.
20
+ */
21
+ const getMergedLocalIds = (dictionary) => dictionary.localIds ?? (dictionary.localId ? [dictionary.localId] : []);
22
+ const removeArtifacts = async (paths, baseDir, appLogger) => await Promise.all(paths.map(async (path) => {
23
+ const relativePath = relative(baseDir, path);
24
+ try {
25
+ await rm(path, { force: true });
26
+ appLogger(`Deleted artifact: ${colorizePath(relativePath)}`, { isVerbose: true });
27
+ } catch {
28
+ appLogger(`Error while removing file ${colorizePath(relativePath)}`, { isVerbose: true });
29
+ }
30
+ }));
11
31
  const cleanRemovedContentDeclaration = async (filePath, keysToKeep, configuration) => {
12
32
  const appLogger = getAppLogger(configuration);
13
33
  const unmergedDictionaries = readDictionariesFromDisk(configuration.system.unmergedDictionariesDir);
@@ -16,6 +36,7 @@ const cleanRemovedContentDeclaration = async (filePath, keysToKeep, configuratio
16
36
  const uniqueUnmergedDictionaries = Object.values(unmergedDictionaries).flat().filter((dictionary) => dictionary.filePath === relativeFilePath && !keysToKeep.includes(dictionary.key)).filter((dictionary, index, self) => index === self.findIndex((t) => t.key === dictionary.key));
17
37
  const changedDictionariesLocalIds = [];
18
38
  const filesToRemove = [];
39
+ const typeFilesToRemove = [];
19
40
  const excludeKeys = [];
20
41
  await Promise.all(uniqueUnmergedDictionaries.map(async (dictionary) => {
21
42
  const unmergedFilePath = normalize(join(configuration.system.unmergedDictionariesDir, `${dictionary.key}.json`));
@@ -40,28 +61,30 @@ const cleanRemovedContentDeclaration = async (filePath, keysToKeep, configuratio
40
61
  }
41
62
  }));
42
63
  const dictionaries = readDictionariesFromDisk(configuration.system.dictionariesDir);
43
- const uniqueMergedDictionaries = (Object.values(dictionaries)?.filter((dictionary) => !keysToKeep.includes(dictionary.key) && dictionary.localIds?.length === 1 && dictionary.localIds[0].endsWith(`::local::${relativeFilePath}`))).filter((dictionary, index, self) => index === self.findIndex((t) => t.key === dictionary.key));
64
+ const flatDictionaries = Object.values(dictionaries);
65
+ const isFromChangedFile = (localId) => localId.endsWith(`::local::${relativeFilePath}`);
66
+ const uniqueMergedDictionaries = (flatDictionaries?.filter((dictionary) => !keysToKeep.includes(dictionary.key) && getMergedLocalIds(dictionary).some(isFromChangedFile))).filter((dictionary, index, self) => index === self.findIndex((t) => t.key === dictionary.key));
44
67
  await Promise.all(uniqueMergedDictionaries.map(async (dictionary) => {
45
68
  const mergedFilePath = normalize(join(configuration.system.dictionariesDir, `${dictionary.key}.json`));
46
69
  try {
47
70
  const fileContent = await readFile(mergedFilePath, "utf8");
48
71
  const parsedContent = JSON.parse(fileContent);
49
- if (parsedContent.localIds?.length === 1) {
50
- if (parsedContent.localIds[0].endsWith(`::local::${relativeFilePath}`)) {
72
+ const localIds = getMergedLocalIds(parsedContent);
73
+ if (localIds.length === 1) {
74
+ if (isFromChangedFile(localIds[0])) {
51
75
  appLogger(`Removing outdated unmerged dictionary ${colorizeKey(dictionary.key)}`, { isVerbose: true });
52
76
  filesToRemove.push(mergedFilePath);
53
77
  const typesFilePath = normalize(join(configuration.system.typesDir, `${dictionary.key}.ts`));
54
- filesToRemove.push(typesFilePath);
78
+ typeFilesToRemove.push(typesFilePath);
55
79
  const dynamicFilesGlob = join(configuration.system.dynamicDictionariesDir, `${dictionary.key}.*`);
56
80
  const dynamicFiles = await fg(normalizePath(dynamicFilesGlob), { absolute: true });
57
81
  filesToRemove.push(...dynamicFiles);
58
82
  if (!excludeKeys.includes(dictionary.key)) excludeKeys.push(dictionary.key);
59
83
  }
60
84
  } else {
61
- const localIds = parsedContent.localIds?.filter((localeId) => !localeId.endsWith(`::local::${relativeFilePath}`));
62
85
  const newContent = {
63
86
  ...parsedContent,
64
- localIds
87
+ localIds: localIds.filter((localId) => !isFromChangedFile(localId))
65
88
  };
66
89
  await writeJsonIfChanged(mergedFilePath, newContent);
67
90
  }
@@ -69,26 +92,20 @@ const cleanRemovedContentDeclaration = async (filePath, keysToKeep, configuratio
69
92
  if (error.code === "ENOENT") {
70
93
  if (!excludeKeys.includes(dictionary.key)) excludeKeys.push(dictionary.key);
71
94
  const typesFilePath = normalize(join(configuration.system.typesDir, `${dictionary.key}.ts`));
72
- filesToRemove.push(typesFilePath);
95
+ typeFilesToRemove.push(typesFilePath);
73
96
  }
74
97
  }
75
98
  }));
76
- if (filesToRemove.length > 0 || excludeKeys.length > 0) {
99
+ const hasRebuilt = filesToRemove.length > 0 || typeFilesToRemove.length > 0 || excludeKeys.length > 0;
100
+ if (hasRebuilt) {
77
101
  await createDictionaryEntryPoint(configuration, { excludeKeys });
78
- if (filesToRemove.length > 0) setTimeout(async () => await Promise.all(filesToRemove.map(async (path) => {
79
- const relativePath = relative(baseDir, path);
80
- try {
81
- await rm(path, { force: true });
82
- appLogger(`Deleted artifact: ${colorizePath(relativePath)}`, { isVerbose: true });
83
- } catch {
84
- appLogger(`Error while removing file ${colorizePath(relativePath)}`, { isVerbose: true });
85
- }
86
- })), 3e3);
102
+ await removeArtifacts(typeFilesToRemove, baseDir, appLogger);
103
+ if (filesToRemove.length > 0) setTimeout(() => removeArtifacts(filesToRemove, baseDir, appLogger), ARTIFACT_REMOVAL_DELAY_MS);
87
104
  }
88
105
  return {
89
106
  changedDictionariesLocalIds,
90
107
  excludeKeys,
91
- hasRebuilt: filesToRemove.length > 0 || excludeKeys.length > 0
108
+ hasRebuilt
92
109
  };
93
110
  };
94
111
 
@@ -1 +1 @@
1
- {"version":3,"file":"cleanRemovedContentDeclaration.mjs","names":[],"sources":["../../src/cleanRemovedContentDeclaration.ts"],"sourcesContent":["import { readFile, rm } from 'node:fs/promises';\nimport { join, normalize, relative } from 'node:path';\nimport { normalizePath } from '@intlayer/config/client';\nimport {\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport fg from 'fast-glob';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint';\nimport { readDictionariesFromDisk } from './utils/readDictionariesFromDisk';\nimport { writeJsonIfChanged } from './writeJsonIfChanged';\n\nexport const cleanRemovedContentDeclaration = async (\n filePath: string,\n keysToKeep: string[],\n configuration: IntlayerConfig\n): Promise<{\n changedDictionariesLocalIds: string[];\n excludeKeys: string[];\n hasRebuilt: boolean;\n}> => {\n const appLogger = getAppLogger(configuration);\n\n const unmergedDictionaries = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n\n const baseDir = configuration.system.baseDir;\n\n const relativeFilePath = relative(baseDir, filePath);\n const flatUnmergedDictionaries = Object.values(unmergedDictionaries).flat();\n\n const filteredUnmergedDictionaries = flatUnmergedDictionaries.filter(\n (dictionary) =>\n dictionary.filePath === relativeFilePath &&\n !keysToKeep.includes(dictionary.key)\n );\n\n // Deduplicate dictionaries by key\n const uniqueUnmergedDictionaries = filteredUnmergedDictionaries.filter(\n (dictionary, index, self) =>\n index === self.findIndex((t) => t.key === dictionary.key)\n );\n\n const changedDictionariesLocalIds: string[] = [];\n const filesToRemove: string[] = [];\n const excludeKeys: string[] = [];\n\n // Identify Unmerged Dictionaries to remove or clean\n await Promise.all(\n uniqueUnmergedDictionaries.map(async (dictionary) => {\n const unmergedFilePath = normalize(\n join(\n configuration.system.unmergedDictionariesDir,\n `${dictionary.key}.json`\n )\n );\n\n try {\n const jsonContent = await readFile(unmergedFilePath, 'utf8');\n const parsedContent = JSON.parse(jsonContent);\n\n if (parsedContent.length === 1) {\n if (parsedContent[0].filePath === relativeFilePath) {\n appLogger(\n `Removing outdated dictionary ${colorizeKey(dictionary.key)}`,\n { isVerbose: true }\n );\n filesToRemove.push(unmergedFilePath);\n excludeKeys.push(dictionary.key);\n }\n } else {\n const filteredContent = parsedContent.filter(\n (content: any) => content.filePath !== relativeFilePath\n );\n await writeJsonIfChanged(unmergedFilePath, filteredContent);\n changedDictionariesLocalIds.push(dictionary.localId!);\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n if (!excludeKeys.includes(dictionary.key)) {\n excludeKeys.push(dictionary.key);\n }\n }\n }\n })\n );\n\n const dictionaries = readDictionariesFromDisk<Record<string, Dictionary>>(\n configuration.system.dictionariesDir\n );\n const flatDictionaries = Object.values(dictionaries) as Dictionary[];\n\n const filteredMergedDictionaries = flatDictionaries?.filter(\n (dictionary) =>\n !keysToKeep.includes(dictionary.key) &&\n dictionary.localIds?.length === 1 &&\n (dictionary.localIds[0] as string).endsWith(\n `::local::${relativeFilePath}`\n )\n );\n\n const uniqueMergedDictionaries = filteredMergedDictionaries.filter(\n (dictionary, index, self) =>\n index === self.findIndex((t) => t.key === dictionary.key)\n );\n\n // Identify Merged Dictionaries, Types, and Dynamic Dictionaries to remove\n await Promise.all(\n uniqueMergedDictionaries.map(async (dictionary) => {\n const mergedFilePath = normalize(\n join(configuration.system.dictionariesDir, `${dictionary.key}.json`)\n );\n\n try {\n const fileContent = await readFile(mergedFilePath, 'utf8');\n const parsedContent = JSON.parse(fileContent) as Dictionary;\n\n if (parsedContent.localIds?.length === 1) {\n if (\n parsedContent.localIds[0].endsWith(`::local::${relativeFilePath}`)\n ) {\n appLogger(\n `Removing outdated unmerged dictionary ${colorizeKey(dictionary.key)}`,\n { isVerbose: true }\n );\n\n // Mark JSON for removal\n filesToRemove.push(mergedFilePath);\n\n // Mark TS Types for removal\n const typesFilePath = normalize(\n join(configuration.system.typesDir, `${dictionary.key}.ts`)\n );\n filesToRemove.push(typesFilePath);\n\n // Mark Dynamic Dictionaries for removal\n // We use glob to catch the loader files (.cjs, .mjs) AND the split locale files (.en.json, etc.)\n const dynamicFilesGlob = join(\n configuration.system.dynamicDictionariesDir,\n `${dictionary.key}.*`\n );\n const dynamicFiles = await fg(normalizePath(dynamicFilesGlob), {\n absolute: true,\n });\n filesToRemove.push(...dynamicFiles);\n\n if (!excludeKeys.includes(dictionary.key)) {\n excludeKeys.push(dictionary.key);\n }\n }\n } else {\n const localIds = parsedContent.localIds?.filter(\n (localeId) => !localeId.endsWith(`::local::${relativeFilePath}`)\n ) as string[];\n const newContent = { ...parsedContent, localIds };\n await writeJsonIfChanged(mergedFilePath, newContent);\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n if (!excludeKeys.includes(dictionary.key)) {\n excludeKeys.push(dictionary.key);\n }\n const typesFilePath = normalize(\n join(configuration.system.typesDir, `${dictionary.key}.ts`)\n );\n filesToRemove.push(typesFilePath);\n }\n }\n })\n );\n\n // Execute Cleanup\n if (filesToRemove.length > 0 || excludeKeys.length > 0) {\n // Update entry points (indexes) first so the app doesn't import dead files\n await createDictionaryEntryPoint(configuration, { excludeKeys });\n\n // Remove the files synchronously (awaited) immediately after.\n if (filesToRemove.length > 0) {\n setTimeout(\n async () =>\n await Promise.all(\n filesToRemove.map(async (path) => {\n const relativePath = relative(baseDir, path);\n try {\n await rm(path, { force: true });\n\n appLogger(`Deleted artifact: ${colorizePath(relativePath)}`, {\n isVerbose: true,\n });\n } catch {\n appLogger(\n `Error while removing file ${colorizePath(relativePath)}`,\n {\n isVerbose: true,\n }\n );\n }\n })\n ),\n 3000\n );\n }\n }\n\n return {\n changedDictionariesLocalIds,\n excludeKeys,\n hasRebuilt: filesToRemove.length > 0 || excludeKeys.length > 0,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"cleanRemovedContentDeclaration.mjs","names":[],"sources":["../../src/cleanRemovedContentDeclaration.ts"],"sourcesContent":["import { readFile, rm } from 'node:fs/promises';\nimport { join, normalize, relative } from 'node:path';\nimport { normalizePath } from '@intlayer/config/client';\nimport {\n colorizeKey,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary, LocalDictionaryId } from '@intlayer/types/dictionary';\nimport fg from 'fast-glob';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint';\nimport { readDictionariesFromDisk } from './utils/readDictionariesFromDisk';\nimport { writeJsonIfChanged } from './writeJsonIfChanged';\n\n/**\n * Grace period before bundler-graph artifacts (JSON, dynamic chunks) are\n * deleted, so a bundler rebuild started from the previous entry point can\n * still resolve them.\n */\nconst ARTIFACT_REMOVAL_DELAY_MS = 3000;\n\n/**\n * Source ids of a merged dictionary. A dictionary built from a single source\n * is written as-is, so it carries `localId` rather than `localIds`.\n */\nconst getMergedLocalIds = (dictionary: Dictionary): LocalDictionaryId[] =>\n dictionary.localIds ?? (dictionary.localId ? [dictionary.localId] : []);\n\nconst removeArtifacts = async (\n paths: string[],\n baseDir: string,\n appLogger: ReturnType<typeof getAppLogger>\n) =>\n await Promise.all(\n paths.map(async (path) => {\n const relativePath = relative(baseDir, path);\n try {\n await rm(path, { force: true });\n\n appLogger(`Deleted artifact: ${colorizePath(relativePath)}`, {\n isVerbose: true,\n });\n } catch {\n appLogger(`Error while removing file ${colorizePath(relativePath)}`, {\n isVerbose: true,\n });\n }\n })\n );\n\nexport const cleanRemovedContentDeclaration = async (\n filePath: string,\n keysToKeep: string[],\n configuration: IntlayerConfig\n): Promise<{\n changedDictionariesLocalIds: string[];\n excludeKeys: string[];\n hasRebuilt: boolean;\n}> => {\n const appLogger = getAppLogger(configuration);\n\n const unmergedDictionaries = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n\n const baseDir = configuration.system.baseDir;\n\n const relativeFilePath = relative(baseDir, filePath);\n const flatUnmergedDictionaries = Object.values(unmergedDictionaries).flat();\n\n const filteredUnmergedDictionaries = flatUnmergedDictionaries.filter(\n (dictionary) =>\n dictionary.filePath === relativeFilePath &&\n !keysToKeep.includes(dictionary.key)\n );\n\n // Deduplicate dictionaries by key\n const uniqueUnmergedDictionaries = filteredUnmergedDictionaries.filter(\n (dictionary, index, self) =>\n index === self.findIndex((t) => t.key === dictionary.key)\n );\n\n const changedDictionariesLocalIds: string[] = [];\n // Bundler-graph artifacts, deleted after the entry points stop importing them\n const filesToRemove: string[] = [];\n // Type declarations are not in the bundler graph and must be gone before the\n // module augmentation is regenerated, so they are deleted right away\n const typeFilesToRemove: string[] = [];\n const excludeKeys: string[] = [];\n\n // Identify Unmerged Dictionaries to remove or clean\n await Promise.all(\n uniqueUnmergedDictionaries.map(async (dictionary) => {\n const unmergedFilePath = normalize(\n join(\n configuration.system.unmergedDictionariesDir,\n `${dictionary.key}.json`\n )\n );\n\n try {\n const jsonContent = await readFile(unmergedFilePath, 'utf8');\n const parsedContent = JSON.parse(jsonContent);\n\n if (parsedContent.length === 1) {\n if (parsedContent[0].filePath === relativeFilePath) {\n appLogger(\n `Removing outdated dictionary ${colorizeKey(dictionary.key)}`,\n { isVerbose: true }\n );\n filesToRemove.push(unmergedFilePath);\n excludeKeys.push(dictionary.key);\n }\n } else {\n const filteredContent = parsedContent.filter(\n (content: any) => content.filePath !== relativeFilePath\n );\n await writeJsonIfChanged(unmergedFilePath, filteredContent);\n changedDictionariesLocalIds.push(dictionary.localId!);\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n if (!excludeKeys.includes(dictionary.key)) {\n excludeKeys.push(dictionary.key);\n }\n }\n }\n })\n );\n\n const dictionaries = readDictionariesFromDisk<Record<string, Dictionary>>(\n configuration.system.dictionariesDir\n );\n const flatDictionaries = Object.values(dictionaries) as Dictionary[];\n\n const isFromChangedFile = (localId: LocalDictionaryId) =>\n localId.endsWith(`::local::${relativeFilePath}`);\n\n const filteredMergedDictionaries = flatDictionaries?.filter(\n (dictionary) =>\n !keysToKeep.includes(dictionary.key) &&\n getMergedLocalIds(dictionary).some(isFromChangedFile)\n );\n\n const uniqueMergedDictionaries = filteredMergedDictionaries.filter(\n (dictionary, index, self) =>\n index === self.findIndex((t) => t.key === dictionary.key)\n );\n\n // Identify Merged Dictionaries, Types, and Dynamic Dictionaries to remove\n await Promise.all(\n uniqueMergedDictionaries.map(async (dictionary) => {\n const mergedFilePath = normalize(\n join(configuration.system.dictionariesDir, `${dictionary.key}.json`)\n );\n\n try {\n const fileContent = await readFile(mergedFilePath, 'utf8');\n const parsedContent = JSON.parse(fileContent) as Dictionary;\n const localIds = getMergedLocalIds(parsedContent);\n\n if (localIds.length === 1) {\n if (isFromChangedFile(localIds[0]!)) {\n appLogger(\n `Removing outdated unmerged dictionary ${colorizeKey(dictionary.key)}`,\n { isVerbose: true }\n );\n\n // Mark JSON for removal\n filesToRemove.push(mergedFilePath);\n\n // Mark TS Types for removal\n const typesFilePath = normalize(\n join(configuration.system.typesDir, `${dictionary.key}.ts`)\n );\n typeFilesToRemove.push(typesFilePath);\n\n // Mark Dynamic Dictionaries for removal\n // We use glob to catch the loader files (.cjs, .mjs) AND the split locale files (.en.json, etc.)\n const dynamicFilesGlob = join(\n configuration.system.dynamicDictionariesDir,\n `${dictionary.key}.*`\n );\n const dynamicFiles = await fg(normalizePath(dynamicFilesGlob), {\n absolute: true,\n });\n filesToRemove.push(...dynamicFiles);\n\n if (!excludeKeys.includes(dictionary.key)) {\n excludeKeys.push(dictionary.key);\n }\n }\n } else {\n const newContent = {\n ...parsedContent,\n localIds: localIds.filter((localId) => !isFromChangedFile(localId)),\n };\n await writeJsonIfChanged(mergedFilePath, newContent);\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n if (!excludeKeys.includes(dictionary.key)) {\n excludeKeys.push(dictionary.key);\n }\n const typesFilePath = normalize(\n join(configuration.system.typesDir, `${dictionary.key}.ts`)\n );\n typeFilesToRemove.push(typesFilePath);\n }\n }\n })\n );\n\n const hasRebuilt =\n filesToRemove.length > 0 ||\n typeFilesToRemove.length > 0 ||\n excludeKeys.length > 0;\n\n // Execute Cleanup\n if (hasRebuilt) {\n // Update entry points (indexes) first so the app doesn't import dead files\n await createDictionaryEntryPoint(configuration, { excludeKeys });\n\n await removeArtifacts(typeFilesToRemove, baseDir, appLogger);\n\n if (filesToRemove.length > 0) {\n setTimeout(\n () => removeArtifacts(filesToRemove, baseDir, appLogger),\n ARTIFACT_REMOVAL_DELAY_MS\n );\n }\n }\n\n return {\n changedDictionariesLocalIds,\n excludeKeys,\n hasRebuilt,\n };\n};\n"],"mappings":"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"}
package/dist/esm/cli.mjs CHANGED
@@ -1,5 +1,3 @@
1
- import { getGitRootDir, listProjects } from "./listProjects.mjs";
2
- import { installLSP } from "./installLSP.mjs";
3
1
  import { listDictionaries, listDictionariesWithStats } from "./listDictionariesPath.mjs";
4
2
  import { prepareIntlayer } from "./prepareIntlayer.mjs";
5
3
  import { detectExportedComponentName } from "./writeContentDeclaration/detectExportedComponentName.mjs";
@@ -8,6 +6,8 @@ import { detectFormatCommand } from "./detectFormatCommand.mjs";
8
6
  import { getContentDeclarationFileTemplate } from "./getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs";
9
7
  import { writeJSFile } from "./writeContentDeclaration/writeJSFile.mjs";
10
8
  import { writeContentDeclaration } from "./writeContentDeclaration/writeContentDeclaration.mjs";
9
+ import { installLSP } from "./installLSP.mjs";
10
+ import { getGitRootDir, listProjects } from "./listProjects.mjs";
11
11
  import { enableEditorInConfig, setupCmsCredentials, writeCmsCredentialsToEnv } from "./init/cms.mjs";
12
12
  import { COMPAT_I18N_LIBRARIES, detectCompatI18nLibraries, detectPackageManager, installPackages } from "./init/utils/packageManager.mjs";
13
13
  import { NEXT_INTLAYER_BABEL_CONFIG_CONTENT } from "./init/utils/nextCompilerBabel.mjs";
@@ -1,8 +1,8 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { mkdir } from "node:fs/promises";
2
3
  import { basename } from "node:path";
3
- import fg from "fast-glob";
4
- import { existsSync } from "node:fs";
5
4
  import { normalizePath } from "@intlayer/config/utils";
5
+ import fg from "fast-glob";
6
6
 
7
7
  //#region src/createDictionaryEntryPoint/getBuiltDictionariesPath.ts
8
8
  /**
@@ -1,8 +1,8 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { mkdir } from "node:fs/promises";
2
3
  import { basename } from "node:path";
3
- import fg from "fast-glob";
4
- import { existsSync } from "node:fs";
5
4
  import { normalizePath } from "@intlayer/config/utils";
5
+ import fg from "fast-glob";
6
6
 
7
7
  //#region src/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.ts
8
8
  /**
@@ -1,8 +1,8 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { mkdir } from "node:fs/promises";
2
3
  import { basename } from "node:path";
3
- import fg from "fast-glob";
4
- import { existsSync } from "node:fs";
5
4
  import { normalizePath } from "@intlayer/config/utils";
5
+ import fg from "fast-glob";
6
6
 
7
7
  //#region src/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.ts
8
8
  /**
@@ -1,8 +1,8 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { mkdir } from "node:fs/promises";
2
3
  import { basename } from "node:path";
3
- import fg from "fast-glob";
4
- import { existsSync } from "node:fs";
5
4
  import { normalizePath } from "@intlayer/config/utils";
5
+ import fg from "fast-glob";
6
6
 
7
7
  //#region src/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.ts
8
8
  /**
@@ -1,8 +1,8 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { mkdir } from "node:fs/promises";
2
3
  import { basename } from "node:path";
3
- import fg from "fast-glob";
4
- import { existsSync } from "node:fs";
5
4
  import { normalizePath } from "@intlayer/config/utils";
5
+ import fg from "fast-glob";
6
6
 
7
7
  //#region src/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.ts
8
8
  /**
@@ -2,9 +2,9 @@ import { writeFileIfChanged } from "../writeFileIfChanged.mjs";
2
2
  import { getPathHash } from "../utils/getPathHash.mjs";
3
3
  import { mkdir } from "node:fs/promises";
4
4
  import { basename, extname, join, relative } from "node:path";
5
- import fg from "fast-glob";
6
5
  import { kebabCaseToCamelCase, normalizePath } from "@intlayer/config/utils";
7
6
  import { getDomainOrigin, getRewriteRules, isLocaleExclusiveOnDomain } from "@intlayer/core/localization";
7
+ import fg from "fast-glob";
8
8
 
9
9
  //#region src/createType/createModuleAugmentation.ts
10
10
  const getTypeName = (key) => `${kebabCaseToCamelCase(key)}Content`;
@@ -1,12 +1,12 @@
1
- import { planAlignmentActions } from "./planActions.mjs";
2
- import { normalizeBlock } from "./normalizeBlock.mjs";
3
- import { fingerprintBlock } from "./fingerprintBlock.mjs";
4
- import { computeJaccardSimilarity, generateCharacterShingles } from "./computeSimilarity.mjs";
5
1
  import { mapChangedLinesToBlocks } from "./mapChangedLinesToBlocks.mjs";
2
+ import { computeJaccardSimilarity, generateCharacterShingles } from "./computeSimilarity.mjs";
6
3
  import { alignBaseAndTargetBlocks } from "./alignBlocks.mjs";
4
+ import { fingerprintBlock } from "./fingerprintBlock.mjs";
5
+ import { normalizeBlock } from "./normalizeBlock.mjs";
7
6
  import { identifySegmentsToReview, mergeReviewedSegments } from "./rebuildDocument.mjs";
8
7
  import { segmentDocument } from "./segmentDocument.mjs";
9
8
  import { buildAlignmentPlan } from "./pipeline.mjs";
9
+ import { planAlignmentActions } from "./planActions.mjs";
10
10
  import { buildReviewReport, formatReviewReport } from "./reviewReport.mjs";
11
11
 
12
12
  export { alignBaseAndTargetBlocks, buildAlignmentPlan, buildReviewReport, computeJaccardSimilarity, fingerprintBlock, formatReviewReport, generateCharacterShingles, identifySegmentsToReview, mapChangedLinesToBlocks, mergeReviewedSegments, normalizeBlock, planAlignmentActions, segmentDocument };
@@ -1,7 +1,7 @@
1
- import { normalizeBlock } from "./normalizeBlock.mjs";
2
- import { fingerprintBlock } from "./fingerprintBlock.mjs";
3
1
  import { mapChangedLinesToBlocks } from "./mapChangedLinesToBlocks.mjs";
4
2
  import { alignBaseAndTargetBlocks } from "./alignBlocks.mjs";
3
+ import { fingerprintBlock } from "./fingerprintBlock.mjs";
4
+ import { normalizeBlock } from "./normalizeBlock.mjs";
5
5
  import { identifySegmentsToReview, mergeReviewedSegments } from "./rebuildDocument.mjs";
6
6
  import { segmentDocument, segmentSections } from "./segmentDocument.mjs";
7
7
 
@@ -1,6 +1,6 @@
1
1
  import { buildAlignmentPlan } from "./pipeline.mjs";
2
- import { colorize, colorizeNumber } from "@intlayer/config/logger";
3
2
  import * as ANSIColors from "@intlayer/config/colors";
3
+ import { colorize, colorizeNumber } from "@intlayer/config/logger";
4
4
 
5
5
  //#region src/docReview/reviewReport.ts
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { formatLocale, formatPath } from "./utils/formatter.mjs";
2
- import { colorize, colorizeKey, colorizePath, getAppLogger, x } from "@intlayer/config/logger";
3
2
  import * as ANSIColors from "@intlayer/config/colors";
3
+ import { colorize, colorizeKey, colorizePath, getAppLogger, x } from "@intlayer/config/logger";
4
4
  import { getBasePlugins, getContent } from "@intlayer/core/interpreter";
5
5
 
6
6
  //#region src/filterInvalidDictionaries.ts
@@ -1,6 +1,6 @@
1
- import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
2
1
  import { formatPath } from "./utils/formatter.mjs";
3
2
  import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
3
+ import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
4
4
  import { createModuleAugmentation } from "./createType/createModuleAugmentation.mjs";
5
5
  import { createTypes } from "./createType/createType.mjs";
6
6
  import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
@@ -1,15 +1,15 @@
1
- import { getBuiltDictionariesPath } from "./createDictionaryEntryPoint/getBuiltDictionariesPath.mjs";
2
- import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
3
- import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
4
1
  import { formatPath } from "./utils/formatter.mjs";
5
2
  import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
3
+ import { getBuiltDictionariesPath } from "./createDictionaryEntryPoint/getBuiltDictionariesPath.mjs";
4
+ import { createDictionaryEntryPoint } from "./createDictionaryEntryPoint/createDictionaryEntryPoint.mjs";
6
5
  import { createModuleAugmentation } from "./createType/createModuleAugmentation.mjs";
7
6
  import { createTypes } from "./createType/createType.mjs";
8
7
  import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
8
+ import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
9
+ import { existsSync } from "node:fs";
9
10
  import { readFile, writeFile } from "node:fs/promises";
10
11
  import { join } from "node:path";
11
12
  import { getAppLogger } from "@intlayer/config/logger";
12
- import { existsSync } from "node:fs";
13
13
 
14
14
  //#region src/handleContentDeclarationFileChange.ts
15
15
  const handleContentDeclarationFileChange = async (filePath, config) => {
@@ -1,6 +1,6 @@
1
- import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
2
1
  import { formatPath } from "./utils/formatter.mjs";
3
2
  import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
3
+ import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
4
4
  import { handleContentDeclarationFileChange } from "./handleContentDeclarationFileChange.mjs";
5
5
  import { getAppLogger } from "@intlayer/config/logger";
6
6
 
@@ -1,9 +1,9 @@
1
- import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
2
1
  import { formatPath } from "./utils/formatter.mjs";
3
2
  import { buildDictionary } from "./buildIntlayerDictionary/buildIntlayerDictionary.mjs";
4
3
  import { createModuleAugmentation } from "./createType/createModuleAugmentation.mjs";
5
4
  import { createTypes } from "./createType/createType.mjs";
6
5
  import { loadLocalDictionaries } from "./loadDictionaries/loadLocalDictionaries.mjs";
6
+ import { cleanRemovedContentDeclaration } from "./cleanRemovedContentDeclaration.mjs";
7
7
  import { listDictionaries } from "./listDictionariesPath.mjs";
8
8
  import { normalize } from "node:path";
9
9
  import { getAppLogger } from "@intlayer/config/logger";
@@ -1,8 +1,8 @@
1
1
  import { enableIntlayerEditorConfig, setIntlayerConfigCompilerOutput, setIntlayerConfigRoutingMode } from "./utils/configManipulation.mjs";
2
2
  import { exists, readFileFromRoot, writeFileToRoot } from "./utils/fileSystem.mjs";
3
+ import * as ANSIColors from "@intlayer/config/colors";
3
4
  import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
4
5
  import fg from "fast-glob";
5
- import * as ANSIColors from "@intlayer/config/colors";
6
6
 
7
7
  //#region src/init/cms.ts
8
8
  /**
@@ -5,8 +5,8 @@ import { restructureAppIntoLocale } from "./restructure.mjs";
5
5
  import { LOCALE_LAYOUT_TEMPLATE_JS, LOCALE_LAYOUT_TEMPLATE_TS, LOCALE_PAGE_TEMPLATE_JS, LOCALE_PAGE_TEMPLATE_TS, MIDDLEWARE_TEMPLATE, PROXY_TEMPLATE, ROOT_LAYOUT_TEMPLATE_JS, ROOT_LAYOUT_TEMPLATE_TS } from "./templates.mjs";
6
6
  import { wrapLayoutWithProvider } from "./transforms.mjs";
7
7
  import { join } from "node:path";
8
- import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
9
8
  import * as ANSIColors from "@intlayer/config/colors";
9
+ import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
10
10
 
11
11
  //#region src/init/frameworkSetup/nextAppRouter/index.ts
12
12
  /**
@@ -5,8 +5,8 @@ import { getLocaleSegment, restructureRoutesIntoLocale } from "./restructure.mjs
5
5
  import { buildLocaleRouteTemplate, buildRootTemplateJs, buildRootTemplateTs } from "./templates.mjs";
6
6
  import { wrapRootWithProvider } from "./transforms.mjs";
7
7
  import { join } from "node:path";
8
- import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
9
8
  import * as ANSIColors from "@intlayer/config/colors";
9
+ import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
10
10
 
11
11
  //#region src/init/frameworkSetup/tanstackStart/index.ts
12
12
  /** Logs the outcome of the root-document provider-wrap transform. */
@@ -10,10 +10,10 @@ import { parseJSONWithComments } from "./utils/jsonParser.mjs";
10
10
  import { setupNextCompilerBabelConfig } from "./utils/nextCompilerBabel.mjs";
11
11
  import { findTsConfigFiles } from "./utils/tsConfig.mjs";
12
12
  import { join } from "node:path";
13
+ import * as ANSIColors from "@intlayer/config/colors";
13
14
  import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
14
15
  import { getConfiguration } from "@intlayer/config/node";
15
16
  import { getAlias } from "@intlayer/config/utils";
16
- import * as ANSIColors from "@intlayer/config/colors";
17
17
 
18
18
  //#region src/init/index.ts
19
19
  /**
@@ -1,7 +1,7 @@
1
1
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { dirname, join, relative, resolve, sep } from "node:path";
3
- import fg from "fast-glob";
4
3
  import { EXCLUDED_PATHS } from "@intlayer/config/defaultValues";
4
+ import fg from "fast-glob";
5
5
  import { ALL_LOCALES } from "@intlayer/types/allLocales";
6
6
 
7
7
  //#region src/init/utils/fileSystem.ts
@@ -1,7 +1,7 @@
1
1
  import { getGitRootDir, listProjects } from "../../listProjects.mjs";
2
2
  import { detectPackageManager } from "./packageManager.mjs";
3
- import { join, relative, resolve, sep } from "node:path";
4
3
  import { existsSync, readFileSync } from "node:fs";
4
+ import { join, relative, resolve, sep } from "node:path";
5
5
 
6
6
  //#region src/init/utils/githubActions.ts
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  import { exists, readFileFromRoot } from "./fileSystem.mjs";
2
2
  import { installPackages } from "./packageManager.mjs";
3
- import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
4
3
  import * as ANSIColors from "@intlayer/config/colors";
4
+ import { colorize, colorizePath, logger, v, x } from "@intlayer/config/logger";
5
5
 
6
6
  //#region src/init/utils/nextCompilerBabel.ts
7
7
  /**
@@ -1,5 +1,5 @@
1
- import { join } from "node:path";
2
1
  import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
3
  import { compareVersions } from "@intlayer/config/utils";
4
4
  import { execSync } from "node:child_process";
5
5
 
@@ -1,5 +1,5 @@
1
- import path from "node:path";
2
1
  import { promises } from "node:fs";
2
+ import path from "node:path";
3
3
 
4
4
  //#region src/installLSP.ts
5
5
  const VSCODE_DIR = ".vscode";
@@ -1,6 +1,6 @@
1
1
  import { PLATFORMS_METADATA } from "../installSkills/index.mjs";
2
- import path from "node:path";
3
2
  import { promises } from "node:fs";
3
+ import path from "node:path";
4
4
  import os from "node:os";
5
5
 
6
6
  //#region src/installMCP/installMCP.ts
@@ -1,7 +1,7 @@
1
1
  import { readAsset } from "../_virtual/_utils_asset.mjs";
2
+ import { promises } from "node:fs";
2
3
  import path from "node:path";
3
4
  import { v } from "@intlayer/config/logger";
4
- import { promises } from "node:fs";
5
5
  import { getMarkdownMetadata } from "@intlayer/core/markdown";
6
6
 
7
7
  //#region src/installSkills/index.ts
@@ -1,6 +1,6 @@
1
1
  import { stat } from "node:fs/promises";
2
- import fg from "fast-glob";
3
2
  import { normalizePath } from "@intlayer/config/utils";
3
+ import fg from "fast-glob";
4
4
 
5
5
  //#region src/listDictionariesPath.ts
6
6
  /**
@@ -1,8 +1,8 @@
1
+ import { readFileSync } from "node:fs";
1
2
  import { join } from "node:path";
2
3
  import { getAppLogger } from "@intlayer/config/logger";
3
- import { readFileSync } from "node:fs";
4
- import simpleGit from "simple-git";
5
4
  import { log } from "@intlayer/config/built";
5
+ import simpleGit from "simple-git";
6
6
 
7
7
  //#region src/listGitFiles.ts
8
8
  const getGitRootDir = async () => {
@@ -1,6 +1,6 @@
1
1
  import { dirname } from "node:path";
2
- import fg from "fast-glob";
3
2
  import { configurationFilesCandidates } from "@intlayer/config/node";
3
+ import fg from "fast-glob";
4
4
  import simpleGit from "simple-git";
5
5
 
6
6
  //#region src/listProjects.ts
@@ -1,7 +1,7 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
- import { getProjectRequire } from "@intlayer/config/utils";
4
3
  import { bundleFile } from "@intlayer/config/file";
4
+ import { getProjectRequire } from "@intlayer/config/utils";
5
5
  import { builtinModules, createRequire } from "node:module";
6
6
 
7
7
  //#region src/loadDictionaries/getIntlayerBundle.ts
@@ -7,8 +7,8 @@ import { loadYamlContentDeclaration } from "./loadYamlContentDeclaration.mjs";
7
7
  import { logTypeScriptErrors } from "./logTypeScriptErrors.mjs";
8
8
  import { readFile, writeFile } from "node:fs/promises";
9
9
  import { dirname, extname, join, relative } from "node:path";
10
- import { cacheDisk, getPackageJsonPath, getProjectRequire } from "@intlayer/config/utils";
11
10
  import { loadExternalFile } from "@intlayer/config/file";
11
+ import { cacheDisk, getPackageJsonPath, getProjectRequire } from "@intlayer/config/utils";
12
12
 
13
13
  //#region src/loadDictionaries/loadContentDeclaration.ts
14
14
  const formatLocalDictionaries = (dictionariesRecord, configuration) => Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({
@@ -3,8 +3,8 @@ import { loadContentDeclarations } from "./loadContentDeclaration.mjs";
3
3
  import { formatDictionaries } from "../formatDictionary.mjs";
4
4
  import { loadRemoteDictionaries } from "./loadRemoteDictionaries.mjs";
5
5
  import { DictionariesLogger } from "./log.mjs";
6
- import { colon, colorize, colorizeKey, getAppLogger } from "@intlayer/config/logger";
7
6
  import * as ANSIColors from "@intlayer/config/colors";
7
+ import { colon, colorize, colorizeKey, getAppLogger } from "@intlayer/config/logger";
8
8
 
9
9
  //#region src/loadDictionaries/loadDictionaries.ts
10
10
  let loadDictionariesStatus = [];
@@ -3,7 +3,7 @@ import { fetchDistantDictionaries } from "../fetchDistantDictionaries.mjs";
3
3
  import { getConfiguration } from "@intlayer/config/node";
4
4
  import { createIntlayerCMS } from "@intlayer/api";
5
5
  import { dictionaryEndpoint } from "@intlayer/api/dictionary";
6
- import { getRemoteDictionaries } from "@intlayer/remote-dictionaries-entry";
6
+ import { getRemoteDictionaries } from "@intlayer/dictionaries-entry/remote";
7
7
 
8
8
  //#region src/loadDictionaries/loadRemoteDictionaries.ts
9
9
  const formatDistantDictionaries = (dictionaries) => dictionaries.map((dict) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"loadRemoteDictionaries.mjs","names":[],"sources":["../../../src/loadDictionaries/loadRemoteDictionaries.ts"],"sourcesContent":["import { createIntlayerCMS } from '@intlayer/api';\nimport { dictionaryEndpoint } from '@intlayer/api/dictionary';\n// @ts-ignore @intlayer/backend is not build yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getRemoteDictionaries } from '@intlayer/remote-dictionaries-entry';\nimport type {\n Dictionary,\n DictionaryId,\n DictionaryKey,\n} from '@intlayer/types/dictionary';\nimport { fetchDistantDictionaries } from '../fetchDistantDictionaries';\nimport { sortAlphabetically } from '../utils/sortAlphabetically';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport const formatDistantDictionaries = (\n dictionaries: (DictionaryAPI | Dictionary)[]\n): Dictionary[] =>\n dictionaries.map((dict) => ({\n ...dict,\n localId: `${dict.key}::remote::${dict.id}`,\n location: 'remote' as const,\n }));\n\nexport const loadRemoteDictionaries = async (\n configuration = getConfiguration(),\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: {\n onStartRemoteCheck?: () => void;\n onStopRemoteCheck?: () => void;\n onError?: (error: Error) => void;\n }\n): Promise<Dictionary[]> => {\n const { editor } = configuration;\n const remoteDictionariesRecord = getRemoteDictionaries(configuration);\n\n const hasRemoteDictionaries = Boolean(editor.clientId && editor.clientSecret);\n\n if (!hasRemoteDictionaries) return [];\n\n try {\n options?.onStartRemoteCheck?.();\n\n const dictionary = dictionaryEndpoint(createIntlayerCMS(configuration));\n\n // Get the list of dictionary keys\n const getDictionariesKeysResult =\n await dictionary.getDictionariesUpdateTimestamp();\n\n const distantDictionaryUpdateTimeStamp: Record<\n DictionaryId,\n { key: DictionaryKey; updatedAt: number }\n > | null = getDictionariesKeysResult.data;\n\n if (!distantDictionaryUpdateTimeStamp) {\n throw new Error('No distant dictionaries found');\n }\n\n const dictionariesIdToFetch = Object.entries(\n distantDictionaryUpdateTimeStamp\n ).filter(([dictionaryId, data]) => {\n // If remote doesn't provide updatedAt, fetch to be safe\n if (!data.updatedAt) return true;\n\n // If no local cache exists, fetch\n const local: Dictionary | undefined = remoteDictionariesRecord[\n data.key\n ]?.find((dictionary) => dictionary.id === dictionaryId);\n if (!local) return true;\n\n const localUpdatedAtRaw = (local as any)?.updatedAt as\n | number\n | string\n | undefined;\n\n const localUpdatedAt =\n typeof localUpdatedAtRaw === 'number'\n ? localUpdatedAtRaw\n : localUpdatedAtRaw\n ? new Date(localUpdatedAtRaw).getTime()\n : undefined;\n\n // If local timestamp missing or older than remote, fetch\n if (typeof localUpdatedAt !== 'number') return true;\n\n return data.updatedAt > localUpdatedAt;\n });\n\n const flatRemoteDictionariesRecord: DictionaryAPI[] = Object.values(\n remoteDictionariesRecord\n ).flat();\n\n const cachedDictionaries: Dictionary[] =\n flatRemoteDictionariesRecord.filter((dictionary) => {\n const remoteUpdatedAt =\n distantDictionaryUpdateTimeStamp[dictionary.id!].updatedAt;\n\n const localUpdatedAtRaw = dictionary.updatedAt;\n\n const localUpdatedAt =\n typeof localUpdatedAtRaw === 'number'\n ? localUpdatedAtRaw\n : localUpdatedAtRaw\n ? new Date(localUpdatedAtRaw).getTime()\n : undefined;\n\n // Consider as cached/imported when local exists and is up-to-date or newer\n return (\n typeof localUpdatedAt === 'number' &&\n typeof remoteUpdatedAt === 'number' &&\n localUpdatedAt >= remoteUpdatedAt\n );\n });\n\n // Report cached as already imported\n if (cachedDictionaries.length > 0) {\n onStatusUpdate?.(\n cachedDictionaries.map((dictionary) => ({\n dictionaryKey: dictionary.key,\n type: 'remote',\n status: 'imported',\n }))\n );\n }\n\n // Several qualified dictionaries can share a key, so keys are deduplicated:\n // one request per key already returns all of its siblings.\n const orderedDistantDictionaryKeys = [\n ...new Set(dictionariesIdToFetch.map(([, data]) => data.key)),\n ].sort(sortAlphabetically);\n\n // Report pending for keys to be fetched so totals are visible immediately\n if (orderedDistantDictionaryKeys.length > 0) {\n onStatusUpdate?.(\n orderedDistantDictionaryKeys.map((key) => ({\n dictionaryKey: key,\n type: 'remote',\n status: 'pending',\n }))\n );\n }\n\n const distantDictionariesData = await fetchDistantDictionaries(\n {\n dictionaryKeys: orderedDistantDictionaryKeys,\n },\n onStatusUpdate\n );\n\n const distantDictionaries: Dictionary[] = formatDistantDictionaries(\n distantDictionariesData\n );\n\n // Fetching by key also returns the up-to-date siblings of a stale\n // dictionary, so drop the cached copies the remote just sent back.\n const fetchedDictionaryIds = new Set(\n distantDictionaries.map((dictionary) => dictionary.id)\n );\n\n const notRefetchedCachedDictionaries = cachedDictionaries.filter(\n (dictionary) => !fetchedDictionaryIds.has(dictionary.id)\n );\n\n return [...notRefetchedCachedDictionaries, ...distantDictionaries];\n } catch (error) {\n options?.onError?.(error as Error);\n return [];\n } finally {\n options?.onStopRemoteCheck?.();\n }\n};\n"],"mappings":";;;;;;;;AAeA,MAAa,6BACX,iBAEA,aAAa,KAAK,UAAU;CAC1B,GAAG;CACH,SAAS,GAAG,KAAK,IAAI,YAAY,KAAK;CACtC,UAAU;AACZ,EAAE;AAEJ,MAAa,yBAAyB,OACpC,gBAAgB,iBAAiB,GACjC,gBACA,YAK0B;CAC1B,MAAM,EAAE,WAAW;CACnB,MAAM,2BAA2B,sBAAsB,aAAa;CAIpE,IAAI,CAF0B,QAAQ,OAAO,YAAY,OAAO,YAEvC,GAAG,OAAO,CAAC;CAEpC,IAAI;EACF,SAAS,qBAAqB;EAQ9B,MAAM,oCAGK,MATQ,mBAAmB,kBAAkB,aAAa,CAIpD,CAAC,CAAC,+BAA+B,EAKd,CAAC;EAErC,IAAI,CAAC,kCACH,MAAM,IAAI,MAAM,+BAA+B;EAGjD,MAAM,wBAAwB,OAAO,QACnC,gCACF,CAAC,CAAC,QAAQ,CAAC,cAAc,UAAU;GAEjC,IAAI,CAAC,KAAK,WAAW,OAAO;GAG5B,MAAM,QAAgC,yBACpC,KAAK,IACN,EAAE,MAAM,eAAe,WAAW,OAAO,YAAY;GACtD,IAAI,CAAC,OAAO,OAAO;GAEnB,MAAM,oBAAqB,OAAe;GAK1C,MAAM,iBACJ,OAAO,sBAAsB,WACzB,oBACA,oBACE,IAAI,KAAK,iBAAiB,CAAC,CAAC,QAAQ,IACpC;GAGR,IAAI,OAAO,mBAAmB,UAAU,OAAO;GAE/C,OAAO,KAAK,YAAY;EAC1B,CAAC;EAMD,MAAM,qBAJgD,OAAO,OAC3D,wBACF,CAAC,CAAC,KAG2B,CAAC,CAAC,QAAQ,eAAe;GAClD,MAAM,kBACJ,iCAAiC,WAAW,GAAI,CAAC;GAEnD,MAAM,oBAAoB,WAAW;GAErC,MAAM,iBACJ,OAAO,sBAAsB,WACzB,oBACA,oBACE,IAAI,KAAK,iBAAiB,CAAC,CAAC,QAAQ,IACpC;GAGR,OACE,OAAO,mBAAmB,YAC1B,OAAO,oBAAoB,YAC3B,kBAAkB;EAEtB,CAAC;EAGH,IAAI,mBAAmB,SAAS,GAC9B,iBACE,mBAAmB,KAAK,gBAAgB;GACtC,eAAe,WAAW;GAC1B,MAAM;GACN,QAAQ;EACV,EAAE,CACJ;EAKF,MAAM,+BAA+B,CACnC,GAAG,IAAI,IAAI,sBAAsB,KAAK,GAAG,UAAU,KAAK,GAAG,CAAC,CAC9D,CAAC,CAAC,KAAK,kBAAkB;EAGzB,IAAI,6BAA6B,SAAS,GACxC,iBACE,6BAA6B,KAAK,SAAS;GACzC,eAAe;GACf,MAAM;GACN,QAAQ;EACV,EAAE,CACJ;EAGF,MAAM,0BAA0B,MAAM,yBACpC,EACE,gBAAgB,6BAClB,GACA,cACF;EAEA,MAAM,sBAAoC,0BACxC,uBACF;EAIA,MAAM,uBAAuB,IAAI,IAC/B,oBAAoB,KAAK,eAAe,WAAW,EAAE,CACvD;EAMA,OAAO,CAAC,GAJ+B,mBAAmB,QACvD,eAAe,CAAC,qBAAqB,IAAI,WAAW,EAAE,CAGjB,GAAG,GAAG,mBAAmB;CACnE,SAAS,OAAO;EACd,SAAS,UAAU,KAAc;EACjC,OAAO,CAAC;CACV,UAAU;EACR,SAAS,oBAAoB;CAC/B;AACF"}
1
+ {"version":3,"file":"loadRemoteDictionaries.mjs","names":[],"sources":["../../../src/loadDictionaries/loadRemoteDictionaries.ts"],"sourcesContent":["import { createIntlayerCMS } from '@intlayer/api';\nimport { dictionaryEndpoint } from '@intlayer/api/dictionary';\n// @ts-ignore @intlayer/backend is not build yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getRemoteDictionaries } from '@intlayer/dictionaries-entry/remote';\nimport type {\n Dictionary,\n DictionaryId,\n DictionaryKey,\n} from '@intlayer/types/dictionary';\nimport { fetchDistantDictionaries } from '../fetchDistantDictionaries';\nimport { sortAlphabetically } from '../utils/sortAlphabetically';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport const formatDistantDictionaries = (\n dictionaries: (DictionaryAPI | Dictionary)[]\n): Dictionary[] =>\n dictionaries.map((dict) => ({\n ...dict,\n localId: `${dict.key}::remote::${dict.id}`,\n location: 'remote' as const,\n }));\n\nexport const loadRemoteDictionaries = async (\n configuration = getConfiguration(),\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: {\n onStartRemoteCheck?: () => void;\n onStopRemoteCheck?: () => void;\n onError?: (error: Error) => void;\n }\n): Promise<Dictionary[]> => {\n const { editor } = configuration;\n const remoteDictionariesRecord = getRemoteDictionaries(configuration);\n\n const hasRemoteDictionaries = Boolean(editor.clientId && editor.clientSecret);\n\n if (!hasRemoteDictionaries) return [];\n\n try {\n options?.onStartRemoteCheck?.();\n\n const dictionary = dictionaryEndpoint(createIntlayerCMS(configuration));\n\n // Get the list of dictionary keys\n const getDictionariesKeysResult =\n await dictionary.getDictionariesUpdateTimestamp();\n\n const distantDictionaryUpdateTimeStamp: Record<\n DictionaryId,\n { key: DictionaryKey; updatedAt: number }\n > | null = getDictionariesKeysResult.data;\n\n if (!distantDictionaryUpdateTimeStamp) {\n throw new Error('No distant dictionaries found');\n }\n\n const dictionariesIdToFetch = Object.entries(\n distantDictionaryUpdateTimeStamp\n ).filter(([dictionaryId, data]) => {\n // If remote doesn't provide updatedAt, fetch to be safe\n if (!data.updatedAt) return true;\n\n // If no local cache exists, fetch\n const local: Dictionary | undefined = remoteDictionariesRecord[\n data.key\n ]?.find((dictionary) => dictionary.id === dictionaryId);\n if (!local) return true;\n\n const localUpdatedAtRaw = (local as any)?.updatedAt as\n | number\n | string\n | undefined;\n\n const localUpdatedAt =\n typeof localUpdatedAtRaw === 'number'\n ? localUpdatedAtRaw\n : localUpdatedAtRaw\n ? new Date(localUpdatedAtRaw).getTime()\n : undefined;\n\n // If local timestamp missing or older than remote, fetch\n if (typeof localUpdatedAt !== 'number') return true;\n\n return data.updatedAt > localUpdatedAt;\n });\n\n const flatRemoteDictionariesRecord: DictionaryAPI[] = Object.values(\n remoteDictionariesRecord\n ).flat();\n\n const cachedDictionaries: Dictionary[] =\n flatRemoteDictionariesRecord.filter((dictionary) => {\n const remoteUpdatedAt =\n distantDictionaryUpdateTimeStamp[dictionary.id!].updatedAt;\n\n const localUpdatedAtRaw = dictionary.updatedAt;\n\n const localUpdatedAt =\n typeof localUpdatedAtRaw === 'number'\n ? localUpdatedAtRaw\n : localUpdatedAtRaw\n ? new Date(localUpdatedAtRaw).getTime()\n : undefined;\n\n // Consider as cached/imported when local exists and is up-to-date or newer\n return (\n typeof localUpdatedAt === 'number' &&\n typeof remoteUpdatedAt === 'number' &&\n localUpdatedAt >= remoteUpdatedAt\n );\n });\n\n // Report cached as already imported\n if (cachedDictionaries.length > 0) {\n onStatusUpdate?.(\n cachedDictionaries.map((dictionary) => ({\n dictionaryKey: dictionary.key,\n type: 'remote',\n status: 'imported',\n }))\n );\n }\n\n // Several qualified dictionaries can share a key, so keys are deduplicated:\n // one request per key already returns all of its siblings.\n const orderedDistantDictionaryKeys = [\n ...new Set(dictionariesIdToFetch.map(([, data]) => data.key)),\n ].sort(sortAlphabetically);\n\n // Report pending for keys to be fetched so totals are visible immediately\n if (orderedDistantDictionaryKeys.length > 0) {\n onStatusUpdate?.(\n orderedDistantDictionaryKeys.map((key) => ({\n dictionaryKey: key,\n type: 'remote',\n status: 'pending',\n }))\n );\n }\n\n const distantDictionariesData = await fetchDistantDictionaries(\n {\n dictionaryKeys: orderedDistantDictionaryKeys,\n },\n onStatusUpdate\n );\n\n const distantDictionaries: Dictionary[] = formatDistantDictionaries(\n distantDictionariesData\n );\n\n // Fetching by key also returns the up-to-date siblings of a stale\n // dictionary, so drop the cached copies the remote just sent back.\n const fetchedDictionaryIds = new Set(\n distantDictionaries.map((dictionary) => dictionary.id)\n );\n\n const notRefetchedCachedDictionaries = cachedDictionaries.filter(\n (dictionary) => !fetchedDictionaryIds.has(dictionary.id)\n );\n\n return [...notRefetchedCachedDictionaries, ...distantDictionaries];\n } catch (error) {\n options?.onError?.(error as Error);\n return [];\n } finally {\n options?.onStopRemoteCheck?.();\n }\n};\n"],"mappings":";;;;;;;;AAeA,MAAa,6BACX,iBAEA,aAAa,KAAK,UAAU;CAC1B,GAAG;CACH,SAAS,GAAG,KAAK,IAAI,YAAY,KAAK;CACtC,UAAU;AACZ,EAAE;AAEJ,MAAa,yBAAyB,OACpC,gBAAgB,iBAAiB,GACjC,gBACA,YAK0B;CAC1B,MAAM,EAAE,WAAW;CACnB,MAAM,2BAA2B,sBAAsB,aAAa;CAIpE,IAAI,CAF0B,QAAQ,OAAO,YAAY,OAAO,YAEvC,GAAG,OAAO,CAAC;CAEpC,IAAI;EACF,SAAS,qBAAqB;EAQ9B,MAAM,oCAGK,MATQ,mBAAmB,kBAAkB,aAAa,CAIpD,CAAC,CAAC,+BAA+B,EAKd,CAAC;EAErC,IAAI,CAAC,kCACH,MAAM,IAAI,MAAM,+BAA+B;EAGjD,MAAM,wBAAwB,OAAO,QACnC,gCACF,CAAC,CAAC,QAAQ,CAAC,cAAc,UAAU;GAEjC,IAAI,CAAC,KAAK,WAAW,OAAO;GAG5B,MAAM,QAAgC,yBACpC,KAAK,IACN,EAAE,MAAM,eAAe,WAAW,OAAO,YAAY;GACtD,IAAI,CAAC,OAAO,OAAO;GAEnB,MAAM,oBAAqB,OAAe;GAK1C,MAAM,iBACJ,OAAO,sBAAsB,WACzB,oBACA,oBACE,IAAI,KAAK,iBAAiB,CAAC,CAAC,QAAQ,IACpC;GAGR,IAAI,OAAO,mBAAmB,UAAU,OAAO;GAE/C,OAAO,KAAK,YAAY;EAC1B,CAAC;EAMD,MAAM,qBAJgD,OAAO,OAC3D,wBACF,CAAC,CAAC,KAG2B,CAAC,CAAC,QAAQ,eAAe;GAClD,MAAM,kBACJ,iCAAiC,WAAW,GAAI,CAAC;GAEnD,MAAM,oBAAoB,WAAW;GAErC,MAAM,iBACJ,OAAO,sBAAsB,WACzB,oBACA,oBACE,IAAI,KAAK,iBAAiB,CAAC,CAAC,QAAQ,IACpC;GAGR,OACE,OAAO,mBAAmB,YAC1B,OAAO,oBAAoB,YAC3B,kBAAkB;EAEtB,CAAC;EAGH,IAAI,mBAAmB,SAAS,GAC9B,iBACE,mBAAmB,KAAK,gBAAgB;GACtC,eAAe,WAAW;GAC1B,MAAM;GACN,QAAQ;EACV,EAAE,CACJ;EAKF,MAAM,+BAA+B,CACnC,GAAG,IAAI,IAAI,sBAAsB,KAAK,GAAG,UAAU,KAAK,GAAG,CAAC,CAC9D,CAAC,CAAC,KAAK,kBAAkB;EAGzB,IAAI,6BAA6B,SAAS,GACxC,iBACE,6BAA6B,KAAK,SAAS;GACzC,eAAe;GACf,MAAM;GACN,QAAQ;EACV,EAAE,CACJ;EAGF,MAAM,0BAA0B,MAAM,yBACpC,EACE,gBAAgB,6BAClB,GACA,cACF;EAEA,MAAM,sBAAoC,0BACxC,uBACF;EAIA,MAAM,uBAAuB,IAAI,IAC/B,oBAAoB,KAAK,eAAe,WAAW,EAAE,CACvD;EAMA,OAAO,CAAC,GAJ+B,mBAAmB,QACvD,eAAe,CAAC,qBAAqB,IAAI,WAAW,EAAE,CAGjB,GAAG,GAAG,mBAAmB;CACnE,SAAS,OAAO;EACd,SAAS,UAAU,KAAc;EACjC,OAAO,CAAC;CACV,UAAU;EACR,SAAS,oBAAoB;CAC/B;AACF"}
@@ -1,6 +1,6 @@
1
+ import * as ANSIColors from "@intlayer/config/colors";
1
2
  import { colorize, getPrefix, spinnerFrames, v, x } from "@intlayer/config/logger";
2
3
  import { extractErrorMessage } from "@intlayer/config/utils";
3
- import * as ANSIColors from "@intlayer/config/colors";
4
4
  import { log } from "@intlayer/config/built";
5
5
 
6
6
  //#region src/loadDictionaries/log.ts