@intlayer/chokidar 8.9.8 → 8.10.0-canary.1

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 (47) hide show
  1. package/README.md +14 -0
  2. package/dist/cjs/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.cjs +21 -0
  3. package/dist/cjs/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.cjs.map +1 -1
  4. package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs +4 -0
  5. package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs.map +1 -1
  6. package/dist/cjs/loadDictionaries/loadMarkdownContentDeclaration.cjs +45 -0
  7. package/dist/cjs/loadDictionaries/loadMarkdownContentDeclaration.cjs.map +1 -0
  8. package/dist/cjs/loadDictionaries/loadYamlContentDeclaration.cjs +27 -0
  9. package/dist/cjs/loadDictionaries/loadYamlContentDeclaration.cjs.map +1 -0
  10. package/dist/cjs/utils/getFormatFromExtension.cjs +6 -0
  11. package/dist/cjs/utils/getFormatFromExtension.cjs.map +1 -1
  12. package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs +10 -0
  13. package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs.map +1 -1
  14. package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs +64 -0
  15. package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs.map +1 -0
  16. package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs +44 -0
  17. package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs.map +1 -0
  18. package/dist/esm/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs +21 -0
  19. package/dist/esm/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs.map +1 -1
  20. package/dist/esm/loadDictionaries/loadContentDeclaration.mjs +5 -1
  21. package/dist/esm/loadDictionaries/loadContentDeclaration.mjs.map +1 -1
  22. package/dist/esm/loadDictionaries/loadMarkdownContentDeclaration.mjs +43 -0
  23. package/dist/esm/loadDictionaries/loadMarkdownContentDeclaration.mjs.map +1 -0
  24. package/dist/esm/loadDictionaries/loadYamlContentDeclaration.mjs +25 -0
  25. package/dist/esm/loadDictionaries/loadYamlContentDeclaration.mjs.map +1 -0
  26. package/dist/esm/utils/getFormatFromExtension.mjs +6 -0
  27. package/dist/esm/utils/getFormatFromExtension.mjs.map +1 -1
  28. package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs +10 -0
  29. package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs.map +1 -1
  30. package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs +62 -0
  31. package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs.map +1 -0
  32. package/dist/esm/writeContentDeclaration/writeYamlFile.mjs +42 -0
  33. package/dist/esm/writeContentDeclaration/writeYamlFile.mjs.map +1 -0
  34. package/dist/types/intlayer/dist/types/index.d.ts +3 -0
  35. package/dist/types/loadDictionaries/loadContentDeclaration.d.ts.map +1 -1
  36. package/dist/types/loadDictionaries/loadMarkdownContentDeclaration.d.ts +7 -0
  37. package/dist/types/loadDictionaries/loadMarkdownContentDeclaration.d.ts.map +1 -0
  38. package/dist/types/loadDictionaries/loadYamlContentDeclaration.d.ts +7 -0
  39. package/dist/types/loadDictionaries/loadYamlContentDeclaration.d.ts.map +1 -0
  40. package/dist/types/utils/getFormatFromExtension.d.ts +2 -2
  41. package/dist/types/utils/getFormatFromExtension.d.ts.map +1 -1
  42. package/dist/types/writeContentDeclaration/writeContentDeclaration.d.ts.map +1 -1
  43. package/dist/types/writeContentDeclaration/writeMarkdownFile.d.ts +8 -0
  44. package/dist/types/writeContentDeclaration/writeMarkdownFile.d.ts.map +1 -0
  45. package/dist/types/writeContentDeclaration/writeYamlFile.d.ts +8 -0
  46. package/dist/types/writeContentDeclaration/writeYamlFile.d.ts.map +1 -0
  47. package/package.json +9 -9
package/README.md CHANGED
@@ -67,6 +67,7 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
67
67
  | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
68
68
  | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
69
69
  | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
70
+ | <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
70
71
 
71
72
  ---
72
73
 
@@ -249,6 +250,19 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
249
250
  </ul>
250
251
  </details>
251
252
 
253
+ ## Multilingual content management system
254
+
255
+ More than an i18n library, Intlayer is a complete **multilingual content management system**. A full CMS is available for free at [app.intlayer.org](https://app.intlayer.org).
256
+
257
+ Intlayer connects **developers**, **copywriters**, and **AI agents** in one workflow for creating and maintaining multilingual websites effortlessly.Intlayer replaces the following stack in a single solution:
258
+
259
+ - i18n solutions (e.g. `i18next`, `next-intl`, `vue-i18n`)
260
+ - TMSs (Translation Management Systems) (e.g. Crowdin, Phrase, Lokalise)
261
+ - Feature flags
262
+ - Headless CMSs (e.g. Contentful, Strapi, Sanity)
263
+
264
+ ![CMS Preview](https://github.com/aymericzip/intlayer/blob/main/docs/assets/CMS.png?raw=true)
265
+
252
266
  ## 🌐 Readme in other languages
253
267
 
254
268
  <p align="center">
@@ -29,6 +29,27 @@ const getContentDeclarationFileTemplate = async (key, format, fileParams = {}, n
29
29
  const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? "['content']" : ""}} **/`;
30
30
  const satisfiesType = noMetadata ? "Dictionary['content']" : "Dictionary";
31
31
  switch (format) {
32
+ case "yaml": return `${[
33
+ `key: ${key}`,
34
+ ...fileParams.locale ? [`locale: ${fileParams.locale}`] : [],
35
+ ...fileParams.title ? [`title: ${JSON.stringify(fileParams.title)}`] : [],
36
+ ...fileParams.description ? [`description: ${JSON.stringify(fileParams.description)}`] : [],
37
+ ...fileParams.tags?.length ? ["tags:", ...fileParams.tags.map((tag) => ` - ${JSON.stringify(tag)}`)] : [],
38
+ "content: {}"
39
+ ].join("\n")}\n`;
40
+ case "md": return [
41
+ "---",
42
+ ...[
43
+ `key: ${key}`,
44
+ ...fileParams.locale ? [`locale: ${fileParams.locale}`] : [],
45
+ ...fileParams.title ? [`title: ${JSON.stringify(fileParams.title)}`] : [],
46
+ ...fileParams.description ? [`description: ${JSON.stringify(fileParams.description)}`] : [],
47
+ ...fileParams.tags?.length ? ["tags:", ...fileParams.tags.map((t) => ` - ${JSON.stringify(t)}`)] : []
48
+ ],
49
+ "---",
50
+ "",
51
+ ""
52
+ ].join("\n");
32
53
  case "ts": return [
33
54
  "import { type Dictionary } from 'intlayer';",
34
55
  "",
@@ -1 +1 @@
1
- {"version":3,"file":"getContentDeclarationFileTemplate.cjs","names":[],"sources":["../../../src/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.ts"],"sourcesContent":["import { kebabCaseToCamelCase } from '@intlayer/config/utils';\nimport type { Format } from '../utils/getFormatFromExtension';\n\nexport const getContentDeclarationFileTemplate = async (\n key: string,\n format: Format,\n fileParams: Record<string, any> = {},\n noMetadata?: boolean\n) => {\n const camelCaseKey = kebabCaseToCamelCase(key);\n const name = camelCaseKey.charAt(0).toLowerCase() + camelCaseKey.slice(1);\n\n const fileParamsString = Object.entries(fileParams)\n .filter(([, value]) => value !== undefined)\n .map(([paramKey, value]) => {\n const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(paramKey)\n ? paramKey\n : JSON.stringify(paramKey);\n\n const formattedValue =\n typeof value === 'object' || typeof value === 'string'\n ? JSON.stringify(value)\n : value;\n\n return `\\n ${formattedKey}: ${formattedValue},`;\n })\n .join('');\n\n let content: string;\n\n if (noMetadata) {\n content = '{}';\n } else if (format === 'json' || format === 'jsonc' || format === 'json5') {\n content = [\n '{',\n ' \"$schema\": \"https://intlayer.org/schema.json\",',\n ` \"key\": \"${key}\",${fileParamsString}`,\n ' \"content\": {',\n ' }',\n '}',\n ].join('\\n');\n } else {\n content = [\n '{',\n ` key: '${key}',${fileParamsString}`,\n ' content: {',\n ' },',\n '}',\n ].join('\\n');\n }\n\n const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? \"['content']\" : ''}} **/`;\n const satisfiesType = noMetadata ? \"Dictionary['content']\" : 'Dictionary';\n\n switch (format) {\n case 'ts':\n return [\n \"import { type Dictionary } from 'intlayer';\",\n '',\n `const ${name}Content = ${content} satisfies ${satisfiesType};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'cjs':\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `module.exports = ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'json':\n case 'jsonc':\n case 'json5':\n return [content, ''].join('\\n');\n\n default: // esm\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n }\n};\n"],"mappings":";;;;;AAGA,MAAa,oCAAoC,OAC/C,KACA,QACA,aAAkC,CAAC,GACnC,eACG;CACH,MAAM,gEAAoC,GAAG;CAC7C,MAAM,OAAO,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,aAAa,MAAM,CAAC;CAExE,MAAM,mBAAmB,OAAO,QAAQ,UAAU,EAC/C,QAAQ,GAAG,WAAW,UAAU,MAAS,EACzC,KAAK,CAAC,UAAU,WAAW;EAU1B,OAAO,OATc,6BAA6B,KAAK,QAAQ,IAC3D,WACA,KAAK,UAAU,QAAQ,EAOA,IAJzB,OAAO,UAAU,YAAY,OAAO,UAAU,WAC1C,KAAK,UAAU,KAAK,IACpB,MAEwC;CAChD,CAAC,EACA,KAAK,EAAE;CAEV,IAAI;CAEJ,IAAI,YACF,UAAU;MACL,IAAI,WAAW,UAAU,WAAW,WAAW,WAAW,SAC/D,UAAU;EACR;EACA;EACA,aAAa,IAAI,IAAI;EACrB;EACA;EACA;CACF,EAAE,KAAK,IAAI;MAEX,UAAU;EACR;EACA,WAAW,IAAI,IAAI;EACnB;EACA;EACA;CACF,EAAE,KAAK,IAAI;CAGb,MAAM,QAAQ,2CAA2C,aAAa,gBAAgB,GAAG;CACzF,MAAM,gBAAgB,aAAa,0BAA0B;CAE7D,QAAQ,QAAR;EACE,KAAK,MACH,OAAO;GACL;GACA;GACA,SAAS,KAAK,YAAY,QAAQ,aAAa,cAAc;GAC7D;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK,OACH,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,oBAAoB,KAAK;GACzB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO,CAAC,SAAS,EAAE,EAAE,KAAK,IAAI;EAEhC,SACE,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;CACf;AACF"}
1
+ {"version":3,"file":"getContentDeclarationFileTemplate.cjs","names":[],"sources":["../../../src/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.ts"],"sourcesContent":["import { kebabCaseToCamelCase } from '@intlayer/config/utils';\nimport type { Format } from '../utils/getFormatFromExtension';\n\nexport const getContentDeclarationFileTemplate = async (\n key: string,\n format: Format,\n fileParams: Record<string, any> = {},\n noMetadata?: boolean\n) => {\n const camelCaseKey = kebabCaseToCamelCase(key);\n const name = camelCaseKey.charAt(0).toLowerCase() + camelCaseKey.slice(1);\n\n const fileParamsString = Object.entries(fileParams)\n .filter(([, value]) => value !== undefined)\n .map(([paramKey, value]) => {\n const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(paramKey)\n ? paramKey\n : JSON.stringify(paramKey);\n\n const formattedValue =\n typeof value === 'object' || typeof value === 'string'\n ? JSON.stringify(value)\n : value;\n\n return `\\n ${formattedKey}: ${formattedValue},`;\n })\n .join('');\n\n let content: string;\n\n if (noMetadata) {\n content = '{}';\n } else if (format === 'json' || format === 'jsonc' || format === 'json5') {\n content = [\n '{',\n ' \"$schema\": \"https://intlayer.org/schema.json\",',\n ` \"key\": \"${key}\",${fileParamsString}`,\n ' \"content\": {',\n ' }',\n '}',\n ].join('\\n');\n } else {\n content = [\n '{',\n ` key: '${key}',${fileParamsString}`,\n ' content: {',\n ' },',\n '}',\n ].join('\\n');\n }\n\n const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? \"['content']\" : ''}} **/`;\n const satisfiesType = noMetadata ? \"Dictionary['content']\" : 'Dictionary';\n\n switch (format) {\n case 'yaml': {\n const yamlLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (tag) => ` - ${JSON.stringify(tag)}`\n ),\n ]\n : []),\n 'content: {}',\n ];\n return `${yamlLines.join('\\n')}\\n`;\n }\n\n case 'md': {\n const mdFrontmatterLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (t) => ` - ${JSON.stringify(t)}`\n ),\n ]\n : []),\n ];\n return ['---', ...mdFrontmatterLines, '---', '', ''].join('\\n');\n }\n\n case 'ts':\n return [\n \"import { type Dictionary } from 'intlayer';\",\n '',\n `const ${name}Content = ${content} satisfies ${satisfiesType};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'cjs':\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `module.exports = ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'json':\n case 'jsonc':\n case 'json5':\n return [content, ''].join('\\n');\n\n default: // esm\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n }\n};\n"],"mappings":";;;;;AAGA,MAAa,oCAAoC,OAC/C,KACA,QACA,aAAkC,CAAC,GACnC,eACG;CACH,MAAM,gEAAoC,GAAG;CAC7C,MAAM,OAAO,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,aAAa,MAAM,CAAC;CAExE,MAAM,mBAAmB,OAAO,QAAQ,UAAU,EAC/C,QAAQ,GAAG,WAAW,UAAU,MAAS,EACzC,KAAK,CAAC,UAAU,WAAW;EAU1B,OAAO,OATc,6BAA6B,KAAK,QAAQ,IAC3D,WACA,KAAK,UAAU,QAAQ,EAOA,IAJzB,OAAO,UAAU,YAAY,OAAO,UAAU,WAC1C,KAAK,UAAU,KAAK,IACpB,MAEwC;CAChD,CAAC,EACA,KAAK,EAAE;CAEV,IAAI;CAEJ,IAAI,YACF,UAAU;MACL,IAAI,WAAW,UAAU,WAAW,WAAW,WAAW,SAC/D,UAAU;EACR;EACA;EACA,aAAa,IAAI,IAAI;EACrB;EACA;EACA;CACF,EAAE,KAAK,IAAI;MAEX,UAAU;EACR;EACA,WAAW,IAAI,IAAI;EACnB;EACA;EACA;CACF,EAAE,KAAK,IAAI;CAGb,MAAM,QAAQ,2CAA2C,aAAa,gBAAgB,GAAG;CACzF,MAAM,gBAAgB,aAAa,0BAA0B;CAE7D,QAAQ,QAAR;EACE,KAAK,QAoBH,OAAO,GAAG;GAlBR,QAAQ;GACR,GAAI,WAAW,SAAS,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC;GAC5D,GAAI,WAAW,QACX,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK,GAAG,IAC7C,CAAC;GACL,GAAI,WAAW,cACX,CAAC,gBAAgB,KAAK,UAAU,WAAW,WAAW,GAAG,IACzD,CAAC;GACL,GAAI,WAAW,MAAM,SACjB,CACE,SACA,GAAI,WAAW,KAAkB,KAC9B,QAAQ,OAAO,KAAK,UAAU,GAAG,GACpC,CACF,IACA,CAAC;GACL;EAEgB,EAAE,KAAK,IAAI,EAAE;EAGjC,KAAK,MAmBH,OAAO;GAAC;GAAO,GAAG;IAjBhB,QAAQ;IACR,GAAI,WAAW,SAAS,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC;IAC5D,GAAI,WAAW,QACX,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK,GAAG,IAC7C,CAAC;IACL,GAAI,WAAW,cACX,CAAC,gBAAgB,KAAK,UAAU,WAAW,WAAW,GAAG,IACzD,CAAC;IACL,GAAI,WAAW,MAAM,SACjB,CACE,SACA,GAAI,WAAW,KAAkB,KAC9B,MAAM,OAAO,KAAK,UAAU,CAAC,GAChC,CACF,IACA,CAAC;GAE4B;GAAG;GAAO;GAAI;EAAE,EAAE,KAAK,IAAI;EAGhE,KAAK,MACH,OAAO;GACL;GACA;GACA,SAAS,KAAK,YAAY,QAAQ,aAAa,cAAc;GAC7D;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK,OACH,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,oBAAoB,KAAK;GACzB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO,CAAC,SAAS,EAAE,EAAE,KAAK,IAAI;EAEhC,SACE,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;CACf;AACF"}
@@ -4,6 +4,8 @@ const require_utils_parallelize = require('../utils/parallelize.cjs');
4
4
  const require_filterInvalidDictionaries = require('../filterInvalidDictionaries.cjs');
5
5
  const require_buildIntlayerDictionary_processContentDeclaration = require('../buildIntlayerDictionary/processContentDeclaration.cjs');
6
6
  const require_loadDictionaries_getIntlayerBundle = require('./getIntlayerBundle.cjs');
7
+ const require_loadDictionaries_loadMarkdownContentDeclaration = require('./loadMarkdownContentDeclaration.cjs');
8
+ const require_loadDictionaries_loadYamlContentDeclaration = require('./loadYamlContentDeclaration.cjs');
7
9
  const require_loadDictionaries_logTypeScriptErrors = require('./logTypeScriptErrors.cjs');
8
10
  let node_fs_promises = require("node:fs/promises");
9
11
  let node_path = require("node:path");
@@ -48,6 +50,8 @@ const getExternalDeps = async (baseDir) => {
48
50
  return cachedExternalDeps;
49
51
  };
50
52
  const loadContentDeclaration = async (path, configuration, bundleFilePath, options) => {
53
+ if ((0, node_path.extname)(path) === ".md" || (0, node_path.extname)(path) === ".mdx") return require_loadDictionaries_loadMarkdownContentDeclaration.loadMarkdownContentDeclaration(path);
54
+ if ((0, node_path.extname)(path) === ".yaml" || (0, node_path.extname)(path) === ".yml") return require_loadDictionaries_loadYamlContentDeclaration.loadYamlContentDeclaration(path);
51
55
  const { build, system } = configuration;
52
56
  const externalDeps = await getExternalDeps(system.baseDir);
53
57
  const resolvedBundleFilePath = bundleFilePath ?? await ensureIntlayerBundle(configuration);
@@ -1 +1 @@
1
- {"version":3,"file":"loadContentDeclaration.cjs","names":["getIntlayerBundle","filterInvalidDictionaries","parallelize","processContentDeclaration"],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"loadContentDeclaration.cjs","names":["getIntlayerBundle","loadMarkdownContentDeclaration","loadYamlContentDeclaration","filterInvalidDictionaries","parallelize","processContentDeclaration"],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, extname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { loadMarkdownContentDeclaration } from './loadMarkdownContentDeclaration';\nimport { loadYamlContentDeclaration } from './loadYamlContentDeclaration';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n if (extname(path) === '.md' || extname(path) === '.mdx') {\n return loadMarkdownContentDeclaration(path);\n }\n\n if (extname(path) === '.yaml' || extname(path) === '.yml') {\n return loadYamlContentDeclaration(path);\n }\n\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ let node_fs_promises = require("node:fs/promises");
4
+ let node_path = require("node:path");
5
+ let _intlayer_core_markdown = require("@intlayer/core/markdown");
6
+ let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
7
+
8
+ //#region src/loadDictionaries/loadMarkdownContentDeclaration.ts
9
+ const loadMarkdownContentDeclaration = async (path) => {
10
+ try {
11
+ const fileContent = await (0, node_fs_promises.readFile)(path, "utf-8");
12
+ const frontmatter = (0, _intlayer_core_markdown.getMarkdownMetadata)(fileContent);
13
+ const fileName = (0, node_path.basename)(path).replace(/\.content\.md$/, "");
14
+ const key = frontmatter.key ?? fileName;
15
+ if (!key) {
16
+ console.error(`[intlayer] Missing key in markdown content declaration: ${path}`);
17
+ return;
18
+ }
19
+ const { key: _key, locale, title, description, tags, fill, importMode, location, priority, version } = frontmatter;
20
+ return {
21
+ key,
22
+ ...locale !== void 0 && { locale },
23
+ ...title !== void 0 && { title },
24
+ ...description !== void 0 && { description },
25
+ ...tags !== void 0 && { tags },
26
+ ...fill !== void 0 && { fill },
27
+ ...importMode !== void 0 && { importMode },
28
+ ...location !== void 0 && { location },
29
+ ...priority !== void 0 && { priority },
30
+ ...version !== void 0 && { version },
31
+ content: {
32
+ nodeType: _intlayer_types_nodeType.MARKDOWN,
33
+ [_intlayer_types_nodeType.MARKDOWN]: fileContent,
34
+ metadata: frontmatter
35
+ }
36
+ };
37
+ } catch (error) {
38
+ console.error(`Error loading markdown content declaration at ${path}:`, error);
39
+ return;
40
+ }
41
+ };
42
+
43
+ //#endregion
44
+ exports.loadMarkdownContentDeclaration = loadMarkdownContentDeclaration;
45
+ //# sourceMappingURL=loadMarkdownContentDeclaration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadMarkdownContentDeclaration.cjs","names":["MARKDOWN"],"sources":["../../../src/loadDictionaries/loadMarkdownContentDeclaration.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { MARKDOWN } from '@intlayer/types/nodeType';\n\ntype MarkdownFrontmatter = {\n key?: string;\n locale?: string;\n title?: string;\n description?: string;\n tags?: string[];\n fill?: any;\n importMode?: string;\n location?: string;\n priority?: number;\n version?: string;\n [key: string]: any;\n};\n\nexport const loadMarkdownContentDeclaration = async (\n path: string\n): Promise<Dictionary | undefined> => {\n try {\n const fileContent = await readFile(path, 'utf-8');\n const frontmatter = getMarkdownMetadata<MarkdownFrontmatter>(fileContent);\n\n // Derive key from filename (e.g. \"my-doc.content.md\" → \"my-doc\") if not in frontmatter\n const fileName = basename(path).replace(/\\.content\\.md$/, '');\n const key = frontmatter.key ?? fileName;\n\n if (!key) {\n console.error(\n `[intlayer] Missing key in markdown content declaration: ${path}`\n );\n return undefined;\n }\n\n const {\n key: _key,\n locale,\n title,\n description,\n tags,\n fill,\n importMode,\n location,\n priority,\n version,\n } = frontmatter;\n\n return {\n key,\n ...(locale !== undefined && { locale }),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(tags !== undefined && { tags }),\n ...(fill !== undefined && { fill }),\n ...(importMode !== undefined && { importMode }),\n ...(location !== undefined && { location }),\n ...(priority !== undefined && { priority }),\n ...(version !== undefined && { version }),\n content: {\n nodeType: MARKDOWN,\n [MARKDOWN]: fileContent,\n metadata: frontmatter,\n },\n } as Dictionary;\n } catch (error) {\n console.error(\n `Error loading markdown content declaration at ${path}:`,\n error\n );\n return undefined;\n }\n};\n"],"mappings":";;;;;;;;AAoBA,MAAa,iCAAiC,OAC5C,SACoC;CACpC,IAAI;EACF,MAAM,cAAc,qCAAe,MAAM,OAAO;EAChD,MAAM,+DAAuD,WAAW;EAGxE,MAAM,mCAAoB,IAAI,EAAE,QAAQ,kBAAkB,EAAE;EAC5D,MAAM,MAAM,YAAY,OAAO;EAE/B,IAAI,CAAC,KAAK;GACR,QAAQ,MACN,2DAA2D,MAC7D;GACA;EACF;EAEA,MAAM,EACJ,KAAK,MACL,QACA,OACA,aACA,MACA,MACA,YACA,UACA,UACA,YACE;EAEJ,OAAO;GACL;GACA,GAAI,WAAW,UAAa,EAAE,OAAO;GACrC,GAAI,UAAU,UAAa,EAAE,MAAM;GACnC,GAAI,gBAAgB,UAAa,EAAE,YAAY;GAC/C,GAAI,SAAS,UAAa,EAAE,KAAK;GACjC,GAAI,SAAS,UAAa,EAAE,KAAK;GACjC,GAAI,eAAe,UAAa,EAAE,WAAW;GAC7C,GAAI,aAAa,UAAa,EAAE,SAAS;GACzC,GAAI,aAAa,UAAa,EAAE,SAAS;GACzC,GAAI,YAAY,UAAa,EAAE,QAAQ;GACvC,SAAS;IACP,UAAUA;KACTA,oCAAW;IACZ,UAAU;GACZ;EACF;CACF,SAAS,OAAO;EACd,QAAQ,MACN,iDAAiD,KAAK,IACtD,KACF;EACA;CACF;AACF"}
@@ -0,0 +1,27 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ let node_fs_promises = require("node:fs/promises");
4
+ let _intlayer_core_utils = require("@intlayer/core/utils");
5
+
6
+ //#region src/loadDictionaries/loadYamlContentDeclaration.ts
7
+ const loadYamlContentDeclaration = async (path) => {
8
+ try {
9
+ const parsed = (0, _intlayer_core_utils.parseYaml)(await (0, node_fs_promises.readFile)(path, "utf-8"));
10
+ if (!parsed || typeof parsed !== "object") {
11
+ console.error(`[intlayer] Invalid YAML content declaration: ${path}`);
12
+ return;
13
+ }
14
+ if (!parsed.key) {
15
+ console.error(`[intlayer] Missing key in YAML content declaration: ${path}`);
16
+ return;
17
+ }
18
+ return parsed;
19
+ } catch (error) {
20
+ console.error(`Error loading YAML content declaration at ${path}:`, error);
21
+ return;
22
+ }
23
+ };
24
+
25
+ //#endregion
26
+ exports.loadYamlContentDeclaration = loadYamlContentDeclaration;
27
+ //# sourceMappingURL=loadYamlContentDeclaration.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadYamlContentDeclaration.cjs","names":[],"sources":["../../../src/loadDictionaries/loadYamlContentDeclaration.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { parseYaml } from '@intlayer/core/utils';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\nexport const loadYamlContentDeclaration = async (\n path: string\n): Promise<Dictionary | undefined> => {\n try {\n const fileContent = await readFile(path, 'utf-8');\n const parsed = parseYaml<Dictionary>(fileContent);\n\n if (!parsed || typeof parsed !== 'object') {\n console.error(`[intlayer] Invalid YAML content declaration: ${path}`);\n return undefined;\n }\n\n if (!parsed.key) {\n console.error(\n `[intlayer] Missing key in YAML content declaration: ${path}`\n );\n return undefined;\n }\n\n return parsed;\n } catch (error) {\n console.error(`Error loading YAML content declaration at ${path}:`, error);\n return undefined;\n }\n};\n"],"mappings":";;;;;;AAIA,MAAa,6BAA6B,OACxC,SACoC;CACpC,IAAI;EAEF,MAAM,6CAA+B,qCADF,MAAM,OAAO,CACA;EAEhD,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU;GACzC,QAAQ,MAAM,gDAAgD,MAAM;GACpE;EACF;EAEA,IAAI,CAAC,OAAO,KAAK;GACf,QAAQ,MACN,uDAAuD,MACzD;GACA;EACF;EAEA,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MAAM,6CAA6C,KAAK,IAAI,KAAK;EACzE;CACF;AACF"}
@@ -14,6 +14,10 @@ const getFormatFromExtension = (extension) => {
14
14
  case ".json":
15
15
  case ".jsonc":
16
16
  case ".json5": return "json";
17
+ case ".md":
18
+ case ".mdx": return "md";
19
+ case ".yaml":
20
+ case ".yml": return "yaml";
17
21
  }
18
22
  return "ts";
19
23
  };
@@ -25,6 +29,8 @@ const getExtensionFromFormat = (format) => {
25
29
  case "jsonc": return ".jsonc";
26
30
  case "json5": return ".json5";
27
31
  case "esm": return ".mjs";
32
+ case "md": return ".md";
33
+ case "yaml": return ".yaml";
28
34
  }
29
35
  return ".ts";
30
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"getFormatFromExtension.cjs","names":[],"sources":["../../../src/utils/getFormatFromExtension.ts"],"sourcesContent":["export type Format = 'ts' | 'cjs' | 'esm' | 'json' | 'jsonc' | 'json5';\nexport type Extension =\n | '.ts'\n | '.tsx'\n | '.js'\n | '.jsx'\n | '.cjs'\n | '.cjsx'\n | '.mjs'\n | '.mjsx'\n | '.json'\n | '.jsonc'\n | '.json5';\n\nexport const getFormatFromExtension = (\n extension: Extension | (string & {})\n): Format => {\n switch (extension) {\n case '.ts':\n case '.tsx':\n return 'ts';\n case '.cjs':\n case '.cjsx':\n return 'cjs';\n case '.js':\n case '.jsx':\n case '.mjs':\n case '.mjsx':\n return 'esm';\n case '.json':\n case '.jsonc':\n case '.json5':\n return 'json';\n }\n\n return 'ts';\n};\n\nexport const getExtensionFromFormat = (\n format: Format | (string & {})\n): Extension => {\n switch (format) {\n case 'ts':\n return '.ts';\n case 'cjs':\n return '.cjs';\n case 'json':\n return '.json';\n case 'jsonc':\n return '.jsonc';\n case 'json5':\n return '.json5';\n case 'esm':\n return '.mjs';\n }\n\n return '.ts';\n};\n"],"mappings":";;;AAcA,MAAa,0BACX,cACW;CACX,QAAQ,WAAR;EACE,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;CACX;CAEA,OAAO;AACT;AAEA,MAAa,0BACX,WACc;CACd,QAAQ,QAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,OACH,OAAO;CACX;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"getFormatFromExtension.cjs","names":[],"sources":["../../../src/utils/getFormatFromExtension.ts"],"sourcesContent":["export type Format =\n | 'ts'\n | 'cjs'\n | 'esm'\n | 'json'\n | 'jsonc'\n | 'json5'\n | 'md'\n | 'yaml';\nexport type Extension =\n | '.ts'\n | '.tsx'\n | '.js'\n | '.jsx'\n | '.cjs'\n | '.cjsx'\n | '.mjs'\n | '.mjsx'\n | '.json'\n | '.jsonc'\n | '.json5'\n | '.md'\n | '.mdx'\n | '.yaml'\n | '.yml';\n\nexport const getFormatFromExtension = (\n extension: Extension | (string & {})\n): Format => {\n switch (extension) {\n case '.ts':\n case '.tsx':\n return 'ts';\n case '.cjs':\n case '.cjsx':\n return 'cjs';\n case '.js':\n case '.jsx':\n case '.mjs':\n case '.mjsx':\n return 'esm';\n case '.json':\n case '.jsonc':\n case '.json5':\n return 'json';\n case '.md':\n case '.mdx':\n return 'md';\n case '.yaml':\n case '.yml':\n return 'yaml';\n }\n\n return 'ts';\n};\n\nexport const getExtensionFromFormat = (\n format: Format | (string & {})\n): Extension => {\n switch (format) {\n case 'ts':\n return '.ts';\n case 'cjs':\n return '.cjs';\n case 'json':\n return '.json';\n case 'jsonc':\n return '.jsonc';\n case 'json5':\n return '.json5';\n case 'esm':\n return '.mjs';\n case 'md':\n return '.md';\n case 'yaml':\n return '.yaml';\n }\n\n return '.ts';\n};\n"],"mappings":";;;AA0BA,MAAa,0BACX,cACW;CACX,QAAQ,WAAR;EACE,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK;EACL,KAAK,QACH,OAAO;CACX;CAEA,OAAO;AACT;AAEA,MAAa,0BACX,WACc;CACd,QAAQ,QAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,QACH,OAAO;CACX;CAEA,OAAO;AACT"}
@@ -6,6 +6,8 @@ const require_detectFormatCommand = require('../detectFormatCommand.cjs');
6
6
  const require_writeContentDeclaration_processContentDeclarationContent = require('./processContentDeclarationContent.cjs');
7
7
  const require_writeContentDeclaration_transformJSONFile = require('./transformJSONFile.cjs');
8
8
  const require_writeContentDeclaration_writeJSFile = require('./writeJSFile.cjs');
9
+ const require_writeContentDeclaration_writeMarkdownFile = require('./writeMarkdownFile.cjs');
10
+ const require_writeContentDeclaration_writeYamlFile = require('./writeYamlFile.cjs');
9
11
  let node_fs_promises = require("node:fs/promises");
10
12
  let node_path = require("node:path");
11
13
  let node_fs = require("node:fs");
@@ -104,6 +106,14 @@ const writeContentDeclaration = async (dictionary, configuration, options) => {
104
106
  const writeFileWithDirectories = async (absoluteFilePath, dictionary, configuration, noMetadata) => {
105
107
  await (0, node_fs_promises.mkdir)((0, node_path.dirname)(absoluteFilePath), { recursive: true });
106
108
  const extension = (0, node_path.extname)(absoluteFilePath);
109
+ if (extension === ".md" || extension === ".mdx") {
110
+ await require_writeContentDeclaration_writeMarkdownFile.writeMarkdownFile(absoluteFilePath, dictionary, configuration);
111
+ return;
112
+ }
113
+ if (extension === ".yaml" || extension === ".yml") {
114
+ await require_writeContentDeclaration_writeYamlFile.writeYamlFile(absoluteFilePath, dictionary, configuration);
115
+ return;
116
+ }
107
117
  if ([
108
118
  ".json",
109
119
  ".jsonc",
@@ -1 +1 @@
1
- {"version":3,"file":"writeContentDeclaration.cjs","names":["processContentDeclarationContent","getFormatFromExtension","COMPILER_NO_METADATA","readDictionariesFromDisk","transformJSONFile","detectFormatCommand","writeJSFile"],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { COMPILER_NO_METADATA } from '@intlayer/config/defaultValues';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n let result: Dictionary = {\n key: dictionary.key,\n id: dictionary.id,\n title: dictionary.title,\n description: dictionary.description,\n tags: dictionary.tags,\n locale: dictionary.locale,\n fill: dictionary.fill,\n filled: dictionary.filled,\n priority: dictionary.priority,\n importMode: dictionary.importMode,\n version: dictionary.version,\n content,\n };\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { system, compiler } = configuration;\n const { baseDir } = system;\n\n const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.system.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(configuration.system.baseDir, dictionary.filePath);\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n noMetadata?: boolean\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n\n // Handle JSON, JSONC, and JSON5 via the AST transformer\n if (['.json', '.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(\n fileContent,\n dictionary,\n noMetadata\n );\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"writeContentDeclaration.cjs","names":["processContentDeclarationContent","getFormatFromExtension","COMPILER_NO_METADATA","readDictionariesFromDisk","writeMarkdownFile","writeYamlFile","transformJSONFile","detectFormatCommand","writeJSFile"],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { COMPILER_NO_METADATA } from '@intlayer/config/defaultValues';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\nimport { writeMarkdownFile } from './writeMarkdownFile';\nimport { writeYamlFile } from './writeYamlFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n let result: Dictionary = {\n key: dictionary.key,\n id: dictionary.id,\n title: dictionary.title,\n description: dictionary.description,\n tags: dictionary.tags,\n locale: dictionary.locale,\n fill: dictionary.fill,\n filled: dictionary.filled,\n priority: dictionary.priority,\n importMode: dictionary.importMode,\n version: dictionary.version,\n content,\n };\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { system, compiler } = configuration;\n const { baseDir } = system;\n\n const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.system.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(configuration.system.baseDir, dictionary.filePath);\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n noMetadata?: boolean\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n\n if (extension === '.md' || extension === '.mdx') {\n await writeMarkdownFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n if (extension === '.yaml' || extension === '.yml') {\n await writeYamlFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n // Handle JSON, JSONC, and JSON5 via the AST transformer\n if (['.json', '.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(\n fileContent,\n dictionary,\n noMetadata\n );\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ const require_detectFormatCommand = require('../detectFormatCommand.cjs');
4
+ let node_fs_promises = require("node:fs/promises");
5
+ let node_path = require("node:path");
6
+ let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
7
+ let node_child_process = require("node:child_process");
8
+
9
+ //#region src/writeContentDeclaration/writeMarkdownFile.ts
10
+ const stringifyYamlFrontmatter = (fields) => Object.entries(fields).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => {
11
+ if (Array.isArray(value)) return `${key}:\n${value.map((item) => ` - ${JSON.stringify(item)}`).join("\n")}`;
12
+ if (typeof value === "string" && (value.includes(":") || value.includes("\n") || value.includes("#"))) return `${key}: ${JSON.stringify(value)}`;
13
+ return `${key}: ${value}`;
14
+ }).join("\n");
15
+ const getMarkdownBody = (content) => {
16
+ const lines = content.split(/\r?\n/);
17
+ const firstNonEmptyIndex = lines.findIndex((line) => line.trim() !== "");
18
+ if (firstNonEmptyIndex === -1 || lines[firstNonEmptyIndex].trim() !== "---") return content;
19
+ let endIndex = -1;
20
+ for (let i = firstNonEmptyIndex + 1; i < lines.length; i++) if (lines[i].trim() === "---") {
21
+ endIndex = i;
22
+ break;
23
+ }
24
+ if (endIndex === -1) return content;
25
+ return lines.slice(endIndex + 1).join("\n").trimStart();
26
+ };
27
+ const EXCLUDED_FRONTMATTER_KEYS = new Set([
28
+ "content",
29
+ "$schema",
30
+ "id",
31
+ "filePath"
32
+ ]);
33
+ const writeMarkdownFile = async (absoluteFilePath, dictionary, configuration) => {
34
+ const content = dictionary.content;
35
+ const markdownBody = getMarkdownBody(typeof content === "object" && content?.nodeType === _intlayer_types_nodeType.MARKDOWN ? content[_intlayer_types_nodeType.MARKDOWN] ?? "" : "");
36
+ const fileContent = `---\n${stringifyYamlFrontmatter(Object.fromEntries(Object.entries(dictionary).filter(([k, v]) => !EXCLUDED_FRONTMATTER_KEYS.has(k) && v !== void 0)))}\n---\n\n${markdownBody}`;
37
+ await (0, node_fs_promises.mkdir)((0, node_path.dirname)(absoluteFilePath), { recursive: true });
38
+ const tempDir = configuration.system?.tempDir;
39
+ if (tempDir) await (0, node_fs_promises.mkdir)(tempDir, { recursive: true });
40
+ const tempFileName = `${(0, node_path.basename)(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
41
+ const tempPath = tempDir ? (0, node_path.join)(tempDir, tempFileName) : `${absoluteFilePath}.${tempFileName}`;
42
+ try {
43
+ await (0, node_fs_promises.writeFile)(tempPath, fileContent, "utf-8");
44
+ await (0, node_fs_promises.rename)(tempPath, absoluteFilePath);
45
+ } catch (error) {
46
+ try {
47
+ await (0, node_fs_promises.rm)(tempPath, { force: true });
48
+ } catch {}
49
+ throw error;
50
+ }
51
+ const formatCommand = require_detectFormatCommand.detectFormatCommand(configuration);
52
+ if (formatCommand) try {
53
+ (0, node_child_process.execSync)(formatCommand.replace("{{file}}", absoluteFilePath), {
54
+ stdio: "inherit",
55
+ cwd: configuration.system.baseDir
56
+ });
57
+ } catch (error) {
58
+ console.error(error);
59
+ }
60
+ };
61
+
62
+ //#endregion
63
+ exports.writeMarkdownFile = writeMarkdownFile;
64
+ //# sourceMappingURL=writeMarkdownFile.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeMarkdownFile.cjs","names":["MARKDOWN","detectFormatCommand"],"sources":["../../../src/writeContentDeclaration/writeMarkdownFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { MARKDOWN } from '@intlayer/types/nodeType';\nimport { detectFormatCommand } from '../detectFormatCommand';\n\nconst stringifyYamlFrontmatter = (fields: Record<string, any>): string =>\n Object.entries(fields)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n return `${key}:\\n${value.map((item) => ` - ${JSON.stringify(item)}`).join('\\n')}`;\n }\n if (\n typeof value === 'string' &&\n (value.includes(':') || value.includes('\\n') || value.includes('#'))\n ) {\n return `${key}: ${JSON.stringify(value)}`;\n }\n return `${key}: ${value}`;\n })\n .join('\\n');\n\n// Strips YAML frontmatter from a markdown string, returning only the body\nconst getMarkdownBody = (content: string): string => {\n const lines = content.split(/\\r?\\n/);\n const firstNonEmptyIndex = lines.findIndex((line) => line.trim() !== '');\n\n if (firstNonEmptyIndex === -1 || lines[firstNonEmptyIndex].trim() !== '---') {\n return content;\n }\n\n let endIndex = -1;\n for (let i = firstNonEmptyIndex + 1; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n endIndex = i;\n break;\n }\n }\n\n if (endIndex === -1) return content;\n\n return lines.slice(endIndex + 1).join('\\n').trimStart();\n};\n\n// Fields that are auto-generated or belong to the body, not the frontmatter\nconst EXCLUDED_FRONTMATTER_KEYS = new Set<string>([\n 'content',\n '$schema',\n 'id',\n 'filePath',\n]);\n\nexport const writeMarkdownFile = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const content = dictionary.content as any;\n const markdownRaw =\n typeof content === 'object' && content?.nodeType === MARKDOWN\n ? (content[MARKDOWN] ?? '')\n : '';\n // content.markdown now stores the full file (frontmatter + body); extract only the body\n const markdownBody = getMarkdownBody(markdownRaw);\n\n const frontmatterFields = Object.fromEntries(\n Object.entries(dictionary).filter(\n ([k, v]) => !EXCLUDED_FRONTMATTER_KEYS.has(k) && v !== undefined\n )\n );\n\n const frontmatterStr = stringifyYamlFrontmatter(frontmatterFields);\n const fileContent = `---\\n${frontmatterStr}\\n---\\n\\n${markdownBody}`;\n\n const dir = dirname(absoluteFilePath);\n await mkdir(dir, { recursive: true });\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) await mkdir(tempDir, { recursive: true });\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n\n try {\n await writeFile(tempPath, fileContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":";;;;;;;;;AAQA,MAAM,4BAA4B,WAChC,OAAO,QAAQ,MAAM,EAClB,QAAQ,GAAG,WAAW,UAAU,UAAa,UAAU,IAAI,EAC3D,KAAK,CAAC,KAAK,WAAW;CACrB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,GAAG,IAAI,KAAK,MAAM,KAAK,SAAS,OAAO,KAAK,UAAU,IAAI,GAAG,EAAE,KAAK,IAAI;CAEjF,IACE,OAAO,UAAU,aAChB,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,SAAS,GAAG,IAElE,OAAO,GAAG,IAAI,IAAI,KAAK,UAAU,KAAK;CAExC,OAAO,GAAG,IAAI,IAAI;AACpB,CAAC,EACA,KAAK,IAAI;AAGd,MAAM,mBAAmB,YAA4B;CACnD,MAAM,QAAQ,QAAQ,MAAM,OAAO;CACnC,MAAM,qBAAqB,MAAM,WAAW,SAAS,KAAK,KAAK,MAAM,EAAE;CAEvE,IAAI,uBAAuB,MAAM,MAAM,oBAAoB,KAAK,MAAM,OACpE,OAAO;CAGT,IAAI,WAAW;CACf,KAAK,IAAI,IAAI,qBAAqB,GAAG,IAAI,MAAM,QAAQ,KACrD,IAAI,MAAM,GAAG,KAAK,MAAM,OAAO;EAC7B,WAAW;EACX;CACF;CAGF,IAAI,aAAa,IAAI,OAAO;CAE5B,OAAO,MAAM,MAAM,WAAW,CAAC,EAAE,KAAK,IAAI,EAAE,UAAU;AACxD;AAGA,MAAM,4BAA4B,IAAI,IAAY;CAChD;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,oBAAoB,OAC/B,kBACA,YACA,kBACkB;CAClB,MAAM,UAAU,WAAW;CAM3B,MAAM,eAAe,gBAJnB,OAAO,YAAY,YAAY,SAAS,aAAaA,oCAChD,QAAQA,sCAAa,KACtB,EAE0C;CAShD,MAAM,cAAc,QADG,yBANG,OAAO,YAC/B,OAAO,QAAQ,UAAU,EAAE,QACxB,CAAC,GAAG,OAAO,CAAC,0BAA0B,IAAI,CAAC,KAAK,MAAM,MACzD,CAG8D,CACvB,EAAE,WAAW;CAGtD,yDADoB,gBACN,GAAG,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,QAAQ;CACtC,IAAI,SAAS,kCAAY,SAAS,EAAE,WAAW,KAAK,CAAC;CAErD,MAAM,eAAe,2BAAY,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE;CACxG,MAAM,WAAW,8BACR,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;CAE3B,IAAI;EACF,sCAAgB,UAAU,aAAa,OAAO;EAC9C,mCAAa,UAAU,gBAAgB;CACzC,SAAS,OAAO;EACd,IAAI;GACF,+BAAS,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAER;EACA,MAAM;CACR;CAEA,MAAM,gBAAgBC,gDAAoB,aAAa;CACvD,IAAI,eACF,IAAI;EACF,iCAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;GAC5D,OAAO;GACP,KAAK,cAAc,OAAO;EAC5B,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;AAEJ"}
@@ -0,0 +1,44 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
+ const require_detectFormatCommand = require('../detectFormatCommand.cjs');
4
+ let node_fs_promises = require("node:fs/promises");
5
+ let node_path = require("node:path");
6
+ let node_child_process = require("node:child_process");
7
+ let _intlayer_core_utils = require("@intlayer/core/utils");
8
+
9
+ //#region src/writeContentDeclaration/writeYamlFile.ts
10
+ const EXCLUDED_YAML_KEYS = new Set([
11
+ "$schema",
12
+ "id",
13
+ "filePath"
14
+ ]);
15
+ const writeYamlFile = async (absoluteFilePath, dictionary, configuration) => {
16
+ const fileContent = (0, _intlayer_core_utils.stringifyYaml)(Object.fromEntries(Object.entries(dictionary).filter(([k, v]) => !EXCLUDED_YAML_KEYS.has(k) && v !== void 0)));
17
+ await (0, node_fs_promises.mkdir)((0, node_path.dirname)(absoluteFilePath), { recursive: true });
18
+ const tempDir = configuration.system?.tempDir;
19
+ if (tempDir) await (0, node_fs_promises.mkdir)(tempDir, { recursive: true });
20
+ const tempFileName = `${(0, node_path.basename)(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
21
+ const tempPath = tempDir ? (0, node_path.join)(tempDir, tempFileName) : `${absoluteFilePath}.${tempFileName}`;
22
+ try {
23
+ await (0, node_fs_promises.writeFile)(tempPath, fileContent, "utf-8");
24
+ await (0, node_fs_promises.rename)(tempPath, absoluteFilePath);
25
+ } catch (error) {
26
+ try {
27
+ await (0, node_fs_promises.rm)(tempPath, { force: true });
28
+ } catch {}
29
+ throw error;
30
+ }
31
+ const formatCommand = require_detectFormatCommand.detectFormatCommand(configuration);
32
+ if (formatCommand) try {
33
+ (0, node_child_process.execSync)(formatCommand.replace("{{file}}", absoluteFilePath), {
34
+ stdio: "inherit",
35
+ cwd: configuration.system.baseDir
36
+ });
37
+ } catch (error) {
38
+ console.error(error);
39
+ }
40
+ };
41
+
42
+ //#endregion
43
+ exports.writeYamlFile = writeYamlFile;
44
+ //# sourceMappingURL=writeYamlFile.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeYamlFile.cjs","names":["detectFormatCommand"],"sources":["../../../src/writeContentDeclaration/writeYamlFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport { stringifyYaml } from '@intlayer/core/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { detectFormatCommand } from '../detectFormatCommand';\n\n// Fields that are auto-generated or runtime-only, not persisted in the file\nconst EXCLUDED_YAML_KEYS = new Set<string>(['$schema', 'id', 'filePath']);\n\nexport const writeYamlFile = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const filtered = Object.fromEntries(\n Object.entries(dictionary).filter(\n ([k, v]) => !EXCLUDED_YAML_KEYS.has(k) && v !== undefined\n )\n );\n\n const fileContent = stringifyYaml(filtered);\n\n const dir = dirname(absoluteFilePath);\n await mkdir(dir, { recursive: true });\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) await mkdir(tempDir, { recursive: true });\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n\n try {\n await writeFile(tempPath, fileContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":";;;;;;;;;AASA,MAAM,qBAAqB,IAAI,IAAY;CAAC;CAAW;CAAM;AAAU,CAAC;AAExE,MAAa,gBAAgB,OAC3B,kBACA,YACA,kBACkB;CAOlB,MAAM,sDANW,OAAO,YACtB,OAAO,QAAQ,UAAU,EAAE,QACxB,CAAC,GAAG,OAAO,CAAC,mBAAmB,IAAI,CAAC,KAAK,MAAM,MAClD,CAGuC,CAAC;CAG1C,yDADoB,gBACN,GAAG,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,QAAQ;CACtC,IAAI,SAAS,kCAAY,SAAS,EAAE,WAAW,KAAK,CAAC;CAErD,MAAM,eAAe,2BAAY,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE;CACxG,MAAM,WAAW,8BACR,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;CAE3B,IAAI;EACF,sCAAgB,UAAU,aAAa,OAAO;EAC9C,mCAAa,UAAU,gBAAgB;CACzC,SAAS,OAAO;EACd,IAAI;GACF,+BAAS,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAER;EACA,MAAM;CACR;CAEA,MAAM,gBAAgBA,gDAAoB,aAAa;CACvD,IAAI,eACF,IAAI;EACF,iCAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;GAC5D,OAAO;GACP,KAAK,cAAc,OAAO;EAC5B,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;AAEJ"}
@@ -27,6 +27,27 @@ const getContentDeclarationFileTemplate = async (key, format, fileParams = {}, n
27
27
  const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? "['content']" : ""}} **/`;
28
28
  const satisfiesType = noMetadata ? "Dictionary['content']" : "Dictionary";
29
29
  switch (format) {
30
+ case "yaml": return `${[
31
+ `key: ${key}`,
32
+ ...fileParams.locale ? [`locale: ${fileParams.locale}`] : [],
33
+ ...fileParams.title ? [`title: ${JSON.stringify(fileParams.title)}`] : [],
34
+ ...fileParams.description ? [`description: ${JSON.stringify(fileParams.description)}`] : [],
35
+ ...fileParams.tags?.length ? ["tags:", ...fileParams.tags.map((tag) => ` - ${JSON.stringify(tag)}`)] : [],
36
+ "content: {}"
37
+ ].join("\n")}\n`;
38
+ case "md": return [
39
+ "---",
40
+ ...[
41
+ `key: ${key}`,
42
+ ...fileParams.locale ? [`locale: ${fileParams.locale}`] : [],
43
+ ...fileParams.title ? [`title: ${JSON.stringify(fileParams.title)}`] : [],
44
+ ...fileParams.description ? [`description: ${JSON.stringify(fileParams.description)}`] : [],
45
+ ...fileParams.tags?.length ? ["tags:", ...fileParams.tags.map((t) => ` - ${JSON.stringify(t)}`)] : []
46
+ ],
47
+ "---",
48
+ "",
49
+ ""
50
+ ].join("\n");
30
51
  case "ts": return [
31
52
  "import { type Dictionary } from 'intlayer';",
32
53
  "",
@@ -1 +1 @@
1
- {"version":3,"file":"getContentDeclarationFileTemplate.mjs","names":[],"sources":["../../../src/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.ts"],"sourcesContent":["import { kebabCaseToCamelCase } from '@intlayer/config/utils';\nimport type { Format } from '../utils/getFormatFromExtension';\n\nexport const getContentDeclarationFileTemplate = async (\n key: string,\n format: Format,\n fileParams: Record<string, any> = {},\n noMetadata?: boolean\n) => {\n const camelCaseKey = kebabCaseToCamelCase(key);\n const name = camelCaseKey.charAt(0).toLowerCase() + camelCaseKey.slice(1);\n\n const fileParamsString = Object.entries(fileParams)\n .filter(([, value]) => value !== undefined)\n .map(([paramKey, value]) => {\n const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(paramKey)\n ? paramKey\n : JSON.stringify(paramKey);\n\n const formattedValue =\n typeof value === 'object' || typeof value === 'string'\n ? JSON.stringify(value)\n : value;\n\n return `\\n ${formattedKey}: ${formattedValue},`;\n })\n .join('');\n\n let content: string;\n\n if (noMetadata) {\n content = '{}';\n } else if (format === 'json' || format === 'jsonc' || format === 'json5') {\n content = [\n '{',\n ' \"$schema\": \"https://intlayer.org/schema.json\",',\n ` \"key\": \"${key}\",${fileParamsString}`,\n ' \"content\": {',\n ' }',\n '}',\n ].join('\\n');\n } else {\n content = [\n '{',\n ` key: '${key}',${fileParamsString}`,\n ' content: {',\n ' },',\n '}',\n ].join('\\n');\n }\n\n const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? \"['content']\" : ''}} **/`;\n const satisfiesType = noMetadata ? \"Dictionary['content']\" : 'Dictionary';\n\n switch (format) {\n case 'ts':\n return [\n \"import { type Dictionary } from 'intlayer';\",\n '',\n `const ${name}Content = ${content} satisfies ${satisfiesType};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'cjs':\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `module.exports = ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'json':\n case 'jsonc':\n case 'json5':\n return [content, ''].join('\\n');\n\n default: // esm\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n }\n};\n"],"mappings":";;;AAGA,MAAa,oCAAoC,OAC/C,KACA,QACA,aAAkC,CAAC,GACnC,eACG;CACH,MAAM,eAAe,qBAAqB,GAAG;CAC7C,MAAM,OAAO,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,aAAa,MAAM,CAAC;CAExE,MAAM,mBAAmB,OAAO,QAAQ,UAAU,EAC/C,QAAQ,GAAG,WAAW,UAAU,MAAS,EACzC,KAAK,CAAC,UAAU,WAAW;EAU1B,OAAO,OATc,6BAA6B,KAAK,QAAQ,IAC3D,WACA,KAAK,UAAU,QAAQ,EAOA,IAJzB,OAAO,UAAU,YAAY,OAAO,UAAU,WAC1C,KAAK,UAAU,KAAK,IACpB,MAEwC;CAChD,CAAC,EACA,KAAK,EAAE;CAEV,IAAI;CAEJ,IAAI,YACF,UAAU;MACL,IAAI,WAAW,UAAU,WAAW,WAAW,WAAW,SAC/D,UAAU;EACR;EACA;EACA,aAAa,IAAI,IAAI;EACrB;EACA;EACA;CACF,EAAE,KAAK,IAAI;MAEX,UAAU;EACR;EACA,WAAW,IAAI,IAAI;EACnB;EACA;EACA;CACF,EAAE,KAAK,IAAI;CAGb,MAAM,QAAQ,2CAA2C,aAAa,gBAAgB,GAAG;CACzF,MAAM,gBAAgB,aAAa,0BAA0B;CAE7D,QAAQ,QAAR;EACE,KAAK,MACH,OAAO;GACL;GACA;GACA,SAAS,KAAK,YAAY,QAAQ,aAAa,cAAc;GAC7D;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK,OACH,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,oBAAoB,KAAK;GACzB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO,CAAC,SAAS,EAAE,EAAE,KAAK,IAAI;EAEhC,SACE,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;CACf;AACF"}
1
+ {"version":3,"file":"getContentDeclarationFileTemplate.mjs","names":[],"sources":["../../../src/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.ts"],"sourcesContent":["import { kebabCaseToCamelCase } from '@intlayer/config/utils';\nimport type { Format } from '../utils/getFormatFromExtension';\n\nexport const getContentDeclarationFileTemplate = async (\n key: string,\n format: Format,\n fileParams: Record<string, any> = {},\n noMetadata?: boolean\n) => {\n const camelCaseKey = kebabCaseToCamelCase(key);\n const name = camelCaseKey.charAt(0).toLowerCase() + camelCaseKey.slice(1);\n\n const fileParamsString = Object.entries(fileParams)\n .filter(([, value]) => value !== undefined)\n .map(([paramKey, value]) => {\n const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(paramKey)\n ? paramKey\n : JSON.stringify(paramKey);\n\n const formattedValue =\n typeof value === 'object' || typeof value === 'string'\n ? JSON.stringify(value)\n : value;\n\n return `\\n ${formattedKey}: ${formattedValue},`;\n })\n .join('');\n\n let content: string;\n\n if (noMetadata) {\n content = '{}';\n } else if (format === 'json' || format === 'jsonc' || format === 'json5') {\n content = [\n '{',\n ' \"$schema\": \"https://intlayer.org/schema.json\",',\n ` \"key\": \"${key}\",${fileParamsString}`,\n ' \"content\": {',\n ' }',\n '}',\n ].join('\\n');\n } else {\n content = [\n '{',\n ` key: '${key}',${fileParamsString}`,\n ' content: {',\n ' },',\n '}',\n ].join('\\n');\n }\n\n const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? \"['content']\" : ''}} **/`;\n const satisfiesType = noMetadata ? \"Dictionary['content']\" : 'Dictionary';\n\n switch (format) {\n case 'yaml': {\n const yamlLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (tag) => ` - ${JSON.stringify(tag)}`\n ),\n ]\n : []),\n 'content: {}',\n ];\n return `${yamlLines.join('\\n')}\\n`;\n }\n\n case 'md': {\n const mdFrontmatterLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (t) => ` - ${JSON.stringify(t)}`\n ),\n ]\n : []),\n ];\n return ['---', ...mdFrontmatterLines, '---', '', ''].join('\\n');\n }\n\n case 'ts':\n return [\n \"import { type Dictionary } from 'intlayer';\",\n '',\n `const ${name}Content = ${content} satisfies ${satisfiesType};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'cjs':\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `module.exports = ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'json':\n case 'jsonc':\n case 'json5':\n return [content, ''].join('\\n');\n\n default: // esm\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n }\n};\n"],"mappings":";;;AAGA,MAAa,oCAAoC,OAC/C,KACA,QACA,aAAkC,CAAC,GACnC,eACG;CACH,MAAM,eAAe,qBAAqB,GAAG;CAC7C,MAAM,OAAO,aAAa,OAAO,CAAC,EAAE,YAAY,IAAI,aAAa,MAAM,CAAC;CAExE,MAAM,mBAAmB,OAAO,QAAQ,UAAU,EAC/C,QAAQ,GAAG,WAAW,UAAU,MAAS,EACzC,KAAK,CAAC,UAAU,WAAW;EAU1B,OAAO,OATc,6BAA6B,KAAK,QAAQ,IAC3D,WACA,KAAK,UAAU,QAAQ,EAOA,IAJzB,OAAO,UAAU,YAAY,OAAO,UAAU,WAC1C,KAAK,UAAU,KAAK,IACpB,MAEwC;CAChD,CAAC,EACA,KAAK,EAAE;CAEV,IAAI;CAEJ,IAAI,YACF,UAAU;MACL,IAAI,WAAW,UAAU,WAAW,WAAW,WAAW,SAC/D,UAAU;EACR;EACA;EACA,aAAa,IAAI,IAAI;EACrB;EACA;EACA;CACF,EAAE,KAAK,IAAI;MAEX,UAAU;EACR;EACA,WAAW,IAAI,IAAI;EACnB;EACA;EACA;CACF,EAAE,KAAK,IAAI;CAGb,MAAM,QAAQ,2CAA2C,aAAa,gBAAgB,GAAG;CACzF,MAAM,gBAAgB,aAAa,0BAA0B;CAE7D,QAAQ,QAAR;EACE,KAAK,QAoBH,OAAO,GAAG;GAlBR,QAAQ;GACR,GAAI,WAAW,SAAS,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC;GAC5D,GAAI,WAAW,QACX,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK,GAAG,IAC7C,CAAC;GACL,GAAI,WAAW,cACX,CAAC,gBAAgB,KAAK,UAAU,WAAW,WAAW,GAAG,IACzD,CAAC;GACL,GAAI,WAAW,MAAM,SACjB,CACE,SACA,GAAI,WAAW,KAAkB,KAC9B,QAAQ,OAAO,KAAK,UAAU,GAAG,GACpC,CACF,IACA,CAAC;GACL;EAEgB,EAAE,KAAK,IAAI,EAAE;EAGjC,KAAK,MAmBH,OAAO;GAAC;GAAO,GAAG;IAjBhB,QAAQ;IACR,GAAI,WAAW,SAAS,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC;IAC5D,GAAI,WAAW,QACX,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK,GAAG,IAC7C,CAAC;IACL,GAAI,WAAW,cACX,CAAC,gBAAgB,KAAK,UAAU,WAAW,WAAW,GAAG,IACzD,CAAC;IACL,GAAI,WAAW,MAAM,SACjB,CACE,SACA,GAAI,WAAW,KAAkB,KAC9B,MAAM,OAAO,KAAK,UAAU,CAAC,GAChC,CACF,IACA,CAAC;GAE4B;GAAG;GAAO;GAAI;EAAE,EAAE,KAAK,IAAI;EAGhE,KAAK,MACH,OAAO;GACL;GACA;GACA,SAAS,KAAK,YAAY,QAAQ,aAAa,cAAc;GAC7D;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK,OACH,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,oBAAoB,KAAK;GACzB;EACF,EAAE,KAAK,IAAI;EAEb,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO,CAAC,SAAS,EAAE,EAAE,KAAK,IAAI;EAEhC,SACE,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,kBAAkB,KAAK;GACvB;EACF,EAAE,KAAK,IAAI;CACf;AACF"}
@@ -2,9 +2,11 @@ import { parallelize } from "../utils/parallelize.mjs";
2
2
  import { filterInvalidDictionaries } from "../filterInvalidDictionaries.mjs";
3
3
  import { processContentDeclaration } from "../buildIntlayerDictionary/processContentDeclaration.mjs";
4
4
  import { getIntlayerBundle } from "./getIntlayerBundle.mjs";
5
+ import { loadMarkdownContentDeclaration } from "./loadMarkdownContentDeclaration.mjs";
6
+ import { loadYamlContentDeclaration } from "./loadYamlContentDeclaration.mjs";
5
7
  import { logTypeScriptErrors } from "./logTypeScriptErrors.mjs";
6
8
  import { readFile, writeFile } from "node:fs/promises";
7
- import { dirname, join, relative } from "node:path";
9
+ import { dirname, extname, join, relative } from "node:path";
8
10
  import { cacheDisk, getPackageJsonPath, getProjectRequire } from "@intlayer/config/utils";
9
11
  import { loadExternalFile } from "@intlayer/config/file";
10
12
 
@@ -46,6 +48,8 @@ const getExternalDeps = async (baseDir) => {
46
48
  return cachedExternalDeps;
47
49
  };
48
50
  const loadContentDeclaration = async (path, configuration, bundleFilePath, options) => {
51
+ if (extname(path) === ".md" || extname(path) === ".mdx") return loadMarkdownContentDeclaration(path);
52
+ if (extname(path) === ".yaml" || extname(path) === ".yml") return loadYamlContentDeclaration(path);
49
53
  const { build, system } = configuration;
50
54
  const externalDeps = await getExternalDeps(system.baseDir);
51
55
  const resolvedBundleFilePath = bundleFilePath ?? await ensureIntlayerBundle(configuration);
@@ -1 +1 @@
1
- {"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, extname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { loadMarkdownContentDeclaration } from './loadMarkdownContentDeclaration';\nimport { loadYamlContentDeclaration } from './loadYamlContentDeclaration';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n if (extname(path) === '.md' || extname(path) === '.mdx') {\n return loadMarkdownContentDeclaration(path);\n }\n\n if (extname(path) === '.yaml' || extname(path) === '.yml') {\n return loadYamlContentDeclaration(path);\n }\n\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ import { getMarkdownMetadata } from "@intlayer/core/markdown";
4
+ import { MARKDOWN } from "@intlayer/types/nodeType";
5
+
6
+ //#region src/loadDictionaries/loadMarkdownContentDeclaration.ts
7
+ const loadMarkdownContentDeclaration = async (path) => {
8
+ try {
9
+ const fileContent = await readFile(path, "utf-8");
10
+ const frontmatter = getMarkdownMetadata(fileContent);
11
+ const fileName = basename(path).replace(/\.content\.md$/, "");
12
+ const key = frontmatter.key ?? fileName;
13
+ if (!key) {
14
+ console.error(`[intlayer] Missing key in markdown content declaration: ${path}`);
15
+ return;
16
+ }
17
+ const { key: _key, locale, title, description, tags, fill, importMode, location, priority, version } = frontmatter;
18
+ return {
19
+ key,
20
+ ...locale !== void 0 && { locale },
21
+ ...title !== void 0 && { title },
22
+ ...description !== void 0 && { description },
23
+ ...tags !== void 0 && { tags },
24
+ ...fill !== void 0 && { fill },
25
+ ...importMode !== void 0 && { importMode },
26
+ ...location !== void 0 && { location },
27
+ ...priority !== void 0 && { priority },
28
+ ...version !== void 0 && { version },
29
+ content: {
30
+ nodeType: MARKDOWN,
31
+ [MARKDOWN]: fileContent,
32
+ metadata: frontmatter
33
+ }
34
+ };
35
+ } catch (error) {
36
+ console.error(`Error loading markdown content declaration at ${path}:`, error);
37
+ return;
38
+ }
39
+ };
40
+
41
+ //#endregion
42
+ export { loadMarkdownContentDeclaration };
43
+ //# sourceMappingURL=loadMarkdownContentDeclaration.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadMarkdownContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadMarkdownContentDeclaration.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { MARKDOWN } from '@intlayer/types/nodeType';\n\ntype MarkdownFrontmatter = {\n key?: string;\n locale?: string;\n title?: string;\n description?: string;\n tags?: string[];\n fill?: any;\n importMode?: string;\n location?: string;\n priority?: number;\n version?: string;\n [key: string]: any;\n};\n\nexport const loadMarkdownContentDeclaration = async (\n path: string\n): Promise<Dictionary | undefined> => {\n try {\n const fileContent = await readFile(path, 'utf-8');\n const frontmatter = getMarkdownMetadata<MarkdownFrontmatter>(fileContent);\n\n // Derive key from filename (e.g. \"my-doc.content.md\" → \"my-doc\") if not in frontmatter\n const fileName = basename(path).replace(/\\.content\\.md$/, '');\n const key = frontmatter.key ?? fileName;\n\n if (!key) {\n console.error(\n `[intlayer] Missing key in markdown content declaration: ${path}`\n );\n return undefined;\n }\n\n const {\n key: _key,\n locale,\n title,\n description,\n tags,\n fill,\n importMode,\n location,\n priority,\n version,\n } = frontmatter;\n\n return {\n key,\n ...(locale !== undefined && { locale }),\n ...(title !== undefined && { title }),\n ...(description !== undefined && { description }),\n ...(tags !== undefined && { tags }),\n ...(fill !== undefined && { fill }),\n ...(importMode !== undefined && { importMode }),\n ...(location !== undefined && { location }),\n ...(priority !== undefined && { priority }),\n ...(version !== undefined && { version }),\n content: {\n nodeType: MARKDOWN,\n [MARKDOWN]: fileContent,\n metadata: frontmatter,\n },\n } as Dictionary;\n } catch (error) {\n console.error(\n `Error loading markdown content declaration at ${path}:`,\n error\n );\n return undefined;\n }\n};\n"],"mappings":";;;;;;AAoBA,MAAa,iCAAiC,OAC5C,SACoC;CACpC,IAAI;EACF,MAAM,cAAc,MAAM,SAAS,MAAM,OAAO;EAChD,MAAM,cAAc,oBAAyC,WAAW;EAGxE,MAAM,WAAW,SAAS,IAAI,EAAE,QAAQ,kBAAkB,EAAE;EAC5D,MAAM,MAAM,YAAY,OAAO;EAE/B,IAAI,CAAC,KAAK;GACR,QAAQ,MACN,2DAA2D,MAC7D;GACA;EACF;EAEA,MAAM,EACJ,KAAK,MACL,QACA,OACA,aACA,MACA,MACA,YACA,UACA,UACA,YACE;EAEJ,OAAO;GACL;GACA,GAAI,WAAW,UAAa,EAAE,OAAO;GACrC,GAAI,UAAU,UAAa,EAAE,MAAM;GACnC,GAAI,gBAAgB,UAAa,EAAE,YAAY;GAC/C,GAAI,SAAS,UAAa,EAAE,KAAK;GACjC,GAAI,SAAS,UAAa,EAAE,KAAK;GACjC,GAAI,eAAe,UAAa,EAAE,WAAW;GAC7C,GAAI,aAAa,UAAa,EAAE,SAAS;GACzC,GAAI,aAAa,UAAa,EAAE,SAAS;GACzC,GAAI,YAAY,UAAa,EAAE,QAAQ;GACvC,SAAS;IACP,UAAU;KACT,WAAW;IACZ,UAAU;GACZ;EACF;CACF,SAAS,OAAO;EACd,QAAQ,MACN,iDAAiD,KAAK,IACtD,KACF;EACA;CACF;AACF"}
@@ -0,0 +1,25 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { parseYaml } from "@intlayer/core/utils";
3
+
4
+ //#region src/loadDictionaries/loadYamlContentDeclaration.ts
5
+ const loadYamlContentDeclaration = async (path) => {
6
+ try {
7
+ const parsed = parseYaml(await readFile(path, "utf-8"));
8
+ if (!parsed || typeof parsed !== "object") {
9
+ console.error(`[intlayer] Invalid YAML content declaration: ${path}`);
10
+ return;
11
+ }
12
+ if (!parsed.key) {
13
+ console.error(`[intlayer] Missing key in YAML content declaration: ${path}`);
14
+ return;
15
+ }
16
+ return parsed;
17
+ } catch (error) {
18
+ console.error(`Error loading YAML content declaration at ${path}:`, error);
19
+ return;
20
+ }
21
+ };
22
+
23
+ //#endregion
24
+ export { loadYamlContentDeclaration };
25
+ //# sourceMappingURL=loadYamlContentDeclaration.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadYamlContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadYamlContentDeclaration.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { parseYaml } from '@intlayer/core/utils';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\nexport const loadYamlContentDeclaration = async (\n path: string\n): Promise<Dictionary | undefined> => {\n try {\n const fileContent = await readFile(path, 'utf-8');\n const parsed = parseYaml<Dictionary>(fileContent);\n\n if (!parsed || typeof parsed !== 'object') {\n console.error(`[intlayer] Invalid YAML content declaration: ${path}`);\n return undefined;\n }\n\n if (!parsed.key) {\n console.error(\n `[intlayer] Missing key in YAML content declaration: ${path}`\n );\n return undefined;\n }\n\n return parsed;\n } catch (error) {\n console.error(`Error loading YAML content declaration at ${path}:`, error);\n return undefined;\n }\n};\n"],"mappings":";;;;AAIA,MAAa,6BAA6B,OACxC,SACoC;CACpC,IAAI;EAEF,MAAM,SAAS,UAAsB,MADX,SAAS,MAAM,OAAO,CACA;EAEhD,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU;GACzC,QAAQ,MAAM,gDAAgD,MAAM;GACpE;EACF;EAEA,IAAI,CAAC,OAAO,KAAK;GACf,QAAQ,MACN,uDAAuD,MACzD;GACA;EACF;EAEA,OAAO;CACT,SAAS,OAAO;EACd,QAAQ,MAAM,6CAA6C,KAAK,IAAI,KAAK;EACzE;CACF;AACF"}
@@ -12,6 +12,10 @@ const getFormatFromExtension = (extension) => {
12
12
  case ".json":
13
13
  case ".jsonc":
14
14
  case ".json5": return "json";
15
+ case ".md":
16
+ case ".mdx": return "md";
17
+ case ".yaml":
18
+ case ".yml": return "yaml";
15
19
  }
16
20
  return "ts";
17
21
  };
@@ -23,6 +27,8 @@ const getExtensionFromFormat = (format) => {
23
27
  case "jsonc": return ".jsonc";
24
28
  case "json5": return ".json5";
25
29
  case "esm": return ".mjs";
30
+ case "md": return ".md";
31
+ case "yaml": return ".yaml";
26
32
  }
27
33
  return ".ts";
28
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"getFormatFromExtension.mjs","names":[],"sources":["../../../src/utils/getFormatFromExtension.ts"],"sourcesContent":["export type Format = 'ts' | 'cjs' | 'esm' | 'json' | 'jsonc' | 'json5';\nexport type Extension =\n | '.ts'\n | '.tsx'\n | '.js'\n | '.jsx'\n | '.cjs'\n | '.cjsx'\n | '.mjs'\n | '.mjsx'\n | '.json'\n | '.jsonc'\n | '.json5';\n\nexport const getFormatFromExtension = (\n extension: Extension | (string & {})\n): Format => {\n switch (extension) {\n case '.ts':\n case '.tsx':\n return 'ts';\n case '.cjs':\n case '.cjsx':\n return 'cjs';\n case '.js':\n case '.jsx':\n case '.mjs':\n case '.mjsx':\n return 'esm';\n case '.json':\n case '.jsonc':\n case '.json5':\n return 'json';\n }\n\n return 'ts';\n};\n\nexport const getExtensionFromFormat = (\n format: Format | (string & {})\n): Extension => {\n switch (format) {\n case 'ts':\n return '.ts';\n case 'cjs':\n return '.cjs';\n case 'json':\n return '.json';\n case 'jsonc':\n return '.jsonc';\n case 'json5':\n return '.json5';\n case 'esm':\n return '.mjs';\n }\n\n return '.ts';\n};\n"],"mappings":";AAcA,MAAa,0BACX,cACW;CACX,QAAQ,WAAR;EACE,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;CACX;CAEA,OAAO;AACT;AAEA,MAAa,0BACX,WACc;CACd,QAAQ,QAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,OACH,OAAO;CACX;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"getFormatFromExtension.mjs","names":[],"sources":["../../../src/utils/getFormatFromExtension.ts"],"sourcesContent":["export type Format =\n | 'ts'\n | 'cjs'\n | 'esm'\n | 'json'\n | 'jsonc'\n | 'json5'\n | 'md'\n | 'yaml';\nexport type Extension =\n | '.ts'\n | '.tsx'\n | '.js'\n | '.jsx'\n | '.cjs'\n | '.cjsx'\n | '.mjs'\n | '.mjsx'\n | '.json'\n | '.jsonc'\n | '.json5'\n | '.md'\n | '.mdx'\n | '.yaml'\n | '.yml';\n\nexport const getFormatFromExtension = (\n extension: Extension | (string & {})\n): Format => {\n switch (extension) {\n case '.ts':\n case '.tsx':\n return 'ts';\n case '.cjs':\n case '.cjsx':\n return 'cjs';\n case '.js':\n case '.jsx':\n case '.mjs':\n case '.mjsx':\n return 'esm';\n case '.json':\n case '.jsonc':\n case '.json5':\n return 'json';\n case '.md':\n case '.mdx':\n return 'md';\n case '.yaml':\n case '.yml':\n return 'yaml';\n }\n\n return 'ts';\n};\n\nexport const getExtensionFromFormat = (\n format: Format | (string & {})\n): Extension => {\n switch (format) {\n case 'ts':\n return '.ts';\n case 'cjs':\n return '.cjs';\n case 'json':\n return '.json';\n case 'jsonc':\n return '.jsonc';\n case 'json5':\n return '.json5';\n case 'esm':\n return '.mjs';\n case 'md':\n return '.md';\n case 'yaml':\n return '.yaml';\n }\n\n return '.ts';\n};\n"],"mappings":";AA0BA,MAAa,0BACX,cACW;CACX,QAAQ,WAAR;EACE,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO;EACT,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO;EACT,KAAK;EACL,KAAK,QACH,OAAO;EACT,KAAK;EACL,KAAK,QACH,OAAO;CACX;CAEA,OAAO;AACT;AAEA,MAAa,0BACX,WACc;CACd,QAAQ,QAAR;EACE,KAAK,MACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,KAAK,OACH,OAAO;EACT,KAAK,MACH,OAAO;EACT,KAAK,QACH,OAAO;CACX;CAEA,OAAO;AACT"}
@@ -4,6 +4,8 @@ import { detectFormatCommand } from "../detectFormatCommand.mjs";
4
4
  import { processContentDeclarationContent } from "./processContentDeclarationContent.mjs";
5
5
  import { transformJSONFile } from "./transformJSONFile.mjs";
6
6
  import { writeJSFile } from "./writeJSFile.mjs";
7
+ import { writeMarkdownFile } from "./writeMarkdownFile.mjs";
8
+ import { writeYamlFile } from "./writeYamlFile.mjs";
7
9
  import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
8
10
  import { basename, dirname, extname, join, resolve } from "node:path";
9
11
  import { existsSync } from "node:fs";
@@ -102,6 +104,14 @@ const writeContentDeclaration = async (dictionary, configuration, options) => {
102
104
  const writeFileWithDirectories = async (absoluteFilePath, dictionary, configuration, noMetadata) => {
103
105
  await mkdir(dirname(absoluteFilePath), { recursive: true });
104
106
  const extension = extname(absoluteFilePath);
107
+ if (extension === ".md" || extension === ".mdx") {
108
+ await writeMarkdownFile(absoluteFilePath, dictionary, configuration);
109
+ return;
110
+ }
111
+ if (extension === ".yaml" || extension === ".yml") {
112
+ await writeYamlFile(absoluteFilePath, dictionary, configuration);
113
+ return;
114
+ }
105
115
  if ([
106
116
  ".json",
107
117
  ".jsonc",
@@ -1 +1 @@
1
- {"version":3,"file":"writeContentDeclaration.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { COMPILER_NO_METADATA } from '@intlayer/config/defaultValues';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n let result: Dictionary = {\n key: dictionary.key,\n id: dictionary.id,\n title: dictionary.title,\n description: dictionary.description,\n tags: dictionary.tags,\n locale: dictionary.locale,\n fill: dictionary.fill,\n filled: dictionary.filled,\n priority: dictionary.priority,\n importMode: dictionary.importMode,\n version: dictionary.version,\n content,\n };\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { system, compiler } = configuration;\n const { baseDir } = system;\n\n const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.system.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(configuration.system.baseDir, dictionary.filePath);\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n noMetadata?: boolean\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n\n // Handle JSON, JSONC, and JSON5 via the AST transformer\n if (['.json', '.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(\n fileContent,\n dictionary,\n noMetadata\n );\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"writeContentDeclaration.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport { COMPILER_NO_METADATA } from '@intlayer/config/defaultValues';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { detectFormatCommand } from '../detectFormatCommand';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { readDictionariesFromDisk } from '../utils/readDictionariesFromDisk';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\nimport { writeMarkdownFile } from './writeMarkdownFile';\nimport { writeYamlFile } from './writeYamlFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n let result: Dictionary = {\n key: dictionary.key,\n id: dictionary.id,\n title: dictionary.title,\n description: dictionary.description,\n tags: dictionary.tags,\n locale: dictionary.locale,\n fill: dictionary.fill,\n filled: dictionary.filled,\n priority: dictionary.priority,\n importMode: dictionary.importMode,\n version: dictionary.version,\n content,\n };\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { system, compiler } = configuration;\n const { baseDir } = system;\n\n const noMetadata = compiler?.noMetadata ?? COMPILER_NO_METADATA;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = readDictionariesFromDisk<\n Record<string, Dictionary[]>\n >(configuration.system.unmergedDictionariesDir);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.system.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(configuration.system.baseDir, dictionary.filePath);\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration,\n noMetadata\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n noMetadata?: boolean\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n\n if (extension === '.md' || extension === '.mdx') {\n await writeMarkdownFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n if (extension === '.yaml' || extension === '.yml') {\n await writeYamlFile(absoluteFilePath, dictionary, configuration);\n return;\n }\n\n // Handle JSON, JSONC, and JSON5 via the AST transformer\n if (['.json', '.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(\n fileContent,\n dictionary,\n noMetadata\n );\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration, noMetadata);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,MAAM,2BAA2B,OAC/B,YACA,eACA,eACG;;;;CAIH,MAAM,sBACJ,MAAM,iCAAiC,UAAU;CAEnD,IAAI,UAAU,oBAAoB;;;;CAMlC,IAAI,WAAW,QACb,UAAU,uBACR,qBACA,WAAW,MACb,EAAE;MACG,IAAI,YACT,UAAU,6BACR,qBACA,UACF,EAAE;CAGJ,IAAI,qBAA0B;EAC5B,GAAG;EACH;CACF;;;;CAMA,WAAW,MAAM,UAAU,cAAc,WAAW,CAAC,GACnD,IAAI,OAAO,cAAc;EACvB,MAAM,kBAAkB,MAAM,OAAO,eAAe;GAClD,YAAY;GACZ;EACF,CAAC;EAED,IAAI,iBACF,qBAAqB;CAEzB;CAMF,IAAI,EAFF,mBAAmB,WAAW,mBAAmB,MAE1B,OAAO;CAEhC,IAAI,SAAqB;EACvB,KAAK,WAAW;EAChB,IAAI,WAAW;EACf,OAAO,WAAW;EAClB,aAAa,WAAW;EACxB,MAAM,WAAW;EACjB,QAAQ,WAAW;EACnB,MAAM,WAAW;EACjB,QAAQ,WAAW;EACnB,UAAU,WAAW;EACrB,YAAY,WAAW;EACvB,SAAS,WAAW;EACpB;CACF;CAUA,IAFe,uBAFb,WAAW,WAAW,QAAQ,WAAW,QAAQ,IAAI,OAKhD,MAAM,UACX,mBAAmB,WACnB,mBAAmB,KAEnB,SAAS;EACP,SAAS;EACT,GAAG;CACL;CAGF,OAAO;AACT;AAQA,MAAM,iBAAiB,EACrB,qBAAqB,wBACvB;AAEA,MAAa,0BAA0B,OACrC,YACA,eACA,YACwD;CACxD,MAAM,EAAE,QAAQ,aAAa;CAC7B,MAAM,EAAE,YAAY;CAEpB,MAAM,aAAa,UAAU,cAAc;CAC3C,MAAM,EAAE,qBAAqB,eAAe;EAC1C,GAAG;EACH,GAAG;CACL;CAEA,MAAM,4BAA4B,KAAK,SAAS,mBAAmB;CASnE,MAAM,qBAP6B,yBAEjC,cAAc,OAAO,uBAC+B,EACpD,WAAW,MAGoC,MAC9C,OAAO,GAAG,YAAY,WAAW,OACpC;CAEA,MAAM,8BAA8B,MAAM,yBACxC,YACA,eACA,UACF;CAEA,IAAI,oBAAoB,UAAU;EAEhC,MAAM,gBAAgB,kBAAkB,oBAAoB,UAAU;EAEtE,MAAM,WAAW,QACf,cAAc,OAAO,SACrB,mBAAmB,QACrB;EAGA,IAAI,eACF,OAAO;GACL,QAAQ;GACR,MAAM;EACR;EAGF,MAAM,yBACJ,UACA,6BACA,eACA,UACF;EAEA,OAAO;GAAE,QAAQ;GAAW,MAAM;EAAS;CAC7C;CAEA,IAAI,WAAW,UAAU;EACvB,MAAM,WAAW,QAAQ,cAAc,OAAO,SAAS,WAAW,QAAQ;EAE1E,MAAM,yBACJ,UACA,6BACA,eACA,UACF;EAEA,OAAO;GAAE,QAAQ;GAAW,MAAM;EAAS;CAC7C;CAGA,MAAM,yBAAyB,KAC7B,2BACA,GAAG,WAAW,IAAI,cACpB;CAEA,MAAM,yBACJ,wBACA,6BACA,eACA,UACF;CAEA,OAAO;EACL,QAAQ;EACR,MAAM;CACR;AACF;AAEA,MAAM,2BAA2B,OAC/B,kBACA,YACA,eACA,eACkB;CAKlB,MAAM,MAHM,QAAQ,gBAGN,GAAG,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,YAAY,QAAQ,gBAAgB;CAE1C,IAAI,cAAc,SAAS,cAAc,QAAQ;EAC/C,MAAM,kBAAkB,kBAAkB,YAAY,aAAa;EACnE;CACF;CAEA,IAAI,cAAc,WAAW,cAAc,QAAQ;EACjD,MAAM,cAAc,kBAAkB,YAAY,aAAa;EAC/D;CACF;CAGA,IAAI;EAAC;EAAS;EAAU;CAAQ,EAAE,SAAS,SAAS,GAAG;EACrD,IAAI,cAAc;EAElB,IAAI,WAAW,gBAAgB,GAC7B,IAAI;GACF,cAAc,MAAM,SAAS,kBAAkB,OAAO;EACxD,QAAQ,CAER;EAGF,MAAM,qBAAqB,kBACzB,aACA,YACA,UACF;EAGA,MAAM,UAAU,cAAc,QAAQ;EACtC,IAAI,SACF,MAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;EAG1C,MAAM,eAAe,GAAG,SAAS,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE;EACxG,MAAM,WAAW,UACb,KAAK,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;EAC3B,IAAI;GACF,MAAM,UAAU,UAAU,oBAAoB,OAAO;GACrD,MAAM,OAAO,UAAU,gBAAgB;EACzC,SAAS,OAAO;GACd,IAAI;IACF,MAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;GACpC,QAAQ,CAER;GACA,MAAM;EACR;EAEA,MAAM,gBAAgB,oBAAoB,aAAa;EAEvD,IAAI,eACF,IAAI;GACF,SAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;IAC5D,OAAO;IACP,KAAK,cAAc,OAAO;GAC5B,CAAC;EACH,SAAS,OAAO;GACd,QAAQ,MAAM,KAAK;EACrB;EAGF;CACF;CAEA,MAAM,YAAY,kBAAkB,YAAY,eAAe,UAAU;CAIzE,IAAI;EAKF,MAAM,GAJe,KACnB,cAAc,OAAO,UACrB,wBAEkB,GAAG,EAAE,WAAW,KAAK,CAAC;CAC5C,QAAQ,CAAC;AACX"}
@@ -0,0 +1,62 @@
1
+ import { detectFormatCommand } from "../detectFormatCommand.mjs";
2
+ import { mkdir, rename, rm, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, join } from "node:path";
4
+ import { MARKDOWN } from "@intlayer/types/nodeType";
5
+ import { execSync } from "node:child_process";
6
+
7
+ //#region src/writeContentDeclaration/writeMarkdownFile.ts
8
+ const stringifyYamlFrontmatter = (fields) => Object.entries(fields).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => {
9
+ if (Array.isArray(value)) return `${key}:\n${value.map((item) => ` - ${JSON.stringify(item)}`).join("\n")}`;
10
+ if (typeof value === "string" && (value.includes(":") || value.includes("\n") || value.includes("#"))) return `${key}: ${JSON.stringify(value)}`;
11
+ return `${key}: ${value}`;
12
+ }).join("\n");
13
+ const getMarkdownBody = (content) => {
14
+ const lines = content.split(/\r?\n/);
15
+ const firstNonEmptyIndex = lines.findIndex((line) => line.trim() !== "");
16
+ if (firstNonEmptyIndex === -1 || lines[firstNonEmptyIndex].trim() !== "---") return content;
17
+ let endIndex = -1;
18
+ for (let i = firstNonEmptyIndex + 1; i < lines.length; i++) if (lines[i].trim() === "---") {
19
+ endIndex = i;
20
+ break;
21
+ }
22
+ if (endIndex === -1) return content;
23
+ return lines.slice(endIndex + 1).join("\n").trimStart();
24
+ };
25
+ const EXCLUDED_FRONTMATTER_KEYS = new Set([
26
+ "content",
27
+ "$schema",
28
+ "id",
29
+ "filePath"
30
+ ]);
31
+ const writeMarkdownFile = async (absoluteFilePath, dictionary, configuration) => {
32
+ const content = dictionary.content;
33
+ const markdownBody = getMarkdownBody(typeof content === "object" && content?.nodeType === MARKDOWN ? content[MARKDOWN] ?? "" : "");
34
+ const fileContent = `---\n${stringifyYamlFrontmatter(Object.fromEntries(Object.entries(dictionary).filter(([k, v]) => !EXCLUDED_FRONTMATTER_KEYS.has(k) && v !== void 0)))}\n---\n\n${markdownBody}`;
35
+ await mkdir(dirname(absoluteFilePath), { recursive: true });
36
+ const tempDir = configuration.system?.tempDir;
37
+ if (tempDir) await mkdir(tempDir, { recursive: true });
38
+ const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
39
+ const tempPath = tempDir ? join(tempDir, tempFileName) : `${absoluteFilePath}.${tempFileName}`;
40
+ try {
41
+ await writeFile(tempPath, fileContent, "utf-8");
42
+ await rename(tempPath, absoluteFilePath);
43
+ } catch (error) {
44
+ try {
45
+ await rm(tempPath, { force: true });
46
+ } catch {}
47
+ throw error;
48
+ }
49
+ const formatCommand = detectFormatCommand(configuration);
50
+ if (formatCommand) try {
51
+ execSync(formatCommand.replace("{{file}}", absoluteFilePath), {
52
+ stdio: "inherit",
53
+ cwd: configuration.system.baseDir
54
+ });
55
+ } catch (error) {
56
+ console.error(error);
57
+ }
58
+ };
59
+
60
+ //#endregion
61
+ export { writeMarkdownFile };
62
+ //# sourceMappingURL=writeMarkdownFile.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeMarkdownFile.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeMarkdownFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { MARKDOWN } from '@intlayer/types/nodeType';\nimport { detectFormatCommand } from '../detectFormatCommand';\n\nconst stringifyYamlFrontmatter = (fields: Record<string, any>): string =>\n Object.entries(fields)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n return `${key}:\\n${value.map((item) => ` - ${JSON.stringify(item)}`).join('\\n')}`;\n }\n if (\n typeof value === 'string' &&\n (value.includes(':') || value.includes('\\n') || value.includes('#'))\n ) {\n return `${key}: ${JSON.stringify(value)}`;\n }\n return `${key}: ${value}`;\n })\n .join('\\n');\n\n// Strips YAML frontmatter from a markdown string, returning only the body\nconst getMarkdownBody = (content: string): string => {\n const lines = content.split(/\\r?\\n/);\n const firstNonEmptyIndex = lines.findIndex((line) => line.trim() !== '');\n\n if (firstNonEmptyIndex === -1 || lines[firstNonEmptyIndex].trim() !== '---') {\n return content;\n }\n\n let endIndex = -1;\n for (let i = firstNonEmptyIndex + 1; i < lines.length; i++) {\n if (lines[i].trim() === '---') {\n endIndex = i;\n break;\n }\n }\n\n if (endIndex === -1) return content;\n\n return lines.slice(endIndex + 1).join('\\n').trimStart();\n};\n\n// Fields that are auto-generated or belong to the body, not the frontmatter\nconst EXCLUDED_FRONTMATTER_KEYS = new Set<string>([\n 'content',\n '$schema',\n 'id',\n 'filePath',\n]);\n\nexport const writeMarkdownFile = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const content = dictionary.content as any;\n const markdownRaw =\n typeof content === 'object' && content?.nodeType === MARKDOWN\n ? (content[MARKDOWN] ?? '')\n : '';\n // content.markdown now stores the full file (frontmatter + body); extract only the body\n const markdownBody = getMarkdownBody(markdownRaw);\n\n const frontmatterFields = Object.fromEntries(\n Object.entries(dictionary).filter(\n ([k, v]) => !EXCLUDED_FRONTMATTER_KEYS.has(k) && v !== undefined\n )\n );\n\n const frontmatterStr = stringifyYamlFrontmatter(frontmatterFields);\n const fileContent = `---\\n${frontmatterStr}\\n---\\n\\n${markdownBody}`;\n\n const dir = dirname(absoluteFilePath);\n await mkdir(dir, { recursive: true });\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) await mkdir(tempDir, { recursive: true });\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n\n try {\n await writeFile(tempPath, fileContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":";;;;;;;AAQA,MAAM,4BAA4B,WAChC,OAAO,QAAQ,MAAM,EAClB,QAAQ,GAAG,WAAW,UAAU,UAAa,UAAU,IAAI,EAC3D,KAAK,CAAC,KAAK,WAAW;CACrB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,GAAG,IAAI,KAAK,MAAM,KAAK,SAAS,OAAO,KAAK,UAAU,IAAI,GAAG,EAAE,KAAK,IAAI;CAEjF,IACE,OAAO,UAAU,aAChB,MAAM,SAAS,GAAG,KAAK,MAAM,SAAS,IAAI,KAAK,MAAM,SAAS,GAAG,IAElE,OAAO,GAAG,IAAI,IAAI,KAAK,UAAU,KAAK;CAExC,OAAO,GAAG,IAAI,IAAI;AACpB,CAAC,EACA,KAAK,IAAI;AAGd,MAAM,mBAAmB,YAA4B;CACnD,MAAM,QAAQ,QAAQ,MAAM,OAAO;CACnC,MAAM,qBAAqB,MAAM,WAAW,SAAS,KAAK,KAAK,MAAM,EAAE;CAEvE,IAAI,uBAAuB,MAAM,MAAM,oBAAoB,KAAK,MAAM,OACpE,OAAO;CAGT,IAAI,WAAW;CACf,KAAK,IAAI,IAAI,qBAAqB,GAAG,IAAI,MAAM,QAAQ,KACrD,IAAI,MAAM,GAAG,KAAK,MAAM,OAAO;EAC7B,WAAW;EACX;CACF;CAGF,IAAI,aAAa,IAAI,OAAO;CAE5B,OAAO,MAAM,MAAM,WAAW,CAAC,EAAE,KAAK,IAAI,EAAE,UAAU;AACxD;AAGA,MAAM,4BAA4B,IAAI,IAAY;CAChD;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,oBAAoB,OAC/B,kBACA,YACA,kBACkB;CAClB,MAAM,UAAU,WAAW;CAM3B,MAAM,eAAe,gBAJnB,OAAO,YAAY,YAAY,SAAS,aAAa,WAChD,QAAQ,aAAa,KACtB,EAE0C;CAShD,MAAM,cAAc,QADG,yBANG,OAAO,YAC/B,OAAO,QAAQ,UAAU,EAAE,QACxB,CAAC,GAAG,OAAO,CAAC,0BAA0B,IAAI,CAAC,KAAK,MAAM,MACzD,CAG8D,CACvB,EAAE,WAAW;CAGtD,MAAM,MADM,QAAQ,gBACN,GAAG,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,QAAQ;CACtC,IAAI,SAAS,MAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CAErD,MAAM,eAAe,GAAG,SAAS,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE;CACxG,MAAM,WAAW,UACb,KAAK,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;CAE3B,IAAI;EACF,MAAM,UAAU,UAAU,aAAa,OAAO;EAC9C,MAAM,OAAO,UAAU,gBAAgB;CACzC,SAAS,OAAO;EACd,IAAI;GACF,MAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAER;EACA,MAAM;CACR;CAEA,MAAM,gBAAgB,oBAAoB,aAAa;CACvD,IAAI,eACF,IAAI;EACF,SAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;GAC5D,OAAO;GACP,KAAK,cAAc,OAAO;EAC5B,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;AAEJ"}
@@ -0,0 +1,42 @@
1
+ import { detectFormatCommand } from "../detectFormatCommand.mjs";
2
+ import { mkdir, rename, rm, writeFile } from "node:fs/promises";
3
+ import { basename, dirname, join } from "node:path";
4
+ import { execSync } from "node:child_process";
5
+ import { stringifyYaml } from "@intlayer/core/utils";
6
+
7
+ //#region src/writeContentDeclaration/writeYamlFile.ts
8
+ const EXCLUDED_YAML_KEYS = new Set([
9
+ "$schema",
10
+ "id",
11
+ "filePath"
12
+ ]);
13
+ const writeYamlFile = async (absoluteFilePath, dictionary, configuration) => {
14
+ const fileContent = stringifyYaml(Object.fromEntries(Object.entries(dictionary).filter(([k, v]) => !EXCLUDED_YAML_KEYS.has(k) && v !== void 0)));
15
+ await mkdir(dirname(absoluteFilePath), { recursive: true });
16
+ const tempDir = configuration.system?.tempDir;
17
+ if (tempDir) await mkdir(tempDir, { recursive: true });
18
+ const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
19
+ const tempPath = tempDir ? join(tempDir, tempFileName) : `${absoluteFilePath}.${tempFileName}`;
20
+ try {
21
+ await writeFile(tempPath, fileContent, "utf-8");
22
+ await rename(tempPath, absoluteFilePath);
23
+ } catch (error) {
24
+ try {
25
+ await rm(tempPath, { force: true });
26
+ } catch {}
27
+ throw error;
28
+ }
29
+ const formatCommand = detectFormatCommand(configuration);
30
+ if (formatCommand) try {
31
+ execSync(formatCommand.replace("{{file}}", absoluteFilePath), {
32
+ stdio: "inherit",
33
+ cwd: configuration.system.baseDir
34
+ });
35
+ } catch (error) {
36
+ console.error(error);
37
+ }
38
+ };
39
+
40
+ //#endregion
41
+ export { writeYamlFile };
42
+ //# sourceMappingURL=writeYamlFile.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeYamlFile.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeYamlFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { mkdir, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, join } from 'node:path';\nimport { stringifyYaml } from '@intlayer/core/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { detectFormatCommand } from '../detectFormatCommand';\n\n// Fields that are auto-generated or runtime-only, not persisted in the file\nconst EXCLUDED_YAML_KEYS = new Set<string>(['$schema', 'id', 'filePath']);\n\nexport const writeYamlFile = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const filtered = Object.fromEntries(\n Object.entries(dictionary).filter(\n ([k, v]) => !EXCLUDED_YAML_KEYS.has(k) && v !== undefined\n )\n );\n\n const fileContent = stringifyYaml(filtered);\n\n const dir = dirname(absoluteFilePath);\n await mkdir(dir, { recursive: true });\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) await mkdir(tempDir, { recursive: true });\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n\n try {\n await writeFile(tempPath, fileContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // ignore\n }\n throw error;\n }\n\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', absoluteFilePath), {\n stdio: 'inherit',\n cwd: configuration.system.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":";;;;;;;AASA,MAAM,qBAAqB,IAAI,IAAY;CAAC;CAAW;CAAM;AAAU,CAAC;AAExE,MAAa,gBAAgB,OAC3B,kBACA,YACA,kBACkB;CAOlB,MAAM,cAAc,cANH,OAAO,YACtB,OAAO,QAAQ,UAAU,EAAE,QACxB,CAAC,GAAG,OAAO,CAAC,mBAAmB,IAAI,CAAC,KAAK,MAAM,MAClD,CAGuC,CAAC;CAG1C,MAAM,MADM,QAAQ,gBACN,GAAG,EAAE,WAAW,KAAK,CAAC;CAEpC,MAAM,UAAU,cAAc,QAAQ;CACtC,IAAI,SAAS,MAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;CAErD,MAAM,eAAe,GAAG,SAAS,gBAAgB,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE;CACxG,MAAM,WAAW,UACb,KAAK,SAAS,YAAY,IAC1B,GAAG,iBAAiB,GAAG;CAE3B,IAAI;EACF,MAAM,UAAU,UAAU,aAAa,OAAO;EAC9C,MAAM,OAAO,UAAU,gBAAgB;CACzC,SAAS,OAAO;EACd,IAAI;GACF,MAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;EACpC,QAAQ,CAER;EACA,MAAM;CACR;CAEA,MAAM,gBAAgB,oBAAoB,aAAa;CACvD,IAAI,eACF,IAAI;EACF,SAAS,cAAc,QAAQ,YAAY,gBAAgB,GAAG;GAC5D,OAAO;GACP,KAAK,cAAc,OAAO;EAC5B,CAAC;CACH,SAAS,OAAO;EACd,QAAQ,MAAM,KAAK;CACrB;AAEJ"}
@@ -0,0 +1,3 @@
1
+ import { Dictionary } from "@intlayer/types/dictionary";
2
+ import { LocalesValues as LocalesValues$1 } from "@intlayer/types/module_augmentation";
3
+ export type { LocalesValues$1 as LocalesValues };
@@ -1 +1 @@
1
- {"version":3,"file":"loadContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"mappings":";;;;;cAiBa,uBAAA,GACX,kBAAA,EAAoB,MAAA,SAAe,UAAA,GACnC,aAAA,EAAe,cAAA,KACd,UAAA;AAAA,cAQU,oBAAA,GACX,aAAA,EAAe,cAAA,KACd,OAAO;AAAA,KAmBL,6BAAA;EACH,QAAQ;AAAA;AAAA,cA+CG,sBAAA,GACX,IAAA,UACA,aAAA,EAAe,cAAA,EACf,cAAA,WACA,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA;AAAA,cA+CE,uBAAA,GACX,0BAAA,YACA,aAAA,EAAe,cAAA,EACf,cAAA,IAAkB,MAAA,EAAQ,kBAAA,aAC1B,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"loadContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"mappings":";;;;;cAmBa,uBAAA,GACX,kBAAA,EAAoB,MAAA,SAAe,UAAA,GACnC,aAAA,EAAe,cAAA,KACd,UAAA;AAAA,cAQU,oBAAA,GACX,aAAA,EAAe,cAAA,KACd,OAAO;AAAA,KAmBL,6BAAA;EACH,QAAQ;AAAA;AAAA,cA+CG,sBAAA,GACX,IAAA,UACA,aAAA,EAAe,cAAA,EACf,cAAA,WACA,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA;AAAA,cAuDE,uBAAA,GACX,0BAAA,YACA,aAAA,EAAe,cAAA,EACf,cAAA,IAAkB,MAAA,EAAQ,kBAAA,aAC1B,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA"}
@@ -0,0 +1,7 @@
1
+ import { Dictionary } from "@intlayer/types/dictionary";
2
+
3
+ //#region src/loadDictionaries/loadMarkdownContentDeclaration.d.ts
4
+ declare const loadMarkdownContentDeclaration: (path: string) => Promise<Dictionary | undefined>;
5
+ //#endregion
6
+ export { loadMarkdownContentDeclaration };
7
+ //# sourceMappingURL=loadMarkdownContentDeclaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadMarkdownContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadMarkdownContentDeclaration.ts"],"mappings":";;;cAoBa,8BAAA,GACX,IAAA,aACC,OAAO,CAAC,UAAA"}
@@ -0,0 +1,7 @@
1
+ import { Dictionary } from "@intlayer/types/dictionary";
2
+
3
+ //#region src/loadDictionaries/loadYamlContentDeclaration.d.ts
4
+ declare const loadYamlContentDeclaration: (path: string) => Promise<Dictionary | undefined>;
5
+ //#endregion
6
+ export { loadYamlContentDeclaration };
7
+ //# sourceMappingURL=loadYamlContentDeclaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadYamlContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadYamlContentDeclaration.ts"],"mappings":";;;cAIa,0BAAA,GACX,IAAA,aACC,OAAO,CAAC,UAAA"}
@@ -1,6 +1,6 @@
1
1
  //#region src/utils/getFormatFromExtension.d.ts
2
- type Format = 'ts' | 'cjs' | 'esm' | 'json' | 'jsonc' | 'json5';
3
- type Extension = '.ts' | '.tsx' | '.js' | '.jsx' | '.cjs' | '.cjsx' | '.mjs' | '.mjsx' | '.json' | '.jsonc' | '.json5';
2
+ type Format = 'ts' | 'cjs' | 'esm' | 'json' | 'jsonc' | 'json5' | 'md' | 'yaml';
3
+ type Extension = '.ts' | '.tsx' | '.js' | '.jsx' | '.cjs' | '.cjsx' | '.mjs' | '.mjsx' | '.json' | '.jsonc' | '.json5' | '.md' | '.mdx' | '.yaml' | '.yml';
4
4
  declare const getFormatFromExtension: (extension: Extension | (string & {})) => Format;
5
5
  declare const getExtensionFromFormat: (format: Format | (string & {})) => Extension;
6
6
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"getFormatFromExtension.d.ts","names":[],"sources":["../../../src/utils/getFormatFromExtension.ts"],"mappings":";KAAY,MAAA;AAAA,KACA,SAAA;AAAA,cAaC,sBAAA,GACX,SAAA,EAAW,SAAA,qBACV,MAoBF;AAAA,cAEY,sBAAA,GACX,MAAA,EAAQ,MAAA,qBACP,SAiBF"}
1
+ {"version":3,"file":"getFormatFromExtension.d.ts","names":[],"sources":["../../../src/utils/getFormatFromExtension.ts"],"mappings":";KAAY,MAAA;AAAA,KASA,SAAA;AAAA,cAiBC,sBAAA,GACX,SAAA,EAAW,SAAA,qBACV,MA0BF;AAAA,cAEY,sBAAA,GACX,MAAA,EAAQ,MAAA,qBACP,SAqBF"}
@@ -1 +1 @@
1
- {"version":3,"file":"writeContentDeclaration.d.ts","names":[],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"mappings":";;;;;;;KAsHK,8BAAA;EACH,mBAAA;EACA,UAAA,GAAa,aAAA;EACb,cAAA,GAAiB,MAAM;AAAA;AAAA,cAOZ,uBAAA,GACX,UAAA,EAAY,UAAA,EACZ,aAAA,EAAe,cAAA,EACf,OAAA,GAAU,8BAAA,KACT,OAAA;EAAU,MAAA,EAAQ,gBAAA;EAAkB,IAAA;AAAA"}
1
+ {"version":3,"file":"writeContentDeclaration.d.ts","names":[],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"mappings":";;;;;;;KAwHK,8BAAA;EACH,mBAAA;EACA,UAAA,GAAa,aAAA;EACb,cAAA,GAAiB,MAAM;AAAA;AAAA,cAOZ,uBAAA,GACX,UAAA,EAAY,UAAA,EACZ,aAAA,EAAe,cAAA,EACf,OAAA,GAAU,8BAAA,KACT,OAAA;EAAU,MAAA,EAAQ,gBAAA;EAAkB,IAAA;AAAA"}
@@ -0,0 +1,8 @@
1
+ import { IntlayerConfig } from "@intlayer/types/config";
2
+ import { Dictionary } from "@intlayer/types/dictionary";
3
+
4
+ //#region src/writeContentDeclaration/writeMarkdownFile.d.ts
5
+ declare const writeMarkdownFile: (absoluteFilePath: string, dictionary: Dictionary, configuration: IntlayerConfig) => Promise<void>;
6
+ //#endregion
7
+ export { writeMarkdownFile };
8
+ //# sourceMappingURL=writeMarkdownFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeMarkdownFile.d.ts","names":[],"sources":["../../../src/writeContentDeclaration/writeMarkdownFile.ts"],"mappings":";;;;cAuDa,iBAAA,GACX,gBAAA,UACA,UAAA,EAAY,UAAA,EACZ,aAAA,EAAe,cAAA,KACd,OAAA"}
@@ -0,0 +1,8 @@
1
+ import { IntlayerConfig } from "@intlayer/types/config";
2
+ import { Dictionary } from "@intlayer/types/dictionary";
3
+
4
+ //#region src/writeContentDeclaration/writeYamlFile.d.ts
5
+ declare const writeYamlFile: (absoluteFilePath: string, dictionary: Dictionary, configuration: IntlayerConfig) => Promise<void>;
6
+ //#endregion
7
+ export { writeYamlFile };
8
+ //# sourceMappingURL=writeYamlFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeYamlFile.d.ts","names":[],"sources":["../../../src/writeContentDeclaration/writeYamlFile.ts"],"mappings":";;;;cAWa,aAAA,GACX,gBAAA,UACA,UAAA,EAAY,UAAA,EACZ,aAAA,EAAe,cAAA,KACd,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/chokidar",
3
- "version": "8.9.8",
3
+ "version": "8.10.0-canary.1",
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.9.8",
113
- "@intlayer/config": "8.9.8",
114
- "@intlayer/core": "8.9.8",
115
- "@intlayer/dictionaries-entry": "8.9.8",
116
- "@intlayer/remote-dictionaries-entry": "8.9.8",
117
- "@intlayer/types": "8.9.8",
118
- "@intlayer/unmerged-dictionaries-entry": "8.9.8",
112
+ "@intlayer/api": "8.10.0-canary.1",
113
+ "@intlayer/config": "8.10.0-canary.1",
114
+ "@intlayer/core": "8.10.0-canary.1",
115
+ "@intlayer/dictionaries-entry": "8.10.0-canary.1",
116
+ "@intlayer/remote-dictionaries-entry": "8.10.0-canary.1",
117
+ "@intlayer/types": "8.10.0-canary.1",
118
+ "@intlayer/unmerged-dictionaries-entry": "8.10.0-canary.1",
119
119
  "chokidar": "5.0.0",
120
120
  "defu": "6.1.7",
121
121
  "fast-glob": "3.3.3",
@@ -124,7 +124,7 @@
124
124
  "zod-to-ts": "2.0.0"
125
125
  },
126
126
  "devDependencies": {
127
- "@types/node": "25.8.0",
127
+ "@types/node": "25.9.1",
128
128
  "@utils/ts-config": "1.0.4",
129
129
  "@utils/ts-config-types": "1.0.4",
130
130
  "@utils/tsdown-config": "1.0.4",