@intlayer/core 9.5.0 → 9.5.2
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/index.cjs +2 -0
- package/dist/cjs/localization/getPrefix.cjs +6 -6
- package/dist/cjs/localization/getPrefix.cjs.map +1 -1
- package/dist/cjs/messageFormat/index.cjs +2 -0
- package/dist/cjs/messageFormat/resolveMessage.cjs +41 -11
- package/dist/cjs/messageFormat/resolveMessage.cjs.map +1 -1
- package/dist/cjs/utils/getCookie.cjs +1 -1
- package/dist/cjs/utils/getCookie.cjs.map +1 -1
- package/dist/esm/index.mjs +2 -2
- package/dist/esm/localization/getPrefix.mjs +6 -6
- package/dist/esm/localization/getPrefix.mjs.map +1 -1
- package/dist/esm/messageFormat/index.mjs +2 -2
- package/dist/esm/messageFormat/resolveMessage.mjs +40 -12
- package/dist/esm/messageFormat/resolveMessage.mjs.map +1 -1
- package/dist/esm/utils/getCookie.mjs +1 -1
- package/dist/esm/utils/getCookie.mjs.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/localization/getPrefix.d.ts.map +1 -1
- package/dist/types/messageFormat/index.d.ts +2 -2
- package/dist/types/messageFormat/resolveMessage.d.ts +36 -1
- package/dist/types/messageFormat/resolveMessage.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/cjs/index.cjs
CHANGED
|
@@ -215,6 +215,7 @@ exports.compileWithOptions = require_markdown_compiler.compileWithOptions;
|
|
|
215
215
|
exports.cond = require_transpiler_condition_condition.cond;
|
|
216
216
|
exports.conditionPlugin = require_interpreter_getContent_plugins.conditionPlugin;
|
|
217
217
|
exports.createCompiler = require_markdown_compiler.createCompiler;
|
|
218
|
+
exports.createMessageResolver = require_messageFormat_resolveMessage.createMessageResolver;
|
|
218
219
|
exports.createRenderer = require_markdown_renderer.createRenderer;
|
|
219
220
|
exports.currency = require_formatters_currency.currency;
|
|
220
221
|
exports.cx = require_markdown_utils.cx;
|
|
@@ -390,6 +391,7 @@ exports.resolveEffectiveVariantId = require_dictionaryManipulator_qualifiedDicti
|
|
|
390
391
|
exports.resolveLocalizedPath = require_localization_rewriteUtils.resolveLocalizedPath;
|
|
391
392
|
exports.resolveMessage = require_messageFormat_resolveMessage.resolveMessage;
|
|
392
393
|
exports.resolveMessageNode = require_messageFormat_resolveMessage.resolveMessageNode;
|
|
394
|
+
exports.resolveMessageNodeToString = require_messageFormat_resolveMessage.resolveMessageNodeToString;
|
|
393
395
|
exports.resolvePlainDynamicLoader = require_dictionaryManipulator_plainDynamicLoader.resolvePlainDynamicLoader;
|
|
394
396
|
exports.resolveProviderVariant = require_dictionaryManipulator_qualifiedDictionary.resolveProviderVariant;
|
|
395
397
|
exports.resolveProxyMode = require_localization_proxyMode.resolveProxyMode;
|
|
@@ -9,12 +9,12 @@ let _intlayer_config_defaultValues = require("@intlayer/config/defaultValues");
|
|
|
9
9
|
* Single source of truth for default routing config resolution across all localization functions.
|
|
10
10
|
*/
|
|
11
11
|
const resolveRoutingConfig = (options = {}) => ({
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
...options,
|
|
13
|
+
defaultLocale: options.defaultLocale ?? _intlayer_config_built.internationalization?.defaultLocale ?? _intlayer_config_defaultValues.DEFAULT_LOCALE,
|
|
14
|
+
mode: options.mode ?? _intlayer_config_built.routing?.mode ?? _intlayer_config_defaultValues.ROUTING_MODE,
|
|
15
|
+
locales: options.locales ?? _intlayer_config_built.internationalization?.locales ?? _intlayer_config_defaultValues.LOCALES,
|
|
16
|
+
rewrite: options.rewrite ?? _intlayer_config_built.routing?.rewrite,
|
|
17
|
+
domains: options.domains ?? _intlayer_config_built.routing?.domains
|
|
18
18
|
});
|
|
19
19
|
/**
|
|
20
20
|
* Narrows an arbitrary string to a declared locale by membership test.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.cjs","names":["internationalization","DEFAULT_LOCALE","routing","ROUTING_MODE","LOCALES","isLocaleExclusiveOnDomain"],"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';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n DomainRuleMap,\n IsDomainExclusive,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedDomains,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\nimport { isLocaleExclusiveOnDomain } from './domainUtils';\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'] | RewriteRules;\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 = (\n options: RoutingOptions = {}\n): Omit<RoutingOptions, 'defaultLocale' | 'mode' | 'locales'> & {\n defaultLocale: DeclaredLocales;\n mode: RoutingConfig['mode'];\n locales: DeclaredLocales[];\n} => ({\n defaultLocale: internationalization?.defaultLocale
|
|
1
|
+
{"version":3,"file":"getPrefix.cjs","names":["internationalization","DEFAULT_LOCALE","routing","ROUTING_MODE","LOCALES","isLocaleExclusiveOnDomain"],"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';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n DomainRuleMap,\n IsDomainExclusive,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedDomains,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\nimport { isLocaleExclusiveOnDomain } from './domainUtils';\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'] | RewriteRules;\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 = (\n options: RoutingOptions = {}\n): Omit<RoutingOptions, 'defaultLocale' | 'mode' | 'locales'> & {\n defaultLocale: DeclaredLocales;\n mode: RoutingConfig['mode'];\n locales: DeclaredLocales[];\n} => ({\n ...options,\n defaultLocale: (options.defaultLocale ??\n internationalization?.defaultLocale ??\n DEFAULT_LOCALE) as DeclaredLocales,\n mode: options.mode ?? routing?.mode ?? ROUTING_MODE,\n locales: (options.locales ??\n internationalization?.locales ??\n LOCALES) as DeclaredLocales[],\n rewrite: options.rewrite ?? routing?.rewrite,\n domains: options.domains ?? routing?.domains,\n});\n\n/**\n * Narrows an arbitrary string to a declared locale by membership test.\n *\n * `locales` is typed as `DeclaredLocales[]`, so a plain `includes` rejects the\n * `string` values that actually need testing (a URL segment, a query param, a\n * stored value). This keeps the check honest and hands back a narrowed type\n * instead of forcing a cast at every call site.\n *\n * @param value - The candidate locale, from a URL segment / storage / header.\n * @param locales - The locales declared by the configuration.\n * @returns Whether `value` is one of the declared locales.\n */\nexport const isDeclaredLocale = (\n value: LocalesValues | undefined | null,\n locales?: readonly LocalesValues[]\n): value is DeclaredLocales =>\n !!value && (locales ?? internationalization.locales).includes(value);\n\nexport type GetPrefixOptions = {\n defaultLocale?: ResolvedDefaultLocale;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The locale path segment appended to `/`, with a trailing slash (e.g. `'fr/'`).\n * Empty string when no prefix is needed.\n */\n prefix: string;\n /**\n * The bare locale identifier (e.g. `'fr'`), or `undefined` when no prefix is applied.\n */\n localePrefix: DeclaredLocales | undefined;\n};\n\n/**\n * Narrowed return type for {@link getPrefix} that carries the locale literal through.\n *\n * Distributes over union locales — calling `getPrefix('fr')` in `prefix-no-default`\n * mode with `defaultLocale = 'en'` resolves to `{ prefix: 'fr/'; localePrefix: 'fr' }`.\n * A locale served from its own exclusive domain resolves to an empty prefix, as\n * the hostname already identifies it.\n *\n * Note: the \"locale not in locales\" edge case returns an empty result at runtime\n * regardless of what this type reports.\n */\nexport type GetPrefixResultNarrowed<\n L extends LocalesValues | undefined,\n Mode extends string = ResolvedRoutingMode,\n Default extends LocalesValues = ResolvedDefaultLocale,\n Domains extends DomainRuleMap = ResolvedDomains,\n> = L extends string\n ? [string] extends [L] // L is wide (string / LocalesValues) → distribute over declared locales\n ? GetPrefixResultNarrowed<DeclaredLocales, Mode, Default, Domains>\n : IsDomainExclusive<L, Domains> extends true\n ? { prefix: ''; localePrefix: undefined } // the domain identifies the locale\n : [string] extends [Mode]\n ? GetPrefixResult // mode is wide → fall back to generic result\n : Mode extends 'prefix-all'\n ? { prefix: `${L}/`; localePrefix: L }\n : Mode extends 'prefix-no-default'\n ? L extends Default\n ? { prefix: ''; localePrefix: undefined }\n : { prefix: `${L}/`; localePrefix: L }\n : { prefix: ''; localePrefix: undefined } // no-prefix / search-params\n : { prefix: ''; localePrefix: undefined }; // locale is undefined\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 = <const L extends LocalesValues | undefined>(\n locale: L,\n options: RoutingOptions = {}\n): GetPrefixResultNarrowed<L> => {\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 !isDeclaredLocale(locale, locales)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\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 (\n process.env.INTLAYER_ROUTING_DOMAINS !== 'false' &&\n isLocaleExclusiveOnDomain(locale as LocalesValues, domains)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\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 DeclaredLocales,\n } as GetPrefixResultNarrowed<L>;\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n};\n"],"mappings":";;;;;;;;;;AA6CA,MAAa,wBACX,UAA0B,CAAC,OAKvB;CACJ,GAAG;CACH,eAAgB,QAAQ,iBACtBA,6CAAsB,iBACtBC;CACF,MAAM,QAAQ,QAAQC,gCAAS,QAAQC;CACvC,SAAU,QAAQ,WAChBH,6CAAsB,WACtBI;CACF,SAAS,QAAQ,WAAWF,gCAAS;CACrC,SAAS,QAAQ,WAAWA,gCAAS;AACvC;;;;;;;;;;;;;AAcA,MAAa,oBACX,OACA,YAEA,CAAC,CAAC,UAAU,WAAWF,4CAAqB,QAAO,CAAE,SAAS,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFrE,MAAa,aACX,QACA,UAA0B,CAAC,MACI;CAC/B,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,OAAO;CAE9B,IACG,QAAQ,IAAI,yBACX,QAAQ,IAAI,0BAA0B,gBACtC,QAAQ,IAAI,0BAA0B,uBACxC,CAAC,UACD,CAAC,iBAAiB,QAAQ,OAAO,GAEjC,OAAO;EACL,QAAQ;EACR,cAAc;CAChB;CAKF,IACE,QAAQ,IAAI,6BAA6B,WACzCK,2DAA0B,QAAyB,OAAO,GAE1D,OAAO;EACL,QAAQ;EACR,cAAc;CAChB;CAQF,IAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,QAGnD,OAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;CAChB;CAGF,OAAO;EACL,QAAQ;EACR,cAAc;CAChB;AACF"}
|
|
@@ -6,6 +6,7 @@ const require_messageFormat_po = require('./po.cjs');
|
|
|
6
6
|
const require_messageFormat_vue_i18n = require('./vue-i18n.cjs');
|
|
7
7
|
const require_messageFormat_resolveMessage = require('./resolveMessage.cjs');
|
|
8
8
|
|
|
9
|
+
exports.createMessageResolver = require_messageFormat_resolveMessage.createMessageResolver;
|
|
9
10
|
exports.i18nextToIntlayerFormatter = require_messageFormat_i18next.i18nextToIntlayerFormatter;
|
|
10
11
|
exports.icuToIntlayerFormatter = require_messageFormat_ICU.icuToIntlayerFormatter;
|
|
11
12
|
exports.interpolateMessage = require_messageFormat_resolveMessage.interpolateMessage;
|
|
@@ -18,4 +19,5 @@ exports.parseTaggedMessage = require_messageFormat_resolveMessage.parseTaggedMes
|
|
|
18
19
|
exports.portableObjectToIntlayerFormatter = require_messageFormat_po.portableObjectToIntlayerFormatter;
|
|
19
20
|
exports.resolveMessage = require_messageFormat_resolveMessage.resolveMessage;
|
|
20
21
|
exports.resolveMessageNode = require_messageFormat_resolveMessage.resolveMessageNode;
|
|
22
|
+
exports.resolveMessageNodeToString = require_messageFormat_resolveMessage.resolveMessageNodeToString;
|
|
21
23
|
exports.vueI18nToIntlayerFormatter = require_messageFormat_vue_i18n.vueI18nToIntlayerFormatter;
|
|
@@ -55,13 +55,15 @@ const formatArgument = (value, type, style, locale) => {
|
|
|
55
55
|
* Interpolates a message template with values.
|
|
56
56
|
*
|
|
57
57
|
* Handles, in order:
|
|
58
|
-
* 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths)
|
|
58
|
+
* 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths),
|
|
59
|
+
* optionally formatted the i18next way (`{{price, number}}`)
|
|
59
60
|
* 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`
|
|
60
61
|
* 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)
|
|
61
62
|
*/
|
|
62
|
-
const interpolateMessage = (template, values = {}, locale = "en") => template.replace(/\{\{\s*([^{}]+?)\s
|
|
63
|
+
const interpolateMessage = (template, values = {}, locale = "en") => template.replace(/\{\{\s*([^{},]+?)\s*(?:,\s*(\w+)\s*(?:,\s*([^{}]+?)\s*)?)?\}\}/g, (match, path, type, style) => {
|
|
63
64
|
const value = resolveValuePath(values, path);
|
|
64
|
-
|
|
65
|
+
if (value === void 0) return match;
|
|
66
|
+
return type ? formatArgument(value, type, style, locale) : String(value);
|
|
65
67
|
}).replace(/\{\s*([\w.]+)\s*,\s*(\w+)\s*(?:,\s*([^}]+?)\s*)?\}/g, (match, path, type, style) => {
|
|
66
68
|
const value = resolveValuePath(values, path);
|
|
67
69
|
if (value === void 0) return match;
|
|
@@ -129,15 +131,45 @@ const resolveMessageNode = (node, values = {}, locale = "en") => {
|
|
|
129
131
|
}
|
|
130
132
|
return node;
|
|
131
133
|
};
|
|
134
|
+
/**
|
|
135
|
+
* {@link resolveMessageNode} coerced to a string.
|
|
136
|
+
*
|
|
137
|
+
* This is the whole runtime a compat adapter needs for content that reached
|
|
138
|
+
* the bundle through a built dictionary: the build already converted every
|
|
139
|
+
* dialect construct into intlayer nodes, and the interpreter turned those into
|
|
140
|
+
* callables, so no message parser is involved. Plain strings still get
|
|
141
|
+
* `{{name}}` / `{name}` / `{value, number}` interpolation.
|
|
142
|
+
*/
|
|
143
|
+
const resolveMessageNodeToString = (node, values = {}, locale = "en") => {
|
|
144
|
+
const resolved = resolveMessageNode(node, values, locale);
|
|
145
|
+
return typeof resolved === "string" ? resolved : String(resolved ?? "");
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Binds {@link resolveMessageNode} to one dialect converter.
|
|
149
|
+
*
|
|
150
|
+
* The compat adapters each speak a single dialect, and referencing the
|
|
151
|
+
* converter directly — rather than picking it from a record keyed by dialect —
|
|
152
|
+
* is what lets a bundler drop the two parsers the adapter never uses.
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```ts
|
|
156
|
+
* const resolveIcuMessage = createMessageResolver(icuToIntlayerFormatter);
|
|
157
|
+
* resolveIcuMessage('Hello {name}', { name: 'John' }, 'en'); // 'Hello John'
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
const createMessageResolver = (formatter) => (message, values = {}, locale = "en") => resolveMessageNodeToString(typeof message === "string" ? formatter(message) : message, values, locale);
|
|
132
161
|
const DIALECT_FORMATTERS = {
|
|
133
|
-
icu:
|
|
134
|
-
i18next:
|
|
135
|
-
"vue-i18n":
|
|
162
|
+
icu: require_messageFormat_ICU.icuToIntlayerFormatter,
|
|
163
|
+
i18next: require_messageFormat_i18next.i18nextToIntlayerFormatter,
|
|
164
|
+
"vue-i18n": require_messageFormat_vue_i18n.vueI18nToIntlayerFormatter
|
|
136
165
|
};
|
|
137
166
|
/**
|
|
138
167
|
* Resolves a raw message — string in a library dialect, or an intlayer node
|
|
139
168
|
* tree — into a final string using interpolation values and locale.
|
|
140
169
|
*
|
|
170
|
+
* Selecting the dialect at runtime keeps every converter reachable; a package
|
|
171
|
+
* that only ever needs one should bind it with {@link createMessageResolver}.
|
|
172
|
+
*
|
|
141
173
|
* @example
|
|
142
174
|
* ```ts
|
|
143
175
|
* resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');
|
|
@@ -152,11 +184,7 @@ const DIALECT_FORMATTERS = {
|
|
|
152
184
|
* // '3 items'
|
|
153
185
|
* ```
|
|
154
186
|
*/
|
|
155
|
-
const resolveMessage = (message, values = {}, locale = "en", dialect = "icu") =>
|
|
156
|
-
const node = typeof message === "string" ? DIALECT_FORMATTERS[dialect](message) : message;
|
|
157
|
-
const resolved = resolveMessageNode(node, values, locale);
|
|
158
|
-
return typeof resolved === "string" ? resolved : String(resolved ?? "");
|
|
159
|
-
};
|
|
187
|
+
const resolveMessage = (message, values = {}, locale = "en", dialect = "icu") => createMessageResolver(DIALECT_FORMATTERS[dialect])(message, values, locale);
|
|
160
188
|
/**
|
|
161
189
|
* Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,
|
|
162
190
|
* `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.
|
|
@@ -188,8 +216,10 @@ const parseTaggedMessage = (message) => {
|
|
|
188
216
|
};
|
|
189
217
|
|
|
190
218
|
//#endregion
|
|
219
|
+
exports.createMessageResolver = createMessageResolver;
|
|
191
220
|
exports.interpolateMessage = interpolateMessage;
|
|
192
221
|
exports.parseTaggedMessage = parseTaggedMessage;
|
|
193
222
|
exports.resolveMessage = resolveMessage;
|
|
194
223
|
exports.resolveMessageNode = resolveMessageNode;
|
|
224
|
+
exports.resolveMessageNodeToString = resolveMessageNodeToString;
|
|
195
225
|
//# sourceMappingURL=resolveMessage.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveMessage.cjs","names":["getCachedIntl","NodeTypes","getPlural","getEnumeration","getSelect","icuToIntlayerFormatter","i18nextToIntlayerFormatter","vueI18nToIntlayerFormatter"],"sources":["../../../src/messageFormat/resolveMessage.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { getCachedIntl } from '../formatters';\nimport { getEnumeration } from '../interpreter/getEnumeration';\nimport { getPlural } from '../interpreter/getPlural';\nimport { getSelect } from '../interpreter/getSelect';\nimport type { PluralContentState } from '../transpiler/plural/plural';\nimport { icuToIntlayerFormatter } from './ICU';\nimport { i18nextToIntlayerFormatter } from './i18next';\nimport { vueI18nToIntlayerFormatter } from './vue-i18n';\n\n/**\n * Runtime counterpart of the `messageFormat` converters.\n *\n * The converters (`icuToIntlayerFormatter`, `i18nextToIntlayerFormatter`,\n * `vueI18nToIntlayerFormatter`) turn library-specific message syntax into\n * intlayer nodes (`insert`, `plural`, `enu`, `gender`, `html`). This module\n * resolves those nodes — or raw message strings — into a final string using\n * the provided interpolation values and locale.\n *\n * It is the mutualized resolution engine used by the compat adapter packages\n * (`@intlayer/i18next`, `@intlayer/next-intl`, `@intlayer/vue-i18n`, …).\n */\n\n/** Message syntax dialect of the source i18n library. */\nexport type MessageFormatDialect = 'icu' | 'i18next' | 'vue-i18n';\n\n/** Interpolation values passed alongside a translation lookup. */\nexport type MessageValues = Record<string, unknown>;\n\n/** Internal enumeration metadata keys injected by the converters. */\nconst ENUMERATION_METADATA_KEYS = [\n '__intlayer_icu_var',\n '__intlayer_icu_ordinal',\n '__intlayer_vue_i18n_var',\n] as const;\n\n/**\n * Resolves a possibly-dotted path (`user.name`) inside the values object.\n */\nconst resolveValuePath = (values: MessageValues, path: string): unknown => {\n if (path in values) return values[path];\n\n let current: unknown = values;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/** Formats an ICU-style formatted argument (`{value, number, percent}`). */\nconst formatArgument = (\n value: unknown,\n type: string,\n style: string | undefined,\n locale: LocalesValues\n): string => {\n try {\n if (type === 'number') {\n const numberValue = Number(value);\n if (style === 'percent') {\n return getCachedIntl('NumberFormat', locale, {\n style: 'percent',\n }).format(numberValue);\n }\n if (style === 'integer') {\n return getCachedIntl('NumberFormat', locale, {\n maximumFractionDigits: 0,\n }).format(numberValue);\n }\n return getCachedIntl('NumberFormat', locale).format(numberValue);\n }\n\n if (type === 'date' || type === 'time') {\n const dateValue =\n value instanceof Date ? value : new Date(value as string | number);\n const dateTimeStyle = (\n ['short', 'medium', 'long', 'full'].includes(style ?? '')\n ? style\n : type === 'date'\n ? 'medium'\n : 'short'\n ) as 'short' | 'medium' | 'long' | 'full';\n\n return getCachedIntl(\n 'DateTimeFormat',\n locale,\n type === 'date'\n ? { dateStyle: dateTimeStyle }\n : { timeStyle: dateTimeStyle }\n ).format(dateValue);\n }\n } catch {\n // Fall through to the raw string representation below\n }\n\n return String(value);\n};\n\n/**\n * Interpolates a message template with values.\n *\n * Handles, in order:\n * 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths)\n * 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`\n * 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)\n */\nexport const interpolateMessage = (\n template: string,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string =>\n template\n .replace(/\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n })\n .replace(\n /\\{\\s*([\\w.]+)\\s*,\\s*(\\w+)\\s*(?:,\\s*([^}]+?)\\s*)?\\}/g,\n (match, path: string, type: string, style: string | undefined) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return formatArgument(value, type, style, locale);\n }\n )\n .replace(/\\{\\s*([\\w.]+)\\s*\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n });\n\n/** Reads the selector value of an enumeration/plural node from the values. */\nconst getSelectorValue = (\n values: MessageValues,\n variableName: string\n): unknown => values[variableName] ?? values.count ?? values.n;\n\n/**\n * Resolves an intlayer message node tree (as produced by the\n * `*ToIntlayerFormatter` converters, or already present in a built\n * dictionary) into its final value using interpolation values and locale.\n *\n * Function nodes (produced by the interpreter plugins for `insertion`,\n * `enumeration` and `plural` content) are invoked with the values.\n */\nexport const resolveMessageNode = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): unknown => {\n if (node === null || node === undefined) return node;\n\n if (typeof node === 'string') {\n return interpolateMessage(node, values, locale);\n }\n\n if (typeof node === 'number' || typeof node === 'boolean') {\n return String(node);\n }\n\n // Interpreter-transformed nodes (insertion/enumeration/plural plugins)\n // are exposed as callables taking the interpolation values.\n if (typeof node === 'function') {\n try {\n return resolveMessageNode(\n (node as (arg: MessageValues) => unknown)(values),\n values,\n locale\n );\n } catch {\n return undefined;\n }\n }\n\n if (Array.isArray(node)) {\n return node\n .map((item) => String(resolveMessageNode(item, values, locale) ?? ''))\n .join('');\n }\n\n const typedNode = node as Record<string, unknown> & { nodeType?: string };\n\n if (typedNode.nodeType === NodeTypes.INSERTION) {\n return resolveMessageNode(typedNode[NodeTypes.INSERTION], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.HTML) {\n // Tags are kept intact — rich rendering is handled by the caller\n return resolveMessageNode(typedNode[NodeTypes.HTML], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.PLURAL) {\n const pluralState = typedNode[\n NodeTypes.PLURAL\n ] as PluralContentState<unknown>;\n const count = Number(getSelectorValue(values, 'count') ?? 1);\n const selected = getPlural(\n pluralState as PluralContentState<string>,\n count,\n locale\n );\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.ENUMERATION) {\n const enumerationState = typedNode[NodeTypes.ENUMERATION] as Record<\n string,\n unknown\n >;\n\n const variableName = (ENUMERATION_METADATA_KEYS.map(\n (metadataKey) => enumerationState[metadataKey]\n ).find((name) => typeof name === 'string') ?? 'count') as string;\n\n const isOrdinal = enumerationState.__intlayer_icu_ordinal === true;\n\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(enumerationState)) {\n if (!(ENUMERATION_METADATA_KEYS as readonly string[]).includes(key)) {\n options[key] = value;\n }\n }\n\n const selector = getSelectorValue(values, variableName);\n\n let selected: unknown;\n if (isOrdinal && !Number.isNaN(Number(selector))) {\n // ICU `selectordinal` — exact numeric match first, then the CLDR\n // ordinal category, then the fallback\n const ordinalCount = Number(selector);\n const ordinalCategory = getCachedIntl('PluralRules', locale, {\n type: 'ordinal',\n }).select(ordinalCount);\n selected =\n options[String(ordinalCount)] ??\n options[ordinalCategory] ??\n options.fallback ??\n options.other;\n } else if (\n typeof selector === 'number' ||\n !Number.isNaN(Number(selector))\n ) {\n selected = getEnumeration(options, Number(selector));\n } else {\n // String selector — ICU `select` converted to an enumeration\n selected = options[String(selector)] ?? options.fallback ?? options.other;\n }\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.SELECT) {\n const selectState = typedNode[NodeTypes.SELECT] as Record<string, unknown>;\n\n // The node records the ICU variable it was imported from; fall back to\n // `value` for nodes authored directly with `select()`.\n const variableName =\n typeof typedNode.variable === 'string' ? typedNode.variable : 'value';\n\n const selector = getSelectorValue(values, variableName);\n const selected = getSelect(selectState, String(selector ?? ''));\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.GENDER) {\n const genderState = typedNode[NodeTypes.GENDER] as Record<string, unknown>;\n const genderValue = String(values.gender ?? '');\n const selected =\n genderState[genderValue] ?? genderState.fallback ?? genderState.other;\n return resolveMessageNode(selected, values, locale);\n }\n\n return node;\n};\n\nconst DIALECT_FORMATTERS: Record<\n MessageFormatDialect,\n (message: string) => unknown\n> = {\n icu: (message) => icuToIntlayerFormatter(message),\n i18next: (message) => i18nextToIntlayerFormatter(message),\n 'vue-i18n': (message) => vueI18nToIntlayerFormatter(message),\n};\n\n/**\n * Resolves a raw message — string in a library dialect, or an intlayer node\n * tree — into a final string using interpolation values and locale.\n *\n * @example\n * ```ts\n * resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');\n * // 'Hello John'\n *\n * resolveMessage(\n * '{count, plural, one {# item} other {# items}}',\n * { count: 3 },\n * 'en',\n * 'icu'\n * );\n * // '3 items'\n * ```\n */\nexport const resolveMessage = (\n message: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues,\n dialect: MessageFormatDialect = 'icu'\n): string => {\n const node =\n typeof message === 'string'\n ? DIALECT_FORMATTERS[dialect](message)\n : message;\n\n const resolved = resolveMessageNode(node, values, locale);\n\n return typeof resolved === 'string' ? resolved : String(resolved ?? '');\n};\n\n/** A parsed token of a tagged message: plain text or a tag with children. */\nexport type TaggedMessageToken =\n | string\n | { tag: string; children: TaggedMessageToken[] };\n\n/**\n * Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,\n * `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.\n *\n * Used by rich-text renderers (`t.rich`, `<Trans components>`,\n * `<i18n-t>` slots) to map tags to framework elements.\n */\nexport const parseTaggedMessage = (message: string): TaggedMessageToken[] => {\n const tokens: TaggedMessageToken[] = [];\n const tagRegex = /<([\\w-]+)\\s*\\/>|<([\\w-]+)[^>]*>([\\s\\S]*?)<\\/\\2>/g;\n let lastIndex = 0;\n let match = tagRegex.exec(message);\n\n while (match !== null) {\n if (match.index > lastIndex) {\n tokens.push(message.slice(lastIndex, match.index));\n }\n\n const [, selfClosingTag, tag, inner] = match;\n\n if (selfClosingTag) {\n tokens.push({ tag: selfClosingTag, children: [] });\n } else {\n tokens.push({ tag, children: parseTaggedMessage(inner) });\n }\n\n lastIndex = match.index + match[0].length;\n match = tagRegex.exec(message);\n }\n\n if (lastIndex < message.length) {\n tokens.push(message.slice(lastIndex));\n }\n\n return tokens;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolveMessage.cjs","names":["getCachedIntl","NodeTypes","getPlural","getEnumeration","getSelect","icuToIntlayerFormatter","i18nextToIntlayerFormatter","vueI18nToIntlayerFormatter"],"sources":["../../../src/messageFormat/resolveMessage.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { getCachedIntl } from '../formatters';\nimport { getEnumeration } from '../interpreter/getEnumeration';\nimport { getPlural } from '../interpreter/getPlural';\nimport { getSelect } from '../interpreter/getSelect';\nimport type { PluralContentState } from '../transpiler/plural/plural';\nimport { icuToIntlayerFormatter } from './ICU';\nimport { i18nextToIntlayerFormatter } from './i18next';\nimport { vueI18nToIntlayerFormatter } from './vue-i18n';\n\n/**\n * Runtime counterpart of the `messageFormat` converters.\n *\n * The converters (`icuToIntlayerFormatter`, `i18nextToIntlayerFormatter`,\n * `vueI18nToIntlayerFormatter`) turn library-specific message syntax into\n * intlayer nodes (`insert`, `plural`, `enu`, `gender`, `html`). This module\n * resolves those nodes — or raw message strings — into a final string using\n * the provided interpolation values and locale.\n *\n * It is the mutualized resolution engine used by the compat adapter packages\n * (`@intlayer/i18next`, `@intlayer/next-intl`, `@intlayer/vue-i18n`, …).\n */\n\n/** Message syntax dialect of the source i18n library. */\nexport type MessageFormatDialect = 'icu' | 'i18next' | 'vue-i18n';\n\n/** Interpolation values passed alongside a translation lookup. */\nexport type MessageValues = Record<string, unknown>;\n\n/** Internal enumeration metadata keys injected by the converters. */\nconst ENUMERATION_METADATA_KEYS = [\n '__intlayer_icu_var',\n '__intlayer_icu_ordinal',\n '__intlayer_vue_i18n_var',\n] as const;\n\n/**\n * Resolves a possibly-dotted path (`user.name`) inside the values object.\n */\nconst resolveValuePath = (values: MessageValues, path: string): unknown => {\n if (path in values) return values[path];\n\n let current: unknown = values;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/** Formats an ICU-style formatted argument (`{value, number, percent}`). */\nconst formatArgument = (\n value: unknown,\n type: string,\n style: string | undefined,\n locale: LocalesValues\n): string => {\n try {\n if (type === 'number') {\n const numberValue = Number(value);\n if (style === 'percent') {\n return getCachedIntl('NumberFormat', locale, {\n style: 'percent',\n }).format(numberValue);\n }\n if (style === 'integer') {\n return getCachedIntl('NumberFormat', locale, {\n maximumFractionDigits: 0,\n }).format(numberValue);\n }\n return getCachedIntl('NumberFormat', locale).format(numberValue);\n }\n\n if (type === 'date' || type === 'time') {\n const dateValue =\n value instanceof Date ? value : new Date(value as string | number);\n const dateTimeStyle = (\n ['short', 'medium', 'long', 'full'].includes(style ?? '')\n ? style\n : type === 'date'\n ? 'medium'\n : 'short'\n ) as 'short' | 'medium' | 'long' | 'full';\n\n return getCachedIntl(\n 'DateTimeFormat',\n locale,\n type === 'date'\n ? { dateStyle: dateTimeStyle }\n : { timeStyle: dateTimeStyle }\n ).format(dateValue);\n }\n } catch {\n // Fall through to the raw string representation below\n }\n\n return String(value);\n};\n\n/**\n * Interpolates a message template with values.\n *\n * Handles, in order:\n * 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths),\n * optionally formatted the i18next way (`{{price, number}}`)\n * 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`\n * 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)\n */\nexport const interpolateMessage = (\n template: string,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string =>\n template\n .replace(\n /\\{\\{\\s*([^{},]+?)\\s*(?:,\\s*(\\w+)\\s*(?:,\\s*([^{}]+?)\\s*)?)?\\}\\}/g,\n (match, path: string, type: string | undefined, style?: string) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return type\n ? formatArgument(value, type, style, locale)\n : String(value);\n }\n )\n .replace(\n /\\{\\s*([\\w.]+)\\s*,\\s*(\\w+)\\s*(?:,\\s*([^}]+?)\\s*)?\\}/g,\n (match, path: string, type: string, style: string | undefined) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return formatArgument(value, type, style, locale);\n }\n )\n .replace(/\\{\\s*([\\w.]+)\\s*\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n });\n\n/** Reads the selector value of an enumeration/plural node from the values. */\nconst getSelectorValue = (\n values: MessageValues,\n variableName: string\n): unknown => values[variableName] ?? values.count ?? values.n;\n\n/**\n * Resolves an intlayer message node tree (as produced by the\n * `*ToIntlayerFormatter` converters, or already present in a built\n * dictionary) into its final value using interpolation values and locale.\n *\n * Function nodes (produced by the interpreter plugins for `insertion`,\n * `enumeration` and `plural` content) are invoked with the values.\n */\nexport const resolveMessageNode = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): unknown => {\n if (node === null || node === undefined) return node;\n\n if (typeof node === 'string') {\n return interpolateMessage(node, values, locale);\n }\n\n if (typeof node === 'number' || typeof node === 'boolean') {\n return String(node);\n }\n\n // Interpreter-transformed nodes (insertion/enumeration/plural plugins)\n // are exposed as callables taking the interpolation values.\n if (typeof node === 'function') {\n try {\n return resolveMessageNode(\n (node as (arg: MessageValues) => unknown)(values),\n values,\n locale\n );\n } catch {\n return undefined;\n }\n }\n\n if (Array.isArray(node)) {\n return node\n .map((item) => String(resolveMessageNode(item, values, locale) ?? ''))\n .join('');\n }\n\n const typedNode = node as Record<string, unknown> & { nodeType?: string };\n\n if (typedNode.nodeType === NodeTypes.INSERTION) {\n return resolveMessageNode(typedNode[NodeTypes.INSERTION], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.HTML) {\n // Tags are kept intact — rich rendering is handled by the caller\n return resolveMessageNode(typedNode[NodeTypes.HTML], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.PLURAL) {\n const pluralState = typedNode[\n NodeTypes.PLURAL\n ] as PluralContentState<unknown>;\n const count = Number(getSelectorValue(values, 'count') ?? 1);\n const selected = getPlural(\n pluralState as PluralContentState<string>,\n count,\n locale\n );\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.ENUMERATION) {\n const enumerationState = typedNode[NodeTypes.ENUMERATION] as Record<\n string,\n unknown\n >;\n\n const variableName = (ENUMERATION_METADATA_KEYS.map(\n (metadataKey) => enumerationState[metadataKey]\n ).find((name) => typeof name === 'string') ?? 'count') as string;\n\n const isOrdinal = enumerationState.__intlayer_icu_ordinal === true;\n\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(enumerationState)) {\n if (!(ENUMERATION_METADATA_KEYS as readonly string[]).includes(key)) {\n options[key] = value;\n }\n }\n\n const selector = getSelectorValue(values, variableName);\n\n let selected: unknown;\n if (isOrdinal && !Number.isNaN(Number(selector))) {\n // ICU `selectordinal` — exact numeric match first, then the CLDR\n // ordinal category, then the fallback\n const ordinalCount = Number(selector);\n const ordinalCategory = getCachedIntl('PluralRules', locale, {\n type: 'ordinal',\n }).select(ordinalCount);\n selected =\n options[String(ordinalCount)] ??\n options[ordinalCategory] ??\n options.fallback ??\n options.other;\n } else if (\n typeof selector === 'number' ||\n !Number.isNaN(Number(selector))\n ) {\n selected = getEnumeration(options, Number(selector));\n } else {\n // String selector — ICU `select` converted to an enumeration\n selected = options[String(selector)] ?? options.fallback ?? options.other;\n }\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.SELECT) {\n const selectState = typedNode[NodeTypes.SELECT] as Record<string, unknown>;\n\n // The node records the ICU variable it was imported from; fall back to\n // `value` for nodes authored directly with `select()`.\n const variableName =\n typeof typedNode.variable === 'string' ? typedNode.variable : 'value';\n\n const selector = getSelectorValue(values, variableName);\n const selected = getSelect(selectState, String(selector ?? ''));\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.GENDER) {\n const genderState = typedNode[NodeTypes.GENDER] as Record<string, unknown>;\n const genderValue = String(values.gender ?? '');\n const selected =\n genderState[genderValue] ?? genderState.fallback ?? genderState.other;\n return resolveMessageNode(selected, values, locale);\n }\n\n return node;\n};\n\n/**\n * {@link resolveMessageNode} coerced to a string.\n *\n * This is the whole runtime a compat adapter needs for content that reached\n * the bundle through a built dictionary: the build already converted every\n * dialect construct into intlayer nodes, and the interpreter turned those into\n * callables, so no message parser is involved. Plain strings still get\n * `{{name}}` / `{name}` / `{value, number}` interpolation.\n */\nexport const resolveMessageNodeToString = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string => {\n const resolved = resolveMessageNode(node, values, locale);\n\n return typeof resolved === 'string' ? resolved : String(resolved ?? '');\n};\n\n/** Converts a raw message string of one dialect into an intlayer node tree. */\nexport type MessageFormatter = (message: string) => unknown;\n\n/**\n * Resolves a raw message — string, or an intlayer node tree — into a final\n * string using interpolation values and locale.\n */\nexport type MessageResolver = (\n message: unknown,\n values?: MessageValues,\n locale?: LocalesValues\n) => string;\n\n/**\n * Binds {@link resolveMessageNode} to one dialect converter.\n *\n * The compat adapters each speak a single dialect, and referencing the\n * converter directly — rather than picking it from a record keyed by dialect —\n * is what lets a bundler drop the two parsers the adapter never uses.\n *\n * @example\n * ```ts\n * const resolveIcuMessage = createMessageResolver(icuToIntlayerFormatter);\n * resolveIcuMessage('Hello {name}', { name: 'John' }, 'en'); // 'Hello John'\n * ```\n */\nexport const createMessageResolver =\n (formatter: MessageFormatter): MessageResolver =>\n (message, values = {}, locale = 'en' as LocalesValues) =>\n resolveMessageNodeToString(\n typeof message === 'string' ? formatter(message) : message,\n values,\n locale\n );\n\nconst DIALECT_FORMATTERS: Record<MessageFormatDialect, MessageFormatter> = {\n icu: icuToIntlayerFormatter,\n i18next: i18nextToIntlayerFormatter,\n 'vue-i18n': vueI18nToIntlayerFormatter,\n};\n\n/**\n * Resolves a raw message — string in a library dialect, or an intlayer node\n * tree — into a final string using interpolation values and locale.\n *\n * Selecting the dialect at runtime keeps every converter reachable; a package\n * that only ever needs one should bind it with {@link createMessageResolver}.\n *\n * @example\n * ```ts\n * resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');\n * // 'Hello John'\n *\n * resolveMessage(\n * '{count, plural, one {# item} other {# items}}',\n * { count: 3 },\n * 'en',\n * 'icu'\n * );\n * // '3 items'\n * ```\n */\nexport const resolveMessage = (\n message: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues,\n dialect: MessageFormatDialect = 'icu'\n): string =>\n createMessageResolver(DIALECT_FORMATTERS[dialect])(message, values, locale);\n\n/** A parsed token of a tagged message: plain text or a tag with children. */\nexport type TaggedMessageToken =\n | string\n | { tag: string; children: TaggedMessageToken[] };\n\n/**\n * Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,\n * `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.\n *\n * Used by rich-text renderers (`t.rich`, `<Trans components>`,\n * `<i18n-t>` slots) to map tags to framework elements.\n */\nexport const parseTaggedMessage = (message: string): TaggedMessageToken[] => {\n const tokens: TaggedMessageToken[] = [];\n const tagRegex = /<([\\w-]+)\\s*\\/>|<([\\w-]+)[^>]*>([\\s\\S]*?)<\\/\\2>/g;\n let lastIndex = 0;\n let match = tagRegex.exec(message);\n\n while (match !== null) {\n if (match.index > lastIndex) {\n tokens.push(message.slice(lastIndex, match.index));\n }\n\n const [, selfClosingTag, tag, inner] = match;\n\n if (selfClosingTag) {\n tokens.push({ tag: selfClosingTag, children: [] });\n } else {\n tokens.push({ tag, children: parseTaggedMessage(inner) });\n }\n\n lastIndex = match.index + match[0].length;\n match = tagRegex.exec(message);\n }\n\n if (lastIndex < message.length) {\n tokens.push(message.slice(lastIndex));\n }\n\n return tokens;\n};\n"],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ const getCookie = (name, cookieString) => {
|
|
|
12
12
|
if (!str) return void 0;
|
|
13
13
|
const pairs = str.split(";");
|
|
14
14
|
for (let i = 0; i < pairs.length; i++) {
|
|
15
|
-
const part = pairs[i]
|
|
15
|
+
const part = pairs[i]?.trim();
|
|
16
16
|
if (!part) continue;
|
|
17
17
|
const equalIndex = part.indexOf("=");
|
|
18
18
|
if ((equalIndex >= 0 ? part.substring(0, equalIndex) : part) === name) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCookie.cjs","names":[],"sources":["../../../src/utils/getCookie.ts"],"sourcesContent":["/**\n * Retrieves a cookie by name from a cookie string or document.cookie\n * @param name - The name of the cookie to retrieve\n * @param cookieString - Optional cookie string to parse (defaults to document.cookie in browser)\n * @returns The cookie value or undefined if not found\n */\nexport const getCookie = (\n name: string,\n cookieString?: string\n): string | undefined => {\n try {\n const str =\n cookieString ?? (typeof document !== 'undefined' ? document.cookie : '');\n\n if (!str) return undefined;\n\n const pairs = str.split(';');\n\n for (let i = 0; i < pairs.length; i++) {\n const part = pairs[i]
|
|
1
|
+
{"version":3,"file":"getCookie.cjs","names":[],"sources":["../../../src/utils/getCookie.ts"],"sourcesContent":["/**\n * Retrieves a cookie by name from a cookie string or document.cookie\n * @param name - The name of the cookie to retrieve\n * @param cookieString - Optional cookie string to parse (defaults to document.cookie in browser)\n * @returns The cookie value or undefined if not found\n */\nexport const getCookie = (\n name: string,\n cookieString?: string\n): string | undefined => {\n try {\n const str =\n cookieString ?? (typeof document !== 'undefined' ? document.cookie : '');\n\n if (!str) return undefined;\n\n const pairs = str.split(';');\n\n for (let i = 0; i < pairs.length; i++) {\n const part = pairs[i]?.trim();\n\n if (!part) continue;\n\n const equalIndex = part.indexOf('=');\n const key = equalIndex >= 0 ? part.substring(0, equalIndex) : part;\n\n if (key === name) {\n const rawValue = equalIndex >= 0 ? part.substring(equalIndex + 1) : '';\n\n try {\n return decodeURIComponent(rawValue);\n } catch {\n return rawValue;\n }\n }\n }\n } catch {}\n return undefined;\n};\n"],"mappings":";;;;;;;;AAMA,MAAa,aACX,MACA,iBACuB;CACvB,IAAI;EACF,MAAM,MACJ,iBAAiB,OAAO,aAAa,cAAc,SAAS,SAAS;EAEvE,IAAI,CAAC,KAAK,OAAO;EAEjB,MAAM,QAAQ,IAAI,MAAM,GAAG;EAE3B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,OAAO,MAAM,EAAE,EAAE,KAAK;GAE5B,IAAI,CAAC,MAAM;GAEX,MAAM,aAAa,KAAK,QAAQ,GAAG;GAGnC,KAFY,cAAc,IAAI,KAAK,UAAU,GAAG,UAAU,IAAI,UAElD,MAAM;IAChB,MAAM,WAAW,cAAc,IAAI,KAAK,UAAU,aAAa,CAAC,IAAI;IAEpE,IAAI;KACF,OAAO,mBAAmB,QAAQ;IACpC,QAAQ;KACN,OAAO;IACT;GACF;EACF;CACF,QAAQ,CAAC;AAEX"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -109,8 +109,8 @@ import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./messag
|
|
|
109
109
|
import { navigatePath } from "./messageFormat/navigatePath.mjs";
|
|
110
110
|
import { intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./messageFormat/po.mjs";
|
|
111
111
|
import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./messageFormat/vue-i18n.mjs";
|
|
112
|
-
import { interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode } from "./messageFormat/resolveMessage.mjs";
|
|
112
|
+
import { createMessageResolver, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode, resolveMessageNodeToString } from "./messageFormat/resolveMessage.mjs";
|
|
113
113
|
import { isSameKeyPath } from "./utils/isSameKeyPath.mjs";
|
|
114
114
|
import { stringifyYaml } from "./utils/stringifyYaml.mjs";
|
|
115
115
|
|
|
116
|
-
export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, COMPOSITE_ID_SEPARATOR, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CachedIntl, CachedIntl as Intl, DEFAULT_VARIANT_ID, DO_NOT_PROCESS_HTML_ELEMENTS, FENCE_DELIMITER_R, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_TAGS, INLINE_SKIP_R, INTERPOLATION_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LOOKAHEAD, LocaleStorage, LocaleStorageClient, LocaleStorageServer, NAMED_CODES_TO_UNICODE, NP_TABLE_R, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, PARAGRAPH_R, PRELOADED_DYNAMIC_KEY, Priority, QUALIFIER_DYNAMIC_TYPES_KEY, QUALIFIER_ORDER, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleScope, RuleType, SCOPE_BLOCK, SCOPE_BOTH, SCOPE_INLINE, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, VOID_HTML_ELEMENTS, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, comparePaths, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, findPlainDynamicLoader, formatProxyEnabledMessage, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getDictionaryAsync, getDictionaryCompositeIds, getDictionaryQualifierIds, getDictionaryQualifierTypes, getDictionarySelectorCacheKey, getDictionaryTransformCacheKey, getDomainHostname, getDomainOrigin, getEditedContent, getEditedDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getGender, getHTML, getHTMLTextDir, getInsertion, getInsertionValues, getInternalPath, getInterpolableContent, getIntlayer, getIntlayerAsync, getLocale, getLocaleFromDomain, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNestedDictionaryGraph, getNestedDictionaryKeys, getNestedDictionaryReferences, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPluginsCacheKey, getPlural, getPrefix, getPreloadLocale, getPreloadedDictionary, getReplacedValuesContent, getRewritePath, getRewriteRules, getRuleSet, getSelect, getSplittedContent, getSplittedDictionaryContent, getTranslation, getVariantIds, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isDeclaredLocale, isInterpolableWrapperNode, isLocaleExclusiveOnDomain, isProxyStorageLocaleEnabled, isQualifiedDictionaryGroup, isQualifiedDynamicLoaderMap, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, mergeQualifiedDictionaries, navigatePath, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizePath, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseDictionarySelector, parseInline, parseMarkdown, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseTaggedMessage, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, readTransformCache, rebuildInterpolableContent, reconstructQualifiedEntry, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderMarkdownAst, renderNothing, resolveBrowserLocale, resolveDictionaryArgument, resolveEffectiveVariantId, resolveLocalizedPath, resolveMessage, resolveMessageNode, resolvePlainDynamicLoader, resolveProviderVariant, resolveProxyMode, resolveQualifiedDictionary, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync, sanitizer, select, selectPlugin, serializeVariant, serializeVariantChain, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, transformInterpolableNode, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter, writeTransformCache };
|
|
116
|
+
export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, COMPOSITE_ID_SEPARATOR, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CachedIntl, CachedIntl as Intl, DEFAULT_VARIANT_ID, DO_NOT_PROCESS_HTML_ELEMENTS, FENCE_DELIMITER_R, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, GFM_TASK_R, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_TAGS, INLINE_SKIP_R, INTERPOLATION_R, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LOOKAHEAD, LocaleStorage, LocaleStorageClient, LocaleStorageServer, NAMED_CODES_TO_UNICODE, NP_TABLE_R, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, PARAGRAPH_R, PRELOADED_DYNAMIC_KEY, Priority, QUALIFIER_DYNAMIC_TYPES_KEY, QUALIFIER_ORDER, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, RuleScope, RuleType, SCOPE_BLOCK, SCOPE_BOTH, SCOPE_INLINE, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, VOID_HTML_ELEMENTS, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, comparePaths, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createMessageResolver, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, findPlainDynamicLoader, formatProxyEnabledMessage, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getDictionaryAsync, getDictionaryCompositeIds, getDictionaryQualifierIds, getDictionaryQualifierTypes, getDictionarySelectorCacheKey, getDictionaryTransformCacheKey, getDomainHostname, getDomainOrigin, getEditedContent, getEditedDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getGender, getHTML, getHTMLTextDir, getInsertion, getInsertionValues, getInternalPath, getInterpolableContent, getIntlayer, getIntlayerAsync, getLocale, getLocaleFromDomain, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNestedDictionaryGraph, getNestedDictionaryKeys, getNestedDictionaryReferences, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPluginsCacheKey, getPlural, getPrefix, getPreloadLocale, getPreloadedDictionary, getReplacedValuesContent, getRewritePath, getRewriteRules, getRuleSet, getSelect, getSplittedContent, getSplittedDictionaryContent, getTranslation, getVariantIds, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isDeclaredLocale, isInterpolableWrapperNode, isLocaleExclusiveOnDomain, isProxyStorageLocaleEnabled, isQualifiedDictionaryGroup, isQualifiedDynamicLoaderMap, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, mergeQualifiedDictionaries, navigatePath, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizePath, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseDictionarySelector, parseInline, parseMarkdown, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseTaggedMessage, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, readTransformCache, rebuildInterpolableContent, reconstructQualifiedEntry, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderMarkdownAst, renderNothing, resolveBrowserLocale, resolveDictionaryArgument, resolveEffectiveVariantId, resolveLocalizedPath, resolveMessage, resolveMessageNode, resolveMessageNodeToString, resolvePlainDynamicLoader, resolveProviderVariant, resolveProxyMode, resolveQualifiedDictionary, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync, sanitizer, select, selectPlugin, serializeVariant, serializeVariantChain, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, transformInterpolableNode, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter, writeTransformCache };
|
|
@@ -8,12 +8,12 @@ import { DEFAULT_LOCALE, LOCALES, ROUTING_MODE } from "@intlayer/config/defaultV
|
|
|
8
8
|
* Single source of truth for default routing config resolution across all localization functions.
|
|
9
9
|
*/
|
|
10
10
|
const resolveRoutingConfig = (options = {}) => ({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
...options,
|
|
12
|
+
defaultLocale: options.defaultLocale ?? internationalization?.defaultLocale ?? DEFAULT_LOCALE,
|
|
13
|
+
mode: options.mode ?? routing?.mode ?? ROUTING_MODE,
|
|
14
|
+
locales: options.locales ?? internationalization?.locales ?? LOCALES,
|
|
15
|
+
rewrite: options.rewrite ?? routing?.rewrite,
|
|
16
|
+
domains: options.domains ?? routing?.domains
|
|
17
17
|
});
|
|
18
18
|
/**
|
|
19
19
|
* Narrows an arbitrary string to a declared locale by membership test.
|
|
@@ -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';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n DomainRuleMap,\n IsDomainExclusive,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedDomains,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\nimport { isLocaleExclusiveOnDomain } from './domainUtils';\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'] | RewriteRules;\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 = (\n options: RoutingOptions = {}\n): Omit<RoutingOptions, 'defaultLocale' | 'mode' | 'locales'> & {\n defaultLocale: DeclaredLocales;\n mode: RoutingConfig['mode'];\n locales: DeclaredLocales[];\n} => ({\n defaultLocale: internationalization?.defaultLocale
|
|
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';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n DomainRuleMap,\n IsDomainExclusive,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedDomains,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\nimport { isLocaleExclusiveOnDomain } from './domainUtils';\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'] | RewriteRules;\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 = (\n options: RoutingOptions = {}\n): Omit<RoutingOptions, 'defaultLocale' | 'mode' | 'locales'> & {\n defaultLocale: DeclaredLocales;\n mode: RoutingConfig['mode'];\n locales: DeclaredLocales[];\n} => ({\n ...options,\n defaultLocale: (options.defaultLocale ??\n internationalization?.defaultLocale ??\n DEFAULT_LOCALE) as DeclaredLocales,\n mode: options.mode ?? routing?.mode ?? ROUTING_MODE,\n locales: (options.locales ??\n internationalization?.locales ??\n LOCALES) as DeclaredLocales[],\n rewrite: options.rewrite ?? routing?.rewrite,\n domains: options.domains ?? routing?.domains,\n});\n\n/**\n * Narrows an arbitrary string to a declared locale by membership test.\n *\n * `locales` is typed as `DeclaredLocales[]`, so a plain `includes` rejects the\n * `string` values that actually need testing (a URL segment, a query param, a\n * stored value). This keeps the check honest and hands back a narrowed type\n * instead of forcing a cast at every call site.\n *\n * @param value - The candidate locale, from a URL segment / storage / header.\n * @param locales - The locales declared by the configuration.\n * @returns Whether `value` is one of the declared locales.\n */\nexport const isDeclaredLocale = (\n value: LocalesValues | undefined | null,\n locales?: readonly LocalesValues[]\n): value is DeclaredLocales =>\n !!value && (locales ?? internationalization.locales).includes(value);\n\nexport type GetPrefixOptions = {\n defaultLocale?: ResolvedDefaultLocale;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The locale path segment appended to `/`, with a trailing slash (e.g. `'fr/'`).\n * Empty string when no prefix is needed.\n */\n prefix: string;\n /**\n * The bare locale identifier (e.g. `'fr'`), or `undefined` when no prefix is applied.\n */\n localePrefix: DeclaredLocales | undefined;\n};\n\n/**\n * Narrowed return type for {@link getPrefix} that carries the locale literal through.\n *\n * Distributes over union locales — calling `getPrefix('fr')` in `prefix-no-default`\n * mode with `defaultLocale = 'en'` resolves to `{ prefix: 'fr/'; localePrefix: 'fr' }`.\n * A locale served from its own exclusive domain resolves to an empty prefix, as\n * the hostname already identifies it.\n *\n * Note: the \"locale not in locales\" edge case returns an empty result at runtime\n * regardless of what this type reports.\n */\nexport type GetPrefixResultNarrowed<\n L extends LocalesValues | undefined,\n Mode extends string = ResolvedRoutingMode,\n Default extends LocalesValues = ResolvedDefaultLocale,\n Domains extends DomainRuleMap = ResolvedDomains,\n> = L extends string\n ? [string] extends [L] // L is wide (string / LocalesValues) → distribute over declared locales\n ? GetPrefixResultNarrowed<DeclaredLocales, Mode, Default, Domains>\n : IsDomainExclusive<L, Domains> extends true\n ? { prefix: ''; localePrefix: undefined } // the domain identifies the locale\n : [string] extends [Mode]\n ? GetPrefixResult // mode is wide → fall back to generic result\n : Mode extends 'prefix-all'\n ? { prefix: `${L}/`; localePrefix: L }\n : Mode extends 'prefix-no-default'\n ? L extends Default\n ? { prefix: ''; localePrefix: undefined }\n : { prefix: `${L}/`; localePrefix: L }\n : { prefix: ''; localePrefix: undefined } // no-prefix / search-params\n : { prefix: ''; localePrefix: undefined }; // locale is undefined\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 = <const L extends LocalesValues | undefined>(\n locale: L,\n options: RoutingOptions = {}\n): GetPrefixResultNarrowed<L> => {\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 !isDeclaredLocale(locale, locales)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\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 (\n process.env.INTLAYER_ROUTING_DOMAINS !== 'false' &&\n isLocaleExclusiveOnDomain(locale as LocalesValues, domains)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\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 DeclaredLocales,\n } as GetPrefixResultNarrowed<L>;\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n};\n"],"mappings":";;;;;;;;;AA6CA,MAAa,wBACX,UAA0B,CAAC,OAKvB;CACJ,GAAG;CACH,eAAgB,QAAQ,iBACtB,sBAAsB,iBACtB;CACF,MAAM,QAAQ,QAAQ,SAAS,QAAQ;CACvC,SAAU,QAAQ,WAChB,sBAAsB,WACtB;CACF,SAAS,QAAQ,WAAW,SAAS;CACrC,SAAS,QAAQ,WAAW,SAAS;AACvC;;;;;;;;;;;;;AAcA,MAAa,oBACX,OACA,YAEA,CAAC,CAAC,UAAU,WAAW,qBAAqB,QAAO,CAAE,SAAS,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoFrE,MAAa,aACX,QACA,UAA0B,CAAC,MACI;CAC/B,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,OAAO;CAE9B,IACG,QAAQ,IAAI,yBACX,QAAQ,IAAI,0BAA0B,gBACtC,QAAQ,IAAI,0BAA0B,uBACxC,CAAC,UACD,CAAC,iBAAiB,QAAQ,OAAO,GAEjC,OAAO;EACL,QAAQ;EACR,cAAc;CAChB;CAKF,IACE,QAAQ,IAAI,6BAA6B,WACzC,0BAA0B,QAAyB,OAAO,GAE1D,OAAO;EACL,QAAQ;EACR,cAAc;CAChB;CAQF,IAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,QAGnD,OAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;CAChB;CAGF,OAAO;EACL,QAAQ;EACR,cAAc;CAChB;AACF"}
|
|
@@ -3,6 +3,6 @@ import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./i18nex
|
|
|
3
3
|
import { navigatePath } from "./navigatePath.mjs";
|
|
4
4
|
import { intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./po.mjs";
|
|
5
5
|
import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./vue-i18n.mjs";
|
|
6
|
-
import { interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode } from "./resolveMessage.mjs";
|
|
6
|
+
import { createMessageResolver, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode, resolveMessageNodeToString } from "./resolveMessage.mjs";
|
|
7
7
|
|
|
8
|
-
export { i18nextToIntlayerFormatter, icuToIntlayerFormatter, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, navigatePath, parseTaggedMessage, portableObjectToIntlayerFormatter, resolveMessage, resolveMessageNode, vueI18nToIntlayerFormatter };
|
|
8
|
+
export { createMessageResolver, i18nextToIntlayerFormatter, icuToIntlayerFormatter, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, navigatePath, parseTaggedMessage, portableObjectToIntlayerFormatter, resolveMessage, resolveMessageNode, resolveMessageNodeToString, vueI18nToIntlayerFormatter };
|
|
@@ -52,13 +52,15 @@ const formatArgument = (value, type, style, locale) => {
|
|
|
52
52
|
* Interpolates a message template with values.
|
|
53
53
|
*
|
|
54
54
|
* Handles, in order:
|
|
55
|
-
* 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths)
|
|
55
|
+
* 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths),
|
|
56
|
+
* optionally formatted the i18next way (`{{price, number}}`)
|
|
56
57
|
* 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`
|
|
57
58
|
* 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)
|
|
58
59
|
*/
|
|
59
|
-
const interpolateMessage = (template, values = {}, locale = "en") => template.replace(/\{\{\s*([^{}]+?)\s
|
|
60
|
+
const interpolateMessage = (template, values = {}, locale = "en") => template.replace(/\{\{\s*([^{},]+?)\s*(?:,\s*(\w+)\s*(?:,\s*([^{}]+?)\s*)?)?\}\}/g, (match, path, type, style) => {
|
|
60
61
|
const value = resolveValuePath(values, path);
|
|
61
|
-
|
|
62
|
+
if (value === void 0) return match;
|
|
63
|
+
return type ? formatArgument(value, type, style, locale) : String(value);
|
|
62
64
|
}).replace(/\{\s*([\w.]+)\s*,\s*(\w+)\s*(?:,\s*([^}]+?)\s*)?\}/g, (match, path, type, style) => {
|
|
63
65
|
const value = resolveValuePath(values, path);
|
|
64
66
|
if (value === void 0) return match;
|
|
@@ -126,15 +128,45 @@ const resolveMessageNode = (node, values = {}, locale = "en") => {
|
|
|
126
128
|
}
|
|
127
129
|
return node;
|
|
128
130
|
};
|
|
131
|
+
/**
|
|
132
|
+
* {@link resolveMessageNode} coerced to a string.
|
|
133
|
+
*
|
|
134
|
+
* This is the whole runtime a compat adapter needs for content that reached
|
|
135
|
+
* the bundle through a built dictionary: the build already converted every
|
|
136
|
+
* dialect construct into intlayer nodes, and the interpreter turned those into
|
|
137
|
+
* callables, so no message parser is involved. Plain strings still get
|
|
138
|
+
* `{{name}}` / `{name}` / `{value, number}` interpolation.
|
|
139
|
+
*/
|
|
140
|
+
const resolveMessageNodeToString = (node, values = {}, locale = "en") => {
|
|
141
|
+
const resolved = resolveMessageNode(node, values, locale);
|
|
142
|
+
return typeof resolved === "string" ? resolved : String(resolved ?? "");
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Binds {@link resolveMessageNode} to one dialect converter.
|
|
146
|
+
*
|
|
147
|
+
* The compat adapters each speak a single dialect, and referencing the
|
|
148
|
+
* converter directly — rather than picking it from a record keyed by dialect —
|
|
149
|
+
* is what lets a bundler drop the two parsers the adapter never uses.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* const resolveIcuMessage = createMessageResolver(icuToIntlayerFormatter);
|
|
154
|
+
* resolveIcuMessage('Hello {name}', { name: 'John' }, 'en'); // 'Hello John'
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
const createMessageResolver = (formatter) => (message, values = {}, locale = "en") => resolveMessageNodeToString(typeof message === "string" ? formatter(message) : message, values, locale);
|
|
129
158
|
const DIALECT_FORMATTERS = {
|
|
130
|
-
icu:
|
|
131
|
-
i18next:
|
|
132
|
-
"vue-i18n":
|
|
159
|
+
icu: icuToIntlayerFormatter,
|
|
160
|
+
i18next: i18nextToIntlayerFormatter,
|
|
161
|
+
"vue-i18n": vueI18nToIntlayerFormatter
|
|
133
162
|
};
|
|
134
163
|
/**
|
|
135
164
|
* Resolves a raw message — string in a library dialect, or an intlayer node
|
|
136
165
|
* tree — into a final string using interpolation values and locale.
|
|
137
166
|
*
|
|
167
|
+
* Selecting the dialect at runtime keeps every converter reachable; a package
|
|
168
|
+
* that only ever needs one should bind it with {@link createMessageResolver}.
|
|
169
|
+
*
|
|
138
170
|
* @example
|
|
139
171
|
* ```ts
|
|
140
172
|
* resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');
|
|
@@ -149,11 +181,7 @@ const DIALECT_FORMATTERS = {
|
|
|
149
181
|
* // '3 items'
|
|
150
182
|
* ```
|
|
151
183
|
*/
|
|
152
|
-
const resolveMessage = (message, values = {}, locale = "en", dialect = "icu") =>
|
|
153
|
-
const node = typeof message === "string" ? DIALECT_FORMATTERS[dialect](message) : message;
|
|
154
|
-
const resolved = resolveMessageNode(node, values, locale);
|
|
155
|
-
return typeof resolved === "string" ? resolved : String(resolved ?? "");
|
|
156
|
-
};
|
|
184
|
+
const resolveMessage = (message, values = {}, locale = "en", dialect = "icu") => createMessageResolver(DIALECT_FORMATTERS[dialect])(message, values, locale);
|
|
157
185
|
/**
|
|
158
186
|
* Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,
|
|
159
187
|
* `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.
|
|
@@ -185,5 +213,5 @@ const parseTaggedMessage = (message) => {
|
|
|
185
213
|
};
|
|
186
214
|
|
|
187
215
|
//#endregion
|
|
188
|
-
export { interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode };
|
|
216
|
+
export { createMessageResolver, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode, resolveMessageNodeToString };
|
|
189
217
|
//# sourceMappingURL=resolveMessage.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveMessage.mjs","names":[],"sources":["../../../src/messageFormat/resolveMessage.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { getCachedIntl } from '../formatters';\nimport { getEnumeration } from '../interpreter/getEnumeration';\nimport { getPlural } from '../interpreter/getPlural';\nimport { getSelect } from '../interpreter/getSelect';\nimport type { PluralContentState } from '../transpiler/plural/plural';\nimport { icuToIntlayerFormatter } from './ICU';\nimport { i18nextToIntlayerFormatter } from './i18next';\nimport { vueI18nToIntlayerFormatter } from './vue-i18n';\n\n/**\n * Runtime counterpart of the `messageFormat` converters.\n *\n * The converters (`icuToIntlayerFormatter`, `i18nextToIntlayerFormatter`,\n * `vueI18nToIntlayerFormatter`) turn library-specific message syntax into\n * intlayer nodes (`insert`, `plural`, `enu`, `gender`, `html`). This module\n * resolves those nodes — or raw message strings — into a final string using\n * the provided interpolation values and locale.\n *\n * It is the mutualized resolution engine used by the compat adapter packages\n * (`@intlayer/i18next`, `@intlayer/next-intl`, `@intlayer/vue-i18n`, …).\n */\n\n/** Message syntax dialect of the source i18n library. */\nexport type MessageFormatDialect = 'icu' | 'i18next' | 'vue-i18n';\n\n/** Interpolation values passed alongside a translation lookup. */\nexport type MessageValues = Record<string, unknown>;\n\n/** Internal enumeration metadata keys injected by the converters. */\nconst ENUMERATION_METADATA_KEYS = [\n '__intlayer_icu_var',\n '__intlayer_icu_ordinal',\n '__intlayer_vue_i18n_var',\n] as const;\n\n/**\n * Resolves a possibly-dotted path (`user.name`) inside the values object.\n */\nconst resolveValuePath = (values: MessageValues, path: string): unknown => {\n if (path in values) return values[path];\n\n let current: unknown = values;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/** Formats an ICU-style formatted argument (`{value, number, percent}`). */\nconst formatArgument = (\n value: unknown,\n type: string,\n style: string | undefined,\n locale: LocalesValues\n): string => {\n try {\n if (type === 'number') {\n const numberValue = Number(value);\n if (style === 'percent') {\n return getCachedIntl('NumberFormat', locale, {\n style: 'percent',\n }).format(numberValue);\n }\n if (style === 'integer') {\n return getCachedIntl('NumberFormat', locale, {\n maximumFractionDigits: 0,\n }).format(numberValue);\n }\n return getCachedIntl('NumberFormat', locale).format(numberValue);\n }\n\n if (type === 'date' || type === 'time') {\n const dateValue =\n value instanceof Date ? value : new Date(value as string | number);\n const dateTimeStyle = (\n ['short', 'medium', 'long', 'full'].includes(style ?? '')\n ? style\n : type === 'date'\n ? 'medium'\n : 'short'\n ) as 'short' | 'medium' | 'long' | 'full';\n\n return getCachedIntl(\n 'DateTimeFormat',\n locale,\n type === 'date'\n ? { dateStyle: dateTimeStyle }\n : { timeStyle: dateTimeStyle }\n ).format(dateValue);\n }\n } catch {\n // Fall through to the raw string representation below\n }\n\n return String(value);\n};\n\n/**\n * Interpolates a message template with values.\n *\n * Handles, in order:\n * 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths)\n * 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`\n * 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)\n */\nexport const interpolateMessage = (\n template: string,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string =>\n template\n .replace(/\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n })\n .replace(\n /\\{\\s*([\\w.]+)\\s*,\\s*(\\w+)\\s*(?:,\\s*([^}]+?)\\s*)?\\}/g,\n (match, path: string, type: string, style: string | undefined) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return formatArgument(value, type, style, locale);\n }\n )\n .replace(/\\{\\s*([\\w.]+)\\s*\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n });\n\n/** Reads the selector value of an enumeration/plural node from the values. */\nconst getSelectorValue = (\n values: MessageValues,\n variableName: string\n): unknown => values[variableName] ?? values.count ?? values.n;\n\n/**\n * Resolves an intlayer message node tree (as produced by the\n * `*ToIntlayerFormatter` converters, or already present in a built\n * dictionary) into its final value using interpolation values and locale.\n *\n * Function nodes (produced by the interpreter plugins for `insertion`,\n * `enumeration` and `plural` content) are invoked with the values.\n */\nexport const resolveMessageNode = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): unknown => {\n if (node === null || node === undefined) return node;\n\n if (typeof node === 'string') {\n return interpolateMessage(node, values, locale);\n }\n\n if (typeof node === 'number' || typeof node === 'boolean') {\n return String(node);\n }\n\n // Interpreter-transformed nodes (insertion/enumeration/plural plugins)\n // are exposed as callables taking the interpolation values.\n if (typeof node === 'function') {\n try {\n return resolveMessageNode(\n (node as (arg: MessageValues) => unknown)(values),\n values,\n locale\n );\n } catch {\n return undefined;\n }\n }\n\n if (Array.isArray(node)) {\n return node\n .map((item) => String(resolveMessageNode(item, values, locale) ?? ''))\n .join('');\n }\n\n const typedNode = node as Record<string, unknown> & { nodeType?: string };\n\n if (typedNode.nodeType === NodeTypes.INSERTION) {\n return resolveMessageNode(typedNode[NodeTypes.INSERTION], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.HTML) {\n // Tags are kept intact — rich rendering is handled by the caller\n return resolveMessageNode(typedNode[NodeTypes.HTML], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.PLURAL) {\n const pluralState = typedNode[\n NodeTypes.PLURAL\n ] as PluralContentState<unknown>;\n const count = Number(getSelectorValue(values, 'count') ?? 1);\n const selected = getPlural(\n pluralState as PluralContentState<string>,\n count,\n locale\n );\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.ENUMERATION) {\n const enumerationState = typedNode[NodeTypes.ENUMERATION] as Record<\n string,\n unknown\n >;\n\n const variableName = (ENUMERATION_METADATA_KEYS.map(\n (metadataKey) => enumerationState[metadataKey]\n ).find((name) => typeof name === 'string') ?? 'count') as string;\n\n const isOrdinal = enumerationState.__intlayer_icu_ordinal === true;\n\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(enumerationState)) {\n if (!(ENUMERATION_METADATA_KEYS as readonly string[]).includes(key)) {\n options[key] = value;\n }\n }\n\n const selector = getSelectorValue(values, variableName);\n\n let selected: unknown;\n if (isOrdinal && !Number.isNaN(Number(selector))) {\n // ICU `selectordinal` — exact numeric match first, then the CLDR\n // ordinal category, then the fallback\n const ordinalCount = Number(selector);\n const ordinalCategory = getCachedIntl('PluralRules', locale, {\n type: 'ordinal',\n }).select(ordinalCount);\n selected =\n options[String(ordinalCount)] ??\n options[ordinalCategory] ??\n options.fallback ??\n options.other;\n } else if (\n typeof selector === 'number' ||\n !Number.isNaN(Number(selector))\n ) {\n selected = getEnumeration(options, Number(selector));\n } else {\n // String selector — ICU `select` converted to an enumeration\n selected = options[String(selector)] ?? options.fallback ?? options.other;\n }\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.SELECT) {\n const selectState = typedNode[NodeTypes.SELECT] as Record<string, unknown>;\n\n // The node records the ICU variable it was imported from; fall back to\n // `value` for nodes authored directly with `select()`.\n const variableName =\n typeof typedNode.variable === 'string' ? typedNode.variable : 'value';\n\n const selector = getSelectorValue(values, variableName);\n const selected = getSelect(selectState, String(selector ?? ''));\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.GENDER) {\n const genderState = typedNode[NodeTypes.GENDER] as Record<string, unknown>;\n const genderValue = String(values.gender ?? '');\n const selected =\n genderState[genderValue] ?? genderState.fallback ?? genderState.other;\n return resolveMessageNode(selected, values, locale);\n }\n\n return node;\n};\n\nconst DIALECT_FORMATTERS: Record<\n MessageFormatDialect,\n (message: string) => unknown\n> = {\n icu: (message) => icuToIntlayerFormatter(message),\n i18next: (message) => i18nextToIntlayerFormatter(message),\n 'vue-i18n': (message) => vueI18nToIntlayerFormatter(message),\n};\n\n/**\n * Resolves a raw message — string in a library dialect, or an intlayer node\n * tree — into a final string using interpolation values and locale.\n *\n * @example\n * ```ts\n * resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');\n * // 'Hello John'\n *\n * resolveMessage(\n * '{count, plural, one {# item} other {# items}}',\n * { count: 3 },\n * 'en',\n * 'icu'\n * );\n * // '3 items'\n * ```\n */\nexport const resolveMessage = (\n message: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues,\n dialect: MessageFormatDialect = 'icu'\n): string => {\n const node =\n typeof message === 'string'\n ? DIALECT_FORMATTERS[dialect](message)\n : message;\n\n const resolved = resolveMessageNode(node, values, locale);\n\n return typeof resolved === 'string' ? resolved : String(resolved ?? '');\n};\n\n/** A parsed token of a tagged message: plain text or a tag with children. */\nexport type TaggedMessageToken =\n | string\n | { tag: string; children: TaggedMessageToken[] };\n\n/**\n * Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,\n * `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.\n *\n * Used by rich-text renderers (`t.rich`, `<Trans components>`,\n * `<i18n-t>` slots) to map tags to framework elements.\n */\nexport const parseTaggedMessage = (message: string): TaggedMessageToken[] => {\n const tokens: TaggedMessageToken[] = [];\n const tagRegex = /<([\\w-]+)\\s*\\/>|<([\\w-]+)[^>]*>([\\s\\S]*?)<\\/\\2>/g;\n let lastIndex = 0;\n let match = tagRegex.exec(message);\n\n while (match !== null) {\n if (match.index > lastIndex) {\n tokens.push(message.slice(lastIndex, match.index));\n }\n\n const [, selfClosingTag, tag, inner] = match;\n\n if (selfClosingTag) {\n tokens.push({ tag: selfClosingTag, children: [] });\n } else {\n tokens.push({ tag, children: parseTaggedMessage(inner) });\n }\n\n lastIndex = match.index + match[0].length;\n match = tagRegex.exec(message);\n }\n\n if (lastIndex < message.length) {\n tokens.push(message.slice(lastIndex));\n }\n\n return tokens;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolveMessage.mjs","names":[],"sources":["../../../src/messageFormat/resolveMessage.ts"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { getCachedIntl } from '../formatters';\nimport { getEnumeration } from '../interpreter/getEnumeration';\nimport { getPlural } from '../interpreter/getPlural';\nimport { getSelect } from '../interpreter/getSelect';\nimport type { PluralContentState } from '../transpiler/plural/plural';\nimport { icuToIntlayerFormatter } from './ICU';\nimport { i18nextToIntlayerFormatter } from './i18next';\nimport { vueI18nToIntlayerFormatter } from './vue-i18n';\n\n/**\n * Runtime counterpart of the `messageFormat` converters.\n *\n * The converters (`icuToIntlayerFormatter`, `i18nextToIntlayerFormatter`,\n * `vueI18nToIntlayerFormatter`) turn library-specific message syntax into\n * intlayer nodes (`insert`, `plural`, `enu`, `gender`, `html`). This module\n * resolves those nodes — or raw message strings — into a final string using\n * the provided interpolation values and locale.\n *\n * It is the mutualized resolution engine used by the compat adapter packages\n * (`@intlayer/i18next`, `@intlayer/next-intl`, `@intlayer/vue-i18n`, …).\n */\n\n/** Message syntax dialect of the source i18n library. */\nexport type MessageFormatDialect = 'icu' | 'i18next' | 'vue-i18n';\n\n/** Interpolation values passed alongside a translation lookup. */\nexport type MessageValues = Record<string, unknown>;\n\n/** Internal enumeration metadata keys injected by the converters. */\nconst ENUMERATION_METADATA_KEYS = [\n '__intlayer_icu_var',\n '__intlayer_icu_ordinal',\n '__intlayer_vue_i18n_var',\n] as const;\n\n/**\n * Resolves a possibly-dotted path (`user.name`) inside the values object.\n */\nconst resolveValuePath = (values: MessageValues, path: string): unknown => {\n if (path in values) return values[path];\n\n let current: unknown = values;\n for (const part of path.split('.')) {\n if (\n current === null ||\n current === undefined ||\n typeof current !== 'object'\n ) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n};\n\n/** Formats an ICU-style formatted argument (`{value, number, percent}`). */\nconst formatArgument = (\n value: unknown,\n type: string,\n style: string | undefined,\n locale: LocalesValues\n): string => {\n try {\n if (type === 'number') {\n const numberValue = Number(value);\n if (style === 'percent') {\n return getCachedIntl('NumberFormat', locale, {\n style: 'percent',\n }).format(numberValue);\n }\n if (style === 'integer') {\n return getCachedIntl('NumberFormat', locale, {\n maximumFractionDigits: 0,\n }).format(numberValue);\n }\n return getCachedIntl('NumberFormat', locale).format(numberValue);\n }\n\n if (type === 'date' || type === 'time') {\n const dateValue =\n value instanceof Date ? value : new Date(value as string | number);\n const dateTimeStyle = (\n ['short', 'medium', 'long', 'full'].includes(style ?? '')\n ? style\n : type === 'date'\n ? 'medium'\n : 'short'\n ) as 'short' | 'medium' | 'long' | 'full';\n\n return getCachedIntl(\n 'DateTimeFormat',\n locale,\n type === 'date'\n ? { dateStyle: dateTimeStyle }\n : { timeStyle: dateTimeStyle }\n ).format(dateValue);\n }\n } catch {\n // Fall through to the raw string representation below\n }\n\n return String(value);\n};\n\n/**\n * Interpolates a message template with values.\n *\n * Handles, in order:\n * 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths),\n * optionally formatted the i18next way (`{{price, number}}`)\n * 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`\n * 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)\n */\nexport const interpolateMessage = (\n template: string,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string =>\n template\n .replace(\n /\\{\\{\\s*([^{},]+?)\\s*(?:,\\s*(\\w+)\\s*(?:,\\s*([^{}]+?)\\s*)?)?\\}\\}/g,\n (match, path: string, type: string | undefined, style?: string) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return type\n ? formatArgument(value, type, style, locale)\n : String(value);\n }\n )\n .replace(\n /\\{\\s*([\\w.]+)\\s*,\\s*(\\w+)\\s*(?:,\\s*([^}]+?)\\s*)?\\}/g,\n (match, path: string, type: string, style: string | undefined) => {\n const value = resolveValuePath(values, path);\n if (value === undefined) return match;\n return formatArgument(value, type, style, locale);\n }\n )\n .replace(/\\{\\s*([\\w.]+)\\s*\\}/g, (match, path: string) => {\n const value = resolveValuePath(values, path);\n return value === undefined ? match : String(value);\n });\n\n/** Reads the selector value of an enumeration/plural node from the values. */\nconst getSelectorValue = (\n values: MessageValues,\n variableName: string\n): unknown => values[variableName] ?? values.count ?? values.n;\n\n/**\n * Resolves an intlayer message node tree (as produced by the\n * `*ToIntlayerFormatter` converters, or already present in a built\n * dictionary) into its final value using interpolation values and locale.\n *\n * Function nodes (produced by the interpreter plugins for `insertion`,\n * `enumeration` and `plural` content) are invoked with the values.\n */\nexport const resolveMessageNode = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): unknown => {\n if (node === null || node === undefined) return node;\n\n if (typeof node === 'string') {\n return interpolateMessage(node, values, locale);\n }\n\n if (typeof node === 'number' || typeof node === 'boolean') {\n return String(node);\n }\n\n // Interpreter-transformed nodes (insertion/enumeration/plural plugins)\n // are exposed as callables taking the interpolation values.\n if (typeof node === 'function') {\n try {\n return resolveMessageNode(\n (node as (arg: MessageValues) => unknown)(values),\n values,\n locale\n );\n } catch {\n return undefined;\n }\n }\n\n if (Array.isArray(node)) {\n return node\n .map((item) => String(resolveMessageNode(item, values, locale) ?? ''))\n .join('');\n }\n\n const typedNode = node as Record<string, unknown> & { nodeType?: string };\n\n if (typedNode.nodeType === NodeTypes.INSERTION) {\n return resolveMessageNode(typedNode[NodeTypes.INSERTION], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.HTML) {\n // Tags are kept intact — rich rendering is handled by the caller\n return resolveMessageNode(typedNode[NodeTypes.HTML], values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.PLURAL) {\n const pluralState = typedNode[\n NodeTypes.PLURAL\n ] as PluralContentState<unknown>;\n const count = Number(getSelectorValue(values, 'count') ?? 1);\n const selected = getPlural(\n pluralState as PluralContentState<string>,\n count,\n locale\n );\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.ENUMERATION) {\n const enumerationState = typedNode[NodeTypes.ENUMERATION] as Record<\n string,\n unknown\n >;\n\n const variableName = (ENUMERATION_METADATA_KEYS.map(\n (metadataKey) => enumerationState[metadataKey]\n ).find((name) => typeof name === 'string') ?? 'count') as string;\n\n const isOrdinal = enumerationState.__intlayer_icu_ordinal === true;\n\n const options: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(enumerationState)) {\n if (!(ENUMERATION_METADATA_KEYS as readonly string[]).includes(key)) {\n options[key] = value;\n }\n }\n\n const selector = getSelectorValue(values, variableName);\n\n let selected: unknown;\n if (isOrdinal && !Number.isNaN(Number(selector))) {\n // ICU `selectordinal` — exact numeric match first, then the CLDR\n // ordinal category, then the fallback\n const ordinalCount = Number(selector);\n const ordinalCategory = getCachedIntl('PluralRules', locale, {\n type: 'ordinal',\n }).select(ordinalCount);\n selected =\n options[String(ordinalCount)] ??\n options[ordinalCategory] ??\n options.fallback ??\n options.other;\n } else if (\n typeof selector === 'number' ||\n !Number.isNaN(Number(selector))\n ) {\n selected = getEnumeration(options, Number(selector));\n } else {\n // String selector — ICU `select` converted to an enumeration\n selected = options[String(selector)] ?? options.fallback ?? options.other;\n }\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.SELECT) {\n const selectState = typedNode[NodeTypes.SELECT] as Record<string, unknown>;\n\n // The node records the ICU variable it was imported from; fall back to\n // `value` for nodes authored directly with `select()`.\n const variableName =\n typeof typedNode.variable === 'string' ? typedNode.variable : 'value';\n\n const selector = getSelectorValue(values, variableName);\n const selected = getSelect(selectState, String(selector ?? ''));\n\n return resolveMessageNode(selected, values, locale);\n }\n\n if (typedNode.nodeType === NodeTypes.GENDER) {\n const genderState = typedNode[NodeTypes.GENDER] as Record<string, unknown>;\n const genderValue = String(values.gender ?? '');\n const selected =\n genderState[genderValue] ?? genderState.fallback ?? genderState.other;\n return resolveMessageNode(selected, values, locale);\n }\n\n return node;\n};\n\n/**\n * {@link resolveMessageNode} coerced to a string.\n *\n * This is the whole runtime a compat adapter needs for content that reached\n * the bundle through a built dictionary: the build already converted every\n * dialect construct into intlayer nodes, and the interpreter turned those into\n * callables, so no message parser is involved. Plain strings still get\n * `{{name}}` / `{name}` / `{value, number}` interpolation.\n */\nexport const resolveMessageNodeToString = (\n node: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues\n): string => {\n const resolved = resolveMessageNode(node, values, locale);\n\n return typeof resolved === 'string' ? resolved : String(resolved ?? '');\n};\n\n/** Converts a raw message string of one dialect into an intlayer node tree. */\nexport type MessageFormatter = (message: string) => unknown;\n\n/**\n * Resolves a raw message — string, or an intlayer node tree — into a final\n * string using interpolation values and locale.\n */\nexport type MessageResolver = (\n message: unknown,\n values?: MessageValues,\n locale?: LocalesValues\n) => string;\n\n/**\n * Binds {@link resolveMessageNode} to one dialect converter.\n *\n * The compat adapters each speak a single dialect, and referencing the\n * converter directly — rather than picking it from a record keyed by dialect —\n * is what lets a bundler drop the two parsers the adapter never uses.\n *\n * @example\n * ```ts\n * const resolveIcuMessage = createMessageResolver(icuToIntlayerFormatter);\n * resolveIcuMessage('Hello {name}', { name: 'John' }, 'en'); // 'Hello John'\n * ```\n */\nexport const createMessageResolver =\n (formatter: MessageFormatter): MessageResolver =>\n (message, values = {}, locale = 'en' as LocalesValues) =>\n resolveMessageNodeToString(\n typeof message === 'string' ? formatter(message) : message,\n values,\n locale\n );\n\nconst DIALECT_FORMATTERS: Record<MessageFormatDialect, MessageFormatter> = {\n icu: icuToIntlayerFormatter,\n i18next: i18nextToIntlayerFormatter,\n 'vue-i18n': vueI18nToIntlayerFormatter,\n};\n\n/**\n * Resolves a raw message — string in a library dialect, or an intlayer node\n * tree — into a final string using interpolation values and locale.\n *\n * Selecting the dialect at runtime keeps every converter reachable; a package\n * that only ever needs one should bind it with {@link createMessageResolver}.\n *\n * @example\n * ```ts\n * resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');\n * // 'Hello John'\n *\n * resolveMessage(\n * '{count, plural, one {# item} other {# items}}',\n * { count: 3 },\n * 'en',\n * 'icu'\n * );\n * // '3 items'\n * ```\n */\nexport const resolveMessage = (\n message: unknown,\n values: MessageValues = {},\n locale: LocalesValues = 'en' as LocalesValues,\n dialect: MessageFormatDialect = 'icu'\n): string =>\n createMessageResolver(DIALECT_FORMATTERS[dialect])(message, values, locale);\n\n/** A parsed token of a tagged message: plain text or a tag with children. */\nexport type TaggedMessageToken =\n | string\n | { tag: string; children: TaggedMessageToken[] };\n\n/**\n * Tokenizes a message containing XML-like tags (`'Visit <link>the docs</link>'`,\n * `'hello <1>{{name}}</1>'`, `'line<br/>break'`) into a token tree.\n *\n * Used by rich-text renderers (`t.rich`, `<Trans components>`,\n * `<i18n-t>` slots) to map tags to framework elements.\n */\nexport const parseTaggedMessage = (message: string): TaggedMessageToken[] => {\n const tokens: TaggedMessageToken[] = [];\n const tagRegex = /<([\\w-]+)\\s*\\/>|<([\\w-]+)[^>]*>([\\s\\S]*?)<\\/\\2>/g;\n let lastIndex = 0;\n let match = tagRegex.exec(message);\n\n while (match !== null) {\n if (match.index > lastIndex) {\n tokens.push(message.slice(lastIndex, match.index));\n }\n\n const [, selfClosingTag, tag, inner] = match;\n\n if (selfClosingTag) {\n tokens.push({ tag: selfClosingTag, children: [] });\n } else {\n tokens.push({ tag, children: parseTaggedMessage(inner) });\n }\n\n lastIndex = match.index + match[0].length;\n match = tagRegex.exec(message);\n }\n\n if (lastIndex < message.length) {\n tokens.push(message.slice(lastIndex));\n }\n\n return tokens;\n};\n"],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ const getCookie = (name, cookieString) => {
|
|
|
11
11
|
if (!str) return void 0;
|
|
12
12
|
const pairs = str.split(";");
|
|
13
13
|
for (let i = 0; i < pairs.length; i++) {
|
|
14
|
-
const part = pairs[i]
|
|
14
|
+
const part = pairs[i]?.trim();
|
|
15
15
|
if (!part) continue;
|
|
16
16
|
const equalIndex = part.indexOf("=");
|
|
17
17
|
if ((equalIndex >= 0 ? part.substring(0, equalIndex) : part) === name) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCookie.mjs","names":[],"sources":["../../../src/utils/getCookie.ts"],"sourcesContent":["/**\n * Retrieves a cookie by name from a cookie string or document.cookie\n * @param name - The name of the cookie to retrieve\n * @param cookieString - Optional cookie string to parse (defaults to document.cookie in browser)\n * @returns The cookie value or undefined if not found\n */\nexport const getCookie = (\n name: string,\n cookieString?: string\n): string | undefined => {\n try {\n const str =\n cookieString ?? (typeof document !== 'undefined' ? document.cookie : '');\n\n if (!str) return undefined;\n\n const pairs = str.split(';');\n\n for (let i = 0; i < pairs.length; i++) {\n const part = pairs[i]
|
|
1
|
+
{"version":3,"file":"getCookie.mjs","names":[],"sources":["../../../src/utils/getCookie.ts"],"sourcesContent":["/**\n * Retrieves a cookie by name from a cookie string or document.cookie\n * @param name - The name of the cookie to retrieve\n * @param cookieString - Optional cookie string to parse (defaults to document.cookie in browser)\n * @returns The cookie value or undefined if not found\n */\nexport const getCookie = (\n name: string,\n cookieString?: string\n): string | undefined => {\n try {\n const str =\n cookieString ?? (typeof document !== 'undefined' ? document.cookie : '');\n\n if (!str) return undefined;\n\n const pairs = str.split(';');\n\n for (let i = 0; i < pairs.length; i++) {\n const part = pairs[i]?.trim();\n\n if (!part) continue;\n\n const equalIndex = part.indexOf('=');\n const key = equalIndex >= 0 ? part.substring(0, equalIndex) : part;\n\n if (key === name) {\n const rawValue = equalIndex >= 0 ? part.substring(equalIndex + 1) : '';\n\n try {\n return decodeURIComponent(rawValue);\n } catch {\n return rawValue;\n }\n }\n }\n } catch {}\n return undefined;\n};\n"],"mappings":";;;;;;;AAMA,MAAa,aACX,MACA,iBACuB;CACvB,IAAI;EACF,MAAM,MACJ,iBAAiB,OAAO,aAAa,cAAc,SAAS,SAAS;EAEvE,IAAI,CAAC,KAAK,OAAO;EAEjB,MAAM,QAAQ,IAAI,MAAM,GAAG;EAE3B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;GACrC,MAAM,OAAO,MAAM,EAAE,EAAE,KAAK;GAE5B,IAAI,CAAC,MAAM;GAEX,MAAM,aAAa,KAAK,QAAQ,GAAG;GAGnC,KAFY,cAAc,IAAI,KAAK,UAAU,GAAG,UAAU,IAAI,UAElD,MAAM;IAChB,MAAM,WAAW,cAAc,IAAI,KAAK,UAAU,aAAa,CAAC,IAAI;IAEpE,IAAI;KACF,OAAO,mBAAmB,QAAQ;IACpC,QAAQ;KACN,OAAO;IACT;GACF;EACF;CACF,QAAQ,CAAC;AAEX"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -112,7 +112,7 @@ import { JsonValue, icuToIntlayerFormatter, intlayerToICUFormatter } from "./mes
|
|
|
112
112
|
import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./messageFormat/i18next.js";
|
|
113
113
|
import { navigatePath } from "./messageFormat/navigatePath.js";
|
|
114
114
|
import { PortableObject, intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./messageFormat/po.js";
|
|
115
|
-
import { MessageFormatDialect, MessageValues, TaggedMessageToken, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode } from "./messageFormat/resolveMessage.js";
|
|
115
|
+
import { MessageFormatDialect, MessageFormatter, MessageResolver, MessageValues, TaggedMessageToken, createMessageResolver, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode, resolveMessageNodeToString } from "./messageFormat/resolveMessage.js";
|
|
116
116
|
import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./messageFormat/vue-i18n.js";
|
|
117
117
|
import "./messageFormat/index.js";
|
|
118
118
|
import { checkIsURLAbsolute } from "./utils/checkIsURLAbsolute.js";
|
|
@@ -123,4 +123,4 @@ import { CookieBuildAttributes, LocaleStorage, LocaleStorageClient, LocaleStorag
|
|
|
123
123
|
import { YamlRecord, YamlValue, parseYaml } from "./utils/parseYaml.js";
|
|
124
124
|
import { stringifyYaml } from "./utils/stringifyYaml.js";
|
|
125
125
|
import "./utils/index.js";
|
|
126
|
-
export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, type BlockQuoteNode, BlockSyntaxProbe, type BoldTextNode, type BreakLineNode, type BreakThematicNode, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, COMPOSITE_ID_SEPARATOR, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CachedIntl, CachedIntl as Intl, type CodeBlockNode, type CodeFencedNode, type CodeInlineNode, type CompileOptions, type ComponentOverrides, ConditionCond, ConditionContent, ConditionContentStates, CookieBuildAttributes, type CustomComponentNode, DEFAULT_VARIANT_ID, DO_NOT_PROCESS_HTML_ELEMENTS, DateTimePreset, DeepTransformContent, DotPath, DynamicDictionaryLoader, type ElementType, EnterFormat, EnumerationCond, EnumerationContent, EnumerationContentState, type EscapedTextNode, FENCE_DELIMITER_R, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, FileCond, type FileContent, type FileContentConstructor, type FootnoteNode, type FootnoteReferenceNode, type GFMTaskNode, GFM_TASK_R, Gender, GenderCond, GenderContent, GenderContentStates, type GenerateSitemapOptions, GetNestingResult, type GetPrefixOptions, type GetPrefixResult, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, type HTMLCommentNode, HTMLContent, HTMLContentConstructor, type HTMLNode, type HTMLSelfClosingNode, type HTMLTag, HTMLTagsType, HTMLValidationIssue, HTMLValidationResult, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_TAGS, type HeadingNode, type HeadingSetextNode, IInterpreterPlugin, IInterpreterPluginState, INLINE_SKIP_R, INTERPOLATION_R, type ImageNode, InsertionCond, InsertionContent, InsertionContentConstructor, InterpolableNode, IntlConstructorName, IsAny, type ItalicTextNode, JsonValue, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LOOKAHEAD, type LinkAngleBraceNode, type LinkBareURLNode, type LinkNode, ListFormatOptions, ListType, type LocaleDomainMap, LocaleStorage, LocaleStorageClient, LocaleStorageClientOptions, LocaleStorageOptions, LocaleStorageServer, LocaleStorageServerOptions, type LocalizedPathResult, MarkdownContent, MarkdownContentConstructor, type MarkdownContext, type MarkdownOptions, MarkdownReferences, type MarkdownRuntime, type HTMLValidationIssue as MarkdownValidationIssue, MarkdownValidationResult, type MarkedTextNode, MessageFormatDialect, MessageValues, NAMED_CODES_TO_UNICODE, NP_TABLE_R, NestedCond, NestedContent, NestedContentState, NestedFieldReferences, type NestedParser, type NewlineNode, NodeProps, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, type OrderedListNode, PARAGRAPH_R, PRELOADED_DYNAMIC_KEY, type ParagraphNode, type ParseState, ParsedMarkdown, type Parser, type ParserResult, PlainDynamicLoaderMap, Plugins, PluralCategory, PluralCond, PluralContent, PluralContentState, PortableObject, PreloadableDynamicLoaderMap, PreloadedDynamicEntry, Priority, PriorityValue, type ProxyMode, QUALIFIER_DYNAMIC_TYPES_KEY, QUALIFIER_ORDER, QualifiedDynamicLoaderMap, QualifiedDynamicLoaderTree, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, type ReferenceImageNode, type ReferenceLinkNode, type ReferenceNode, type RenderRuleHook, ResolvedDynamicLoader, type Rule, type RuleOutput, RuleScope, RuleScopeValue, RuleType, RuleTypeValue, type Rules, SCOPE_BLOCK, SCOPE_BOTH, SCOPE_INLINE, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, SelectCond, SelectContent, SelectContentStates, SelectSelector, type SitemapUrlEntry, type StrikethroughTextNode, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, type TableNode, type TableSeparatorNode, TaggedMessageToken, type TextNode, TranslationCond, TranslationContent, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, UnionKeys, type UnorderedListNode, VOID_HTML_ELEMENTS, ValidDotPathsFor, ValueAtKey, WrappedIntl, YamlRecord, YamlValue, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, comparePaths, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, type file, type fileContent, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, findPlainDynamicLoader, formatProxyEnabledMessage, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getDictionaryAsync, getDictionaryCompositeIds, getDictionaryQualifierIds, getDictionaryQualifierTypes, getDictionarySelectorCacheKey, getDictionaryTransformCacheKey, getDomainHostname, getDomainOrigin, getEditedContent, getEditedDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getGender, getHTML, getHTMLTextDir, getInsertion, getInsertionValues, getInternalPath, getInterpolableContent, getIntlayer, getIntlayerAsync, getLocale, getLocaleFromDomain, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNestedDictionaryGraph, getNestedDictionaryKeys, getNestedDictionaryReferences, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPluginsCacheKey, getPlural, getPrefix, getPreloadLocale, getPreloadedDictionary, getReplacedValuesContent, getRewritePath, getRewriteRules, getRuleSet, getSelect, getSplittedContent, getSplittedDictionaryContent, getTranslation, getVariantIds, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isDeclaredLocale, isInterpolableWrapperNode, isLocaleExclusiveOnDomain, isProxyStorageLocaleEnabled, isQualifiedDictionaryGroup, isQualifiedDynamicLoaderMap, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, mergeQualifiedDictionaries, navigatePath, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizePath, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseDictionarySelector, parseInline, parseMarkdown, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseTaggedMessage, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, readTransformCache, rebuildInterpolableContent, reconstructQualifiedEntry, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderMarkdownAst, renderNothing, resolveBrowserLocale, resolveDictionaryArgument, resolveEffectiveVariantId, resolveLocalizedPath, resolveMessage, resolveMessageNode, resolvePlainDynamicLoader, resolveProviderVariant, resolveProxyMode, resolveQualifiedDictionary, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync, sanitizer, select, selectPlugin, serializeVariant, serializeVariantChain, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, transformInterpolableNode, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter, writeTransformCache };
|
|
126
|
+
export { ATTRIBUTES_TO_SANITIZE, ATTRIBUTE_TO_NODE_PROP_MAP, ATTR_EXTRACTOR_R, BLOCKQUOTE_ALERT_R, BLOCKQUOTE_R, BLOCKQUOTE_TRIM_LEFT_MULTILINE_R, BLOCK_END_R, BREAK_LINE_R, BREAK_THEMATIC_R, type BlockQuoteNode, BlockSyntaxProbe, type BoldTextNode, type BreakLineNode, type BreakThematicNode, CAPTURE_LETTER_AFTER_HYPHEN, CODE_BLOCK_FENCED_R, CODE_BLOCK_R, CODE_INLINE_R, COMPOSITE_ID_SEPARATOR, CONSECUTIVE_NEWLINE_R, CR_NEWLINE_R, CachedIntl, CachedIntl as Intl, type CodeBlockNode, type CodeFencedNode, type CodeInlineNode, type CompileOptions, type ComponentOverrides, ConditionCond, ConditionContent, ConditionContentStates, CookieBuildAttributes, type CustomComponentNode, DEFAULT_VARIANT_ID, DO_NOT_PROCESS_HTML_ELEMENTS, DateTimePreset, DeepTransformContent, DotPath, DynamicDictionaryLoader, type ElementType, EnterFormat, EnumerationCond, EnumerationContent, EnumerationContentState, type EscapedTextNode, FENCE_DELIMITER_R, FOOTNOTE_R, FOOTNOTE_REFERENCE_R, FORMFEED_R, FRONT_MATTER_R, FileCond, type FileContent, type FileContentConstructor, type FootnoteNode, type FootnoteReferenceNode, type GFMTaskNode, GFM_TASK_R, Gender, GenderCond, GenderContent, GenderContentStates, type GenerateSitemapOptions, GetNestingResult, type GetPrefixOptions, type GetPrefixResult, HEADING_ATX_COMPLIANT_R, HEADING_R, HEADING_SETEXT_R, type HTMLCommentNode, HTMLContent, HTMLContentConstructor, type HTMLNode, type HTMLSelfClosingNode, type HTMLTag, HTMLTagsType, HTMLValidationIssue, HTMLValidationResult, HTML_CHAR_CODE_R, HTML_COMMENT_R, HTML_CUSTOM_ATTR_R, HTML_LEFT_TRIM_AMOUNT_R, HTML_TAGS, type HeadingNode, type HeadingSetextNode, IInterpreterPlugin, IInterpreterPluginState, INLINE_SKIP_R, INTERPOLATION_R, type ImageNode, InsertionCond, InsertionContent, InsertionContentConstructor, InterpolableNode, IntlConstructorName, IsAny, type ItalicTextNode, JsonValue, LINK_AUTOLINK_BARE_URL_R, LINK_AUTOLINK_R, LOOKAHEAD, type LinkAngleBraceNode, type LinkBareURLNode, type LinkNode, ListFormatOptions, ListType, type LocaleDomainMap, LocaleStorage, LocaleStorageClient, LocaleStorageClientOptions, LocaleStorageOptions, LocaleStorageServer, LocaleStorageServerOptions, type LocalizedPathResult, MarkdownContent, MarkdownContentConstructor, type MarkdownContext, type MarkdownOptions, MarkdownReferences, type MarkdownRuntime, type HTMLValidationIssue as MarkdownValidationIssue, MarkdownValidationResult, type MarkedTextNode, MessageFormatDialect, MessageFormatter, MessageResolver, MessageValues, NAMED_CODES_TO_UNICODE, NP_TABLE_R, NestedCond, NestedContent, NestedContentState, NestedFieldReferences, type NestedParser, type NewlineNode, NodeProps, ORDERED, ORDERED_LIST_BULLET, ORDERED_LIST_ITEM_PREFIX, ORDERED_LIST_ITEM_PREFIX_R, ORDERED_LIST_ITEM_R, ORDERED_LIST_R, type OrderedListNode, PARAGRAPH_R, PRELOADED_DYNAMIC_KEY, type ParagraphNode, type ParseState, ParsedMarkdown, type Parser, type ParserResult, PlainDynamicLoaderMap, Plugins, PluralCategory, PluralCond, PluralContent, PluralContentState, PortableObject, PreloadableDynamicLoaderMap, PreloadedDynamicEntry, Priority, PriorityValue, type ProxyMode, QUALIFIER_DYNAMIC_TYPES_KEY, QUALIFIER_ORDER, QualifiedDynamicLoaderMap, QualifiedDynamicLoaderTree, REFERENCE_IMAGE_OR_LINK, REFERENCE_IMAGE_R, REFERENCE_LINK_R, type ReferenceImageNode, type ReferenceLinkNode, type ReferenceNode, type RenderRuleHook, ResolvedDynamicLoader, type Rule, type RuleOutput, RuleScope, RuleScopeValue, RuleType, RuleTypeValue, type Rules, SCOPE_BLOCK, SCOPE_BOTH, SCOPE_INLINE, SHORTCODE_R, SHOULD_RENDER_AS_BLOCK_R, SelectCond, SelectContent, SelectContentStates, SelectSelector, type SitemapUrlEntry, type StrikethroughTextNode, TABLE_CENTER_ALIGN, TABLE_LEFT_ALIGN, TABLE_RIGHT_ALIGN, TABLE_TRIM_PIPES, TAB_R, TEXT_BOLD_R, TEXT_EMPHASIZED_R, TEXT_ESCAPED_R, TEXT_MARKED_R, TEXT_STRIKETHROUGHED_R, TRIM_STARTING_NEWLINES, type TableNode, type TableSeparatorNode, TaggedMessageToken, type TextNode, TranslationCond, TranslationContent, UNESCAPE_R, UNORDERED, UNORDERED_LIST_BULLET, UNORDERED_LIST_ITEM_PREFIX, UNORDERED_LIST_ITEM_PREFIX_R, UNORDERED_LIST_ITEM_R, UNORDERED_LIST_R, UnionKeys, type UnorderedListNode, VOID_HTML_ELEMENTS, ValidDotPathsFor, ValueAtKey, WrappedIntl, YamlRecord, YamlValue, allowInline, anyScopeRegex, attributeValueToNodePropValue, bindIntl, blockRegex, buildMaskPlugin, captureNothing, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, comparePaths, compile, compileWithOptions, condition as cond, conditionPlugin, createCompiler, createMessageResolver, createRenderer, currency, cx, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, fallbackPlugin, type file, type fileContent, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, findPlainDynamicLoader, formatProxyEnabledMessage, gender, genderPlugin, generateListItemPrefix, generateListItemPrefixRegex, generateListItemRegex, generateListRegex, generateSitemap, generateSitemapUrl, get, getBasePlugins, getBrowserLocale, getCachedIntl, getCanonicalPath, getCondition, getContent, getContentNodeByKeyPath, getCookie, getDefaultNode, getDictionary, getDictionaryAsync, getDictionaryCompositeIds, getDictionaryQualifierIds, getDictionaryQualifierTypes, getDictionarySelectorCacheKey, getDictionaryTransformCacheKey, getDomainHostname, getDomainOrigin, getEditedContent, getEditedDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getGender, getHTML, getHTMLTextDir, getInsertion, getInsertionValues, getInternalPath, getInterpolableContent, getIntlayer, getIntlayerAsync, getLocale, getLocaleFromDomain, getLocaleFromPath, getLocaleFromStorage, getLocaleFromStorageClient, getLocaleFromStorageServer, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedPath, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNestedDictionaryGraph, getNestedDictionaryKeys, getNestedDictionaryReferences, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getPluginsCacheKey, getPlural, getPrefix, getPreloadLocale, getPreloadedDictionary, getReplacedValuesContent, getRewritePath, getRewriteRules, getRuleSet, getSelect, getSplittedContent, getSplittedDictionaryContent, getTranslation, getVariantIds, html, i18nextToIntlayerFormatter, icuToIntlayerFormatter, inlineRegex, insertion as insert, insertContentInDictionary, insertionPlugin, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, isDeclaredLocale, isInterpolableWrapperNode, isLocaleExclusiveOnDomain, isProxyStorageLocaleEnabled, isQualifiedDictionaryGroup, isQualifiedDynamicLoaderMap, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, mergeQualifiedDictionaries, navigatePath, nesting as nest, nestedPlugin, normalizeAttributeKey, normalizeDictionaries, normalizeDictionary, normalizePath, normalizeWhitespace, number, orderDictionaries, parseBlock, parseCaptureInline, parseDictionarySelector, parseInline, parseMarkdown, parseSimpleInline, parseStyleAttribute, parseTableAlign, parseTableAlignCapture, parseTableCells, parseTableRow, parseTaggedMessage, parseYaml, parserFor, percentage, plural, pluralPlugin, portableObjectToIntlayerFormatter, presets, qualifies, readTransformCache, rebuildInterpolableContent, reconstructQualifiedEntry, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, renderFor, renderMarkdownAst, renderNothing, resolveBrowserLocale, resolveDictionaryArgument, resolveEffectiveVariantId, resolveLocalizedPath, resolveMessage, resolveMessageNode, resolveMessageNodeToString, resolvePlainDynamicLoader, resolveProviderVariant, resolveProxyMode, resolveQualifiedDictionary, resolveQualifiedDynamicContent, resolveQualifiedDynamicContentAsync, sanitizer, select, selectPlugin, serializeVariant, serializeVariantChain, setLocaleInStorage, setLocaleInStorageClient, setLocaleInStorageServer, simpleInlineRegex, slugify, some, splitInsertionTemplate, startsWith, stringifyYaml, translation as t, transformInterpolableNode, translationPlugin, trimEnd, trimLeadingWhitespaceOutsideFences, unescapeString, units, unquote, updateNodeChildren, validateHTML, validateMarkdown, validatePrefix, vueI18nToIntlayerFormatter, writeTransformCache };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.d.ts","names":[],"sources":["../../../src/localization/getPrefix.ts"],"mappings":";;;;;;YAqBY;EACV,UAAU;EACV,gBAAgB;EAChB,OAAO;EACP,UAAU,2BAA2B;EACrC,UAAU;;;;;;;;;;;;EAYV;;;;;;qBAOW,uBAAoB,UACtB,mBACR,KAAK;EACN,eAAe;EACf,MAAM;EACN,SAAS;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"getPrefix.d.ts","names":[],"sources":["../../../src/localization/getPrefix.ts"],"mappings":";;;;;;YAqBY;EACV,UAAU;EACV,gBAAgB;EAChB,OAAO;EACP,UAAU,2BAA2B;EACrC,UAAU;;;;;;;;;;;;EAYV;;;;;;qBAOW,uBAAoB,UACtB,mBACR,KAAK;EACN,eAAe;EACf,MAAM;EACN,SAAS;;;;;;;;;;;;;;qBA0BE,mBAAgB,OACpB,kCAAgC,mBACpB,oBAClB,SAAS;YAGA;EACV,gBAAgB;EAChB,OAAO;;YAGG;;;;;EAKV;;;;EAIA,cAAc;;;;;;;;;;;;;YAcJ,wBACV,UAAU,2BACV,sBAAsB,qBACtB,gBAAgB,gBAAgB,uBAChC,gBAAgB,gBAAgB,mBAC9B,qCACkB,KAChB,wBAAwB,iBAAiB,MAAM,SAAS,WACxD,kBAAkB,GAAG;EACjB;EAAY;sBACI,QAChB,kBACA;EACI,WAAW;EAAM,cAAc;IACjC,mCACE,UAAU;EACN;EAAY;;EACZ,WAAW;EAAM,cAAc;;EACjC;EAAY;;EACtB;EAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAmCL,kBAAmB,UAAU,2BAAyB,QACzD,GAAC,UACA,mBACR,wBAAwB"}
|
|
@@ -2,6 +2,6 @@ import { JsonValue, icuToIntlayerFormatter, intlayerToICUFormatter } from "./ICU
|
|
|
2
2
|
import { i18nextToIntlayerFormatter, intlayerToI18nextFormatter } from "./i18next.js";
|
|
3
3
|
import { navigatePath } from "./navigatePath.js";
|
|
4
4
|
import { PortableObject, intlayerToPortableObjectFormatter, portableObjectToIntlayerFormatter } from "./po.js";
|
|
5
|
-
import { MessageFormatDialect, MessageValues, TaggedMessageToken, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode } from "./resolveMessage.js";
|
|
5
|
+
import { MessageFormatDialect, MessageFormatter, MessageResolver, MessageValues, TaggedMessageToken, createMessageResolver, interpolateMessage, parseTaggedMessage, resolveMessage, resolveMessageNode, resolveMessageNodeToString } from "./resolveMessage.js";
|
|
6
6
|
import { intlayerToVueI18nFormatter, vueI18nToIntlayerFormatter } from "./vue-i18n.js";
|
|
7
|
-
export { JsonValue, MessageFormatDialect, MessageValues, PortableObject, TaggedMessageToken, i18nextToIntlayerFormatter, icuToIntlayerFormatter, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, navigatePath, parseTaggedMessage, portableObjectToIntlayerFormatter, resolveMessage, resolveMessageNode, vueI18nToIntlayerFormatter };
|
|
7
|
+
export { JsonValue, MessageFormatDialect, MessageFormatter, MessageResolver, MessageValues, PortableObject, TaggedMessageToken, createMessageResolver, i18nextToIntlayerFormatter, icuToIntlayerFormatter, interpolateMessage, intlayerToI18nextFormatter, intlayerToICUFormatter, intlayerToPortableObjectFormatter, intlayerToVueI18nFormatter, navigatePath, parseTaggedMessage, portableObjectToIntlayerFormatter, resolveMessage, resolveMessageNode, resolveMessageNodeToString, vueI18nToIntlayerFormatter };
|
|
@@ -20,7 +20,8 @@ export type MessageValues = Record<string, unknown>;
|
|
|
20
20
|
* Interpolates a message template with values.
|
|
21
21
|
*
|
|
22
22
|
* Handles, in order:
|
|
23
|
-
* 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths)
|
|
23
|
+
* 1. Intlayer insertions `{{name}}` (whitespace-tolerant, dotted paths),
|
|
24
|
+
* optionally formatted the i18next way (`{{price, number}}`)
|
|
24
25
|
* 2. ICU formatted arguments `{value, number}` / `{ts, date, long}`
|
|
25
26
|
* 3. Bare single-brace arguments `{name}` (ICU / vue-i18n simple args)
|
|
26
27
|
*/
|
|
@@ -34,10 +35,44 @@ export declare const interpolateMessage: (template: string, values?: MessageValu
|
|
|
34
35
|
* `enumeration` and `plural` content) are invoked with the values.
|
|
35
36
|
*/
|
|
36
37
|
export declare const resolveMessageNode: (node: unknown, values?: MessageValues, locale?: LocalesValues) => unknown;
|
|
38
|
+
/**
|
|
39
|
+
* {@link resolveMessageNode} coerced to a string.
|
|
40
|
+
*
|
|
41
|
+
* This is the whole runtime a compat adapter needs for content that reached
|
|
42
|
+
* the bundle through a built dictionary: the build already converted every
|
|
43
|
+
* dialect construct into intlayer nodes, and the interpreter turned those into
|
|
44
|
+
* callables, so no message parser is involved. Plain strings still get
|
|
45
|
+
* `{{name}}` / `{name}` / `{value, number}` interpolation.
|
|
46
|
+
*/
|
|
47
|
+
export declare const resolveMessageNodeToString: (node: unknown, values?: MessageValues, locale?: LocalesValues) => string;
|
|
48
|
+
/** Converts a raw message string of one dialect into an intlayer node tree. */
|
|
49
|
+
export type MessageFormatter = (message: string) => unknown;
|
|
50
|
+
/**
|
|
51
|
+
* Resolves a raw message — string, or an intlayer node tree — into a final
|
|
52
|
+
* string using interpolation values and locale.
|
|
53
|
+
*/
|
|
54
|
+
export type MessageResolver = (message: unknown, values?: MessageValues, locale?: LocalesValues) => string;
|
|
55
|
+
/**
|
|
56
|
+
* Binds {@link resolveMessageNode} to one dialect converter.
|
|
57
|
+
*
|
|
58
|
+
* The compat adapters each speak a single dialect, and referencing the
|
|
59
|
+
* converter directly — rather than picking it from a record keyed by dialect —
|
|
60
|
+
* is what lets a bundler drop the two parsers the adapter never uses.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* const resolveIcuMessage = createMessageResolver(icuToIntlayerFormatter);
|
|
65
|
+
* resolveIcuMessage('Hello {name}', { name: 'John' }, 'en'); // 'Hello John'
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare const createMessageResolver: (formatter: MessageFormatter) => MessageResolver;
|
|
37
69
|
/**
|
|
38
70
|
* Resolves a raw message — string in a library dialect, or an intlayer node
|
|
39
71
|
* tree — into a final string using interpolation values and locale.
|
|
40
72
|
*
|
|
73
|
+
* Selecting the dialect at runtime keeps every converter reachable; a package
|
|
74
|
+
* that only ever needs one should bind it with {@link createMessageResolver}.
|
|
75
|
+
*
|
|
41
76
|
* @example
|
|
42
77
|
* ```ts
|
|
43
78
|
* resolveMessage('Hello {name}', { name: 'John' }, 'en', 'icu');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveMessage.d.ts","names":[],"sources":["../../../src/messageFormat/resolveMessage.ts"],"mappings":";;;;;;;;;;;;;;;YAyBY;;YAGA,gBAAgB
|
|
1
|
+
{"version":3,"file":"resolveMessage.d.ts","names":[],"sources":["../../../src/messageFormat/resolveMessage.ts"],"mappings":";;;;;;;;;;;;;;;YAyBY;;YAGA,gBAAgB;;;;;;;;;;qBAuFf,qBAAkB,kBACb,SACR,eAAa,SACb;;;;;;;;;qBAwCG,qBAAkB,eAChB,SACL,eAAa,SACb;;;;;;;;;;qBAyIG,6BAA0B,eACxB,SACL,eAAa,SACb;;YAQE,oBAAoB;;;;;YAMpB,mBACV,kBACA,SAAS,eACT,SAAS;;;;;;;;;;;;;;qBAgBE,wBAAqB,WACpB,qBAAmB;;;;;;;;;;;;;;;;;;;;;;qBAmCpB,iBAAc,kBACT,SACR,eAAa,SACb,eAAa,UACZ;;YAKC;EAEN;EAAa,UAAU;;;;;;;;;qBAShB,qBAAkB,oBAAsB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/core",
|
|
3
|
-
"version": "9.5.
|
|
3
|
+
"version": "9.5.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
|
|
6
6
|
"keywords": [
|
|
@@ -172,15 +172,15 @@
|
|
|
172
172
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
173
173
|
},
|
|
174
174
|
"dependencies": {
|
|
175
|
-
"@intlayer/api": "9.5.
|
|
176
|
-
"@intlayer/config": "9.5.
|
|
177
|
-
"@intlayer/dictionaries-entry": "9.5.
|
|
178
|
-
"@intlayer/types": "9.5.
|
|
179
|
-
"@intlayer/unmerged-dictionaries-entry": "9.5.
|
|
175
|
+
"@intlayer/api": "9.5.2",
|
|
176
|
+
"@intlayer/config": "9.5.2",
|
|
177
|
+
"@intlayer/dictionaries-entry": "9.5.2",
|
|
178
|
+
"@intlayer/types": "9.5.2",
|
|
179
|
+
"@intlayer/unmerged-dictionaries-entry": "9.5.2",
|
|
180
180
|
"defu": "6.1.7"
|
|
181
181
|
},
|
|
182
182
|
"devDependencies": {
|
|
183
|
-
"@types/node": "
|
|
183
|
+
"@types/node": "^22",
|
|
184
184
|
"@utils/ts-config": "1.0.4",
|
|
185
185
|
"@utils/ts-config-types": "1.0.4",
|
|
186
186
|
"@utils/tsdown-config": "1.0.4",
|