@intlayer/core 7.3.2-canary.0 → 7.3.2-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/interpreter/getContent/getContent.cjs +1 -10
- package/dist/cjs/interpreter/getContent/getContent.cjs.map +1 -1
- package/dist/cjs/interpreter/getContent/plugins.cjs +1 -3
- package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
- package/dist/cjs/interpreter/getTranslation.cjs +60 -36
- package/dist/cjs/interpreter/getTranslation.cjs.map +1 -1
- package/dist/esm/interpreter/getContent/getContent.mjs +1 -10
- package/dist/esm/interpreter/getContent/getContent.mjs.map +1 -1
- package/dist/esm/interpreter/getContent/plugins.mjs +1 -3
- package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
- package/dist/esm/interpreter/getTranslation.mjs +59 -36
- package/dist/esm/interpreter/getTranslation.mjs.map +1 -1
- package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +7 -7
- package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +7 -7
- package/dist/types/interpreter/getContent/getContent.d.ts.map +1 -1
- package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
- package/dist/types/interpreter/getTranslation.d.ts +1 -1
- package/dist/types/interpreter/getTranslation.d.ts.map +1 -1
- package/dist/types/transpiler/enumeration/enumeration.d.ts.map +1 -1
- package/dist/types/transpiler/translation/translation.d.ts +1 -1
- package/dist/types/transpiler/translation/translation.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -1,7 +1,6 @@
|
|
|
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");
|
|
5
4
|
let __intlayer_config_built = require("@intlayer/config/built");
|
|
6
5
|
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
|
|
7
6
|
|
|
@@ -14,17 +13,9 @@ __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_bui
|
|
|
14
13
|
*/
|
|
15
14
|
const getContent = (node, nodeProps, locale) => {
|
|
16
15
|
const defaultLocale = __intlayer_config_built.default?.internationalization?.defaultLocale;
|
|
17
|
-
const importMode = __intlayer_config_built.default?.build?.importMode;
|
|
18
16
|
const plugins = [
|
|
19
17
|
require_interpreter_getContent_plugins.insertionPlugin,
|
|
20
|
-
require_interpreter_getContent_plugins.translationPlugin(locale ?? defaultLocale, defaultLocale,
|
|
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
|
-
}),
|
|
18
|
+
require_interpreter_getContent_plugins.translationPlugin(locale ?? defaultLocale, defaultLocale),
|
|
28
19
|
require_interpreter_getContent_plugins.enumerationPlugin,
|
|
29
20
|
require_interpreter_getContent_plugins.conditionPlugin,
|
|
30
21
|
require_interpreter_getContent_plugins.nestedPlugin,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getContent.cjs","names":["configuration","plugins: Plugins[]","insertionPlugin","translationPlugin","
|
|
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 { 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\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":";;;;;;;;;;;;;AA2BA,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"}
|
|
@@ -25,9 +25,7 @@ const translationPlugin = (locale, fallback, onContentNotFound) => ({
|
|
|
25
25
|
};
|
|
26
26
|
result[key] = deepTransformNode(result[key], childProps);
|
|
27
27
|
}
|
|
28
|
-
return require_interpreter_getTranslation.getTranslation(result, locale, fallback
|
|
29
|
-
onContentNotFound?.(locale$1, fallback$1, props.keyPath);
|
|
30
|
-
});
|
|
28
|
+
return require_interpreter_getTranslation.getTranslation(result, locale, fallback);
|
|
31
29
|
}
|
|
32
30
|
});
|
|
33
31
|
/** Enumeration plugin. Replaces node with a function that takes quantity => string. */
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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 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);\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,38 +1,32 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let deepmerge = require("deepmerge");
|
|
3
|
+
deepmerge = require_rolldown_runtime.__toESM(deepmerge);
|
|
1
4
|
|
|
2
5
|
//#region src/interpreter/getTranslation.ts
|
|
3
6
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
7
|
+
* Check if a value is a plain object that can be safely merged.
|
|
8
|
+
* Returns false for Promises, React elements, class instances, etc.
|
|
6
9
|
*/
|
|
7
|
-
const
|
|
8
|
-
if (
|
|
9
|
-
if (
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
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;
|
|
10
|
+
const isMergeableObject = (value) => {
|
|
11
|
+
if (value === null || typeof value !== "object") return false;
|
|
12
|
+
if (value instanceof Promise || typeof value.then === "function") return false;
|
|
13
|
+
if (value.$$typeof !== void 0) return false;
|
|
14
|
+
const proto = Object.getPrototypeOf(value);
|
|
15
|
+
return proto === Object.prototype || proto === null || Array.isArray(value);
|
|
20
16
|
};
|
|
21
17
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* 2. Language subtag match (e.g., 'en-GB' -> 'en')
|
|
25
|
-
*
|
|
26
|
-
* @returns The content if found, undefined otherwise
|
|
18
|
+
* Recursively removes undefined values from an object.
|
|
19
|
+
* Handles circular references by tracking visited objects.
|
|
27
20
|
*/
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
const removeUndefinedValues = (object, visited = /* @__PURE__ */ new WeakSet()) => {
|
|
22
|
+
if (typeof object !== "object" || object === null) return object;
|
|
23
|
+
if (visited.has(object)) return object;
|
|
24
|
+
visited.add(object);
|
|
25
|
+
if (!isMergeableObject(object)) return object;
|
|
26
|
+
if (Array.isArray(object)) return object.map((item) => removeUndefinedValues(item, visited));
|
|
27
|
+
const result = {};
|
|
28
|
+
for (const [key, value] of Object.entries(object)) if (value !== void 0) result[key] = removeUndefinedValues(value, visited);
|
|
29
|
+
return result;
|
|
36
30
|
};
|
|
37
31
|
/**
|
|
38
32
|
*
|
|
@@ -55,15 +49,45 @@ const resolveLocaleContent = (languageContent, locale) => {
|
|
|
55
49
|
* - this function will require each locale to be defined if defined in the project configuration.
|
|
56
50
|
* - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
|
|
57
51
|
*/
|
|
58
|
-
const getTranslation = (languageContent, locale, fallback
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
const getTranslation = (languageContent, locale, fallback) => {
|
|
53
|
+
const results = [];
|
|
54
|
+
const getContent = (loc) => languageContent[loc];
|
|
55
|
+
const content = getContent(locale);
|
|
56
|
+
if (typeof content === "string") return content;
|
|
57
|
+
else if (content !== void 0) results.push(content);
|
|
58
|
+
if (locale.includes("-")) {
|
|
59
|
+
const genericLocale = locale.split("-")[0];
|
|
60
|
+
if (genericLocale in languageContent) {
|
|
61
|
+
const genericContent = getContent(genericLocale);
|
|
62
|
+
if (typeof genericContent === "string") {
|
|
63
|
+
if (results.length === 0) return genericContent;
|
|
64
|
+
} else if (genericContent !== void 0) results.push(genericContent);
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
+
if (fallback !== void 0 && fallback !== locale) {
|
|
68
|
+
if (fallback in languageContent) {
|
|
69
|
+
const fallbackContent = getContent(fallback);
|
|
70
|
+
if (typeof fallbackContent === "string") {
|
|
71
|
+
if (results.length === 0) return fallbackContent;
|
|
72
|
+
} else if (fallbackContent !== void 0) results.push(fallbackContent);
|
|
73
|
+
}
|
|
74
|
+
if (fallback.includes("-")) {
|
|
75
|
+
const genericFallback = fallback.split("-")[0];
|
|
76
|
+
if (genericFallback !== locale.split("-")[0] && genericFallback in languageContent) {
|
|
77
|
+
const genericFallbackContent = getContent(genericFallback);
|
|
78
|
+
if (typeof genericFallbackContent === "string") {
|
|
79
|
+
if (results.length === 0) return genericFallbackContent;
|
|
80
|
+
} else if (genericFallbackContent !== void 0) results.push(genericFallbackContent);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (results.length === 0) return;
|
|
85
|
+
results.reverse();
|
|
86
|
+
const cleanResults = results.map((item) => removeUndefinedValues(item));
|
|
87
|
+
return deepmerge.default.all(cleanResults, {
|
|
88
|
+
arrayMerge: (_destinationArray, sourceArray) => sourceArray,
|
|
89
|
+
isMergeableObject
|
|
90
|
+
});
|
|
67
91
|
};
|
|
68
92
|
|
|
69
93
|
//#endregion
|
|
@@ -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 *
|
|
1
|
+
{"version":3,"file":"getTranslation.cjs","names":["result: Record<string, unknown>","results: Content[]","deepMerge"],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport deepMerge from 'deepmerge';\n\n/**\n * Check if a value is a plain object that can be safely merged.\n * Returns false for Promises, React elements, class instances, etc.\n */\nconst isMergeableObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n\n // Don't merge Promises (e.g., Next.js 15+ params)\n if (value instanceof Promise || typeof (value as any).then === 'function') {\n return false;\n }\n\n // Don't merge React elements\n if ((value as any).$$typeof !== undefined) {\n return false;\n }\n\n // Only merge plain objects and arrays\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null || Array.isArray(value);\n};\n\n/**\n * Recursively removes undefined values from an object.\n * Handles circular references by tracking visited objects.\n */\nconst removeUndefinedValues = <T>(\n object: T,\n visited = new WeakSet<object>()\n): T => {\n if (typeof object !== 'object' || object === null) {\n return object;\n }\n\n // Handle circular references - return original to avoid infinite recursion\n if (visited.has(object)) {\n return object;\n }\n visited.add(object);\n\n // Don't process non-mergeable objects (Promises, React elements, etc.)\n if (!isMergeableObject(object)) {\n return object;\n }\n\n if (Array.isArray(object)) {\n return object.map((item) => removeUndefinedValues(item, visited)) as T;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(object)) {\n if (value !== undefined) {\n result[key] = removeUndefinedValues(value, visited);\n }\n }\n return result as T;\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): Content => {\n const results: Content[] = [];\n\n const getContent = (loc: string) =>\n languageContent[loc as keyof typeof languageContent];\n\n // 1. Get Target Content\n const content = getContent(locale);\n if (typeof content === 'string') {\n return content;\n } else if (content !== undefined) {\n results.push(content);\n }\n\n // 2. Get Target Generic Content (e.g. 'en' from 'en-US')\n if (locale.includes('-')) {\n const genericLocale = locale.split('-')[0];\n if (genericLocale in languageContent) {\n const genericContent = getContent(genericLocale);\n\n if (typeof genericContent === 'string') {\n // If we haven't found specific content yet, return generic string\n if (results.length === 0) return genericContent;\n } else if (genericContent !== undefined) {\n results.push(genericContent);\n }\n }\n }\n\n // 3. Get Fallback Content\n if (fallback !== undefined && fallback !== locale) {\n // 3a. Fallback Specific\n if (fallback in languageContent) {\n const fallbackContent = getContent(fallback);\n\n if (typeof fallbackContent === 'string') {\n if (results.length === 0) return fallbackContent;\n } else if (fallbackContent !== undefined) {\n results.push(fallbackContent);\n }\n }\n\n // 3b. Fallback Generic (The missing piece: e.g. 'en' from 'en-GB' fallback)\n if (fallback.includes('-')) {\n const genericFallback = fallback.split('-')[0];\n const genericLocale = locale.split('-')[0];\n\n // Only add if it's different from the target generic (to avoid duplication)\n // and exists in the dictionary\n if (\n genericFallback !== genericLocale &&\n genericFallback in languageContent\n ) {\n const genericFallbackContent = getContent(genericFallback);\n\n if (typeof genericFallbackContent === 'string') {\n if (results.length === 0) return genericFallbackContent;\n } else if (genericFallbackContent !== undefined) {\n results.push(genericFallbackContent);\n }\n }\n }\n }\n\n if (results.length === 0) {\n return undefined as Content;\n }\n\n // Reverse so precedence is correct for deepmerge:\n // [FallbackGeneric, Fallback, Generic, Target]\n // deepmerge.all applies right-most on top of others.\n results.reverse();\n\n // Clean undefined values so they don't overwrite fallbacks\n const cleanResults = results.map((item) => removeUndefinedValues(item));\n\n // Merge with array overwrite strategy and safe object checking\n return deepMerge.all(cleanResults, {\n arrayMerge: (_destinationArray, sourceArray) => sourceArray,\n isMergeableObject,\n }) as Content;\n};\n"],"mappings":";;;;;;;;;AAOA,MAAM,qBAAqB,UAA4B;AACrD,KAAI,UAAU,QAAQ,OAAO,UAAU,SACrC,QAAO;AAIT,KAAI,iBAAiB,WAAW,OAAQ,MAAc,SAAS,WAC7D,QAAO;AAIT,KAAK,MAAc,aAAa,OAC9B,QAAO;CAIT,MAAM,QAAQ,OAAO,eAAe,MAAM;AAC1C,QAAO,UAAU,OAAO,aAAa,UAAU,QAAQ,MAAM,QAAQ,MAAM;;;;;;AAO7E,MAAM,yBACJ,QACA,0BAAU,IAAI,SAAiB,KACzB;AACN,KAAI,OAAO,WAAW,YAAY,WAAW,KAC3C,QAAO;AAIT,KAAI,QAAQ,IAAI,OAAO,CACrB,QAAO;AAET,SAAQ,IAAI,OAAO;AAGnB,KAAI,CAAC,kBAAkB,OAAO,CAC5B,QAAO;AAGT,KAAI,MAAM,QAAQ,OAAO,CACvB,QAAO,OAAO,KAAK,SAAS,sBAAsB,MAAM,QAAQ,CAAC;CAGnE,MAAMA,SAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,KAAI,UAAU,OACZ,QAAO,OAAO,sBAAsB,OAAO,QAAQ;AAGvD,QAAO;;;;;;;;;;;;;;;;;;;;;;;AAwBT,MAAa,kBACX,iBACA,QACA,aACY;CACZ,MAAMC,UAAqB,EAAE;CAE7B,MAAM,cAAc,QAClB,gBAAgB;CAGlB,MAAM,UAAU,WAAW,OAAO;AAClC,KAAI,OAAO,YAAY,SACrB,QAAO;UACE,YAAY,OACrB,SAAQ,KAAK,QAAQ;AAIvB,KAAI,OAAO,SAAS,IAAI,EAAE;EACxB,MAAM,gBAAgB,OAAO,MAAM,IAAI,CAAC;AACxC,MAAI,iBAAiB,iBAAiB;GACpC,MAAM,iBAAiB,WAAW,cAAc;AAEhD,OAAI,OAAO,mBAAmB,UAE5B;QAAI,QAAQ,WAAW,EAAG,QAAO;cACxB,mBAAmB,OAC5B,SAAQ,KAAK,eAAe;;;AAMlC,KAAI,aAAa,UAAa,aAAa,QAAQ;AAEjD,MAAI,YAAY,iBAAiB;GAC/B,MAAM,kBAAkB,WAAW,SAAS;AAE5C,OAAI,OAAO,oBAAoB,UAC7B;QAAI,QAAQ,WAAW,EAAG,QAAO;cACxB,oBAAoB,OAC7B,SAAQ,KAAK,gBAAgB;;AAKjC,MAAI,SAAS,SAAS,IAAI,EAAE;GAC1B,MAAM,kBAAkB,SAAS,MAAM,IAAI,CAAC;AAK5C,OACE,oBALoB,OAAO,MAAM,IAAI,CAAC,MAMtC,mBAAmB,iBACnB;IACA,MAAM,yBAAyB,WAAW,gBAAgB;AAE1D,QAAI,OAAO,2BAA2B,UACpC;SAAI,QAAQ,WAAW,EAAG,QAAO;eACxB,2BAA2B,OACpC,SAAQ,KAAK,uBAAuB;;;;AAM5C,KAAI,QAAQ,WAAW,EACrB;AAMF,SAAQ,SAAS;CAGjB,MAAM,eAAe,QAAQ,KAAK,SAAS,sBAAsB,KAAK,CAAC;AAGvE,QAAOC,kBAAU,IAAI,cAAc;EACjC,aAAa,mBAAmB,gBAAgB;EAChD;EACD,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
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";
|
|
4
3
|
import configuration from "@intlayer/config/built";
|
|
5
4
|
|
|
6
5
|
//#region src/interpreter/getContent/getContent.ts
|
|
@@ -12,17 +11,9 @@ import configuration from "@intlayer/config/built";
|
|
|
12
11
|
*/
|
|
13
12
|
const getContent = (node, nodeProps, locale) => {
|
|
14
13
|
const defaultLocale = configuration?.internationalization?.defaultLocale;
|
|
15
|
-
const importMode = configuration?.build?.importMode;
|
|
16
14
|
const plugins = [
|
|
17
15
|
insertionPlugin,
|
|
18
|
-
translationPlugin(locale ?? defaultLocale, defaultLocale,
|
|
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
|
-
}),
|
|
16
|
+
translationPlugin(locale ?? defaultLocale, defaultLocale),
|
|
26
17
|
enumerationPlugin,
|
|
27
18
|
conditionPlugin,
|
|
28
19
|
nestedPlugin,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getContent.mjs","names":["plugins: Plugins[]"
|
|
1
|
+
{"version":3,"file":"getContent.mjs","names":["plugins: Plugins[]"],"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\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":";;;;;;;;;;;AA2BA,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"}
|
|
@@ -24,9 +24,7 @@ const translationPlugin = (locale, fallback, onContentNotFound) => ({
|
|
|
24
24
|
};
|
|
25
25
|
result[key] = deepTransformNode(result[key], childProps);
|
|
26
26
|
}
|
|
27
|
-
return getTranslation(result, locale, fallback
|
|
28
|
-
onContentNotFound?.(locale$1, fallback$1, props.keyPath);
|
|
29
|
-
});
|
|
27
|
+
return getTranslation(result, locale, fallback);
|
|
30
28
|
}
|
|
31
29
|
});
|
|
32
30
|
/** Enumeration plugin. Replaces node with a function that takes quantity => string. */
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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 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);\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":";;;;;;;;;;AA8DA,MAAa,qBACX,QACA,UACA,uBAKa;CACb,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAA0B,OAAO,sBAAsB;EACjE,MAAM,SAAS,gBAAgB,KAAK,SAAS,aAAa;AAE1D,OAAK,MAAM,OAAO,QAAQ;GACxB,MAAM,aAAa;IACjB,GAAG;IACH,UAAU,OAAO;IACjB,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAM,SAAS;KAAa;KAAK,CACpC;IACF;AACD,UAAO,OAA8B,kBACnC,OAAO,MACP,WACD;;AAGH,SAAO,eAAe,QAAQ,QAAQ,SAAS;;CAElD;;AAmBD,MAAaA,oBAA6B;CACxC,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAA0B,OAAO,sBAAsB;EACjE,MAAM,SAAS,gBAAgB,KAAK,SAAS,aAAa;AAE1D,OAAK,MAAM,OAAO,QAAQ;GACxB,MAAM,QAAQ,OAAO;AASrB,UAAO,OAAyC,kBAC9C,OATiB;IACjB,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAM,SAAS;KAAa;KAAK,CACpC;IACF,CAIA;;AAGH,UAAQ,aAAqB,eAAe,QAAQ,SAAS;;CAEhE;;AAmBD,MAAaC,kBAA2B;CACtC,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAM,SAAS,gBAAgB,KAAK,SAAS,WAAW;AAExD,OAAK,MAAM,OAAO,QAAQ;GACxB,MAAM,QAAQ,OAAO;AASrB,UAAO,OAAyC,kBAC9C,OATiB;IACjB,GAAG;IACH,UAAU;IACV,SAAS,CACP,GAAG,MAAM,SACT;KAAE,MAAM,SAAS;KAAW;KAAK,CAClC;IACF,CAIA;;AAGH,UAAQ,UAAmB,aAAa,QAAQ,MAAM;;CAEzD;;AAgBD,MAAaC,eAAwB;CACnC,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAAqB,OAAO,sBAAsB;EAC5D,MAAM,SAAS,gBAAgB,KAAK,SAAS,QAAQ;AAErD,OAAK,MAAM,OAAO,QAAQ;GACxB,MAAM,QAAQ,OAAO;AAMrB,UAAO,OAAyC,kBAC9C,OANiB;IACjB,GAAG;IACH,UAAU;IACV,SAAS,CAAC,GAAG,MAAM,SAAS;KAAE,MAAM,SAAS;KAAQ;KAAK,CAAY;IACvE,CAIA;;AAGH,UAAQ,UAAkB,UAAU,QAAQ,MAAM;;CAErD;AAgBD,MAAaC,kBAA2B;CACtC,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAMC,aAAwB,CAC5B,GAAG,MAAM,SACT,EACE,MAAM,SAAS,WAChB,CACF;EAED,MAAM,WAAW,KAAK,SAAS;;EAG/B,MAAMC,wBAAiC;GACrC,IAAI;GACJ,YAAY,WAAS,OAAOC,WAAS;GACrC,YAAY,QAAc,UAAU,wBAAsB;IACxD,MAAM,oBAAoBC,oBAAkBD,QAAM;KAChD,GAAG;KACH,UAAUA;KACV,SAAS,CACP,IAAI,MAAM,WAAY,EAAE,EAAgB,QACrC,WAAW,OAAO,OAAO,uBAC3B,CACF;KACF,CAAC;AAEF,YACE,WAGG;KACH,MAAME,aAAW,aAAa,mBAAmB,OAAO;AAExD,YAAOD,oBAAkBC,YAAU;MACjC,GAAG;MACH,SAAS,MAAM;MACf;MACD,CAAC;;;GAGP;AAED,SAAO,kBAAkB,UAAU;GACjC,GAAG;GACH;GACA,SAAS;GACT,SAAS,CAAC,uBAAuB,GAAI,MAAM,WAAW,EAAE,CAAE;GAC3D,CAAC;;CAEL;;AAmBD,MAAaC,eAAwB;CACnC,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAAqB,UAC/B,WAAW,KAAK,OAAO,eAAe,KAAK,OAAO,MAAM,MAAM;CACjE;;AAeD,MAAaC,aAAsB;CACjC,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAa,SAAS;CAC1D,YAAY,MAAmB,OAAO,kBACpC,cAAc,KAAK,SAAS;EAC1B,GAAG;EACH,UAAU,KAAK;EAChB,CAAC;CACL"}
|
|
@@ -1,37 +1,30 @@
|
|
|
1
|
+
import deepMerge from "deepmerge";
|
|
2
|
+
|
|
1
3
|
//#region src/interpreter/getTranslation.ts
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
+
* Check if a value is a plain object that can be safely merged.
|
|
6
|
+
* Returns false for Promises, React elements, class instances, etc.
|
|
5
7
|
*/
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
8
|
-
if (
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
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;
|
|
8
|
+
const isMergeableObject = (value) => {
|
|
9
|
+
if (value === null || typeof value !== "object") return false;
|
|
10
|
+
if (value instanceof Promise || typeof value.then === "function") return false;
|
|
11
|
+
if (value.$$typeof !== void 0) return false;
|
|
12
|
+
const proto = Object.getPrototypeOf(value);
|
|
13
|
+
return proto === Object.prototype || proto === null || Array.isArray(value);
|
|
19
14
|
};
|
|
20
15
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* 2. Language subtag match (e.g., 'en-GB' -> 'en')
|
|
24
|
-
*
|
|
25
|
-
* @returns The content if found, undefined otherwise
|
|
16
|
+
* Recursively removes undefined values from an object.
|
|
17
|
+
* Handles circular references by tracking visited objects.
|
|
26
18
|
*/
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
const removeUndefinedValues = (object, visited = /* @__PURE__ */ new WeakSet()) => {
|
|
20
|
+
if (typeof object !== "object" || object === null) return object;
|
|
21
|
+
if (visited.has(object)) return object;
|
|
22
|
+
visited.add(object);
|
|
23
|
+
if (!isMergeableObject(object)) return object;
|
|
24
|
+
if (Array.isArray(object)) return object.map((item) => removeUndefinedValues(item, visited));
|
|
25
|
+
const result = {};
|
|
26
|
+
for (const [key, value] of Object.entries(object)) if (value !== void 0) result[key] = removeUndefinedValues(value, visited);
|
|
27
|
+
return result;
|
|
35
28
|
};
|
|
36
29
|
/**
|
|
37
30
|
*
|
|
@@ -54,15 +47,45 @@ const resolveLocaleContent = (languageContent, locale) => {
|
|
|
54
47
|
* - this function will require each locale to be defined if defined in the project configuration.
|
|
55
48
|
* - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
|
|
56
49
|
*/
|
|
57
|
-
const getTranslation = (languageContent, locale, fallback
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
const getTranslation = (languageContent, locale, fallback) => {
|
|
51
|
+
const results = [];
|
|
52
|
+
const getContent = (loc) => languageContent[loc];
|
|
53
|
+
const content = getContent(locale);
|
|
54
|
+
if (typeof content === "string") return content;
|
|
55
|
+
else if (content !== void 0) results.push(content);
|
|
56
|
+
if (locale.includes("-")) {
|
|
57
|
+
const genericLocale = locale.split("-")[0];
|
|
58
|
+
if (genericLocale in languageContent) {
|
|
59
|
+
const genericContent = getContent(genericLocale);
|
|
60
|
+
if (typeof genericContent === "string") {
|
|
61
|
+
if (results.length === 0) return genericContent;
|
|
62
|
+
} else if (genericContent !== void 0) results.push(genericContent);
|
|
63
|
+
}
|
|
63
64
|
}
|
|
64
|
-
if (
|
|
65
|
-
|
|
65
|
+
if (fallback !== void 0 && fallback !== locale) {
|
|
66
|
+
if (fallback in languageContent) {
|
|
67
|
+
const fallbackContent = getContent(fallback);
|
|
68
|
+
if (typeof fallbackContent === "string") {
|
|
69
|
+
if (results.length === 0) return fallbackContent;
|
|
70
|
+
} else if (fallbackContent !== void 0) results.push(fallbackContent);
|
|
71
|
+
}
|
|
72
|
+
if (fallback.includes("-")) {
|
|
73
|
+
const genericFallback = fallback.split("-")[0];
|
|
74
|
+
if (genericFallback !== locale.split("-")[0] && genericFallback in languageContent) {
|
|
75
|
+
const genericFallbackContent = getContent(genericFallback);
|
|
76
|
+
if (typeof genericFallbackContent === "string") {
|
|
77
|
+
if (results.length === 0) return genericFallbackContent;
|
|
78
|
+
} else if (genericFallbackContent !== void 0) results.push(genericFallbackContent);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (results.length === 0) return;
|
|
83
|
+
results.reverse();
|
|
84
|
+
const cleanResults = results.map((item) => removeUndefinedValues(item));
|
|
85
|
+
return deepMerge.all(cleanResults, {
|
|
86
|
+
arrayMerge: (_destinationArray, sourceArray) => sourceArray,
|
|
87
|
+
isMergeableObject
|
|
88
|
+
});
|
|
66
89
|
};
|
|
67
90
|
|
|
68
91
|
//#endregion
|
|
@@ -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 *
|
|
1
|
+
{"version":3,"file":"getTranslation.mjs","names":["result: Record<string, unknown>","results: Content[]"],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":["import type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport deepMerge from 'deepmerge';\n\n/**\n * Check if a value is a plain object that can be safely merged.\n * Returns false for Promises, React elements, class instances, etc.\n */\nconst isMergeableObject = (value: unknown): boolean => {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n\n // Don't merge Promises (e.g., Next.js 15+ params)\n if (value instanceof Promise || typeof (value as any).then === 'function') {\n return false;\n }\n\n // Don't merge React elements\n if ((value as any).$$typeof !== undefined) {\n return false;\n }\n\n // Only merge plain objects and arrays\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null || Array.isArray(value);\n};\n\n/**\n * Recursively removes undefined values from an object.\n * Handles circular references by tracking visited objects.\n */\nconst removeUndefinedValues = <T>(\n object: T,\n visited = new WeakSet<object>()\n): T => {\n if (typeof object !== 'object' || object === null) {\n return object;\n }\n\n // Handle circular references - return original to avoid infinite recursion\n if (visited.has(object)) {\n return object;\n }\n visited.add(object);\n\n // Don't process non-mergeable objects (Promises, React elements, etc.)\n if (!isMergeableObject(object)) {\n return object;\n }\n\n if (Array.isArray(object)) {\n return object.map((item) => removeUndefinedValues(item, visited)) as T;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(object)) {\n if (value !== undefined) {\n result[key] = removeUndefinedValues(value, visited);\n }\n }\n return result as T;\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): Content => {\n const results: Content[] = [];\n\n const getContent = (loc: string) =>\n languageContent[loc as keyof typeof languageContent];\n\n // 1. Get Target Content\n const content = getContent(locale);\n if (typeof content === 'string') {\n return content;\n } else if (content !== undefined) {\n results.push(content);\n }\n\n // 2. Get Target Generic Content (e.g. 'en' from 'en-US')\n if (locale.includes('-')) {\n const genericLocale = locale.split('-')[0];\n if (genericLocale in languageContent) {\n const genericContent = getContent(genericLocale);\n\n if (typeof genericContent === 'string') {\n // If we haven't found specific content yet, return generic string\n if (results.length === 0) return genericContent;\n } else if (genericContent !== undefined) {\n results.push(genericContent);\n }\n }\n }\n\n // 3. Get Fallback Content\n if (fallback !== undefined && fallback !== locale) {\n // 3a. Fallback Specific\n if (fallback in languageContent) {\n const fallbackContent = getContent(fallback);\n\n if (typeof fallbackContent === 'string') {\n if (results.length === 0) return fallbackContent;\n } else if (fallbackContent !== undefined) {\n results.push(fallbackContent);\n }\n }\n\n // 3b. Fallback Generic (The missing piece: e.g. 'en' from 'en-GB' fallback)\n if (fallback.includes('-')) {\n const genericFallback = fallback.split('-')[0];\n const genericLocale = locale.split('-')[0];\n\n // Only add if it's different from the target generic (to avoid duplication)\n // and exists in the dictionary\n if (\n genericFallback !== genericLocale &&\n genericFallback in languageContent\n ) {\n const genericFallbackContent = getContent(genericFallback);\n\n if (typeof genericFallbackContent === 'string') {\n if (results.length === 0) return genericFallbackContent;\n } else if (genericFallbackContent !== undefined) {\n results.push(genericFallbackContent);\n }\n }\n }\n }\n\n if (results.length === 0) {\n return undefined as Content;\n }\n\n // Reverse so precedence is correct for deepmerge:\n // [FallbackGeneric, Fallback, Generic, Target]\n // deepmerge.all applies right-most on top of others.\n results.reverse();\n\n // Clean undefined values so they don't overwrite fallbacks\n const cleanResults = results.map((item) => removeUndefinedValues(item));\n\n // Merge with array overwrite strategy and safe object checking\n return deepMerge.all(cleanResults, {\n arrayMerge: (_destinationArray, sourceArray) => sourceArray,\n isMergeableObject,\n }) as Content;\n};\n"],"mappings":";;;;;;;AAOA,MAAM,qBAAqB,UAA4B;AACrD,KAAI,UAAU,QAAQ,OAAO,UAAU,SACrC,QAAO;AAIT,KAAI,iBAAiB,WAAW,OAAQ,MAAc,SAAS,WAC7D,QAAO;AAIT,KAAK,MAAc,aAAa,OAC9B,QAAO;CAIT,MAAM,QAAQ,OAAO,eAAe,MAAM;AAC1C,QAAO,UAAU,OAAO,aAAa,UAAU,QAAQ,MAAM,QAAQ,MAAM;;;;;;AAO7E,MAAM,yBACJ,QACA,0BAAU,IAAI,SAAiB,KACzB;AACN,KAAI,OAAO,WAAW,YAAY,WAAW,KAC3C,QAAO;AAIT,KAAI,QAAQ,IAAI,OAAO,CACrB,QAAO;AAET,SAAQ,IAAI,OAAO;AAGnB,KAAI,CAAC,kBAAkB,OAAO,CAC5B,QAAO;AAGT,KAAI,MAAM,QAAQ,OAAO,CACvB,QAAO,OAAO,KAAK,SAAS,sBAAsB,MAAM,QAAQ,CAAC;CAGnE,MAAMA,SAAkC,EAAE;AAC1C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,CAC/C,KAAI,UAAU,OACZ,QAAO,OAAO,sBAAsB,OAAO,QAAQ;AAGvD,QAAO;;;;;;;;;;;;;;;;;;;;;;;AAwBT,MAAa,kBACX,iBACA,QACA,aACY;CACZ,MAAMC,UAAqB,EAAE;CAE7B,MAAM,cAAc,QAClB,gBAAgB;CAGlB,MAAM,UAAU,WAAW,OAAO;AAClC,KAAI,OAAO,YAAY,SACrB,QAAO;UACE,YAAY,OACrB,SAAQ,KAAK,QAAQ;AAIvB,KAAI,OAAO,SAAS,IAAI,EAAE;EACxB,MAAM,gBAAgB,OAAO,MAAM,IAAI,CAAC;AACxC,MAAI,iBAAiB,iBAAiB;GACpC,MAAM,iBAAiB,WAAW,cAAc;AAEhD,OAAI,OAAO,mBAAmB,UAE5B;QAAI,QAAQ,WAAW,EAAG,QAAO;cACxB,mBAAmB,OAC5B,SAAQ,KAAK,eAAe;;;AAMlC,KAAI,aAAa,UAAa,aAAa,QAAQ;AAEjD,MAAI,YAAY,iBAAiB;GAC/B,MAAM,kBAAkB,WAAW,SAAS;AAE5C,OAAI,OAAO,oBAAoB,UAC7B;QAAI,QAAQ,WAAW,EAAG,QAAO;cACxB,oBAAoB,OAC7B,SAAQ,KAAK,gBAAgB;;AAKjC,MAAI,SAAS,SAAS,IAAI,EAAE;GAC1B,MAAM,kBAAkB,SAAS,MAAM,IAAI,CAAC;AAK5C,OACE,oBALoB,OAAO,MAAM,IAAI,CAAC,MAMtC,mBAAmB,iBACnB;IACA,MAAM,yBAAyB,WAAW,gBAAgB;AAE1D,QAAI,OAAO,2BAA2B,UACpC;SAAI,QAAQ,WAAW,EAAG,QAAO;eACxB,2BAA2B,OACpC,SAAQ,KAAK,uBAAuB;;;;AAM5C,KAAI,QAAQ,WAAW,EACrB;AAMF,SAAQ,SAAS;CAGjB,MAAM,eAAe,QAAQ,KAAK,SAAS,sBAAsB,KAAK,CAAC;AAGvE,QAAO,UAAU,IAAI,cAAc;EACjC,aAAa,mBAAmB,gBAAgB;EAChD;EACD,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NodeProps, Plugins } from "../interpreter/getContent/plugins.js";
|
|
2
2
|
import "../interpreter/index.js";
|
|
3
|
-
import * as
|
|
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/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?:
|
|
27
|
+
id?: _intlayer_types6.DictionaryId;
|
|
28
28
|
projectIds?: string[];
|
|
29
|
-
localId?:
|
|
30
|
-
localIds?:
|
|
31
|
-
key:
|
|
29
|
+
localId?: _intlayer_types6.LocalDictionaryId;
|
|
30
|
+
localIds?: _intlayer_types6.LocalDictionaryId[];
|
|
31
|
+
key: _intlayer_types6.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?:
|
|
39
|
+
fill?: _intlayer_types6.Fill;
|
|
40
40
|
filled?: true;
|
|
41
41
|
priority?: number;
|
|
42
42
|
live?: boolean;
|
|
43
|
-
location?:
|
|
43
|
+
location?: _intlayer_types6.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
|
|
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/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?:
|
|
19
|
+
id?: _intlayer_types0.DictionaryId;
|
|
20
20
|
projectIds?: string[];
|
|
21
|
-
localId?:
|
|
22
|
-
localIds?:
|
|
23
|
-
key:
|
|
21
|
+
localId?: _intlayer_types0.LocalDictionaryId;
|
|
22
|
+
localIds?: _intlayer_types0.LocalDictionaryId[];
|
|
23
|
+
key: _intlayer_types0.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?:
|
|
31
|
+
fill?: _intlayer_types0.Fill;
|
|
32
32
|
filled?: true;
|
|
33
33
|
priority?: number;
|
|
34
34
|
live?: boolean;
|
|
35
|
-
location?:
|
|
35
|
+
location?: _intlayer_types0.DictionaryLocation;
|
|
36
36
|
};
|
|
37
37
|
//#endregion
|
|
38
38
|
export { filterTranslationsOnlyPlugin, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary };
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,GAmBA,oBAnBA,CAmBqB,CAnBrB,EAmBwB,uBAnBxB,EAmBiD,CAnBjD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAoCA;AAcA;;;;;;AAIqB,KAlBT,OAAA,GAkBS;EAAP,EAAA,EAAA,MAAA;EACR,SAAA,EAAA,CAAA,IAAA,EAAA,GAAA,EAAA,GAAA,OAAA;EAAgB,SAAA,EAAA,CAAA,IAAA,EAAA,GAAA,EAAA,KAAA,EAdX,SAcW,EAAA,WAAA,EAAA,CAAA,IAAA,EAAA,GAAA,EAAA,KAAA,EAbc,SAad,EAAA,GAAA,GAAA,EAAA,GAAA,GAAA;CACO;;;;AACA,KAPjB,eAOiB,CAAA,CAAA,EAAA,CAAA,EAAA,UAPe,aAOf,CAAA,GAPgC,CAOhC,SAAA;EAAQ,QAAA,EANzB,QAMyB,GAAA,MAAA;EAAI,CALtC,QAAA,CAAS,WAAA,CAK6B,EAAA,KAAA,EAAA;CAAjC,GAHJ,CAGI,SAHM,MAGN,CAHa,WAGb,EAAA,OAAA,CAAA,GAFF,CAEE,SAAA,MAFc,CAEd,GADA,oBACA,CADqB,CACrB,CADuB,CACvB,CAAA,EAD2B,CAC3B,CAAA,GAAA,oBAAA,CAAqB,CAArB,CAAA,MAA6B,CAA7B,CAAA,EAAiC,CAAjC,CAAA,GAAA,KAAA,GAAA,KAAA;;AAKK,cAAA,
|
|
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
|
|
26
|
+
declare const getTranslation: <Content = string>(languageContent: StrictModeLocaleMap<Content>, locale: LocalesValues, fallback?: LocalesValues) => 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":";;;;;;
|
|
1
|
+
{"version":3,"file":"getTranslation.d.ts","names":[],"sources":["../../../src/interpreter/getTranslation.ts"],"sourcesContent":[],"mappings":";;;;;;AAoFA;;;;;;;;;;;;;;;;;;;cAAa,oDACM,oBAAoB,kBAC7B,0BACG,kBACV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enumeration.d.ts","names":[],"sources":["../../../../src/transpiler/enumeration/enumeration.ts"],"sourcesContent":[],"mappings":";;;KAEK,QAAA;KACA,QAAA;AAH2E,KAI3E,OAAA,GAAU,QAFF,GAEa,QAFb;AAAA,KAIR,KAAA,GAAQ,OAHA;AAAA,KAIR,WAAA,GAHO,IAGW,OAHR,EAAA;AAAmB,KAI7B,QAAA,GAFK,IAEU,OAFP,EAAA;AAAO,KAGf,eAAA,GAFW,KAEY,OAFL,EAAA;AAAO,KAGzB,QAAA,GAFQ,IAEO,
|
|
1
|
+
{"version":3,"file":"enumeration.d.ts","names":[],"sources":["../../../../src/transpiler/enumeration/enumeration.ts"],"sourcesContent":[],"mappings":";;;KAEK,QAAA;KACA,QAAA;AAH2E,KAI3E,OAAA,GAAU,QAFF,GAEa,QAFb;AAAA,KAIR,KAAA,GAAQ,OAHA;AAAA,KAIR,WAAA,GAHO,IAGW,OAHR,EAAA;AAAmB,KAI7B,QAAA,GAFK,IAEU,OAFP,EAAA;AAAO,KAGf,eAAA,GAFW,KAEY,OAFL,EAAA;AAAO,KAGzB,QAAA,GAFQ,IAEO,OAFA,EAAA;AAAO,KAGtB,eAAA,GAFe,KAEQ,OAFA,EAAA;AACvB,KAGO,WAAA,GACR,KAJgB,GAKhB,WALuB,GAMvB,QANuB,GAOvB,eAPuB,GAQvB,QARuB,GASvB,eATuB;AACtB,KAUO,uBAVgB,CAAA,OAAO,CAAA,GAUY,OAVZ,CAWjC,MAXiC,CAW1B,WAX0B,EAWb,OAXa,CAAA,CAAA,GAAA;EAEvB,QAAA,CAAA,EAWC,OAXU;CACnB;AACA,KAYQ,kBAZR,CAAA,UAAA,OAAA,CAAA,GAYgD,cAZhD,CAaF,QAAA,CAAS,WAbP,EAcF,uBAdE,CAcsB,OAdtB,CAAA,CAAA;;;;;;AAMJ;;;;;;;AAMA;;;;;;AAGE;cAqBI,WAA0D,EAAA,CAAA,OAAA,CAAA,CAAA,OAAA,CAAA,EAAxB,uBAAwB,CAAA,OAAA,CAAA,EAAA,GAAQ,cAAR,CAAQ,QAAA,CAAA,WAAR,EAAQ,uBAAR,CAAQ,OAAR,CAAA,EAAA,CAAA,CAAA,CAAA"}
|
|
@@ -23,7 +23,7 @@ type TranslationContent<Content = unknown, RecordContent extends StrictModeLocal
|
|
|
23
23
|
* - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
|
|
24
24
|
*/
|
|
25
25
|
declare const translation: <Content = unknown, ContentRecord extends StrictModeLocaleMap<Content> = StrictModeLocaleMap<Content>>(content: ContentRecord) => TypedNodeModel<NodeType.Translation, ContentRecord, {
|
|
26
|
-
nodeType: "translation"
|
|
26
|
+
nodeType: NodeType.Translation | "translation";
|
|
27
27
|
} & {
|
|
28
28
|
translation: ContentRecord;
|
|
29
29
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation.d.ts","names":[],"sources":["../../../../src/transpiler/translation/translation.ts"],"sourcesContent":[],"mappings":";;;KAOY,4DAGR,oBAAoB,WAAW,oBAAoB,YACnD,eAAe,QAAA,CAAS,aAAa;;AAJzC;;;;;;;;;AAIwD;;;;;;;;;;cAsBlD,WAKkB,EAAA,CAAA,UAAA,OAAA,EAAA,sBAFpB,mBAEoB,CAFA,OAEA,CAAA,GAFW,mBAEX,CAF+B,OAE/B,CAAA,CAAA,CAAA,OAAA,EAAb,aAAa,EAAA,GAAA,cAAA,CAAA,QAAA,CAAA,WAAA,EAAA,aAAA,EAAA;EAAA,QAAA,
|
|
1
|
+
{"version":3,"file":"translation.d.ts","names":[],"sources":["../../../../src/transpiler/translation/translation.ts"],"sourcesContent":[],"mappings":";;;KAOY,4DAGR,oBAAoB,WAAW,oBAAoB,YACnD,eAAe,QAAA,CAAS,aAAa;;AAJzC;;;;;;;;;AAIwD;;;;;;;;;;cAsBlD,WAKkB,EAAA,CAAA,UAAA,OAAA,EAAA,sBAFpB,mBAEoB,CAFA,OAEA,CAAA,GAFW,mBAEX,CAF+B,OAE/B,CAAA,CAAA,CAAA,OAAA,EAAb,aAAa,EAAA,GAAA,cAAA,CAAA,QAAA,CAAA,WAAA,EAAA,aAAA,EAAA;EAAA,QAAA,sBAAA,GAAA,aAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/core",
|
|
3
|
-
"version": "7.3.2-canary.
|
|
3
|
+
"version": "7.3.2-canary.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
|
|
6
6
|
"keywords": [
|
|
@@ -102,11 +102,11 @@
|
|
|
102
102
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
103
103
|
},
|
|
104
104
|
"dependencies": {
|
|
105
|
-
"@intlayer/api": "7.3.2-canary.
|
|
106
|
-
"@intlayer/config": "7.3.2-canary.
|
|
107
|
-
"@intlayer/dictionaries-entry": "7.3.2-canary.
|
|
108
|
-
"@intlayer/types": "7.3.2-canary.
|
|
109
|
-
"@intlayer/unmerged-dictionaries-entry": "7.3.2-canary.
|
|
105
|
+
"@intlayer/api": "7.3.2-canary.1",
|
|
106
|
+
"@intlayer/config": "7.3.2-canary.1",
|
|
107
|
+
"@intlayer/dictionaries-entry": "7.3.2-canary.1",
|
|
108
|
+
"@intlayer/types": "7.3.2-canary.1",
|
|
109
|
+
"@intlayer/unmerged-dictionaries-entry": "7.3.2-canary.1",
|
|
110
110
|
"deepmerge": "4.3.1"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
@@ -115,9 +115,9 @@
|
|
|
115
115
|
"@utils/ts-config-types": "1.0.4",
|
|
116
116
|
"@utils/tsdown-config": "1.0.4",
|
|
117
117
|
"rimraf": "6.1.2",
|
|
118
|
-
"tsdown": "0.16.
|
|
118
|
+
"tsdown": "0.16.8",
|
|
119
119
|
"typescript": "5.9.3",
|
|
120
|
-
"vitest": "4.0.
|
|
120
|
+
"vitest": "4.0.14"
|
|
121
121
|
},
|
|
122
122
|
"engines": {
|
|
123
123
|
"node": ">=14.18"
|