@intlayer/core 8.7.11-canary.0 → 8.7.12
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/plugins.cjs +7 -35
- package/dist/cjs/interpreter/getContent/plugins.cjs.map +1 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs +4 -17
- package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
- package/dist/cjs/localization/getPrefix.cjs +2 -12
- package/dist/cjs/localization/getPrefix.cjs.map +1 -1
- package/dist/esm/interpreter/getContent/plugins.mjs +7 -35
- package/dist/esm/interpreter/getContent/plugins.mjs.map +1 -1
- package/dist/esm/localization/getLocalizedUrl.mjs +4 -17
- package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
- package/dist/esm/localization/getPrefix.mjs +2 -12
- package/dist/esm/localization/getPrefix.mjs.map +1 -1
- package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
- package/dist/types/localization/getLocalizedUrl.d.ts.map +1 -1
- package/dist/types/localization/getPrefix.d.ts.map +1 -1
- package/package.json +6 -6
|
@@ -10,34 +10,6 @@ let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
|
|
|
10
10
|
_intlayer_types_nodeType = require_runtime.__toESM(_intlayer_types_nodeType);
|
|
11
11
|
|
|
12
12
|
//#region src/interpreter/getContent/plugins.ts
|
|
13
|
-
/**
|
|
14
|
-
* True when the translation node type is explicitly disabled at build time.
|
|
15
|
-
*/
|
|
16
|
-
const TREE_SHAKE_TRANSLATION = process.env["INTLAYER_NODE_TYPE_TRANSLATION"] === "false";
|
|
17
|
-
/**
|
|
18
|
-
* True when the enumeration node type is explicitly disabled at build time.
|
|
19
|
-
*/
|
|
20
|
-
const TREE_SHAKE_ENUMERATION = process.env["INTLAYER_NODE_TYPE_ENUMERATION"] === "false";
|
|
21
|
-
/**
|
|
22
|
-
* True when the condition node type is explicitly disabled at build time.
|
|
23
|
-
*/
|
|
24
|
-
const TREE_SHAKE_CONDITION = process.env["INTLAYER_NODE_TYPE_CONDITION"] === "false";
|
|
25
|
-
/**
|
|
26
|
-
* True when the insertion node type is explicitly disabled at build time.
|
|
27
|
-
*/
|
|
28
|
-
const TREE_SHAKE_INSERTION = process.env["INTLAYER_NODE_TYPE_INSERTION"] === "false";
|
|
29
|
-
/**
|
|
30
|
-
* True when the gender node type is explicitly disabled at build time.
|
|
31
|
-
*/
|
|
32
|
-
const TREE_SHAKE_GENDER = process.env["INTLAYER_NODE_TYPE_GENDER"] === "false";
|
|
33
|
-
/**
|
|
34
|
-
* True when the nested node type is explicitly disabled at build time.
|
|
35
|
-
*/
|
|
36
|
-
const TREE_SHAKE_NESTED = process.env["INTLAYER_NODE_TYPE_NESTED"] === "false";
|
|
37
|
-
/**
|
|
38
|
-
* True when the file node type is explicitly disabled at build time.
|
|
39
|
-
*/
|
|
40
|
-
const TREE_SHAKE_FILE = process.env["INTLAYER_NODE_TYPE_FILE"] === "false";
|
|
41
13
|
/** ---------------------------------------------
|
|
42
14
|
* FALLBACK PLUGIN
|
|
43
15
|
*
|
|
@@ -49,7 +21,7 @@ const fallbackPlugin = {
|
|
|
49
21
|
transform: (node) => node
|
|
50
22
|
};
|
|
51
23
|
/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
|
|
52
|
-
const translationPlugin = (locale, fallback) =>
|
|
24
|
+
const translationPlugin = (locale, fallback) => process.env["INTLAYER_NODE_TYPE_TRANSLATION"] === "false" ? fallbackPlugin : {
|
|
53
25
|
id: "translation-plugin",
|
|
54
26
|
canHandle: (node) => typeof node === "object" && node?.nodeType === _intlayer_types_nodeType.TRANSLATION,
|
|
55
27
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -70,7 +42,7 @@ const translationPlugin = (locale, fallback) => TREE_SHAKE_TRANSLATION ? fallbac
|
|
|
70
42
|
}
|
|
71
43
|
};
|
|
72
44
|
/** Enumeration plugin. Replaces node with a function that takes quantity => string. */
|
|
73
|
-
const enumerationPlugin =
|
|
45
|
+
const enumerationPlugin = process.env["INTLAYER_NODE_TYPE_ENUMERATION"] === "false" ? fallbackPlugin : {
|
|
74
46
|
id: "enumeration-plugin",
|
|
75
47
|
canHandle: (node) => typeof node === "object" && node?.nodeType === _intlayer_types_nodeType.ENUMERATION,
|
|
76
48
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -95,7 +67,7 @@ const enumerationPlugin = TREE_SHAKE_ENUMERATION ? fallbackPlugin : {
|
|
|
95
67
|
}
|
|
96
68
|
};
|
|
97
69
|
/** Condition plugin. Replaces node with a function that takes boolean => string. */
|
|
98
|
-
const conditionPlugin =
|
|
70
|
+
const conditionPlugin = process.env["INTLAYER_NODE_TYPE_CONDITION"] === "false" ? fallbackPlugin : {
|
|
99
71
|
id: "condition-plugin",
|
|
100
72
|
canHandle: (node) => typeof node === "object" && node?.nodeType === _intlayer_types_nodeType.CONDITION,
|
|
101
73
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -120,7 +92,7 @@ const conditionPlugin = TREE_SHAKE_CONDITION ? fallbackPlugin : {
|
|
|
120
92
|
}
|
|
121
93
|
};
|
|
122
94
|
/** Insertion plugin. Replaces node with a function that takes quantity => string. */
|
|
123
|
-
const insertionPlugin =
|
|
95
|
+
const insertionPlugin = process.env["INTLAYER_NODE_TYPE_INSERTION"] === "false" ? fallbackPlugin : {
|
|
124
96
|
id: "insertion-plugin",
|
|
125
97
|
canHandle: (node) => typeof node === "object" && node?.nodeType === _intlayer_types_nodeType.INSERTION,
|
|
126
98
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -155,7 +127,7 @@ const insertionPlugin = TREE_SHAKE_INSERTION ? fallbackPlugin : {
|
|
|
155
127
|
}
|
|
156
128
|
};
|
|
157
129
|
/** Gender plugin. Replaces node with a function that takes gender => string. */
|
|
158
|
-
const genderPlugin =
|
|
130
|
+
const genderPlugin = process.env["INTLAYER_NODE_TYPE_GENDER"] === "false" ? fallbackPlugin : {
|
|
159
131
|
id: "gender-plugin",
|
|
160
132
|
canHandle: (node) => typeof node === "object" && node?.nodeType === _intlayer_types_nodeType.GENDER,
|
|
161
133
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -176,7 +148,7 @@ const genderPlugin = TREE_SHAKE_GENDER ? fallbackPlugin : {
|
|
|
176
148
|
}
|
|
177
149
|
};
|
|
178
150
|
/** Nested plugin. Replaces node with the result of `getNesting`. */
|
|
179
|
-
const nestedPlugin = (locale) =>
|
|
151
|
+
const nestedPlugin = (locale) => process.env["INTLAYER_NODE_TYPE_NESTED"] === "false" ? fallbackPlugin : {
|
|
180
152
|
id: "nested-plugin",
|
|
181
153
|
canHandle: (node) => typeof node === "object" && (node?.nodeType === _intlayer_types_nodeType.NESTED || node?.nodeType === "n"),
|
|
182
154
|
transform: (node, props) => require_interpreter_getNesting.getNesting(node[_intlayer_types_nodeType.NESTED].dictionaryKey, node[_intlayer_types_nodeType.NESTED].path, {
|
|
@@ -185,7 +157,7 @@ const nestedPlugin = (locale) => TREE_SHAKE_NESTED ? fallbackPlugin : {
|
|
|
185
157
|
})
|
|
186
158
|
};
|
|
187
159
|
/** File plugin. Replaces node with the result of `getNesting`. */
|
|
188
|
-
const filePlugin =
|
|
160
|
+
const filePlugin = process.env["INTLAYER_NODE_TYPE_FILE"] === "false" ? fallbackPlugin : {
|
|
189
161
|
id: "file-plugin",
|
|
190
162
|
canHandle: (node) => typeof node === "object" && node?.nodeType === _intlayer_types_nodeType.FILE,
|
|
191
163
|
transform: (node, props, deepTransform) => deepTransform(node.content, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.cjs","names":["NodeTypes","getTranslation","getEnumeration","getCondition","getInsertion","getGender","getNesting"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\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// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/**\n * True when the translation node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_TRANSLATION =\n process.env['INTLAYER_NODE_TYPE_TRANSLATION'] === 'false';\n\n/**\n * True when the enumeration node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_ENUMERATION =\n process.env['INTLAYER_NODE_TYPE_ENUMERATION'] === 'false';\n\n/**\n * True when the condition node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_CONDITION =\n process.env['INTLAYER_NODE_TYPE_CONDITION'] === 'false';\n\n/**\n * True when the insertion node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_INSERTION =\n process.env['INTLAYER_NODE_TYPE_INSERTION'] === 'false';\n\n/**\n * True when the gender node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_GENDER = process.env['INTLAYER_NODE_TYPE_GENDER'] === 'false';\n\n/**\n * True when the nested node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_NESTED = process.env['INTLAYER_NODE_TYPE_NESTED'] === 'false';\n\n/**\n * True when the file node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_FILE = process.env['INTLAYER_NODE_TYPE_FILE'] === 'false';\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 * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n TREE_SHAKE_TRANSLATION\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\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 [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins = TREE_SHAKE_ENUMERATION\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins = TREE_SHAKE_CONDITION\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins = TREE_SHAKE_INSERTION\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.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 * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins = TREE_SHAKE_GENDER\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 = (locale?: LocalesValues): Plugins =>\n TREE_SHAKE_NESTED\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n getNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 = TREE_SHAKE_FILE\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.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 enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<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 gender: 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<T, S, 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> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> 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 CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.cjs","names":["NodeTypes","getTranslation","getEnumeration","getCondition","getInsertion","getGender","getNesting"],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\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// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\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 * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n process.env['INTLAYER_NODE_TYPE_TRANSLATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\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 [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_ENUMERATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_CONDITION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_INSERTION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.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 * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_GENDER'] === 'false'\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 = (locale?: LocalesValues): Plugins =>\n process.env['INTLAYER_NODE_TYPE_NESTED'] === 'false'\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n getNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 process.env['INTLAYER_NODE_TYPE_FILE'] === 'false'\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.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 enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<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 gender: 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<T, S, 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> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> 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 CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":"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"}
|
|
@@ -7,19 +7,6 @@ const require_localization_rewriteUtils = require('./rewriteUtils.cjs');
|
|
|
7
7
|
let _intlayer_config_built = require("@intlayer/config/built");
|
|
8
8
|
|
|
9
9
|
//#region src/localization/getLocalizedUrl.ts
|
|
10
|
-
/**
|
|
11
|
-
* True when the build-time routing mode is known and is NOT 'no-prefix'.
|
|
12
|
-
*/
|
|
13
|
-
const TREE_SHAKE_NO_PREFIX = process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "no-prefix";
|
|
14
|
-
/**
|
|
15
|
-
* True when the build-time routing mode is known and is NOT 'search-params'.
|
|
16
|
-
*/
|
|
17
|
-
const TREE_SHAKE_SEARCH_PARAMS = process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "search-params";
|
|
18
|
-
/**
|
|
19
|
-
* True when no domain routing is configured at build time
|
|
20
|
-
* (INTLAYER_ROUTING_DOMAINS === 'false').
|
|
21
|
-
*/
|
|
22
|
-
const TREE_SHAKE_DOMAINS = process.env["INTLAYER_ROUTING_DOMAINS"] === "false";
|
|
23
10
|
/** Strips the protocol and returns the bare hostname of a domain string. */
|
|
24
11
|
const extractHostname = (domain) => {
|
|
25
12
|
try {
|
|
@@ -71,16 +58,16 @@ const getLocalizedUrl = (url, currentLocale = _intlayer_config_built.internation
|
|
|
71
58
|
const { defaultLocale, mode, locales, rewrite, domains, currentDomain } = require_localization_getPrefix.resolveRoutingConfig(options);
|
|
72
59
|
const urlWithoutLocale = require_localization_getPathWithoutLocale.getPathWithoutLocale(url, locales);
|
|
73
60
|
const rewriteRules = require_localization_rewriteUtils.getRewriteRules(rewrite, "url");
|
|
74
|
-
if (!
|
|
61
|
+
if (!(process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "no-prefix") && mode === "no-prefix") return require_localization_rewriteUtils.getLocalizedPath(require_localization_rewriteUtils.getCanonicalPath(urlWithoutLocale, void 0, rewriteRules), currentLocale, rewriteRules).path;
|
|
75
62
|
const isAbsoluteUrl = require_utils_checkIsURLAbsolute.checkIsURLAbsolute(urlWithoutLocale);
|
|
76
63
|
const parsedUrl = isAbsoluteUrl ? new URL(urlWithoutLocale) : new URL(urlWithoutLocale, "http://example.com");
|
|
77
64
|
const translatedPathname = require_localization_rewriteUtils.getLocalizedPath(require_localization_rewriteUtils.getCanonicalPath(parsedUrl.pathname, void 0, rewriteRules), currentLocale, rewriteRules).path;
|
|
78
|
-
const detectedCurrentHostname =
|
|
79
|
-
const localeDomain =
|
|
65
|
+
const detectedCurrentHostname = process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" ? extractHostname(currentDomain ?? (isAbsoluteUrl ? parsedUrl.hostname : void 0) ?? (typeof window !== "undefined" ? window?.location?.hostname : void 0) ?? "") || null : null;
|
|
66
|
+
const localeDomain = process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" ? domains?.[currentLocale] : void 0;
|
|
80
67
|
const localeDomainHostname = localeDomain ? extractHostname(localeDomain) : null;
|
|
81
68
|
const normalizedDomain = localeDomainHostname !== null && detectedCurrentHostname !== null && localeDomainHostname !== detectedCurrentHostname && localeDomain ? /^https?:\/\//.test(localeDomain) ? localeDomain : `https://${localeDomain}` : null;
|
|
82
69
|
const baseUrl = normalizedDomain ? normalizedDomain : isAbsoluteUrl ? `${parsedUrl.protocol}//${parsedUrl.host}` : "";
|
|
83
|
-
if (!
|
|
70
|
+
if (!(process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "search-params") && mode === "search-params") {
|
|
84
71
|
const searchParams = new URLSearchParams(parsedUrl.search);
|
|
85
72
|
searchParams.set("locale", currentLocale.toString());
|
|
86
73
|
const queryParams = searchParams.toString();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.cjs","names":["internationalization","resolveRoutingConfig","getPathWithoutLocale","getRewriteRules","getLocalizedPath","getCanonicalPath","checkIsURLAbsolute","getPrefix"],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.cjs","names":["internationalization","resolveRoutingConfig","getPathWithoutLocale","getRewriteRules","getLocalizedPath","getCanonicalPath","checkIsURLAbsolute","getPrefix"],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport {\n getPrefix,\n type RoutingOptions,\n resolveRoutingConfig,\n} from './getPrefix';\nimport {\n getCanonicalPath,\n getLocalizedPath,\n getRewriteRules,\n} from './rewriteUtils';\n\nexport type { RoutingOptions };\n\n/** Strips the protocol and returns the bare hostname of a domain string. */\nconst extractHostname = (domain: string): string => {\n try {\n return /^https?:\\/\\//.test(domain) ? new URL(domain).hostname : domain;\n } catch {\n return domain;\n }\n};\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @param options.currentDomain - Hostname of the page being rendered. Used to decide\n * whether to emit a relative URL (same domain) or an absolute URL (cross-domain).\n * Auto-detected from the input URL or `window.location` when omitted.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues = internationalization?.defaultLocale,\n options: RoutingOptions = {}\n): string => {\n const { defaultLocale, mode, locales, rewrite, domains, currentDomain } =\n resolveRoutingConfig(options);\n\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n const rewriteRules = getRewriteRules(rewrite, 'url');\n\n if (\n !(\n process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'no-prefix'\n ) &&\n mode === 'no-prefix'\n ) {\n return getLocalizedPath(\n getCanonicalPath(urlWithoutLocale, undefined, rewriteRules),\n currentLocale as Locale,\n rewriteRules\n ).path;\n }\n\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n const translatedPathname = getLocalizedPath(\n getCanonicalPath(parsedUrl.pathname, undefined, rewriteRules),\n currentLocale as Locale,\n rewriteRules\n ).path;\n\n // ── Domain routing ────────────────────────────────────────────────────────\n // Resolve the \"current\" hostname so we can choose between a relative URL\n // (same domain) and an absolute URL (cross-domain).\n //\n // Detection priority:\n // 1. Explicit `currentDomain` option passed by the caller.\n // 2. Hostname extracted from an absolute input URL.\n // 3. `window.location.hostname` in browser environments.\n // When none of these is available we fall back to always generating an\n // absolute URL (the previous behaviour, safe for SSR/static generation).\n const detectedCurrentHostname =\n process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false'\n ? extractHostname(\n currentDomain ??\n (isAbsoluteUrl ? parsedUrl.hostname : undefined) ??\n (typeof window !== 'undefined'\n ? window?.location?.hostname\n : undefined) ??\n ''\n ) || null\n : null;\n\n const localeDomain =\n process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false'\n ? domains?.[currentLocale as LocalesValues]\n : undefined;\n\n const localeDomainHostname = localeDomain\n ? extractHostname(localeDomain)\n : null;\n\n // Only prepend the locale's domain when it differs from the current hostname.\n const isCrossDomain =\n localeDomainHostname !== null &&\n detectedCurrentHostname !== null &&\n localeDomainHostname !== detectedCurrentHostname;\n\n const normalizedDomain =\n isCrossDomain && localeDomain\n ? /^https?:\\/\\//.test(localeDomain)\n ? localeDomain\n : `https://${localeDomain}`\n : null;\n\n const baseUrl = normalizedDomain\n ? normalizedDomain\n : isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n // ─────────────────────────────────────────────────────────────────────────\n\n if (\n !(\n process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'search-params'\n ) &&\n mode === 'search-params'\n ) {\n const searchParams = new URLSearchParams(parsedUrl.search);\n\n searchParams.set('locale', currentLocale.toString());\n\n const queryParams = searchParams.toString();\n const path = queryParams\n ? `${translatedPathname}?${queryParams}`\n : translatedPathname;\n\n return `${baseUrl}${path}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, {\n defaultLocale,\n mode,\n locales,\n domains,\n });\n\n let localizedPath = `/${prefix}${translatedPathname}`.replace(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n return `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n};\n"],"mappings":";;;;;;;;;;AAwBA,MAAM,mBAAmB,WAA2B;AAClD,KAAI;AACF,SAAO,eAAe,KAAK,OAAO,GAAG,IAAI,IAAI,OAAO,CAAC,WAAW;SAC1D;AACN,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CX,MAAa,mBACX,KACA,gBAA+BA,6CAAsB,eACrD,UAA0B,EAAE,KACjB;CACX,MAAM,EAAE,eAAe,MAAM,SAAS,SAAS,SAAS,kBACtDC,oDAAqB,QAAQ;CAE/B,MAAM,mBAAmBC,+DAAqB,KAAK,QAAQ;CAC3D,MAAM,eAAeC,kDAAgB,SAAS,MAAM;AAEpD,KACE,EACE,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B,gBAE3C,SAAS,YAET,QAAOC,mDACLC,mDAAiB,kBAAkB,QAAW,aAAa,EAC3D,eACA,aACD,CAAC;CAGJ,MAAM,gBAAgBC,oDAAmB,iBAAiB;CAC1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAEnD,MAAM,qBAAqBF,mDACzBC,mDAAiB,UAAU,UAAU,QAAW,aAAa,EAC7D,eACA,aACD,CAAC;CAYF,MAAM,0BACJ,QAAQ,IAAI,gCAAgC,UACxC,gBACE,kBACG,gBAAgB,UAAU,WAAW,YACrC,OAAO,WAAW,cACf,QAAQ,UAAU,WAClB,WACJ,GACH,IAAI,OACL;CAEN,MAAM,eACJ,QAAQ,IAAI,gCAAgC,UACxC,UAAU,iBACV;CAEN,MAAM,uBAAuB,eACzB,gBAAgB,aAAa,GAC7B;CAQJ,MAAM,mBAJJ,yBAAyB,QACzB,4BAA4B,QAC5B,yBAAyB,2BAGR,eACb,eAAe,KAAK,aAAa,GAC/B,eACA,WAAW,iBACb;CAEN,MAAM,UAAU,mBACZ,mBACA,gBACE,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;AAGN,KACE,EACE,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B,oBAE3C,SAAS,iBACT;EACA,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAE1D,eAAa,IAAI,UAAU,cAAc,UAAU,CAAC;EAEpD,MAAM,cAAc,aAAa,UAAU;AAK3C,SAAO,GAAG,UAJG,cACT,GAAG,mBAAmB,GAAG,gBACzB,qBAEuB,UAAU;;CAGvC,MAAM,EAAE,WAAWE,yCAAU,eAAe;EAC1C;EACA;EACA;EACA;EACD,CAAC;CAEF,IAAI,gBAAgB,IAAI,SAAS,qBAAqB,QAAQ,QAAQ,IAAI;AAE1E,KAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAG5C,QAAO,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU"}
|
|
@@ -5,16 +5,6 @@ let _intlayer_config_defaultValues = require("@intlayer/config/defaultValues");
|
|
|
5
5
|
|
|
6
6
|
//#region src/localization/getPrefix.ts
|
|
7
7
|
/**
|
|
8
|
-
* True when the build-time routing mode is known and is not a prefix-based
|
|
9
|
-
* mode (neither 'prefix-all' nor 'prefix-no-default').
|
|
10
|
-
*/
|
|
11
|
-
const TREE_SHAKE_PREFIX_MODES = process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-all" && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-no-default";
|
|
12
|
-
/**
|
|
13
|
-
* True when no domain routing is configured at build time
|
|
14
|
-
* (INTLAYER_ROUTING_DOMAINS === 'false').
|
|
15
|
-
*/
|
|
16
|
-
const TREE_SHAKE_DOMAINS = process.env["INTLAYER_ROUTING_DOMAINS"] === "false";
|
|
17
|
-
/**
|
|
18
8
|
* Resolves routing configuration by merging provided options with configuration defaults.
|
|
19
9
|
* Single source of truth for default routing config resolution across all localization functions.
|
|
20
10
|
*/
|
|
@@ -61,11 +51,11 @@ const resolveRoutingConfig = (options = {}) => ({
|
|
|
61
51
|
*/
|
|
62
52
|
const getPrefix = (locale, options = {}) => {
|
|
63
53
|
const { defaultLocale, mode, locales, domains } = resolveRoutingConfig(options);
|
|
64
|
-
if (
|
|
54
|
+
if (process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-all" && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-no-default" || !locale || !locales.includes(locale)) return {
|
|
65
55
|
prefix: "",
|
|
66
56
|
localePrefix: void 0
|
|
67
57
|
};
|
|
68
|
-
if (
|
|
58
|
+
if (process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" && domains) {
|
|
69
59
|
const localeDomain = domains[locale];
|
|
70
60
|
if (localeDomain) {
|
|
71
61
|
if (Object.values(domains).filter((domain) => domain === localeDomain).length === 1) return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.cjs","names":["internationalization","DEFAULT_LOCALE","routing","ROUTING_MODE","LOCALES"],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\
|
|
1
|
+
{"version":3,"file":"getPrefix.cjs","names":["internationalization","DEFAULT_LOCALE","routing","ROUTING_MODE","LOCALES"],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { RoutingConfig } from '@intlayer/types/config';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * Shared routing options used across all URL localization functions.\n */\nexport type RoutingOptions = {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n domains?: RoutingConfig['domains'];\n /**\n * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).\n * When provided, `getLocalizedUrl` returns a relative URL for locales whose\n * configured domain matches `currentDomain`, and an absolute URL only when\n * the target locale lives on a different domain.\n *\n * When omitted the function tries to infer it from:\n * 1. The domain of an absolute input URL.\n * 2. `window.location.hostname` in browser environments.\n * Falls back to always generating absolute URLs when neither is available.\n */\n currentDomain?: string;\n};\n\n/**\n * Resolves routing configuration by merging provided options with configuration defaults.\n * Single source of truth for default routing config resolution across all localization functions.\n */\nexport const resolveRoutingConfig = (options: RoutingOptions = {}) => ({\n defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,\n mode: routing?.mode ?? ROUTING_MODE,\n locales: internationalization?.locales ?? LOCALES,\n rewrite: routing?.rewrite,\n domains: routing?.domains,\n ...options,\n});\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The complete base URL path with leading and trailing slashes.\n *\n * @example\n * // https://example.com/fr/about -> '/fr'\n * // https://example.com/about -> ''\n */\n prefix: string;\n /**\n * The locale identifier without slashes.\n *\n * @example\n * // https://example.com/fr/about -> 'fr'\n * // https://example.com/about -> undefined\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = (\n locale: LocalesValues | undefined,\n options: RoutingOptions = {}\n): GetPrefixResult => {\n const { defaultLocale, mode, locales, domains } =\n resolveRoutingConfig(options);\n\n if (\n (process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default') ||\n !locale ||\n !locales.includes(locale)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n };\n }\n\n // If this locale is the only one assigned to its domain, no URL prefix is needed\n // (the domain itself identifies the locale). Shared domains use normal prefix logic.\n if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && domains) {\n const localeDomain = domains[locale as LocalesValues];\n\n if (localeDomain) {\n const localesOnSameDomain = Object.values(domains).filter(\n (domain) => domain === localeDomain\n ).length;\n\n if (localesOnSameDomain === 1) {\n return {\n prefix: '',\n localePrefix: undefined,\n };\n }\n }\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n };\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n };\n};\n"],"mappings":";;;;;;;;;;AA0CA,MAAa,wBAAwB,UAA0B,EAAE,MAAM;CACrE,eAAeA,6CAAsB,iBAAiBC;CACtD,MAAMC,gCAAS,QAAQC;CACvB,SAASH,6CAAsB,WAAWI;CAC1C,SAASF,gCAAS;CAClB,SAASA,gCAAS;CAClB,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DD,MAAa,aACX,QACA,UAA0B,EAAE,KACR;CACpB,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;AAE/B,KACG,QAAQ,IAAI,4BACX,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B,uBAC3C,CAAC,UACD,CAAC,QAAQ,SAAS,OAAO,CAEzB,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAKH,KAAI,QAAQ,IAAI,gCAAgC,WAAW,SAAS;EAClE,MAAM,eAAe,QAAQ;AAE7B,MAAI,cAKF;OAJ4B,OAAO,OAAO,QAAQ,CAAC,QAChD,WAAW,WAAW,aACxB,CAAC,WAE0B,EAC1B,QAAO;IACL,QAAQ;IACR,cAAc;IACf;;;AAUP,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
|
|
@@ -7,34 +7,6 @@ import { getTranslation } from "../getTranslation.mjs";
|
|
|
7
7
|
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
8
8
|
|
|
9
9
|
//#region src/interpreter/getContent/plugins.ts
|
|
10
|
-
/**
|
|
11
|
-
* True when the translation node type is explicitly disabled at build time.
|
|
12
|
-
*/
|
|
13
|
-
const TREE_SHAKE_TRANSLATION = process.env["INTLAYER_NODE_TYPE_TRANSLATION"] === "false";
|
|
14
|
-
/**
|
|
15
|
-
* True when the enumeration node type is explicitly disabled at build time.
|
|
16
|
-
*/
|
|
17
|
-
const TREE_SHAKE_ENUMERATION = process.env["INTLAYER_NODE_TYPE_ENUMERATION"] === "false";
|
|
18
|
-
/**
|
|
19
|
-
* True when the condition node type is explicitly disabled at build time.
|
|
20
|
-
*/
|
|
21
|
-
const TREE_SHAKE_CONDITION = process.env["INTLAYER_NODE_TYPE_CONDITION"] === "false";
|
|
22
|
-
/**
|
|
23
|
-
* True when the insertion node type is explicitly disabled at build time.
|
|
24
|
-
*/
|
|
25
|
-
const TREE_SHAKE_INSERTION = process.env["INTLAYER_NODE_TYPE_INSERTION"] === "false";
|
|
26
|
-
/**
|
|
27
|
-
* True when the gender node type is explicitly disabled at build time.
|
|
28
|
-
*/
|
|
29
|
-
const TREE_SHAKE_GENDER = process.env["INTLAYER_NODE_TYPE_GENDER"] === "false";
|
|
30
|
-
/**
|
|
31
|
-
* True when the nested node type is explicitly disabled at build time.
|
|
32
|
-
*/
|
|
33
|
-
const TREE_SHAKE_NESTED = process.env["INTLAYER_NODE_TYPE_NESTED"] === "false";
|
|
34
|
-
/**
|
|
35
|
-
* True when the file node type is explicitly disabled at build time.
|
|
36
|
-
*/
|
|
37
|
-
const TREE_SHAKE_FILE = process.env["INTLAYER_NODE_TYPE_FILE"] === "false";
|
|
38
10
|
/** ---------------------------------------------
|
|
39
11
|
* FALLBACK PLUGIN
|
|
40
12
|
*
|
|
@@ -46,7 +18,7 @@ const fallbackPlugin = {
|
|
|
46
18
|
transform: (node) => node
|
|
47
19
|
};
|
|
48
20
|
/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
|
|
49
|
-
const translationPlugin = (locale, fallback) =>
|
|
21
|
+
const translationPlugin = (locale, fallback) => process.env["INTLAYER_NODE_TYPE_TRANSLATION"] === "false" ? fallbackPlugin : {
|
|
50
22
|
id: "translation-plugin",
|
|
51
23
|
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.TRANSLATION,
|
|
52
24
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -67,7 +39,7 @@ const translationPlugin = (locale, fallback) => TREE_SHAKE_TRANSLATION ? fallbac
|
|
|
67
39
|
}
|
|
68
40
|
};
|
|
69
41
|
/** Enumeration plugin. Replaces node with a function that takes quantity => string. */
|
|
70
|
-
const enumerationPlugin =
|
|
42
|
+
const enumerationPlugin = process.env["INTLAYER_NODE_TYPE_ENUMERATION"] === "false" ? fallbackPlugin : {
|
|
71
43
|
id: "enumeration-plugin",
|
|
72
44
|
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.ENUMERATION,
|
|
73
45
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -92,7 +64,7 @@ const enumerationPlugin = TREE_SHAKE_ENUMERATION ? fallbackPlugin : {
|
|
|
92
64
|
}
|
|
93
65
|
};
|
|
94
66
|
/** Condition plugin. Replaces node with a function that takes boolean => string. */
|
|
95
|
-
const conditionPlugin =
|
|
67
|
+
const conditionPlugin = process.env["INTLAYER_NODE_TYPE_CONDITION"] === "false" ? fallbackPlugin : {
|
|
96
68
|
id: "condition-plugin",
|
|
97
69
|
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.CONDITION,
|
|
98
70
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -117,7 +89,7 @@ const conditionPlugin = TREE_SHAKE_CONDITION ? fallbackPlugin : {
|
|
|
117
89
|
}
|
|
118
90
|
};
|
|
119
91
|
/** Insertion plugin. Replaces node with a function that takes quantity => string. */
|
|
120
|
-
const insertionPlugin =
|
|
92
|
+
const insertionPlugin = process.env["INTLAYER_NODE_TYPE_INSERTION"] === "false" ? fallbackPlugin : {
|
|
121
93
|
id: "insertion-plugin",
|
|
122
94
|
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.INSERTION,
|
|
123
95
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -152,7 +124,7 @@ const insertionPlugin = TREE_SHAKE_INSERTION ? fallbackPlugin : {
|
|
|
152
124
|
}
|
|
153
125
|
};
|
|
154
126
|
/** Gender plugin. Replaces node with a function that takes gender => string. */
|
|
155
|
-
const genderPlugin =
|
|
127
|
+
const genderPlugin = process.env["INTLAYER_NODE_TYPE_GENDER"] === "false" ? fallbackPlugin : {
|
|
156
128
|
id: "gender-plugin",
|
|
157
129
|
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.GENDER,
|
|
158
130
|
transform: (node, props, deepTransformNode) => {
|
|
@@ -173,7 +145,7 @@ const genderPlugin = TREE_SHAKE_GENDER ? fallbackPlugin : {
|
|
|
173
145
|
}
|
|
174
146
|
};
|
|
175
147
|
/** Nested plugin. Replaces node with the result of `getNesting`. */
|
|
176
|
-
const nestedPlugin = (locale) =>
|
|
148
|
+
const nestedPlugin = (locale) => process.env["INTLAYER_NODE_TYPE_NESTED"] === "false" ? fallbackPlugin : {
|
|
177
149
|
id: "nested-plugin",
|
|
178
150
|
canHandle: (node) => typeof node === "object" && (node?.nodeType === NodeTypes.NESTED || node?.nodeType === "n"),
|
|
179
151
|
transform: (node, props) => getNesting(node[NodeTypes.NESTED].dictionaryKey, node[NodeTypes.NESTED].path, {
|
|
@@ -182,7 +154,7 @@ const nestedPlugin = (locale) => TREE_SHAKE_NESTED ? fallbackPlugin : {
|
|
|
182
154
|
})
|
|
183
155
|
};
|
|
184
156
|
/** File plugin. Replaces node with the result of `getNesting`. */
|
|
185
|
-
const filePlugin =
|
|
157
|
+
const filePlugin = process.env["INTLAYER_NODE_TYPE_FILE"] === "false" ? fallbackPlugin : {
|
|
186
158
|
id: "file-plugin",
|
|
187
159
|
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.FILE,
|
|
188
160
|
transform: (node, props, deepTransform) => deepTransform(node.content, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.mjs","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\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// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\n/**\n * True when the translation node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_TRANSLATION =\n process.env['INTLAYER_NODE_TYPE_TRANSLATION'] === 'false';\n\n/**\n * True when the enumeration node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_ENUMERATION =\n process.env['INTLAYER_NODE_TYPE_ENUMERATION'] === 'false';\n\n/**\n * True when the condition node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_CONDITION =\n process.env['INTLAYER_NODE_TYPE_CONDITION'] === 'false';\n\n/**\n * True when the insertion node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_INSERTION =\n process.env['INTLAYER_NODE_TYPE_INSERTION'] === 'false';\n\n/**\n * True when the gender node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_GENDER = process.env['INTLAYER_NODE_TYPE_GENDER'] === 'false';\n\n/**\n * True when the nested node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_NESTED = process.env['INTLAYER_NODE_TYPE_NESTED'] === 'false';\n\n/**\n * True when the file node type is explicitly disabled at build time.\n */\nconst TREE_SHAKE_FILE = process.env['INTLAYER_NODE_TYPE_FILE'] === 'false';\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 * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n TREE_SHAKE_TRANSLATION\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\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 [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins = TREE_SHAKE_ENUMERATION\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins = TREE_SHAKE_CONDITION\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins = TREE_SHAKE_INSERTION\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.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 * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins = TREE_SHAKE_GENDER\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 = (locale?: LocalesValues): Plugins =>\n TREE_SHAKE_NESTED\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n getNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 = TREE_SHAKE_FILE\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.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 enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<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 gender: 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<T, S, 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> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> 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 CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.mjs","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types/allLocales';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\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// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\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 * FALLBACK PLUGIN\n *\n * Used to fallback a tree-shaken plugin\n * --------------------------------------------- */\n\nexport const fallbackPlugin: Plugins = {\n id: 'fallback-plugin',\n canHandle: () => false,\n transform: (node) => node,\n};\n\n/** ---------------------------------------------\n * TRANSLATION PLUGIN\n * --------------------------------------------- */\n\nexport type UnionKeys<T> = T extends unknown ? keyof T : never;\nexport type ValueAtKey<T, K> = T extends unknown\n ? K extends keyof T\n ? T[K]\n : never\n : never;\n\nexport type TranslationCond<T, S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.TRANSLATION]: infer U;\n}\n ? U extends Record<PropertyKey, unknown>\n ? U[keyof U] extends Record<PropertyKey, unknown>\n ? {\n [K in UnionKeys<U[keyof U]>]: L extends keyof U\n ? K extends keyof U[L]\n ? U[L][K]\n : ValueAtKey<U[keyof U], K>\n : ValueAtKey<U[keyof U], K>;\n } extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : (L extends keyof U ? U[L] : U[keyof U]) extends infer Content\n ? DeepTransformContent<Content, S>\n : never\n : never\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const translationPlugin = (\n locale: LocalesValues,\n fallback?: LocalesValues\n): Plugins =>\n process.env['INTLAYER_NODE_TYPE_TRANSLATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'translation-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.TRANSLATION,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.TRANSLATION] ?? {};\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const childProps = {\n ...props,\n children: original[key as keyof typeof original],\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.TRANSLATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(\n original[key as keyof typeof original],\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 [NodeTypes.ENUMERATION]: object;\n}\n ? (\n quantity: number\n ) => DeepTransformContent<\n T[typeof NodeTypes.ENUMERATION][keyof T[typeof NodeTypes.ENUMERATION]],\n S\n >\n : never;\n\n/** Enumeration plugin. Replaces node with a function that takes quantity => string. */\nexport const enumerationPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_ENUMERATION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'enumeration-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.ENUMERATION,\n transform: (node: EnumerationContent, props, deepTransformNode) => {\n const original = node[NodeTypes.ENUMERATION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as unknown as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.ENUMERATION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: number | { count: number }) => {\n const quantity = typeof arg === 'number' ? arg : arg.count;\n const subResult = getEnumeration(result, quantity);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * CONDITION PLUGIN\n * --------------------------------------------- */\n\nexport type ConditionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.CONDITION]: object;\n}\n ? (\n value: boolean | { value: boolean }\n ) => DeepTransformContent<\n T[typeof NodeTypes.CONDITION][keyof T[typeof NodeTypes.CONDITION]],\n S\n >\n : never;\n\n/** Condition plugin. Replaces node with a function that takes boolean => string. */\nexport const conditionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_CONDITION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'condition-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.CONDITION,\n transform: (node: ConditionContent, props, deepTransformNode) => {\n const original = node[NodeTypes.CONDITION];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.CONDITION, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (arg: boolean | { value: boolean }) => {\n const value = typeof arg === 'boolean' ? arg : arg.value;\n const subResult = getCondition(result as any, value);\n\n if (typeof subResult === 'function' && typeof arg === 'object') {\n return subResult(arg);\n }\n\n return subResult;\n };\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? (\n values: {\n [K in T['fields'][number]]: string | number;\n }\n ) => I extends string\n ? DeepTransformContent<string, S>\n : DeepTransformContent<I, S>\n : never;\n\n/** Insertion plugin. Replaces node with a function that takes quantity => string. */\nexport const insertionPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_INSERTION'] === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.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 * GENDER PLUGIN\n * --------------------------------------------- */\n\nexport type GenderCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.GENDER]: object;\n}\n ? (\n value: Gender\n ) => DeepTransformContent<\n T[typeof NodeTypes.GENDER][keyof T[typeof NodeTypes.GENDER]],\n S\n >\n : never;\n\n/** Gender plugin. Replaces node with a function that takes gender => string. */\nexport const genderPlugin: Plugins =\n process.env['INTLAYER_NODE_TYPE_GENDER'] === 'false'\n ? fallbackPlugin\n : {\n id: 'gender-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.GENDER,\n transform: (node: GenderContent, props, deepTransformNode) => {\n const original = node[NodeTypes.GENDER];\n const result: Record<string, any> = {};\n\n for (const key in original) {\n const child = original[key as keyof typeof original];\n const childProps = {\n ...props,\n children: child,\n keyPath: [\n ...props.keyPath,\n { type: NodeTypes.GENDER, key } as KeyPath,\n ],\n };\n result[key] = deepTransformNode(child, childProps);\n }\n\n return (value: Gender) => getGender(result as any, value);\n },\n };\n\n/** ---------------------------------------------\n * NESTED PLUGIN\n * --------------------------------------------- */\n\nexport type NestedCond<T, S, _L> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 = (locale?: LocalesValues): Plugins =>\n process.env['INTLAYER_NODE_TYPE_NESTED'] === 'false'\n ? fallbackPlugin\n : {\n id: 'nested-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n (node?.nodeType === NodeTypes.NESTED || node?.nodeType === 'n'),\n transform: (node: NestedContent, props) =>\n getNesting(\n node[NodeTypes.NESTED].dictionaryKey,\n node[NodeTypes.NESTED].path,\n {\n ...props,\n locale: (locale ?? props.locale) as Locale,\n }\n ),\n };\n\n/** ---------------------------------------------\n * FILE PLUGIN\n * --------------------------------------------- */\n\nexport type FileCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.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 process.env['INTLAYER_NODE_TYPE_FILE'] === 'false'\n ? fallbackPlugin\n : {\n id: 'file-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.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 enumeration: EnumerationCond<T, S, L>;\n condition: ConditionCond<T, S, L>;\n insertion: InsertionCond<T, S, L>;\n gender: GenderCond<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 gender: 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<T, S, 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> =\n IsAny<T> extends true\n ? T\n : CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L> 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 CheckApplyPlugin<T, keyof IInterpreterPlugin<T, S, L>, S, L>;\n"],"mappings":"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"}
|
|
@@ -5,19 +5,6 @@ import { getCanonicalPath, getLocalizedPath, getRewriteRules } from "./rewriteUt
|
|
|
5
5
|
import { internationalization } from "@intlayer/config/built";
|
|
6
6
|
|
|
7
7
|
//#region src/localization/getLocalizedUrl.ts
|
|
8
|
-
/**
|
|
9
|
-
* True when the build-time routing mode is known and is NOT 'no-prefix'.
|
|
10
|
-
*/
|
|
11
|
-
const TREE_SHAKE_NO_PREFIX = process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "no-prefix";
|
|
12
|
-
/**
|
|
13
|
-
* True when the build-time routing mode is known and is NOT 'search-params'.
|
|
14
|
-
*/
|
|
15
|
-
const TREE_SHAKE_SEARCH_PARAMS = process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "search-params";
|
|
16
|
-
/**
|
|
17
|
-
* True when no domain routing is configured at build time
|
|
18
|
-
* (INTLAYER_ROUTING_DOMAINS === 'false').
|
|
19
|
-
*/
|
|
20
|
-
const TREE_SHAKE_DOMAINS = process.env["INTLAYER_ROUTING_DOMAINS"] === "false";
|
|
21
8
|
/** Strips the protocol and returns the bare hostname of a domain string. */
|
|
22
9
|
const extractHostname = (domain) => {
|
|
23
10
|
try {
|
|
@@ -69,16 +56,16 @@ const getLocalizedUrl = (url, currentLocale = internationalization?.defaultLocal
|
|
|
69
56
|
const { defaultLocale, mode, locales, rewrite, domains, currentDomain } = resolveRoutingConfig(options);
|
|
70
57
|
const urlWithoutLocale = getPathWithoutLocale(url, locales);
|
|
71
58
|
const rewriteRules = getRewriteRules(rewrite, "url");
|
|
72
|
-
if (!
|
|
59
|
+
if (!(process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "no-prefix") && mode === "no-prefix") return getLocalizedPath(getCanonicalPath(urlWithoutLocale, void 0, rewriteRules), currentLocale, rewriteRules).path;
|
|
73
60
|
const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);
|
|
74
61
|
const parsedUrl = isAbsoluteUrl ? new URL(urlWithoutLocale) : new URL(urlWithoutLocale, "http://example.com");
|
|
75
62
|
const translatedPathname = getLocalizedPath(getCanonicalPath(parsedUrl.pathname, void 0, rewriteRules), currentLocale, rewriteRules).path;
|
|
76
|
-
const detectedCurrentHostname =
|
|
77
|
-
const localeDomain =
|
|
63
|
+
const detectedCurrentHostname = process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" ? extractHostname(currentDomain ?? (isAbsoluteUrl ? parsedUrl.hostname : void 0) ?? (typeof window !== "undefined" ? window?.location?.hostname : void 0) ?? "") || null : null;
|
|
64
|
+
const localeDomain = process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" ? domains?.[currentLocale] : void 0;
|
|
78
65
|
const localeDomainHostname = localeDomain ? extractHostname(localeDomain) : null;
|
|
79
66
|
const normalizedDomain = localeDomainHostname !== null && detectedCurrentHostname !== null && localeDomainHostname !== detectedCurrentHostname && localeDomain ? /^https?:\/\//.test(localeDomain) ? localeDomain : `https://${localeDomain}` : null;
|
|
80
67
|
const baseUrl = normalizedDomain ? normalizedDomain : isAbsoluteUrl ? `${parsedUrl.protocol}//${parsedUrl.host}` : "";
|
|
81
|
-
if (!
|
|
68
|
+
if (!(process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "search-params") && mode === "search-params") {
|
|
82
69
|
const searchParams = new URLSearchParams(parsedUrl.search);
|
|
83
70
|
searchParams.set("locale", currentLocale.toString());
|
|
84
71
|
const queryParams = searchParams.toString();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.mjs","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.mjs","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport {\n getPrefix,\n type RoutingOptions,\n resolveRoutingConfig,\n} from './getPrefix';\nimport {\n getCanonicalPath,\n getLocalizedPath,\n getRewriteRules,\n} from './rewriteUtils';\n\nexport type { RoutingOptions };\n\n/** Strips the protocol and returns the bare hostname of a domain string. */\nconst extractHostname = (domain: string): string => {\n try {\n return /^https?:\\/\\//.test(domain) ? new URL(domain).hostname : domain;\n } catch {\n return domain;\n }\n};\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @param options.currentDomain - Hostname of the page being rendered. Used to decide\n * whether to emit a relative URL (same domain) or an absolute URL (cross-domain).\n * Auto-detected from the input URL or `window.location` when omitted.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues = internationalization?.defaultLocale,\n options: RoutingOptions = {}\n): string => {\n const { defaultLocale, mode, locales, rewrite, domains, currentDomain } =\n resolveRoutingConfig(options);\n\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n const rewriteRules = getRewriteRules(rewrite, 'url');\n\n if (\n !(\n process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'no-prefix'\n ) &&\n mode === 'no-prefix'\n ) {\n return getLocalizedPath(\n getCanonicalPath(urlWithoutLocale, undefined, rewriteRules),\n currentLocale as Locale,\n rewriteRules\n ).path;\n }\n\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n const translatedPathname = getLocalizedPath(\n getCanonicalPath(parsedUrl.pathname, undefined, rewriteRules),\n currentLocale as Locale,\n rewriteRules\n ).path;\n\n // ── Domain routing ────────────────────────────────────────────────────────\n // Resolve the \"current\" hostname so we can choose between a relative URL\n // (same domain) and an absolute URL (cross-domain).\n //\n // Detection priority:\n // 1. Explicit `currentDomain` option passed by the caller.\n // 2. Hostname extracted from an absolute input URL.\n // 3. `window.location.hostname` in browser environments.\n // When none of these is available we fall back to always generating an\n // absolute URL (the previous behaviour, safe for SSR/static generation).\n const detectedCurrentHostname =\n process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false'\n ? extractHostname(\n currentDomain ??\n (isAbsoluteUrl ? parsedUrl.hostname : undefined) ??\n (typeof window !== 'undefined'\n ? window?.location?.hostname\n : undefined) ??\n ''\n ) || null\n : null;\n\n const localeDomain =\n process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false'\n ? domains?.[currentLocale as LocalesValues]\n : undefined;\n\n const localeDomainHostname = localeDomain\n ? extractHostname(localeDomain)\n : null;\n\n // Only prepend the locale's domain when it differs from the current hostname.\n const isCrossDomain =\n localeDomainHostname !== null &&\n detectedCurrentHostname !== null &&\n localeDomainHostname !== detectedCurrentHostname;\n\n const normalizedDomain =\n isCrossDomain && localeDomain\n ? /^https?:\\/\\//.test(localeDomain)\n ? localeDomain\n : `https://${localeDomain}`\n : null;\n\n const baseUrl = normalizedDomain\n ? normalizedDomain\n : isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n // ─────────────────────────────────────────────────────────────────────────\n\n if (\n !(\n process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'search-params'\n ) &&\n mode === 'search-params'\n ) {\n const searchParams = new URLSearchParams(parsedUrl.search);\n\n searchParams.set('locale', currentLocale.toString());\n\n const queryParams = searchParams.toString();\n const path = queryParams\n ? `${translatedPathname}?${queryParams}`\n : translatedPathname;\n\n return `${baseUrl}${path}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, {\n defaultLocale,\n mode,\n locales,\n domains,\n });\n\n let localizedPath = `/${prefix}${translatedPathname}`.replace(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n return `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n};\n"],"mappings":";;;;;;;;AAwBA,MAAM,mBAAmB,WAA2B;AAClD,KAAI;AACF,SAAO,eAAe,KAAK,OAAO,GAAG,IAAI,IAAI,OAAO,CAAC,WAAW;SAC1D;AACN,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CX,MAAa,mBACX,KACA,gBAA+B,sBAAsB,eACrD,UAA0B,EAAE,KACjB;CACX,MAAM,EAAE,eAAe,MAAM,SAAS,SAAS,SAAS,kBACtD,qBAAqB,QAAQ;CAE/B,MAAM,mBAAmB,qBAAqB,KAAK,QAAQ;CAC3D,MAAM,eAAe,gBAAgB,SAAS,MAAM;AAEpD,KACE,EACE,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B,gBAE3C,SAAS,YAET,QAAO,iBACL,iBAAiB,kBAAkB,QAAW,aAAa,EAC3D,eACA,aACD,CAAC;CAGJ,MAAM,gBAAgB,mBAAmB,iBAAiB;CAC1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAEnD,MAAM,qBAAqB,iBACzB,iBAAiB,UAAU,UAAU,QAAW,aAAa,EAC7D,eACA,aACD,CAAC;CAYF,MAAM,0BACJ,QAAQ,IAAI,gCAAgC,UACxC,gBACE,kBACG,gBAAgB,UAAU,WAAW,YACrC,OAAO,WAAW,cACf,QAAQ,UAAU,WAClB,WACJ,GACH,IAAI,OACL;CAEN,MAAM,eACJ,QAAQ,IAAI,gCAAgC,UACxC,UAAU,iBACV;CAEN,MAAM,uBAAuB,eACzB,gBAAgB,aAAa,GAC7B;CAQJ,MAAM,mBAJJ,yBAAyB,QACzB,4BAA4B,QAC5B,yBAAyB,2BAGR,eACb,eAAe,KAAK,aAAa,GAC/B,eACA,WAAW,iBACb;CAEN,MAAM,UAAU,mBACZ,mBACA,gBACE,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;AAGN,KACE,EACE,QAAQ,IAAI,4BACZ,QAAQ,IAAI,6BAA6B,oBAE3C,SAAS,iBACT;EACA,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAE1D,eAAa,IAAI,UAAU,cAAc,UAAU,CAAC;EAEpD,MAAM,cAAc,aAAa,UAAU;AAK3C,SAAO,GAAG,UAJG,cACT,GAAG,mBAAmB,GAAG,gBACzB,qBAEuB,UAAU;;CAGvC,MAAM,EAAE,WAAW,UAAU,eAAe;EAC1C;EACA;EACA;EACA;EACD,CAAC;CAEF,IAAI,gBAAgB,IAAI,SAAS,qBAAqB,QAAQ,QAAQ,IAAI;AAE1E,KAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAG5C,QAAO,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU"}
|
|
@@ -3,16 +3,6 @@ import { DEFAULT_LOCALE, LOCALES, ROUTING_MODE } from "@intlayer/config/defaultV
|
|
|
3
3
|
|
|
4
4
|
//#region src/localization/getPrefix.ts
|
|
5
5
|
/**
|
|
6
|
-
* True when the build-time routing mode is known and is not a prefix-based
|
|
7
|
-
* mode (neither 'prefix-all' nor 'prefix-no-default').
|
|
8
|
-
*/
|
|
9
|
-
const TREE_SHAKE_PREFIX_MODES = process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-all" && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-no-default";
|
|
10
|
-
/**
|
|
11
|
-
* True when no domain routing is configured at build time
|
|
12
|
-
* (INTLAYER_ROUTING_DOMAINS === 'false').
|
|
13
|
-
*/
|
|
14
|
-
const TREE_SHAKE_DOMAINS = process.env["INTLAYER_ROUTING_DOMAINS"] === "false";
|
|
15
|
-
/**
|
|
16
6
|
* Resolves routing configuration by merging provided options with configuration defaults.
|
|
17
7
|
* Single source of truth for default routing config resolution across all localization functions.
|
|
18
8
|
*/
|
|
@@ -59,11 +49,11 @@ const resolveRoutingConfig = (options = {}) => ({
|
|
|
59
49
|
*/
|
|
60
50
|
const getPrefix = (locale, options = {}) => {
|
|
61
51
|
const { defaultLocale, mode, locales, domains } = resolveRoutingConfig(options);
|
|
62
|
-
if (
|
|
52
|
+
if (process.env["INTLAYER_ROUTING_MODE"] && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-all" && process.env["INTLAYER_ROUTING_MODE"] !== "prefix-no-default" || !locale || !locales.includes(locale)) return {
|
|
63
53
|
prefix: "",
|
|
64
54
|
localePrefix: void 0
|
|
65
55
|
};
|
|
66
|
-
if (
|
|
56
|
+
if (process.env["INTLAYER_ROUTING_DOMAINS"] !== "false" && domains) {
|
|
67
57
|
const localeDomain = domains[locale];
|
|
68
58
|
if (localeDomain) {
|
|
69
59
|
if (Object.values(domains).filter((domain) => domain === localeDomain).length === 1) return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.mjs","names":[],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\
|
|
1
|
+
{"version":3,"file":"getPrefix.mjs","names":[],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { RoutingConfig } from '@intlayer/types/config';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\n\n/**\n * Shared routing options used across all URL localization functions.\n */\nexport type RoutingOptions = {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n domains?: RoutingConfig['domains'];\n /**\n * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).\n * When provided, `getLocalizedUrl` returns a relative URL for locales whose\n * configured domain matches `currentDomain`, and an absolute URL only when\n * the target locale lives on a different domain.\n *\n * When omitted the function tries to infer it from:\n * 1. The domain of an absolute input URL.\n * 2. `window.location.hostname` in browser environments.\n * Falls back to always generating absolute URLs when neither is available.\n */\n currentDomain?: string;\n};\n\n/**\n * Resolves routing configuration by merging provided options with configuration defaults.\n * Single source of truth for default routing config resolution across all localization functions.\n */\nexport const resolveRoutingConfig = (options: RoutingOptions = {}) => ({\n defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,\n mode: routing?.mode ?? ROUTING_MODE,\n locales: internationalization?.locales ?? LOCALES,\n rewrite: routing?.rewrite,\n domains: routing?.domains,\n ...options,\n});\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The complete base URL path with leading and trailing slashes.\n *\n * @example\n * // https://example.com/fr/about -> '/fr'\n * // https://example.com/about -> ''\n */\n prefix: string;\n /**\n * The locale identifier without slashes.\n *\n * @example\n * // https://example.com/fr/about -> 'fr'\n * // https://example.com/about -> undefined\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = (\n locale: LocalesValues | undefined,\n options: RoutingOptions = {}\n): GetPrefixResult => {\n const { defaultLocale, mode, locales, domains } =\n resolveRoutingConfig(options);\n\n if (\n (process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default') ||\n !locale ||\n !locales.includes(locale)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n };\n }\n\n // If this locale is the only one assigned to its domain, no URL prefix is needed\n // (the domain itself identifies the locale). Shared domains use normal prefix logic.\n if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && domains) {\n const localeDomain = domains[locale as LocalesValues];\n\n if (localeDomain) {\n const localesOnSameDomain = Object.values(domains).filter(\n (domain) => domain === localeDomain\n ).length;\n\n if (localesOnSameDomain === 1) {\n return {\n prefix: '',\n localePrefix: undefined,\n };\n }\n }\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n };\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n };\n};\n"],"mappings":";;;;;;;;AA0CA,MAAa,wBAAwB,UAA0B,EAAE,MAAM;CACrE,eAAe,sBAAsB,iBAAiB;CACtD,MAAM,SAAS,QAAQ;CACvB,SAAS,sBAAsB,WAAW;CAC1C,SAAS,SAAS;CAClB,SAAS,SAAS;CAClB,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DD,MAAa,aACX,QACA,UAA0B,EAAE,KACR;CACpB,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;AAE/B,KACG,QAAQ,IAAI,4BACX,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B,uBAC3C,CAAC,UACD,CAAC,QAAQ,SAAS,OAAO,CAEzB,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAKH,KAAI,QAAQ,IAAI,gCAAgC,WAAW,SAAS;EAClE,MAAM,eAAe,QAAQ;AAE7B,MAAI,cAKF;OAJ4B,OAAO,OAAO,QAAQ,CAAC,QAChD,WAAW,WAAW,aACxB,CAAC,WAE0B,EAC1B,QAAO;IACL,QAAQ;IACR,cAAc;IACf;;;AAUP,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","names":[],"sources":["../../../../src/interpreter/getContent/plugins.ts"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.d.ts","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.d.ts","names":[],"sources":["../../../src/localization/getLocalizedUrl.ts"],"mappings":";;;;;AAuEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,eAAA,GACX,GAAA,UACA,aAAA,GAAe,aAAA,EACf,OAAA,GAAS,cAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.d.ts","names":[],"sources":["../../../src/localization/getPrefix.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"getPrefix.d.ts","names":[],"sources":["../../../src/localization/getPrefix.ts"],"mappings":";;;;;;;AAkBA;KAAY,cAAA;EACV,OAAA,GAAU,aAAA;EACV,aAAA,GAAgB,aAAA;EAChB,IAAA,GAAO,aAAA;EACP,OAAA,GAAU,aAAA;EACV,OAAA,GAAU,aAAA;EAAA;;;;;;;;;;;EAYV,aAAA;AAAA;;;;AAOF;cAAa,oBAAA,GAAwB,OAAA,GAAS,cAAA;WAvBlC,aAAA;;QAEH,aAAA;WACG,aAAA;WACA,aAAA;EAAA;;;;;;;;;;;;;KA4BA,gBAAA;EACV,aAAA,GAAgB,aAAA;EAChB,IAAA,GAAO,aAAA;AAAA;AAAA,KAGG,eAAA;EALgB;;;;;;;EAa1B,MAAA;EAXoB;AAGtB;;;;;;EAgBE,YAAA,EAAc,MAAA;AAAA;;AAoChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,SAAA,GACX,MAAA,EAAQ,aAAA,cACR,OAAA,GAAS,cAAA,KACR,eAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/core",
|
|
3
|
-
"version": "8.7.
|
|
3
|
+
"version": "8.7.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
|
|
6
6
|
"keywords": [
|
|
@@ -168,11 +168,11 @@
|
|
|
168
168
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
169
169
|
},
|
|
170
170
|
"dependencies": {
|
|
171
|
-
"@intlayer/api": "8.7.
|
|
172
|
-
"@intlayer/config": "8.7.
|
|
173
|
-
"@intlayer/dictionaries-entry": "8.7.
|
|
174
|
-
"@intlayer/types": "8.7.
|
|
175
|
-
"@intlayer/unmerged-dictionaries-entry": "8.7.
|
|
171
|
+
"@intlayer/api": "8.7.12",
|
|
172
|
+
"@intlayer/config": "8.7.12",
|
|
173
|
+
"@intlayer/dictionaries-entry": "8.7.12",
|
|
174
|
+
"@intlayer/types": "8.7.12",
|
|
175
|
+
"@intlayer/unmerged-dictionaries-entry": "8.7.12",
|
|
176
176
|
"defu": "6.1.7"
|
|
177
177
|
},
|
|
178
178
|
"devDependencies": {
|