@intlayer/core 7.3.1 → 7.3.2-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +0 -2
  2. package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs +1 -0
  3. package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs.map +1 -1
  4. package/dist/cjs/interpreter/getContent/getContent.cjs +10 -1
  5. package/dist/cjs/interpreter/getContent/getContent.cjs.map +1 -1
  6. package/dist/cjs/interpreter/getContent/plugins.cjs +4 -2
  7. package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
  8. package/dist/cjs/interpreter/getTranslation.cjs +42 -3
  9. package/dist/cjs/interpreter/getTranslation.cjs.map +1 -1
  10. package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs +1 -0
  11. package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs.map +1 -1
  12. package/dist/esm/interpreter/getContent/getContent.mjs +10 -1
  13. package/dist/esm/interpreter/getContent/getContent.mjs.map +1 -1
  14. package/dist/esm/interpreter/getContent/plugins.mjs +4 -2
  15. package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
  16. package/dist/esm/interpreter/getTranslation.mjs +42 -3
  17. package/dist/esm/interpreter/getTranslation.mjs.map +1 -1
  18. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +7 -7
  19. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +7 -7
  20. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +7 -7
  21. package/dist/types/deepTransformPlugins/getMissingLocalesContent.d.ts.map +1 -1
  22. package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +2 -2
  23. package/dist/types/dictionaryManipulator/orderDictionaries.d.ts.map +1 -1
  24. package/dist/types/interpreter/getContent/getContent.d.ts.map +1 -1
  25. package/dist/types/interpreter/getContent/plugins.d.ts +1 -1
  26. package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
  27. package/dist/types/interpreter/getTranslation.d.ts +1 -1
  28. package/dist/types/interpreter/getTranslation.d.ts.map +1 -1
  29. package/package.json +8 -7
package/README.md CHANGED
@@ -24,8 +24,6 @@
24
24
  <a href="https://github.com/aymericzip/intlayer/blob/main/LICENSE" target="_blank" rel="noopener noreferrer nofollow"><img src="https://img.shields.io/github/license/aymericzip/intlayer?style=for-the-badge&labelColor=000000&color=FFFFFF&logoColor=000000&cacheSeconds=86400" alt="license"/></a>
25
25
  <a href="https://github.com/aymericzip/intlayer/commits/main" target="_blank" rel="noopener noreferrer nofollow"><img src="https://img.shields.io/github/last-commit/aymericzip/intlayer?style=for-the-badge&labelColor=000000&color=FFFFFF&logoColor=000000&cacheSeconds=86400" alt="last commit"/>
26
26
  </a>
27
- <a href="https://bountyhub.dev/bounties?repo=intlayer" target="_blank" rel="noopener noreferrer nofollow"><img src="https://img.shields.io/badge/Bounties-on%20BountyHub-yellow?style=for-the-badge&labelColor=000000&color=FFFFFF&logoColor=000000&cacheSeconds=86400" alt="Bounties on BountyHub"/>
28
- </a>
29
27
  </p>
30
28
 
31
29
  ![Watch the video](https://github.com/aymericzip/intlayer/blob/main/docs/assets/demo_video.gif)
@@ -7,6 +7,7 @@ __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_bui
7
7
  //#region src/deepTransformPlugins/getMissingLocalesContent.ts
8
8
  const getDeepKeyPaths = (obj, prefix = []) => {
9
9
  if (typeof obj !== "object" || obj === null) return [];
10
+ if (Array.isArray(obj)) return [];
10
11
  return Object.keys(obj).flatMap((key) => {
11
12
  const newPath = [...prefix, key];
12
13
  return [newPath, ...getDeepKeyPaths(obj[key], newPath)];
@@ -1 +1 @@
1
- {"version":3,"file":"getMissingLocalesContent.cjs","names":["NodeType","configuration","plugins: Plugins[]"],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n type ContentNode,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type { DeepTransformContent, NodeProps, Plugins } from '../interpreter';\nimport { deepTransformNode } from '../interpreter/getContent/deepTransform';\nimport type { TranslationContent } from '../transpiler';\n\nconst getDeepKeyPaths = (obj: any, prefix: string[] = []): string[][] => {\n if (typeof obj !== 'object' || obj === null) {\n return [];\n }\n\n return Object.keys(obj).flatMap((key) => {\n const newPath = [...prefix, key];\n return [newPath, ...getDeepKeyPaths(obj[key], newPath)];\n });\n};\n\nconst hasDeepKeyPath = (obj: any, keyPath: string[]): boolean => {\n let current = obj;\n for (const key of keyPath) {\n if (\n current === undefined ||\n current === null ||\n typeof current !== 'object'\n ) {\n return false;\n }\n if (!(key in current)) {\n return false;\n }\n current = current[key];\n }\n\n return true;\n};\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const checkMissingLocalesPlugin = (\n locales: Locale[],\n onMissingLocale: (locale: Locale) => void\n): Plugins => ({\n id: 'check-missing-locales-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const translations = node[NodeType.Translation] as Record<string, any>;\n const allKeys = new Set<string>();\n\n for (const locale of locales) {\n if (translations[locale]) {\n getDeepKeyPaths(translations[locale]).forEach((path) => {\n allKeys.add(JSON.stringify(path));\n });\n }\n }\n\n for (const locale of locales) {\n if (!translations[locale]) {\n onMissingLocale(locale);\n continue;\n }\n\n for (const pathStr of allKeys) {\n const path = JSON.parse(pathStr);\n if (!hasDeepKeyPath(translations[locale], path)) {\n onMissingLocale(locale);\n break;\n }\n }\n }\n\n // Continue traversal inside the translation values, but avoid re-applying this plugin on the same node\n for (const key in translations) {\n const child = translations[key];\n deepTransformNode(child, {\n ...props,\n children: child,\n });\n }\n\n // Return the original node; the return value is ignored by the caller\n return node;\n },\n});\n\n/**\n * Return the content of a node with only the translation plugin.\n *\n * @param node The node to transform.\n * @param locales The locales to check for missing translations.\n */\nexport const getMissingLocalesContent = <T extends ContentNode>(\n node: T,\n locales: LocalesValues[] = configuration?.internationalization?.locales,\n nodeProps: NodeProps\n): Locale[] => {\n const missingLocales = new Set<Locale>();\n\n const plugins: Plugins[] = [\n checkMissingLocalesPlugin(locales as Locale[], (locale) =>\n missingLocales.add(locale)\n ),\n ...(nodeProps.plugins ?? []),\n ];\n\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T>;\n\n return Array.from(missingLocales);\n};\n\nexport const getMissingLocalesContentFromDictionary = (\n dictionary: Dictionary,\n locales: LocalesValues[] = configuration?.internationalization?.locales\n) =>\n getMissingLocalesContent(dictionary.content, locales, {\n dictionaryKey: dictionary.key,\n keyPath: [],\n });\n"],"mappings":";;;;;;;AAYA,MAAM,mBAAmB,KAAU,SAAmB,EAAE,KAAiB;AACvE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,QAAO,EAAE;AAGX,QAAO,OAAO,KAAK,IAAI,CAAC,SAAS,QAAQ;EACvC,MAAM,UAAU,CAAC,GAAG,QAAQ,IAAI;AAChC,SAAO,CAAC,SAAS,GAAG,gBAAgB,IAAI,MAAM,QAAQ,CAAC;GACvD;;AAGJ,MAAM,kBAAkB,KAAU,YAA+B;CAC/D,IAAI,UAAU;AACd,MAAK,MAAM,OAAO,SAAS;AACzB,MACE,YAAY,UACZ,YAAY,QACZ,OAAO,YAAY,SAEnB,QAAO;AAET,MAAI,EAAE,OAAO,SACX,QAAO;AAET,YAAU,QAAQ;;AAGpB,QAAO;;;AAIT,MAAa,6BACX,SACA,qBACa;CACb,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,0BAAS;CAC1D,YAAY,MAA0B,OAAO,wBAAsB;EACjE,MAAM,eAAe,KAAKA,0BAAS;EACnC,MAAM,0BAAU,IAAI,KAAa;AAEjC,OAAK,MAAM,UAAU,QACnB,KAAI,aAAa,QACf,iBAAgB,aAAa,QAAQ,CAAC,SAAS,SAAS;AACtD,WAAQ,IAAI,KAAK,UAAU,KAAK,CAAC;IACjC;AAIN,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,CAAC,aAAa,SAAS;AACzB,oBAAgB,OAAO;AACvB;;AAGF,QAAK,MAAM,WAAW,SAAS;IAC7B,MAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,CAAC,eAAe,aAAa,SAAS,KAAK,EAAE;AAC/C,qBAAgB,OAAO;AACvB;;;;AAMN,OAAK,MAAM,OAAO,cAAc;GAC9B,MAAM,QAAQ,aAAa;AAC3B,uBAAkB,OAAO;IACvB,GAAG;IACH,UAAU;IACX,CAAC;;AAIJ,SAAO;;CAEV;;;;;;;AAQD,MAAa,4BACX,MACA,UAA2BC,iCAAe,sBAAsB,SAChE,cACa;CACb,MAAM,iCAAiB,IAAI,KAAa;CAExC,MAAMC,UAAqB,CACzB,0BAA0B,UAAsB,WAC9C,eAAe,IAAI,OAAO,CAC3B,EACD,GAAI,UAAU,WAAW,EAAE,CAC5B;AAED,gEAAkB,MAAM;EACtB,GAAG;EACH;EACD,CAAC;AAEF,QAAO,MAAM,KAAK,eAAe;;AAGnC,MAAa,0CACX,YACA,UAA2BD,iCAAe,sBAAsB,YAEhE,yBAAyB,WAAW,SAAS,SAAS;CACpD,eAAe,WAAW;CAC1B,SAAS,EAAE;CACZ,CAAC"}
1
+ {"version":3,"file":"getMissingLocalesContent.cjs","names":["NodeType","configuration","plugins: Plugins[]"],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n type ContentNode,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type { DeepTransformContent, NodeProps, Plugins } from '../interpreter';\nimport { deepTransformNode } from '../interpreter/getContent/deepTransform';\nimport type { TranslationContent } from '../transpiler';\n\nconst getDeepKeyPaths = (obj: any, prefix: string[] = []): string[][] => {\n if (typeof obj !== 'object' || obj === null) {\n return [];\n }\n\n // Skip array indices - arrays of different lengths shouldn't trigger missing translations\n // Each locale can have arrays with different numbers of elements (e.g., keywords)\n if (Array.isArray(obj)) {\n return [];\n }\n\n return Object.keys(obj).flatMap((key) => {\n const newPath = [...prefix, key];\n return [newPath, ...getDeepKeyPaths(obj[key], newPath)];\n });\n};\n\nconst hasDeepKeyPath = (obj: any, keyPath: string[]): boolean => {\n let current = obj;\n for (const key of keyPath) {\n if (\n current === undefined ||\n current === null ||\n typeof current !== 'object'\n ) {\n return false;\n }\n if (!(key in current)) {\n return false;\n }\n current = current[key];\n }\n\n return true;\n};\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const checkMissingLocalesPlugin = (\n locales: Locale[],\n onMissingLocale: (locale: Locale) => void\n): Plugins => ({\n id: 'check-missing-locales-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const translations = node[NodeType.Translation] as Record<string, any>;\n const allKeys = new Set<string>();\n\n for (const locale of locales) {\n if (translations[locale]) {\n getDeepKeyPaths(translations[locale]).forEach((path) => {\n allKeys.add(JSON.stringify(path));\n });\n }\n }\n\n for (const locale of locales) {\n if (!translations[locale]) {\n onMissingLocale(locale);\n continue;\n }\n\n for (const pathStr of allKeys) {\n const path = JSON.parse(pathStr);\n if (!hasDeepKeyPath(translations[locale], path)) {\n onMissingLocale(locale);\n break;\n }\n }\n }\n\n // Continue traversal inside the translation values, but avoid re-applying this plugin on the same node\n for (const key in translations) {\n const child = translations[key];\n deepTransformNode(child, {\n ...props,\n children: child,\n });\n }\n\n // Return the original node; the return value is ignored by the caller\n return node;\n },\n});\n\n/**\n * Return the content of a node with only the translation plugin.\n *\n * @param node The node to transform.\n * @param locales The locales to check for missing translations.\n */\nexport const getMissingLocalesContent = <T extends ContentNode>(\n node: T,\n locales: LocalesValues[] = configuration?.internationalization?.locales,\n nodeProps: NodeProps\n): Locale[] => {\n const missingLocales = new Set<Locale>();\n\n const plugins: Plugins[] = [\n checkMissingLocalesPlugin(locales as Locale[], (locale) =>\n missingLocales.add(locale)\n ),\n ...(nodeProps.plugins ?? []),\n ];\n\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T>;\n\n return Array.from(missingLocales);\n};\n\nexport const getMissingLocalesContentFromDictionary = (\n dictionary: Dictionary,\n locales: LocalesValues[] = configuration?.internationalization?.locales\n) =>\n getMissingLocalesContent(dictionary.content, locales, {\n dictionaryKey: dictionary.key,\n keyPath: [],\n });\n"],"mappings":";;;;;;;AAYA,MAAM,mBAAmB,KAAU,SAAmB,EAAE,KAAiB;AACvE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,QAAO,EAAE;AAKX,KAAI,MAAM,QAAQ,IAAI,CACpB,QAAO,EAAE;AAGX,QAAO,OAAO,KAAK,IAAI,CAAC,SAAS,QAAQ;EACvC,MAAM,UAAU,CAAC,GAAG,QAAQ,IAAI;AAChC,SAAO,CAAC,SAAS,GAAG,gBAAgB,IAAI,MAAM,QAAQ,CAAC;GACvD;;AAGJ,MAAM,kBAAkB,KAAU,YAA+B;CAC/D,IAAI,UAAU;AACd,MAAK,MAAM,OAAO,SAAS;AACzB,MACE,YAAY,UACZ,YAAY,QACZ,OAAO,YAAY,SAEnB,QAAO;AAET,MAAI,EAAE,OAAO,SACX,QAAO;AAET,YAAU,QAAQ;;AAGpB,QAAO;;;AAIT,MAAa,6BACX,SACA,qBACa;CACb,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaA,0BAAS;CAC1D,YAAY,MAA0B,OAAO,wBAAsB;EACjE,MAAM,eAAe,KAAKA,0BAAS;EACnC,MAAM,0BAAU,IAAI,KAAa;AAEjC,OAAK,MAAM,UAAU,QACnB,KAAI,aAAa,QACf,iBAAgB,aAAa,QAAQ,CAAC,SAAS,SAAS;AACtD,WAAQ,IAAI,KAAK,UAAU,KAAK,CAAC;IACjC;AAIN,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,CAAC,aAAa,SAAS;AACzB,oBAAgB,OAAO;AACvB;;AAGF,QAAK,MAAM,WAAW,SAAS;IAC7B,MAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,CAAC,eAAe,aAAa,SAAS,KAAK,EAAE;AAC/C,qBAAgB,OAAO;AACvB;;;;AAMN,OAAK,MAAM,OAAO,cAAc;GAC9B,MAAM,QAAQ,aAAa;AAC3B,uBAAkB,OAAO;IACvB,GAAG;IACH,UAAU;IACX,CAAC;;AAIJ,SAAO;;CAEV;;;;;;;AAQD,MAAa,4BACX,MACA,UAA2BC,iCAAe,sBAAsB,SAChE,cACa;CACb,MAAM,iCAAiB,IAAI,KAAa;CAExC,MAAMC,UAAqB,CACzB,0BAA0B,UAAsB,WAC9C,eAAe,IAAI,OAAO,CAC3B,EACD,GAAI,UAAU,WAAW,EAAE,CAC5B;AAED,gEAAkB,MAAM;EACtB,GAAG;EACH;EACD,CAAC;AAEF,QAAO,MAAM,KAAK,eAAe;;AAGnC,MAAa,0CACX,YACA,UAA2BD,iCAAe,sBAAsB,YAEhE,yBAAyB,WAAW,SAAS,SAAS;CACpD,eAAe,WAAW;CAC1B,SAAS,EAAE;CACZ,CAAC"}
@@ -1,6 +1,7 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
2
  const require_interpreter_getContent_deepTransform = require('./deepTransform.cjs');
3
3
  const require_interpreter_getContent_plugins = require('./plugins.cjs');
4
+ let __intlayer_config_client = require("@intlayer/config/client");
4
5
  let __intlayer_config_built = require("@intlayer/config/built");
5
6
  __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
6
7
 
@@ -13,9 +14,17 @@ __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_bui
13
14
  */
14
15
  const getContent = (node, nodeProps, locale) => {
15
16
  const defaultLocale = __intlayer_config_built.default?.internationalization?.defaultLocale;
17
+ const importMode = __intlayer_config_built.default?.build?.importMode;
16
18
  const plugins = [
17
19
  require_interpreter_getContent_plugins.insertionPlugin,
18
- require_interpreter_getContent_plugins.translationPlugin(locale ?? defaultLocale, defaultLocale),
20
+ require_interpreter_getContent_plugins.translationPlugin(locale ?? defaultLocale, defaultLocale, (locale$1, fallback, keyPath) => {
21
+ const logger = (0, __intlayer_config_client.getAppLogger)();
22
+ if (process.env.NODE_ENV === "development" && importMode === "dynamic") logger([
23
+ `The locale ${locale$1} is not found, using fallback ${fallback}. Key path: ${keyPath.join(".")}.`,
24
+ `In dynamic mode, intlayer will not load the fallback content in production, it will throw an error, or lead to undefined content.`,
25
+ "You can detect missing content using the `npx intlayer test` command"
26
+ ], { level: "error" });
27
+ }),
19
28
  require_interpreter_getContent_plugins.enumerationPlugin,
20
29
  require_interpreter_getContent_plugins.conditionPlugin,
21
30
  require_interpreter_getContent_plugins.nestedPlugin,
@@ -1 +1 @@
1
- {"version":3,"file":"getContent.cjs","names":["configuration","plugins: Plugins[]","insertionPlugin","translationPlugin","enumerationPlugin","conditionPlugin","nestedPlugin","filePlugin","deepTransformNode"],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type {\n ContentNode,\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n translationPlugin,\n} from './plugins';\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n T extends ContentNode,\n L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n locale?: L\n) => {\n const defaultLocale = configuration?.internationalization?.defaultLocale;\n\n const plugins: Plugins[] = [\n insertionPlugin,\n translationPlugin(locale ?? defaultLocale, defaultLocale),\n enumerationPlugin,\n conditionPlugin,\n nestedPlugin,\n filePlugin,\n ...(nodeProps.plugins ?? []),\n ];\n\n return deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n};\n"],"mappings":";;;;;;;;;;;;;AA0BA,MAAa,cAIX,MACA,WACA,WACG;CACH,MAAM,gBAAgBA,iCAAe,sBAAsB;CAE3D,MAAMC,UAAqB;EACzBC;EACAC,yDAAkB,UAAU,eAAe,cAAc;EACzDC;EACAC;EACAC;EACAC;EACA,GAAI,UAAU,WAAW,EAAE;EAC5B;AAED,QAAOC,+DAAkB,MAAM;EAC7B,GAAG;EACH;EACD,CAAC"}
1
+ {"version":3,"file":"getContent.cjs","names":["configuration","plugins: Plugins[]","insertionPlugin","translationPlugin","locale","enumerationPlugin","conditionPlugin","nestedPlugin","filePlugin","deepTransformNode"],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/client';\nimport type {\n ContentNode,\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n translationPlugin,\n} from './plugins';\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n T extends ContentNode,\n L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n locale?: L\n) => {\n const defaultLocale = configuration?.internationalization?.defaultLocale;\n const importMode = configuration?.build?.importMode;\n\n const plugins: Plugins[] = [\n insertionPlugin,\n translationPlugin(\n locale ?? defaultLocale,\n defaultLocale,\n (locale, fallback, keyPath) => {\n const logger = getAppLogger();\n if (\n process.env.NODE_ENV === 'development' &&\n importMode === 'dynamic'\n ) {\n logger(\n [\n `The locale ${locale} is not found, using fallback ${fallback}. Key path: ${keyPath.join('.')}.`,\n `In dynamic mode, intlayer will not load the fallback content in production, it will throw an error, or lead to undefined content.`,\n 'You can detect missing content using the `npx intlayer test` command',\n ],\n { level: 'error' }\n );\n }\n }\n ),\n enumerationPlugin,\n conditionPlugin,\n nestedPlugin,\n filePlugin,\n ...(nodeProps.plugins ?? []),\n ];\n\n return deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n};\n"],"mappings":";;;;;;;;;;;;;;AA2BA,MAAa,cAIX,MACA,WACA,WACG;CACH,MAAM,gBAAgBA,iCAAe,sBAAsB;CAC3D,MAAM,aAAaA,iCAAe,OAAO;CAEzC,MAAMC,UAAqB;EACzBC;EACAC,yDACE,UAAU,eACV,gBACC,UAAQ,UAAU,YAAY;GAC7B,MAAM,qDAAuB;AAC7B,OACE,QAAQ,IAAI,aAAa,iBACzB,eAAe,UAEf,QACE;IACE,cAAcC,SAAO,gCAAgC,SAAS,cAAc,QAAQ,KAAK,IAAI,CAAC;IAC9F;IACA;IACD,EACD,EAAE,OAAO,SAAS,CACnB;IAGN;EACDC;EACAC;EACAC;EACAC;EACA,GAAI,UAAU,WAAW,EAAE;EAC5B;AAED,QAAOC,+DAAkB,MAAM;EAC7B,GAAG;EACH;EACD,CAAC"}
@@ -9,7 +9,7 @@ let __intlayer_types = require("@intlayer/types");
9
9
 
10
10
  //#region src/interpreter/getContent/plugins.ts
11
11
  /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
12
- const translationPlugin = (locale, fallback) => ({
12
+ const translationPlugin = (locale, fallback, onContentNotFound) => ({
13
13
  id: "translation-plugin",
14
14
  canHandle: (node) => typeof node === "object" && node?.nodeType === __intlayer_types.NodeType.Translation,
15
15
  transform: (node, props, deepTransformNode) => {
@@ -25,7 +25,9 @@ const translationPlugin = (locale, fallback) => ({
25
25
  };
26
26
  result[key] = deepTransformNode(result[key], childProps);
27
27
  }
28
- return require_interpreter_getTranslation.getTranslation(result, locale, fallback);
28
+ return require_interpreter_getTranslation.getTranslation(result, locale, fallback, (locale$1, fallback$1) => {
29
+ onContentNotFound?.(locale$1, fallback$1, props.keyPath);
30
+ });
29
31
  }
30
32
  });
31
33
  /** Enumeration plugin. Replaces node with a function that takes quantity => string. */
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.cjs","names":["NodeType","getTranslation","enumerationPlugin: Plugins","getEnumeration","conditionPlugin: Plugins","getCondition","genderPlugin: Plugins","getGender","insertionPlugin: Plugins","newKeyPath: KeyPath[]","insertionStringPlugin: Plugins","node","deepTransformNode","children","getInsertion","nestedPlugin: Plugins","getNesting","filePlugin: Plugins"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import {\n type DeclaredLocales,\n type DictionaryKeys,\n type KeyPath,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getTranslation } from '../getTranslation';\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeType.Translation]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? L extends keyof U\n ? DeepTransformContent<U[L], S>\n : DeepTransformContent<U[keyof U], S>\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins => ({\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Translation]);\n\n for (const key in result) {\n const childProps = {\n ...props,\n children: result[key as keyof typeof result],\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Translation, key } as KeyPath,\n ],\n };\n result[key as keyof typeof result] = deepTransformNode(\n result[key as keyof typeof result],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback);\n },\n});\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Enumeration]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[NodeType.Enumeration][keyof T[NodeType.Enumeration]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins = {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Enumeration,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Enumeration]);\n\n for (const key in result) {\n const child = result[key as unknown as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Enumeration, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (quantity: number) => getEnumeration(result, quantity);\n },\n};\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Condition]: object;\n}\n ? (\n value: boolean\n ) => DeepTransformContent<\n T[NodeType.Condition][keyof T[NodeType.Condition]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins = {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Condition,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Condition]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Condition, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: boolean) => getCondition(result, value);\n },\n};\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Gender]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<T[NodeType.Gender][keyof T[NodeType.Gender]], S>\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins = {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Gender,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Gender]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [...props.keyPath, { type: NodeType.Gender, key } as KeyPath],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: Gender) => getGender(result, value);\n },\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: infer I;\n fields?: infer U;\n}\n ? U extends readonly string[]\n ? (data: Record<U[number], string | number>) => DeepTransformContent<I, S>\n : (data: Record<string, string | number>) => DeepTransformContent<I, S>\n : never;\n\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Nested]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin: Plugins = {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Nested,\n transform: (node: NestedContent, props) =>\n getNesting(node.nested.dictionaryKey, node.nested.path, props),\n};\n\n// /** ---------------------------------------------\n// * FILE PLUGIN\n// * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.File]: string;\n content?: string;\n}\n ? string\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins = {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.File,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n};\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n // file: FileCond<T>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n condition: true;\n insertion: true;\n nested: true;\n // file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<\n T,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> = IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin’s transformation.\n IInterpreterPlugin<T, S, L>[keyof IInterpreterPlugin<T, S, L>];\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugins.cjs","names":["NodeType","getTranslation","locale","fallback","enumerationPlugin: Plugins","getEnumeration","conditionPlugin: Plugins","getCondition","genderPlugin: Plugins","getGender","insertionPlugin: Plugins","newKeyPath: KeyPath[]","insertionStringPlugin: Plugins","node","deepTransformNode","children","getInsertion","nestedPlugin: Plugins","getNesting","filePlugin: Plugins"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import {\n type DeclaredLocales,\n type DictionaryKeys,\n type KeyPath,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getTranslation } from '../getTranslation';\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeType.Translation]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? L extends keyof U\n ? DeepTransformContent<U[L], S>\n : DeepTransformContent<U[keyof U], S>\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues,\n onContentNotFound?: (\n locale: LocalesValues,\n fallback: LocalesValues,\n keyPath: KeyPath[]\n ) => void\n): Plugins => ({\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Translation]);\n\n for (const key in result) {\n const childProps = {\n ...props,\n children: result[key as keyof typeof result],\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Translation, key } as KeyPath,\n ],\n };\n result[key as keyof typeof result] = deepTransformNode(\n result[key as keyof typeof result],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback, (locale, fallback) => {\n onContentNotFound?.(locale, fallback, props.keyPath);\n });\n },\n});\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Enumeration]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[NodeType.Enumeration][keyof T[NodeType.Enumeration]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins = {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Enumeration,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Enumeration]);\n\n for (const key in result) {\n const child = result[key as unknown as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Enumeration, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (quantity: number) => getEnumeration(result, quantity);\n },\n};\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Condition]: object;\n}\n ? (\n value: boolean\n ) => DeepTransformContent<\n T[NodeType.Condition][keyof T[NodeType.Condition]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins = {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Condition,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Condition]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Condition, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: boolean) => getCondition(result, value);\n },\n};\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Gender]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<T[NodeType.Gender][keyof T[NodeType.Gender]], S>\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins = {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Gender,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Gender]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [...props.keyPath, { type: NodeType.Gender, key } as KeyPath],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: Gender) => getGender(result, value);\n },\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: infer I;\n fields?: infer U;\n}\n ? U extends readonly string[]\n ? (data: Record<U[number], string | number>) => DeepTransformContent<I, S>\n : (data: Record<string, string | number>) => DeepTransformContent<I, S>\n : never;\n\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Nested]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin: Plugins = {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Nested,\n transform: (node: NestedContent, props) =>\n getNesting(node.nested.dictionaryKey, node.nested.path, props),\n};\n\n// /** ---------------------------------------------\n// * FILE PLUGIN\n// * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.File]: string;\n content?: string;\n}\n ? string\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins = {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.File,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n};\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n // file: FileCond<T>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n condition: true;\n insertion: true;\n nested: true;\n // file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<\n T,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> = IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin’s transformation.\n IInterpreterPlugin<T, S, L>[keyof IInterpreterPlugin<T, S, L>];\n"],"mappings":"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"}
@@ -1,6 +1,40 @@
1
1
 
2
2
  //#region src/interpreter/getTranslation.ts
3
3
  /**
4
+ * Deep merge two values, replacing undefined values in target with values from source.
5
+ * Handles objects, arrays, and primitive values.
6
+ */
7
+ const deepMergeWithFallback = (target, fallback) => {
8
+ if (target === void 0) return fallback;
9
+ if (fallback === void 0 || target === null || typeof target !== "object") return target;
10
+ if (Array.isArray(target)) {
11
+ if (!Array.isArray(fallback)) return target;
12
+ return target.map((item, index) => deepMergeWithFallback(item, fallback[index]));
13
+ }
14
+ if (typeof fallback !== "object" || fallback === null) return target;
15
+ const result = { ...target };
16
+ const fallbackObj = fallback;
17
+ const allKeys = new Set([...Object.keys(result), ...Object.keys(fallbackObj)]);
18
+ for (const key of allKeys) result[key] = deepMergeWithFallback(result[key], fallbackObj[key]);
19
+ return result;
20
+ };
21
+ /**
22
+ * Try to get content from languageContent using locale resolution:
23
+ * 1. Exact match
24
+ * 2. Language subtag match (e.g., 'en-GB' -> 'en')
25
+ *
26
+ * @returns The content if found, undefined otherwise
27
+ */
28
+ const resolveLocaleContent = (languageContent, locale) => {
29
+ const exactResult = languageContent[locale];
30
+ if (exactResult !== void 0) return exactResult;
31
+ const [languageSubtag] = locale.split("-");
32
+ if (languageSubtag !== locale) {
33
+ const subtagResult = languageContent[languageSubtag];
34
+ if (subtagResult !== void 0) return subtagResult;
35
+ }
36
+ };
37
+ /**
4
38
  *
5
39
  * Allow to pick a content based on a locale.
6
40
  * If not locale found, it will return the content related to the default locale.
@@ -21,9 +55,14 @@
21
55
  * - this function will require each locale to be defined if defined in the project configuration.
22
56
  * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
23
57
  */
24
- const getTranslation = (languageContent, locale, fallback) => {
25
- let result = languageContent[locale];
26
- if (fallback && !result) result = languageContent[fallback];
58
+ const getTranslation = (languageContent, locale, fallback, onContentNotFound) => {
59
+ const result = resolveLocaleContent(languageContent, locale);
60
+ const fallbackResult = fallback ? resolveLocaleContent(languageContent, fallback) : void 0;
61
+ if (result === void 0) {
62
+ if (fallback) onContentNotFound?.(locale, fallback);
63
+ return fallbackResult;
64
+ }
65
+ if (fallbackResult !== void 0) return deepMergeWithFallback(result, fallbackResult);
27
66
  return result;
28
67
  };
29
68
 
@@ -1 +1 @@
1
- {"version":3,"file":"getTranslation.cjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\n\n/**\n *\n * Allow to pick a content based on a locale.\n * If not locale found, it will return the content related to the default locale.\n *\n * Return either the content editor, or the content itself depending on the configuration.\n *\n * Usage:\n *\n * ```ts\n * const content = getTranslation<string>({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n *\n * Using TypeScript:\n * - this function will require each locale to be defined if defined in the project configuration.\n * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.\n */\nexport const getTranslation = <Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues\n): Content => {\n let result = languageContent[locale as keyof typeof languageContent];\n\n if (fallback && !result) {\n result = languageContent[fallback as keyof typeof languageContent];\n }\n\n return result as unknown as Content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,kBACX,iBACA,QACA,aACY;CACZ,IAAI,SAAS,gBAAgB;AAE7B,KAAI,YAAY,CAAC,OACf,UAAS,gBAAgB;AAG3B,QAAO"}
1
+ {"version":3,"file":"getTranslation.cjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\n\n/**\n * Deep merge two values, replacing undefined values in target with values from source.\n * Handles objects, arrays, and primitive values.\n */\nconst deepMergeWithFallback = <T>(target: T, fallback: T): T => {\n // If target is undefined, use fallback\n if (target === undefined) {\n return fallback;\n }\n\n // If fallback is undefined or target is not an object, return target as-is\n if (fallback === undefined || target === null || typeof target !== 'object') {\n return target;\n }\n\n // Handle arrays - merge element by element\n if (Array.isArray(target)) {\n if (!Array.isArray(fallback)) {\n return target;\n }\n return target.map((item, index) =>\n deepMergeWithFallback(item, fallback[index])\n ) as T;\n }\n\n // Handle objects - merge property by property\n if (typeof fallback !== 'object' || fallback === null) {\n return target;\n }\n\n const result = { ...target } as Record<string, unknown>;\n const fallbackObj = fallback as Record<string, unknown>;\n\n // Merge all keys from both target and fallback\n const allKeys = new Set([\n ...Object.keys(result),\n ...Object.keys(fallbackObj),\n ]);\n\n for (const key of allKeys) {\n result[key] = deepMergeWithFallback(\n result[key] as unknown,\n fallbackObj[key] as unknown\n );\n }\n\n return result as T;\n};\n\n/**\n * Try to get content from languageContent using locale resolution:\n * 1. Exact match\n * 2. Language subtag match (e.g., 'en-GB' -> 'en')\n *\n * @returns The content if found, undefined otherwise\n */\nconst resolveLocaleContent = <Content>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues\n): Content | undefined => {\n // 1. Try exact match\n const exactResult = languageContent[locale as keyof typeof languageContent];\n if (exactResult !== undefined) {\n return exactResult;\n }\n\n // 2. Try language subtag match (e.g., 'en-GB' -> 'en')\n const [languageSubtag] = locale.split('-');\n if (languageSubtag !== locale) {\n const subtagResult =\n languageContent[languageSubtag as keyof typeof languageContent];\n if (subtagResult !== undefined) {\n return subtagResult;\n }\n }\n\n return undefined;\n};\n\n/**\n *\n * Allow to pick a content based on a locale.\n * If not locale found, it will return the content related to the default locale.\n *\n * Return either the content editor, or the content itself depending on the configuration.\n *\n * Usage:\n *\n * ```ts\n * const content = getTranslation<string>({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n *\n * Using TypeScript:\n * - this function will require each locale to be defined if defined in the project configuration.\n * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.\n */\nexport const getTranslation = <Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues,\n onContentNotFound?: (locale: LocalesValues, fallback: LocalesValues) => void\n): Content => {\n // Try to resolve locale with subtag matching\n const result = resolveLocaleContent(languageContent, locale);\n\n // Get fallback content if provided\n const fallbackResult = fallback\n ? resolveLocaleContent(languageContent, fallback)\n : undefined;\n\n // If result is undefined, use fallback\n if (result === undefined) {\n if (fallback) {\n onContentNotFound?.(locale, fallback);\n }\n return fallbackResult as Content;\n }\n\n // If we have both result and fallback, deep merge to fill undefined values\n if (fallbackResult !== undefined) {\n return deepMergeWithFallback(result, fallbackResult);\n }\n\n return result as Content;\n};\n"],"mappings":";;;;;;AAMA,MAAM,yBAA4B,QAAW,aAAmB;AAE9D,KAAI,WAAW,OACb,QAAO;AAIT,KAAI,aAAa,UAAa,WAAW,QAAQ,OAAO,WAAW,SACjE,QAAO;AAIT,KAAI,MAAM,QAAQ,OAAO,EAAE;AACzB,MAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,QAAO;AAET,SAAO,OAAO,KAAK,MAAM,UACvB,sBAAsB,MAAM,SAAS,OAAO,CAC7C;;AAIH,KAAI,OAAO,aAAa,YAAY,aAAa,KAC/C,QAAO;CAGT,MAAM,SAAS,EAAE,GAAG,QAAQ;CAC5B,MAAM,cAAc;CAGpB,MAAM,UAAU,IAAI,IAAI,CACtB,GAAG,OAAO,KAAK,OAAO,EACtB,GAAG,OAAO,KAAK,YAAY,CAC5B,CAAC;AAEF,MAAK,MAAM,OAAO,QAChB,QAAO,OAAO,sBACZ,OAAO,MACP,YAAY,KACb;AAGH,QAAO;;;;;;;;;AAUT,MAAM,wBACJ,iBACA,WACwB;CAExB,MAAM,cAAc,gBAAgB;AACpC,KAAI,gBAAgB,OAClB,QAAO;CAIT,MAAM,CAAC,kBAAkB,OAAO,MAAM,IAAI;AAC1C,KAAI,mBAAmB,QAAQ;EAC7B,MAAM,eACJ,gBAAgB;AAClB,MAAI,iBAAiB,OACnB,QAAO;;;;;;;;;;;;;;;;;;;;;;;;AA4Bb,MAAa,kBACX,iBACA,QACA,UACA,sBACY;CAEZ,MAAM,SAAS,qBAAqB,iBAAiB,OAAO;CAG5D,MAAM,iBAAiB,WACnB,qBAAqB,iBAAiB,SAAS,GAC/C;AAGJ,KAAI,WAAW,QAAW;AACxB,MAAI,SACF,qBAAoB,QAAQ,SAAS;AAEvC,SAAO;;AAIT,KAAI,mBAAmB,OACrB,QAAO,sBAAsB,QAAQ,eAAe;AAGtD,QAAO"}
@@ -5,6 +5,7 @@ import configuration from "@intlayer/config/built";
5
5
  //#region src/deepTransformPlugins/getMissingLocalesContent.ts
6
6
  const getDeepKeyPaths = (obj, prefix = []) => {
7
7
  if (typeof obj !== "object" || obj === null) return [];
8
+ if (Array.isArray(obj)) return [];
8
9
  return Object.keys(obj).flatMap((key) => {
9
10
  const newPath = [...prefix, key];
10
11
  return [newPath, ...getDeepKeyPaths(obj[key], newPath)];
@@ -1 +1 @@
1
- {"version":3,"file":"getMissingLocalesContent.mjs","names":["plugins: Plugins[]"],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n type ContentNode,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type { DeepTransformContent, NodeProps, Plugins } from '../interpreter';\nimport { deepTransformNode } from '../interpreter/getContent/deepTransform';\nimport type { TranslationContent } from '../transpiler';\n\nconst getDeepKeyPaths = (obj: any, prefix: string[] = []): string[][] => {\n if (typeof obj !== 'object' || obj === null) {\n return [];\n }\n\n return Object.keys(obj).flatMap((key) => {\n const newPath = [...prefix, key];\n return [newPath, ...getDeepKeyPaths(obj[key], newPath)];\n });\n};\n\nconst hasDeepKeyPath = (obj: any, keyPath: string[]): boolean => {\n let current = obj;\n for (const key of keyPath) {\n if (\n current === undefined ||\n current === null ||\n typeof current !== 'object'\n ) {\n return false;\n }\n if (!(key in current)) {\n return false;\n }\n current = current[key];\n }\n\n return true;\n};\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const checkMissingLocalesPlugin = (\n locales: Locale[],\n onMissingLocale: (locale: Locale) => void\n): Plugins => ({\n id: 'check-missing-locales-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const translations = node[NodeType.Translation] as Record<string, any>;\n const allKeys = new Set<string>();\n\n for (const locale of locales) {\n if (translations[locale]) {\n getDeepKeyPaths(translations[locale]).forEach((path) => {\n allKeys.add(JSON.stringify(path));\n });\n }\n }\n\n for (const locale of locales) {\n if (!translations[locale]) {\n onMissingLocale(locale);\n continue;\n }\n\n for (const pathStr of allKeys) {\n const path = JSON.parse(pathStr);\n if (!hasDeepKeyPath(translations[locale], path)) {\n onMissingLocale(locale);\n break;\n }\n }\n }\n\n // Continue traversal inside the translation values, but avoid re-applying this plugin on the same node\n for (const key in translations) {\n const child = translations[key];\n deepTransformNode(child, {\n ...props,\n children: child,\n });\n }\n\n // Return the original node; the return value is ignored by the caller\n return node;\n },\n});\n\n/**\n * Return the content of a node with only the translation plugin.\n *\n * @param node The node to transform.\n * @param locales The locales to check for missing translations.\n */\nexport const getMissingLocalesContent = <T extends ContentNode>(\n node: T,\n locales: LocalesValues[] = configuration?.internationalization?.locales,\n nodeProps: NodeProps\n): Locale[] => {\n const missingLocales = new Set<Locale>();\n\n const plugins: Plugins[] = [\n checkMissingLocalesPlugin(locales as Locale[], (locale) =>\n missingLocales.add(locale)\n ),\n ...(nodeProps.plugins ?? []),\n ];\n\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T>;\n\n return Array.from(missingLocales);\n};\n\nexport const getMissingLocalesContentFromDictionary = (\n dictionary: Dictionary,\n locales: LocalesValues[] = configuration?.internationalization?.locales\n) =>\n getMissingLocalesContent(dictionary.content, locales, {\n dictionaryKey: dictionary.key,\n keyPath: [],\n });\n"],"mappings":";;;;;AAYA,MAAM,mBAAmB,KAAU,SAAmB,EAAE,KAAiB;AACvE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,QAAO,EAAE;AAGX,QAAO,OAAO,KAAK,IAAI,CAAC,SAAS,QAAQ;EACvC,MAAM,UAAU,CAAC,GAAG,QAAQ,IAAI;AAChC,SAAO,CAAC,SAAS,GAAG,gBAAgB,IAAI,MAAM,QAAQ,CAAC;GACvD;;AAGJ,MAAM,kBAAkB,KAAU,YAA+B;CAC/D,IAAI,UAAU;AACd,MAAK,MAAM,OAAO,SAAS;AACzB,MACE,YAAY,UACZ,YAAY,QACZ,OAAO,YAAY,SAEnB,QAAO;AAET,MAAI,EAAE,OAAO,SACX,QAAO;AAET,YAAU,QAAQ;;AAGpB,QAAO;;;AAIT,MAAa,6BACX,SACA,qBACa;CACb,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAA0B,OAAO,wBAAsB;EACjE,MAAM,eAAe,KAAK,SAAS;EACnC,MAAM,0BAAU,IAAI,KAAa;AAEjC,OAAK,MAAM,UAAU,QACnB,KAAI,aAAa,QACf,iBAAgB,aAAa,QAAQ,CAAC,SAAS,SAAS;AACtD,WAAQ,IAAI,KAAK,UAAU,KAAK,CAAC;IACjC;AAIN,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,CAAC,aAAa,SAAS;AACzB,oBAAgB,OAAO;AACvB;;AAGF,QAAK,MAAM,WAAW,SAAS;IAC7B,MAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,CAAC,eAAe,aAAa,SAAS,KAAK,EAAE;AAC/C,qBAAgB,OAAO;AACvB;;;;AAMN,OAAK,MAAM,OAAO,cAAc;GAC9B,MAAM,QAAQ,aAAa;AAC3B,uBAAkB,OAAO;IACvB,GAAG;IACH,UAAU;IACX,CAAC;;AAIJ,SAAO;;CAEV;;;;;;;AAQD,MAAa,4BACX,MACA,UAA2B,eAAe,sBAAsB,SAChE,cACa;CACb,MAAM,iCAAiB,IAAI,KAAa;CAExC,MAAMA,UAAqB,CACzB,0BAA0B,UAAsB,WAC9C,eAAe,IAAI,OAAO,CAC3B,EACD,GAAI,UAAU,WAAW,EAAE,CAC5B;AAED,mBAAkB,MAAM;EACtB,GAAG;EACH;EACD,CAAC;AAEF,QAAO,MAAM,KAAK,eAAe;;AAGnC,MAAa,0CACX,YACA,UAA2B,eAAe,sBAAsB,YAEhE,yBAAyB,WAAW,SAAS,SAAS;CACpD,eAAe,WAAW;CAC1B,SAAS,EAAE;CACZ,CAAC"}
1
+ {"version":3,"file":"getMissingLocalesContent.mjs","names":["plugins: Plugins[]"],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n type ContentNode,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type { DeepTransformContent, NodeProps, Plugins } from '../interpreter';\nimport { deepTransformNode } from '../interpreter/getContent/deepTransform';\nimport type { TranslationContent } from '../transpiler';\n\nconst getDeepKeyPaths = (obj: any, prefix: string[] = []): string[][] => {\n if (typeof obj !== 'object' || obj === null) {\n return [];\n }\n\n // Skip array indices - arrays of different lengths shouldn't trigger missing translations\n // Each locale can have arrays with different numbers of elements (e.g., keywords)\n if (Array.isArray(obj)) {\n return [];\n }\n\n return Object.keys(obj).flatMap((key) => {\n const newPath = [...prefix, key];\n return [newPath, ...getDeepKeyPaths(obj[key], newPath)];\n });\n};\n\nconst hasDeepKeyPath = (obj: any, keyPath: string[]): boolean => {\n let current = obj;\n for (const key of keyPath) {\n if (\n current === undefined ||\n current === null ||\n typeof current !== 'object'\n ) {\n return false;\n }\n if (!(key in current)) {\n return false;\n }\n current = current[key];\n }\n\n return true;\n};\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const checkMissingLocalesPlugin = (\n locales: Locale[],\n onMissingLocale: (locale: Locale) => void\n): Plugins => ({\n id: 'check-missing-locales-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const translations = node[NodeType.Translation] as Record<string, any>;\n const allKeys = new Set<string>();\n\n for (const locale of locales) {\n if (translations[locale]) {\n getDeepKeyPaths(translations[locale]).forEach((path) => {\n allKeys.add(JSON.stringify(path));\n });\n }\n }\n\n for (const locale of locales) {\n if (!translations[locale]) {\n onMissingLocale(locale);\n continue;\n }\n\n for (const pathStr of allKeys) {\n const path = JSON.parse(pathStr);\n if (!hasDeepKeyPath(translations[locale], path)) {\n onMissingLocale(locale);\n break;\n }\n }\n }\n\n // Continue traversal inside the translation values, but avoid re-applying this plugin on the same node\n for (const key in translations) {\n const child = translations[key];\n deepTransformNode(child, {\n ...props,\n children: child,\n });\n }\n\n // Return the original node; the return value is ignored by the caller\n return node;\n },\n});\n\n/**\n * Return the content of a node with only the translation plugin.\n *\n * @param node The node to transform.\n * @param locales The locales to check for missing translations.\n */\nexport const getMissingLocalesContent = <T extends ContentNode>(\n node: T,\n locales: LocalesValues[] = configuration?.internationalization?.locales,\n nodeProps: NodeProps\n): Locale[] => {\n const missingLocales = new Set<Locale>();\n\n const plugins: Plugins[] = [\n checkMissingLocalesPlugin(locales as Locale[], (locale) =>\n missingLocales.add(locale)\n ),\n ...(nodeProps.plugins ?? []),\n ];\n\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T>;\n\n return Array.from(missingLocales);\n};\n\nexport const getMissingLocalesContentFromDictionary = (\n dictionary: Dictionary,\n locales: LocalesValues[] = configuration?.internationalization?.locales\n) =>\n getMissingLocalesContent(dictionary.content, locales, {\n dictionaryKey: dictionary.key,\n keyPath: [],\n });\n"],"mappings":";;;;;AAYA,MAAM,mBAAmB,KAAU,SAAmB,EAAE,KAAiB;AACvE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KACrC,QAAO,EAAE;AAKX,KAAI,MAAM,QAAQ,IAAI,CACpB,QAAO,EAAE;AAGX,QAAO,OAAO,KAAK,IAAI,CAAC,SAAS,QAAQ;EACvC,MAAM,UAAU,CAAC,GAAG,QAAQ,IAAI;AAChC,SAAO,CAAC,SAAS,GAAG,gBAAgB,IAAI,MAAM,QAAQ,CAAC;GACvD;;AAGJ,MAAM,kBAAkB,KAAU,YAA+B;CAC/D,IAAI,UAAU;AACd,MAAK,MAAM,OAAO,SAAS;AACzB,MACE,YAAY,UACZ,YAAY,QACZ,OAAO,YAAY,SAEnB,QAAO;AAET,MAAI,EAAE,OAAO,SACX,QAAO;AAET,YAAU,QAAQ;;AAGpB,QAAO;;;AAIT,MAAa,6BACX,SACA,qBACa;CACb,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAA0B,OAAO,wBAAsB;EACjE,MAAM,eAAe,KAAK,SAAS;EACnC,MAAM,0BAAU,IAAI,KAAa;AAEjC,OAAK,MAAM,UAAU,QACnB,KAAI,aAAa,QACf,iBAAgB,aAAa,QAAQ,CAAC,SAAS,SAAS;AACtD,WAAQ,IAAI,KAAK,UAAU,KAAK,CAAC;IACjC;AAIN,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,CAAC,aAAa,SAAS;AACzB,oBAAgB,OAAO;AACvB;;AAGF,QAAK,MAAM,WAAW,SAAS;IAC7B,MAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,QAAI,CAAC,eAAe,aAAa,SAAS,KAAK,EAAE;AAC/C,qBAAgB,OAAO;AACvB;;;;AAMN,OAAK,MAAM,OAAO,cAAc;GAC9B,MAAM,QAAQ,aAAa;AAC3B,uBAAkB,OAAO;IACvB,GAAG;IACH,UAAU;IACX,CAAC;;AAIJ,SAAO;;CAEV;;;;;;;AAQD,MAAa,4BACX,MACA,UAA2B,eAAe,sBAAsB,SAChE,cACa;CACb,MAAM,iCAAiB,IAAI,KAAa;CAExC,MAAMA,UAAqB,CACzB,0BAA0B,UAAsB,WAC9C,eAAe,IAAI,OAAO,CAC3B,EACD,GAAI,UAAU,WAAW,EAAE,CAC5B;AAED,mBAAkB,MAAM;EACtB,GAAG;EACH;EACD,CAAC;AAEF,QAAO,MAAM,KAAK,eAAe;;AAGnC,MAAa,0CACX,YACA,UAA2B,eAAe,sBAAsB,YAEhE,yBAAyB,WAAW,SAAS,SAAS;CACpD,eAAe,WAAW;CAC1B,SAAS,EAAE;CACZ,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { deepTransformNode } from "./deepTransform.mjs";
2
2
  import { conditionPlugin, enumerationPlugin, filePlugin, insertionPlugin, nestedPlugin, translationPlugin } from "./plugins.mjs";
3
+ import { getAppLogger } from "@intlayer/config/client";
3
4
  import configuration from "@intlayer/config/built";
4
5
 
5
6
  //#region src/interpreter/getContent/getContent.ts
@@ -11,9 +12,17 @@ import configuration from "@intlayer/config/built";
11
12
  */
12
13
  const getContent = (node, nodeProps, locale) => {
13
14
  const defaultLocale = configuration?.internationalization?.defaultLocale;
15
+ const importMode = configuration?.build?.importMode;
14
16
  const plugins = [
15
17
  insertionPlugin,
16
- translationPlugin(locale ?? defaultLocale, defaultLocale),
18
+ translationPlugin(locale ?? defaultLocale, defaultLocale, (locale$1, fallback, keyPath) => {
19
+ const logger = getAppLogger();
20
+ if (importMode === "dynamic") logger([
21
+ `The locale ${locale$1} is not found, using fallback ${fallback}. Key path: ${keyPath.join(".")}.`,
22
+ `In dynamic mode, intlayer will not load the fallback content in production, it will throw an error, or lead to undefined content.`,
23
+ "You can detect missing content using the `npx intlayer test` command"
24
+ ], { level: "error" });
25
+ }),
17
26
  enumerationPlugin,
18
27
  conditionPlugin,
19
28
  nestedPlugin,
@@ -1 +1 @@
1
- {"version":3,"file":"getContent.mjs","names":["plugins: Plugins[]"],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type {\n ContentNode,\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n translationPlugin,\n} from './plugins';\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n T extends ContentNode,\n L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n locale?: L\n) => {\n const defaultLocale = configuration?.internationalization?.defaultLocale;\n\n const plugins: Plugins[] = [\n insertionPlugin,\n translationPlugin(locale ?? defaultLocale, defaultLocale),\n enumerationPlugin,\n conditionPlugin,\n nestedPlugin,\n filePlugin,\n ...(nodeProps.plugins ?? []),\n ];\n\n return deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n};\n"],"mappings":";;;;;;;;;;;AA0BA,MAAa,cAIX,MACA,WACA,WACG;CACH,MAAM,gBAAgB,eAAe,sBAAsB;CAE3D,MAAMA,UAAqB;EACzB;EACA,kBAAkB,UAAU,eAAe,cAAc;EACzD;EACA;EACA;EACA;EACA,GAAI,UAAU,WAAW,EAAE;EAC5B;AAED,QAAO,kBAAkB,MAAM;EAC7B,GAAG;EACH;EACD,CAAC"}
1
+ {"version":3,"file":"getContent.mjs","names":["plugins: Plugins[]","locale"],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/client';\nimport type {\n ContentNode,\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types';\nimport { deepTransformNode } from './deepTransform';\nimport {\n conditionPlugin,\n type DeepTransformContent,\n enumerationPlugin,\n filePlugin,\n type IInterpreterPluginState,\n insertionPlugin,\n type NodeProps,\n nestedPlugin,\n type Plugins,\n translationPlugin,\n} from './plugins';\n\n/**\n * Transforms a node in a single pass, applying each plugin as needed.\n *\n * @param node The node to transform.\n * @param locale The locale to use if your transformers need it (e.g. for translations).\n */\nexport const getContent = <\n T extends ContentNode,\n L extends LocalesValues = DeclaredLocales,\n>(\n node: T,\n nodeProps: NodeProps,\n locale?: L\n) => {\n const defaultLocale = configuration?.internationalization?.defaultLocale;\n const importMode = configuration?.build?.importMode;\n\n const plugins: Plugins[] = [\n insertionPlugin,\n translationPlugin(\n locale ?? defaultLocale,\n defaultLocale,\n (locale, fallback, keyPath) => {\n const logger = getAppLogger();\n if (\n process.env.NODE_ENV === 'development' &&\n importMode === 'dynamic'\n ) {\n logger(\n [\n `The locale ${locale} is not found, using fallback ${fallback}. Key path: ${keyPath.join('.')}.`,\n `In dynamic mode, intlayer will not load the fallback content in production, it will throw an error, or lead to undefined content.`,\n 'You can detect missing content using the `npx intlayer test` command',\n ],\n { level: 'error' }\n );\n }\n }\n ),\n enumerationPlugin,\n conditionPlugin,\n nestedPlugin,\n filePlugin,\n ...(nodeProps.plugins ?? []),\n ];\n\n return deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T, IInterpreterPluginState, L>;\n};\n"],"mappings":";;;;;;;;;;;;AA2BA,MAAa,cAIX,MACA,WACA,WACG;CACH,MAAM,gBAAgB,eAAe,sBAAsB;CAC3D,MAAM,aAAa,eAAe,OAAO;CAEzC,MAAMA,UAAqB;EACzB;EACA,kBACE,UAAU,eACV,gBACC,UAAQ,UAAU,YAAY;GAC7B,MAAM,SAAS,cAAc;AAC7B,OAEE,eAAe,UAEf,QACE;IACE,cAAcC,SAAO,gCAAgC,SAAS,cAAc,QAAQ,KAAK,IAAI,CAAC;IAC9F;IACA;IACD,EACD,EAAE,OAAO,SAAS,CACnB;IAGN;EACD;EACA;EACA;EACA;EACA,GAAI,UAAU,WAAW,EAAE;EAC5B;AAED,QAAO,kBAAkB,MAAM;EAC7B,GAAG;EACH;EACD,CAAC"}
@@ -8,7 +8,7 @@ import { NodeType } from "@intlayer/types";
8
8
 
9
9
  //#region src/interpreter/getContent/plugins.ts
10
10
  /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
11
- const translationPlugin = (locale, fallback) => ({
11
+ const translationPlugin = (locale, fallback, onContentNotFound) => ({
12
12
  id: "translation-plugin",
13
13
  canHandle: (node) => typeof node === "object" && node?.nodeType === NodeType.Translation,
14
14
  transform: (node, props, deepTransformNode) => {
@@ -24,7 +24,9 @@ const translationPlugin = (locale, fallback) => ({
24
24
  };
25
25
  result[key] = deepTransformNode(result[key], childProps);
26
26
  }
27
- return getTranslation(result, locale, fallback);
27
+ return getTranslation(result, locale, fallback, (locale$1, fallback$1) => {
28
+ onContentNotFound?.(locale$1, fallback$1, props.keyPath);
29
+ });
28
30
  }
29
31
  });
30
32
  /** Enumeration plugin. Replaces node with a function that takes quantity => string. */
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.mjs","names":["enumerationPlugin: Plugins","conditionPlugin: Plugins","genderPlugin: Plugins","insertionPlugin: Plugins","newKeyPath: KeyPath[]","insertionStringPlugin: Plugins","node","deepTransformNode","children","nestedPlugin: Plugins","filePlugin: Plugins"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import {\n type DeclaredLocales,\n type DictionaryKeys,\n type KeyPath,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getTranslation } from '../getTranslation';\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeType.Translation]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? L extends keyof U\n ? DeepTransformContent<U[L], S>\n : DeepTransformContent<U[keyof U], S>\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins => ({\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Translation]);\n\n for (const key in result) {\n const childProps = {\n ...props,\n children: result[key as keyof typeof result],\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Translation, key } as KeyPath,\n ],\n };\n result[key as keyof typeof result] = deepTransformNode(\n result[key as keyof typeof result],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback);\n },\n});\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Enumeration]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[NodeType.Enumeration][keyof T[NodeType.Enumeration]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins = {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Enumeration,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Enumeration]);\n\n for (const key in result) {\n const child = result[key as unknown as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Enumeration, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (quantity: number) => getEnumeration(result, quantity);\n },\n};\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Condition]: object;\n}\n ? (\n value: boolean\n ) => DeepTransformContent<\n T[NodeType.Condition][keyof T[NodeType.Condition]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins = {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Condition,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Condition]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Condition, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: boolean) => getCondition(result, value);\n },\n};\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Gender]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<T[NodeType.Gender][keyof T[NodeType.Gender]], S>\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins = {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Gender,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Gender]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [...props.keyPath, { type: NodeType.Gender, key } as KeyPath],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: Gender) => getGender(result, value);\n },\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: infer I;\n fields?: infer U;\n}\n ? U extends readonly string[]\n ? (data: Record<U[number], string | number>) => DeepTransformContent<I, S>\n : (data: Record<string, string | number>) => DeepTransformContent<I, S>\n : never;\n\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Nested]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin: Plugins = {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Nested,\n transform: (node: NestedContent, props) =>\n getNesting(node.nested.dictionaryKey, node.nested.path, props),\n};\n\n// /** ---------------------------------------------\n// * FILE PLUGIN\n// * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.File]: string;\n content?: string;\n}\n ? string\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins = {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.File,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n};\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n // file: FileCond<T>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n condition: true;\n insertion: true;\n nested: true;\n // file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<\n T,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> = IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin’s transformation.\n IInterpreterPlugin<T, S, L>[keyof IInterpreterPlugin<T, S, L>];\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugins.mjs","names":["locale","fallback","enumerationPlugin: Plugins","conditionPlugin: Plugins","genderPlugin: Plugins","insertionPlugin: Plugins","newKeyPath: KeyPath[]","insertionStringPlugin: Plugins","node","deepTransformNode","children","nestedPlugin: Plugins","filePlugin: Plugins"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import {\n type DeclaredLocales,\n type DictionaryKeys,\n type KeyPath,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type {\n ConditionContent,\n EnumerationContent,\n FileContent,\n Gender,\n GenderContent,\n InsertionContent,\n NestedContent,\n TranslationContent,\n} from '../../transpiler';\nimport { getCondition } from '../getCondition';\nimport { getEnumeration } from '../getEnumeration';\nimport { getGender } from '../getGender';\nimport { getInsertion } from '../getInsertion';\nimport { type GetNestingResult, getNesting } from '../getNesting';\nimport { getTranslation } from '../getTranslation';\n\n/** ---------------------------------------------\n * PLUGIN DEFINITION\n * --------------------------------------------- */\n\n/**\n * A plugin/transformer that can optionally transform a node during a single DFS pass.\n * - `canHandle` decides if the node is transformable by this plugin.\n * - `transform` returns the transformed node (and does not recurse further).\n *\n * > `transformFn` is a function that can be used to deeply transform inside the plugin.\n */\nexport type Plugins = {\n id: string;\n canHandle: (node: any) => boolean;\n transform: (\n node: any,\n props: NodeProps,\n transformFn: (node: any, props: NodeProps) => any\n ) => any;\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeType.Translation]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? L extends keyof U\n ? DeepTransformContent<U[L], S>\n : DeepTransformContent<U[keyof U], S>\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues,\n onContentNotFound?: (\n locale: LocalesValues,\n fallback: LocalesValues,\n keyPath: KeyPath[]\n ) => void\n): Plugins => ({\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Translation]);\n\n for (const key in result) {\n const childProps = {\n ...props,\n children: result[key as keyof typeof result],\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Translation, key } as KeyPath,\n ],\n };\n result[key as keyof typeof result] = deepTransformNode(\n result[key as keyof typeof result],\n childProps\n );\n }\n\n return getTranslation(result, locale, fallback, (locale, fallback) => {\n onContentNotFound?.(locale, fallback, props.keyPath);\n });\n },\n});\n\n/** ---------------------------------------------\n * ENUMERATION PLUGIN\n * --------------------------------------------- */\n\nexport type EnumerationCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Enumeration]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[NodeType.Enumeration][keyof T[NodeType.Enumeration]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins = {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Enumeration,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Enumeration]);\n\n for (const key in result) {\n const child = result[key as unknown as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Enumeration, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (quantity: number) => getEnumeration(result, quantity);\n },\n};\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Condition]: object;\n}\n ? (\n value: boolean\n ) => DeepTransformContent<\n T[NodeType.Condition][keyof T[NodeType.Condition]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins = {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Condition,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Condition]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeType.Condition, key } as KeyPath,\n ],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: boolean) => getCondition(result, value);\n },\n};\n\n/** ---------------------------------------------\n * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Gender]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<T[NodeType.Gender][keyof T[NodeType.Gender]], S>\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins = {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Gender,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const result = structuredClone(node[NodeType.Gender]);\n\n for (const key in result) {\n const child = result[key as keyof typeof result];\n const childProps = {\n ...props,\n children: child,\n keyPath: [...props.keyPath, { type: NodeType.Gender, key } as KeyPath],\n };\n result[key as unknown as keyof typeof result] = deepTransformNode(\n child,\n childProps\n );\n }\n\n return (value: Gender) => getGender(result, value);\n },\n};\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Insertion]: infer I;\n fields?: infer U;\n}\n ? U extends readonly string[]\n ? (data: Record<U[number], string | number>) => DeepTransformContent<I, S>\n : (data: Record<string, string | number>) => DeepTransformContent<I, S>\n : never;\n\nexport const insertionPlugin: Plugins = {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Insertion,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeType.Insertion,\n },\n ];\n\n const children = node[NodeType.Insertion];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, subProps, deepTransformNode) => {\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) => {\n const children = getInsertion(transformedResult, values);\n\n return deepTransformNode(children, {\n ...subProps,\n plugins: props.plugins,\n children,\n });\n };\n },\n };\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n },\n};\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, L> = T extends {\n nodeType: NodeType | string;\n [NodeType.Nested]: infer U;\n}\n ? U extends {\n dictionaryKey: infer K extends DictionaryKeys;\n path?: infer P;\n }\n ? GetNestingResult<K, P, S>\n : never\n : never;\n\n/** Nested plugin. Replaces node with the result of `getNesting`. */\nexport const nestedPlugin: Plugins = {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Nested,\n transform: (node: NestedContent, props) =>\n getNesting(node.nested.dictionaryKey, node.nested.path, props),\n};\n\n// /** ---------------------------------------------\n// * FILE PLUGIN\n// * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeType.File]: string;\n content?: string;\n}\n ? string\n : never;\n\n/** File plugin. Replaces node with the result of `getNesting`. */\nexport const filePlugin: Plugins = {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.File,\n transform: (node: FileContent, props, deepTransform) =>\n deepTransform(node.content, {\n ...props,\n children: node.content,\n }),\n};\n\n/**\n * PLUGIN RESULT\n */\n\n/**\n * Interface that defines the properties of a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface NodeProps {\n dictionaryKey: string;\n keyPath: KeyPath[];\n plugins?: Plugins[];\n locale?: Locale;\n dictionaryPath?: string;\n children?: any;\n}\n\n/**\n * Interface that defines the plugins that can be used to transform a node.\n * This interface can be augmented in other packages, such as `react-intlayer`.\n */\nexport interface IInterpreterPlugin<T, S, L extends LocalesValues> {\n translation: TranslationCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n nested: NestedCond<T, S, L>;\n // file: FileCond<T>;\n}\n\n/**\n * Allow to avoid overwriting import from `intlayer` package when `IInterpreterPlugin<T>` interface is augmented in another package, such as `react-intlayer`.\n */\nexport type IInterpreterPluginState = {\n translation: true;\n enumeration: true;\n condition: true;\n insertion: true;\n nested: true;\n // file: true;\n};\n\n/**\n * Utility type to check if a plugin can be applied to a node.\n */\ntype CheckApplyPlugin<\n T,\n K extends keyof IInterpreterPlugin<T, S, L>,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = K extends keyof S // Test if the key is a key of S.\n ? // Test if the key of S is true. Then the plugin can be applied.\n S[K] extends true\n ? // Test if the key of S exist\n IInterpreterPlugin<T, S, L>[K] extends never\n ? never\n : // Test if the plugin condition is true (if it's not, the plugin is skipped for this node)\n IInterpreterPlugin<T, S, L>[K]\n : never\n : never;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\ntype Traverse<\n T,\n S,\n L extends LocalesValues = DeclaredLocales,\n> = T extends ReadonlyArray<infer U> // Turn any read-only array into a plain mutable array\n ? Array<DeepTransformContent<U, S, L>>\n : T extends object\n ? { [K in keyof T]: DeepTransformContent<T[K], S, L> }\n : T;\n\nexport type IsAny<T> = 0 extends 1 & T ? true : false;\n\n/**\n * Traverse recursively through an object or array, applying each plugin as needed.\n */\nexport type DeepTransformContent<\n T,\n S = IInterpreterPluginState,\n L extends LocalesValues = DeclaredLocales,\n> = IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S> extends never // Check if there is a plugin for T:\n ? // No plugin was found, so try to transform T recursively:\n Traverse<T, S, L>\n : // A plugin was found – use the plugin’s transformation.\n IInterpreterPlugin<T, S, L>[keyof IInterpreterPlugin<T, S, L>];\n"],"mappings":"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"}
@@ -1,5 +1,39 @@
1
1
  //#region src/interpreter/getTranslation.ts
2
2
  /**
3
+ * Deep merge two values, replacing undefined values in target with values from source.
4
+ * Handles objects, arrays, and primitive values.
5
+ */
6
+ const deepMergeWithFallback = (target, fallback) => {
7
+ if (target === void 0) return fallback;
8
+ if (fallback === void 0 || target === null || typeof target !== "object") return target;
9
+ if (Array.isArray(target)) {
10
+ if (!Array.isArray(fallback)) return target;
11
+ return target.map((item, index) => deepMergeWithFallback(item, fallback[index]));
12
+ }
13
+ if (typeof fallback !== "object" || fallback === null) return target;
14
+ const result = { ...target };
15
+ const fallbackObj = fallback;
16
+ const allKeys = new Set([...Object.keys(result), ...Object.keys(fallbackObj)]);
17
+ for (const key of allKeys) result[key] = deepMergeWithFallback(result[key], fallbackObj[key]);
18
+ return result;
19
+ };
20
+ /**
21
+ * Try to get content from languageContent using locale resolution:
22
+ * 1. Exact match
23
+ * 2. Language subtag match (e.g., 'en-GB' -> 'en')
24
+ *
25
+ * @returns The content if found, undefined otherwise
26
+ */
27
+ const resolveLocaleContent = (languageContent, locale) => {
28
+ const exactResult = languageContent[locale];
29
+ if (exactResult !== void 0) return exactResult;
30
+ const [languageSubtag] = locale.split("-");
31
+ if (languageSubtag !== locale) {
32
+ const subtagResult = languageContent[languageSubtag];
33
+ if (subtagResult !== void 0) return subtagResult;
34
+ }
35
+ };
36
+ /**
3
37
  *
4
38
  * Allow to pick a content based on a locale.
5
39
  * If not locale found, it will return the content related to the default locale.
@@ -20,9 +54,14 @@
20
54
  * - this function will require each locale to be defined if defined in the project configuration.
21
55
  * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
22
56
  */
23
- const getTranslation = (languageContent, locale, fallback) => {
24
- let result = languageContent[locale];
25
- if (fallback && !result) result = languageContent[fallback];
57
+ const getTranslation = (languageContent, locale, fallback, onContentNotFound) => {
58
+ const result = resolveLocaleContent(languageContent, locale);
59
+ const fallbackResult = fallback ? resolveLocaleContent(languageContent, fallback) : void 0;
60
+ if (result === void 0) {
61
+ if (fallback) onContentNotFound?.(locale, fallback);
62
+ return fallbackResult;
63
+ }
64
+ if (fallbackResult !== void 0) return deepMergeWithFallback(result, fallbackResult);
26
65
  return result;
27
66
  };
28
67
 
@@ -1 +1 @@
1
- {"version":3,"file":"getTranslation.mjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\n\n/**\n *\n * Allow to pick a content based on a locale.\n * If not locale found, it will return the content related to the default locale.\n *\n * Return either the content editor, or the content itself depending on the configuration.\n *\n * Usage:\n *\n * ```ts\n * const content = getTranslation<string>({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n *\n * Using TypeScript:\n * - this function will require each locale to be defined if defined in the project configuration.\n * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.\n */\nexport const getTranslation = <Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues\n): Content => {\n let result = languageContent[locale as keyof typeof languageContent];\n\n if (fallback && !result) {\n result = languageContent[fallback as keyof typeof languageContent];\n }\n\n return result as unknown as Content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,kBACX,iBACA,QACA,aACY;CACZ,IAAI,SAAS,gBAAgB;AAE7B,KAAI,YAAY,CAAC,OACf,UAAS,gBAAgB;AAG3B,QAAO"}
1
+ {"version":3,"file":"getTranslation.mjs","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\n\n/**\n * Deep merge two values, replacing undefined values in target with values from source.\n * Handles objects, arrays, and primitive values.\n */\nconst deepMergeWithFallback = <T>(target: T, fallback: T): T => {\n // If target is undefined, use fallback\n if (target === undefined) {\n return fallback;\n }\n\n // If fallback is undefined or target is not an object, return target as-is\n if (fallback === undefined || target === null || typeof target !== 'object') {\n return target;\n }\n\n // Handle arrays - merge element by element\n if (Array.isArray(target)) {\n if (!Array.isArray(fallback)) {\n return target;\n }\n return target.map((item, index) =>\n deepMergeWithFallback(item, fallback[index])\n ) as T;\n }\n\n // Handle objects - merge property by property\n if (typeof fallback !== 'object' || fallback === null) {\n return target;\n }\n\n const result = { ...target } as Record<string, unknown>;\n const fallbackObj = fallback as Record<string, unknown>;\n\n // Merge all keys from both target and fallback\n const allKeys = new Set([\n ...Object.keys(result),\n ...Object.keys(fallbackObj),\n ]);\n\n for (const key of allKeys) {\n result[key] = deepMergeWithFallback(\n result[key] as unknown,\n fallbackObj[key] as unknown\n );\n }\n\n return result as T;\n};\n\n/**\n * Try to get content from languageContent using locale resolution:\n * 1. Exact match\n * 2. Language subtag match (e.g., 'en-GB' -> 'en')\n *\n * @returns The content if found, undefined otherwise\n */\nconst resolveLocaleContent = <Content>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues\n): Content | undefined => {\n // 1. Try exact match\n const exactResult = languageContent[locale as keyof typeof languageContent];\n if (exactResult !== undefined) {\n return exactResult;\n }\n\n // 2. Try language subtag match (e.g., 'en-GB' -> 'en')\n const [languageSubtag] = locale.split('-');\n if (languageSubtag !== locale) {\n const subtagResult =\n languageContent[languageSubtag as keyof typeof languageContent];\n if (subtagResult !== undefined) {\n return subtagResult;\n }\n }\n\n return undefined;\n};\n\n/**\n *\n * Allow to pick a content based on a locale.\n * If not locale found, it will return the content related to the default locale.\n *\n * Return either the content editor, or the content itself depending on the configuration.\n *\n * Usage:\n *\n * ```ts\n * const content = getTranslation<string>({\n * en: 'Hello',\n * fr: 'Bonjour',\n * }, 'fr');\n * // 'Bonjour'\n * ```\n *\n * Using TypeScript:\n * - this function will require each locale to be defined if defined in the project configuration.\n * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.\n */\nexport const getTranslation = <Content = string>(\n languageContent: StrictModeLocaleMap<Content>,\n locale: LocalesValues,\n fallback?: LocalesValues,\n onContentNotFound?: (locale: LocalesValues, fallback: LocalesValues) => void\n): Content => {\n // Try to resolve locale with subtag matching\n const result = resolveLocaleContent(languageContent, locale);\n\n // Get fallback content if provided\n const fallbackResult = fallback\n ? resolveLocaleContent(languageContent, fallback)\n : undefined;\n\n // If result is undefined, use fallback\n if (result === undefined) {\n if (fallback) {\n onContentNotFound?.(locale, fallback);\n }\n return fallbackResult as Content;\n }\n\n // If we have both result and fallback, deep merge to fill undefined values\n if (fallbackResult !== undefined) {\n return deepMergeWithFallback(result, fallbackResult);\n }\n\n return result as Content;\n};\n"],"mappings":";;;;;AAMA,MAAM,yBAA4B,QAAW,aAAmB;AAE9D,KAAI,WAAW,OACb,QAAO;AAIT,KAAI,aAAa,UAAa,WAAW,QAAQ,OAAO,WAAW,SACjE,QAAO;AAIT,KAAI,MAAM,QAAQ,OAAO,EAAE;AACzB,MAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,QAAO;AAET,SAAO,OAAO,KAAK,MAAM,UACvB,sBAAsB,MAAM,SAAS,OAAO,CAC7C;;AAIH,KAAI,OAAO,aAAa,YAAY,aAAa,KAC/C,QAAO;CAGT,MAAM,SAAS,EAAE,GAAG,QAAQ;CAC5B,MAAM,cAAc;CAGpB,MAAM,UAAU,IAAI,IAAI,CACtB,GAAG,OAAO,KAAK,OAAO,EACtB,GAAG,OAAO,KAAK,YAAY,CAC5B,CAAC;AAEF,MAAK,MAAM,OAAO,QAChB,QAAO,OAAO,sBACZ,OAAO,MACP,YAAY,KACb;AAGH,QAAO;;;;;;;;;AAUT,MAAM,wBACJ,iBACA,WACwB;CAExB,MAAM,cAAc,gBAAgB;AACpC,KAAI,gBAAgB,OAClB,QAAO;CAIT,MAAM,CAAC,kBAAkB,OAAO,MAAM,IAAI;AAC1C,KAAI,mBAAmB,QAAQ;EAC7B,MAAM,eACJ,gBAAgB;AAClB,MAAI,iBAAiB,OACnB,QAAO;;;;;;;;;;;;;;;;;;;;;;;;AA4Bb,MAAa,kBACX,iBACA,QACA,UACA,sBACY;CAEZ,MAAM,SAAS,qBAAqB,iBAAiB,OAAO;CAG5D,MAAM,iBAAiB,WACnB,qBAAqB,iBAAiB,SAAS,GAC/C;AAGJ,KAAI,WAAW,QAAW;AACxB,MAAI,SACF,qBAAoB,QAAQ,SAAS;AAEvC,SAAO;;AAIT,KAAI,mBAAmB,OACrB,QAAO,sBAAsB,QAAQ,eAAe;AAGtD,QAAO"}
@@ -1,6 +1,6 @@
1
1
  import { NodeProps, Plugins } from "../interpreter/getContent/plugins.js";
2
2
  import "../interpreter/index.js";
3
- import * as _intlayer_types5 from "@intlayer/types";
3
+ import * as _intlayer_types0 from "@intlayer/types";
4
4
  import { ContentNode, DeclaredLocales, Dictionary, LocalesValues } from "@intlayer/types";
5
5
 
6
6
  //#region src/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts
@@ -24,11 +24,11 @@ declare const getFilterMissingTranslationsContent: <T extends ContentNode, L ext
24
24
  declare const getFilterMissingTranslationsDictionary: (dictionary: Dictionary, localeToCheck: LocalesValues) => {
25
25
  content: any;
26
26
  $schema?: string;
27
- id?: _intlayer_types5.DictionaryId;
27
+ id?: _intlayer_types0.DictionaryId;
28
28
  projectIds?: string[];
29
- localId?: _intlayer_types5.LocalDictionaryId;
30
- localIds?: _intlayer_types5.LocalDictionaryId[];
31
- key: _intlayer_types5.DictionaryKey;
29
+ localId?: _intlayer_types0.LocalDictionaryId;
30
+ localIds?: _intlayer_types0.LocalDictionaryId[];
31
+ key: _intlayer_types0.DictionaryKey;
32
32
  title?: string;
33
33
  description?: string;
34
34
  versions?: string[];
@@ -36,11 +36,11 @@ declare const getFilterMissingTranslationsDictionary: (dictionary: Dictionary, l
36
36
  filePath?: string;
37
37
  tags?: string[];
38
38
  locale?: LocalesValues;
39
- fill?: _intlayer_types5.Fill;
39
+ fill?: _intlayer_types0.Fill;
40
40
  filled?: true;
41
41
  priority?: number;
42
42
  live?: boolean;
43
- location?: _intlayer_types5.DictionaryLocation;
43
+ location?: _intlayer_types0.DictionaryLocation;
44
44
  };
45
45
  //#endregion
46
46
  export { filterMissingTranslationsOnlyPlugin, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary };
@@ -1,6 +1,6 @@
1
1
  import { DeepTransformContent, NodeProps, Plugins } from "../interpreter/getContent/plugins.js";
2
2
  import "../interpreter/index.js";
3
- import * as _intlayer_types0 from "@intlayer/types";
3
+ import * as _intlayer_types6 from "@intlayer/types";
4
4
  import { ContentNode, DeclaredLocales, Dictionary, LocalesValues } from "@intlayer/types";
5
5
 
6
6
  //#region src/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts
@@ -16,11 +16,11 @@ declare const getFilterTranslationsOnlyContent: <T extends ContentNode, L extend
16
16
  declare const getFilterTranslationsOnlyDictionary: (dictionary: Dictionary, locale?: LocalesValues, fallback?: LocalesValues) => {
17
17
  content: any;
18
18
  $schema?: string;
19
- id?: _intlayer_types0.DictionaryId;
19
+ id?: _intlayer_types6.DictionaryId;
20
20
  projectIds?: string[];
21
- localId?: _intlayer_types0.LocalDictionaryId;
22
- localIds?: _intlayer_types0.LocalDictionaryId[];
23
- key: _intlayer_types0.DictionaryKey;
21
+ localId?: _intlayer_types6.LocalDictionaryId;
22
+ localIds?: _intlayer_types6.LocalDictionaryId[];
23
+ key: _intlayer_types6.DictionaryKey;
24
24
  title?: string;
25
25
  description?: string;
26
26
  versions?: string[];
@@ -28,11 +28,11 @@ declare const getFilterTranslationsOnlyDictionary: (dictionary: Dictionary, loca
28
28
  filePath?: string;
29
29
  tags?: string[];
30
30
  locale?: LocalesValues;
31
- fill?: _intlayer_types0.Fill;
31
+ fill?: _intlayer_types6.Fill;
32
32
  filled?: true;
33
33
  priority?: number;
34
34
  live?: boolean;
35
- location?: _intlayer_types0.DictionaryLocation;
35
+ location?: _intlayer_types6.DictionaryLocation;
36
36
  };
37
37
  //#endregion
38
38
  export { filterTranslationsOnlyPlugin, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary };
@@ -1,6 +1,6 @@
1
1
  import { NodeProps } from "../interpreter/getContent/plugins.js";
2
2
  import "../interpreter/index.js";
3
- import * as _intlayer_types11 from "@intlayer/types";
3
+ import * as _intlayer_types12 from "@intlayer/types";
4
4
  import { ContentNode, Dictionary, LocalesValues } from "@intlayer/types";
5
5
 
6
6
  //#region src/deepTransformPlugins/getFilteredLocalesContent.d.ts
@@ -8,11 +8,11 @@ declare const getFilteredLocalesContent: (node: ContentNode, locales: LocalesVal
8
8
  declare const getFilteredLocalesDictionary: (dictionary: Dictionary, locale: LocalesValues | LocalesValues[]) => {
9
9
  content: any;
10
10
  $schema?: string;
11
- id?: _intlayer_types11.DictionaryId;
11
+ id?: _intlayer_types12.DictionaryId;
12
12
  projectIds?: string[];
13
- localId?: _intlayer_types11.LocalDictionaryId;
14
- localIds?: _intlayer_types11.LocalDictionaryId[];
15
- key: _intlayer_types11.DictionaryKey;
13
+ localId?: _intlayer_types12.LocalDictionaryId;
14
+ localIds?: _intlayer_types12.LocalDictionaryId[];
15
+ key: _intlayer_types12.DictionaryKey;
16
16
  title?: string;
17
17
  description?: string;
18
18
  versions?: string[];
@@ -20,11 +20,11 @@ declare const getFilteredLocalesDictionary: (dictionary: Dictionary, locale: Loc
20
20
  filePath?: string;
21
21
  tags?: string[];
22
22
  locale?: LocalesValues;
23
- fill?: _intlayer_types11.Fill;
23
+ fill?: _intlayer_types12.Fill;
24
24
  filled?: true;
25
25
  priority?: number;
26
26
  live?: boolean;
27
- location?: _intlayer_types11.DictionaryLocation;
27
+ location?: _intlayer_types12.DictionaryLocation;
28
28
  };
29
29
  //#endregion
30
30
  export { getFilteredLocalesContent, getFilteredLocalesDictionary };
@@ -1 +1 @@
1
- {"version":3,"file":"getMissingLocalesContent.d.ts","names":[],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":[],"mappings":";;;;;;cA2Ca,qCACF,oCACiB,oBACzB;AAHH;;;;;AAsDA;AAAmD,cAAtC,wBAAsC,EAAA,CAAA,UAAA,WAAA,CAAA,CAAA,IAAA,EAC3C,CAD2C,EAAA,OAAA,EAExC,aAFwC,EAAA,EAAA,SAAA,EAGtC,SAHsC,EAAA,GAIhD,MAJgD,EAAA;AAC3C,cAqBK,sCArBL,EAAA,CAAA,UAAA,EAsBM,UAtBN,EAAA,OAAA,CAAA,EAuBG,aAvBH,EAAA,EAAA,GAuBiE,MAvBjE,EAAA"}
1
+ {"version":3,"file":"getMissingLocalesContent.d.ts","names":[],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":[],"mappings":";;;;;;cAiDa,qCACF,oCACiB,oBACzB;AAHH;;;;;AAsDA;AAAmD,cAAtC,wBAAsC,EAAA,CAAA,UAAA,WAAA,CAAA,CAAA,IAAA,EAC3C,CAD2C,EAAA,OAAA,EAExC,aAFwC,EAAA,EAAA,SAAA,EAGtC,SAHsC,EAAA,GAIhD,MAJgD,EAAA;AAC3C,cAqBK,sCArBL,EAAA,CAAA,UAAA,EAsBM,UAtBN,EAAA,OAAA,CAAA,EAuBG,aAvBH,EAAA,EAAA,GAuBiE,MAvBjE,EAAA"}
@@ -1,4 +1,4 @@
1
- import * as _intlayer_types17 from "@intlayer/types";
1
+ import * as _intlayer_types5 from "@intlayer/types";
2
2
  import { Dictionary } from "@intlayer/types";
3
3
 
4
4
  //#region src/dictionaryManipulator/orderDictionaries.d.ts
@@ -10,7 +10,7 @@ import { Dictionary } from "@intlayer/types";
10
10
  * @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')
11
11
  * @returns Ordered array of dictionaries
12
12
  */
13
- declare const orderDictionaries: (dictionaries: Dictionary[], configuration?: _intlayer_types17.IntlayerConfig) => Dictionary[];
13
+ declare const orderDictionaries: (dictionaries: Dictionary[], configuration?: _intlayer_types5.IntlayerConfig) => Dictionary[];
14
14
  //#endregion
15
15
  export { orderDictionaries };
16
16
  //# sourceMappingURL=orderDictionaries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orderDictionaries.d.ts","names":[],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAUA;;;;AAGa,cAHA,iBAGA,EAAA,CAAA,YAAA,EAFG,UAEH,EAAA,EAAA,aAAA,CAAA,EAFa,iBAAA,CACxB,cACW,EAAA,GAAV,UAAU,EAAA"}
1
+ {"version":3,"file":"orderDictionaries.d.ts","names":[],"sources":["../../../src/dictionaryManipulator/orderDictionaries.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAUA;;;;AAGa,cAHA,iBAGA,EAAA,CAAA,YAAA,EAFG,UAEH,EAAA,EAAA,aAAA,CAAA,EAFa,gBAAA,CACxB,cACW,EAAA,GAAV,UAAU,EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"getContent.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":[],"mappings":";;;;;;;AA0BA;;;;AAIQ,cAJK,UAIL,EAAA,CAAA,UAHI,WAGJ,EAAA,UAFI,aAEJ,GAFoB,eAEpB,CAAA,CAAA,IAAA,EAAA,CAAA,EAAA,SAAA,EACK,SADL,EAAA,MAAA,CAAA,EAEG,CAFH,EAAA,GAmBA,oBAnBA,CAmBqB,CAnBrB,EAmBwB,uBAnBxB,EAmBiD,CAnBjD,CAAA"}
1
+ {"version":3,"file":"getContent.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/getContent.ts"],"sourcesContent":[],"mappings":";;;;;;;AA2BA;;;;AAIQ,cAJK,UAIL,EAAA,CAAA,UAHI,WAGJ,EAAA,UAFI,aAEJ,GAFoB,eAEpB,CAAA,CAAA,IAAA,EAAA,CAAA,EAAA,SAAA,EACK,SADL,EAAA,MAAA,CAAA,EAEG,CAFH,EAAA,GAuCA,oBAvCA,CAuCqB,CAvCrB,EAuCwB,uBAvCxB,EAuCiD,CAvCjD,CAAA"}
@@ -28,7 +28,7 @@ type TranslationCond<T, S, L extends LocalesValues> = T extends {
28
28
  [NodeType.Translation]: infer U;
29
29
  } ? U extends Record<PropertyKey, unknown> ? L extends keyof U ? DeepTransformContent<U[L], S> : DeepTransformContent<U[keyof U], S> : never : never;
30
30
  /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
31
- declare const translationPlugin: (locale: LocalesValues, fallback?: LocalesValues) => Plugins;
31
+ declare const translationPlugin: (locale: LocalesValues, fallback?: LocalesValues, onContentNotFound?: (locale: LocalesValues, fallback: LocalesValues, keyPath: KeyPath[]) => void) => Plugins;
32
32
  /** ---------------------------------------------
33
33
  * ENUMERATION PLUGIN
34
34
  * --------------------------------------------- */
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"plugins.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":[],"mappings":"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"}
@@ -23,7 +23,7 @@ import { LocalesValues, StrictModeLocaleMap } from "@intlayer/types";
23
23
  * - this function will require each locale to be defined if defined in the project configuration.
24
24
  * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
25
25
  */
26
- declare const getTranslation: <Content = string>(languageContent: StrictModeLocaleMap<Content>, locale: LocalesValues, fallback?: LocalesValues) => Content;
26
+ declare const getTranslation: <Content = string>(languageContent: StrictModeLocaleMap<Content>, locale: LocalesValues, fallback?: LocalesValues, onContentNotFound?: (locale: LocalesValues, fallback: LocalesValues) => void) => Content;
27
27
  //#endregion
28
28
  export { getTranslation };
29
29
  //# sourceMappingURL=getTranslation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getTranslation.d.ts","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":[],"mappings":";;;;;;AAuBA;;;;;;;;;;;;;;;;;;;cAAa,oDACM,oBAAoB,kBAC7B,0BACG,kBACV"}
1
+ {"version":3,"file":"getTranslation.d.ts","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":[],"mappings":";;;;;;AAsGA;;;;;;;;;;;;;;;;;;;cAAa,oDACM,oBAAoB,kBAC7B,0BACG,4CACkB,yBAAyB,2BACrD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/core",
3
- "version": "7.3.1",
3
+ "version": "7.3.2-canary.0",
4
4
  "private": false,
5
5
  "description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
6
6
  "keywords": [
@@ -83,6 +83,7 @@
83
83
  "./package.json"
84
84
  ],
85
85
  "scripts": {
86
+ "_prepublish": "cp -f ../../../README.md ./README.md",
86
87
  "build": "tsdown --config tsdown.config.ts",
87
88
  "build:ci": "tsdown --config tsdown.config.ts",
88
89
  "clean": "rimraf ./dist .turbo",
@@ -92,7 +93,7 @@
92
93
  "lint": "biome lint .",
93
94
  "lint:fix": "biome lint --write .",
94
95
  "process-files": "ts-node src/transpiler/processFilesCLI.ts --dir $npm_config_dir --extension $npm_config_extension --no-node-snapshot",
95
- "prepublish": "cp -f ../../../README.md ./README.md",
96
+ "prepublish": "echo prepublish temporally disabled to avoid rewrite readme",
96
97
  "publish": "bun publish || true",
97
98
  "publish:canary": "bun publish --access public --tag canary || true",
98
99
  "publish:latest": "bun publish --access public --tag latest || true",
@@ -101,11 +102,11 @@
101
102
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
102
103
  },
103
104
  "dependencies": {
104
- "@intlayer/api": "7.3.1",
105
- "@intlayer/config": "7.3.1",
106
- "@intlayer/dictionaries-entry": "7.3.1",
107
- "@intlayer/types": "7.3.1",
108
- "@intlayer/unmerged-dictionaries-entry": "7.3.1",
105
+ "@intlayer/api": "7.3.2-canary.0",
106
+ "@intlayer/config": "7.3.2-canary.0",
107
+ "@intlayer/dictionaries-entry": "7.3.2-canary.0",
108
+ "@intlayer/types": "7.3.2-canary.0",
109
+ "@intlayer/unmerged-dictionaries-entry": "7.3.2-canary.0",
109
110
  "deepmerge": "4.3.1"
110
111
  },
111
112
  "devDependencies": {