@intlayer/core 9.5.10 → 9.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +7 -2
- package/dist/cjs/interpreter/getDictionary.cjs +4 -3
- package/dist/cjs/interpreter/getDictionary.cjs.map +1 -1
- package/dist/cjs/interpreter/getDictionaryAsync.cjs +2 -2
- package/dist/cjs/interpreter/getDictionaryAsync.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayerAsync.cjs +10 -1
- package/dist/cjs/interpreter/getIntlayerAsync.cjs.map +1 -1
- package/dist/cjs/interpreter/index.cjs +5 -0
- package/dist/cjs/interpreter/resolveInterpreterLocale.cjs +101 -0
- package/dist/cjs/interpreter/resolveInterpreterLocale.cjs.map +1 -0
- package/dist/cjs/localization/getLocaleFromRequest.cjs +1 -1
- package/dist/cjs/localization/resolveBrowserLocale.cjs +1 -1
- package/dist/cjs/localization/rewriteMatch.cjs +11 -1
- package/dist/cjs/localization/rewriteMatch.cjs.map +1 -1
- package/dist/cjs/markdown/compiler.cjs.map +1 -1
- package/dist/cjs/markdown/constants.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs +29 -9
- package/dist/cjs/transpiler/markdown/getMarkdownMetadata.cjs.map +1 -1
- package/dist/cjs/transpiler/markdown/markdown.cjs.map +1 -1
- package/dist/cjs/utils/index.cjs +2 -2
- package/dist/cjs/utils/intl.cjs.map +1 -1
- package/dist/esm/index.mjs +4 -3
- package/dist/esm/interpreter/getDictionary.mjs +4 -3
- package/dist/esm/interpreter/getDictionary.mjs.map +1 -1
- package/dist/esm/interpreter/getDictionaryAsync.mjs +2 -2
- package/dist/esm/interpreter/getDictionaryAsync.mjs.map +1 -1
- package/dist/esm/interpreter/getIntlayer.mjs +1 -1
- package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
- package/dist/esm/interpreter/getIntlayerAsync.mjs +10 -1
- package/dist/esm/interpreter/getIntlayerAsync.mjs.map +1 -1
- package/dist/esm/interpreter/index.mjs +2 -1
- package/dist/esm/interpreter/resolveInterpreterLocale.mjs +97 -0
- package/dist/esm/interpreter/resolveInterpreterLocale.mjs.map +1 -0
- package/dist/esm/localization/getLocaleFromRequest.mjs +1 -1
- package/dist/esm/localization/resolveBrowserLocale.mjs +1 -1
- package/dist/esm/localization/rewriteMatch.mjs +11 -1
- package/dist/esm/localization/rewriteMatch.mjs.map +1 -1
- package/dist/esm/markdown/compiler.mjs +1 -1
- package/dist/esm/markdown/compiler.mjs.map +1 -1
- package/dist/esm/markdown/constants.mjs +3 -0
- package/dist/esm/markdown/constants.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs +29 -9
- package/dist/esm/transpiler/markdown/getMarkdownMetadata.mjs.map +1 -1
- package/dist/esm/transpiler/markdown/markdown.mjs +1 -1
- package/dist/esm/transpiler/markdown/markdown.mjs.map +1 -1
- package/dist/esm/utils/index.mjs +2 -2
- package/dist/esm/utils/intl.mjs +1 -0
- package/dist/esm/utils/intl.mjs.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/interpreter/getIntlayerAsync.d.ts.map +1 -1
- package/dist/types/interpreter/index.d.ts +2 -1
- package/dist/types/interpreter/resolveInterpreterLocale.d.ts +63 -0
- package/dist/types/interpreter/resolveInterpreterLocale.d.ts.map +1 -0
- package/dist/types/localization/rewriteMatch.d.ts.map +1 -1
- package/dist/types/transpiler/markdown/getMarkdownMetadata.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/cjs/index.cjs
CHANGED
|
@@ -7,6 +7,9 @@ const require_interpreter_getEnumeration = require('./interpreter/getEnumeration
|
|
|
7
7
|
const require_interpreter_getGender = require('./interpreter/getGender.cjs');
|
|
8
8
|
const require_interpreter_getInsertion = require('./interpreter/getInsertion.cjs');
|
|
9
9
|
const require_dictionaryManipulator_qualifiedDictionary = require('./dictionaryManipulator/qualifiedDictionary.cjs');
|
|
10
|
+
const require_utils_getCookie = require('./utils/getCookie.cjs');
|
|
11
|
+
const require_utils_localeStorage = require('./utils/localeStorage.cjs');
|
|
12
|
+
const require_interpreter_resolveInterpreterLocale = require('./interpreter/resolveInterpreterLocale.cjs');
|
|
10
13
|
const require_interpreter_getDictionary = require('./interpreter/getDictionary.cjs');
|
|
11
14
|
const require_interpreter_getIntlayer = require('./interpreter/getIntlayer.cjs');
|
|
12
15
|
const require_interpreter_getNesting = require('./interpreter/getNesting.cjs');
|
|
@@ -86,8 +89,6 @@ const require_localization_getLocalizedPath = require('./localization/getLocaliz
|
|
|
86
89
|
const require_localization_getLocalizedUrl = require('./localization/getLocalizedUrl.cjs');
|
|
87
90
|
const require_localization_getMultilingualUrls = require('./localization/getMultilingualUrls.cjs');
|
|
88
91
|
const require_localization_generateSitemap = require('./localization/generateSitemap.cjs');
|
|
89
|
-
const require_utils_getCookie = require('./utils/getCookie.cjs');
|
|
90
|
-
const require_utils_localeStorage = require('./utils/localeStorage.cjs');
|
|
91
92
|
const require_localization_localeResolver = require('./localization/localeResolver.cjs');
|
|
92
93
|
const require_localization_localeDetector = require('./localization/localeDetector.cjs');
|
|
93
94
|
const require_localization_getBrowserLocale = require('./localization/getBrowserLocale.cjs');
|
|
@@ -386,6 +387,8 @@ exports.qualifies = require_markdown_utils.qualifies;
|
|
|
386
387
|
exports.readTransformCache = require_interpreter_dictionaryTransformCache.readTransformCache;
|
|
387
388
|
exports.rebuildInterpolableContent = require_interpreter_interpolableNode.rebuildInterpolableContent;
|
|
388
389
|
exports.reconstructQualifiedEntry = require_dictionaryManipulator_qualifiedDictionary.reconstructQualifiedEntry;
|
|
390
|
+
exports.registerAmbientLocaleResolver = require_interpreter_resolveInterpreterLocale.registerAmbientLocaleResolver;
|
|
391
|
+
exports.registerAsyncAmbientLocaleResolver = require_interpreter_resolveInterpreterLocale.registerAsyncAmbientLocaleResolver;
|
|
389
392
|
exports.relativeTime = require_formatters_relativeTime.relativeTime;
|
|
390
393
|
exports.removeContentNodeByKeyPath = require_dictionaryManipulator_removeContentNodeByKeyPath.removeContentNodeByKeyPath;
|
|
391
394
|
exports.renameContentNodeByKeyPath = require_dictionaryManipulator_renameContentNodeByKeyPath.renameContentNodeByKeyPath;
|
|
@@ -396,6 +399,8 @@ exports.resolveBrowserLocale = require_localization_resolveBrowserLocale.resolve
|
|
|
396
399
|
exports.resolveDictionaryArgument = require_dictionaryManipulator_qualifiedDictionary.resolveDictionaryArgument;
|
|
397
400
|
exports.resolveEffectiveVariantId = require_dictionaryManipulator_qualifiedDictionary.resolveEffectiveVariantId;
|
|
398
401
|
exports.resolveInsertedSelector = require_interpreter_getContent_plugins.resolveInsertedSelector;
|
|
402
|
+
exports.resolveInterpreterLocale = require_interpreter_resolveInterpreterLocale.resolveInterpreterLocale;
|
|
403
|
+
exports.resolveInterpreterLocaleAsync = require_interpreter_resolveInterpreterLocale.resolveInterpreterLocaleAsync;
|
|
399
404
|
exports.resolveLocalizedPath = require_localization_rewriteUtils.resolveLocalizedPath;
|
|
400
405
|
exports.resolveMessage = require_messageFormat_resolveMessage.resolveMessage;
|
|
401
406
|
exports.resolveMessageNode = require_messageFormat_resolveMessage.resolveMessageNode;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_interpreter_dictionaryTransformCache = require('./dictionaryTransformCache.cjs');
|
|
3
3
|
const require_dictionaryManipulator_qualifiedDictionary = require('../dictionaryManipulator/qualifiedDictionary.cjs');
|
|
4
|
+
const require_interpreter_resolveInterpreterLocale = require('./resolveInterpreterLocale.cjs');
|
|
4
5
|
const require_interpreter_getContent_getContent = require('./getContent/getContent.cjs');
|
|
5
|
-
let _intlayer_config_built = require("@intlayer/config/built");
|
|
6
6
|
|
|
7
7
|
//#region src/interpreter/getDictionary.ts
|
|
8
8
|
/**
|
|
@@ -21,11 +21,12 @@ const transformsInProgress = /* @__PURE__ */ new WeakSet();
|
|
|
21
21
|
* If omitted, we’ll use a default set of plugins.
|
|
22
22
|
*/
|
|
23
23
|
const getDictionary = (dictionary, localeOrSelector, plugins) => {
|
|
24
|
-
const { locale, selector } = process.env.INTLAYER_DICTIONARY_SELECTOR !== "false" ? require_dictionaryManipulator_qualifiedDictionary.parseDictionarySelector(localeOrSelector) : {
|
|
24
|
+
const { locale: requestedLocale, selector } = process.env.INTLAYER_DICTIONARY_SELECTOR !== "false" ? require_dictionaryManipulator_qualifiedDictionary.parseDictionarySelector(localeOrSelector) : {
|
|
25
25
|
locale: localeOrSelector,
|
|
26
26
|
selector: void 0
|
|
27
27
|
};
|
|
28
|
-
const
|
|
28
|
+
const locale = require_interpreter_resolveInterpreterLocale.resolveInterpreterLocale(requestedLocale);
|
|
29
|
+
const cacheKey = require_interpreter_dictionaryTransformCache.getDictionaryTransformCacheKey(locale, process.env.INTLAYER_DICTIONARY_SELECTOR !== "false" ? require_dictionaryManipulator_qualifiedDictionary.getDictionarySelectorCacheKey(selector) : "", plugins);
|
|
29
30
|
const cached = require_interpreter_dictionaryTransformCache.readTransformCache(dictionary, cacheKey);
|
|
30
31
|
if (cached.hit) return cached.content;
|
|
31
32
|
const appliedPlugins = plugins ?? require_interpreter_getContent_getContent.getBasePlugins(locale);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionary.cjs","names":["parseDictionarySelector","
|
|
1
|
+
{"version":3,"file":"getDictionary.cjs","names":["parseDictionarySelector","resolveInterpreterLocale","getDictionaryTransformCacheKey","getDictionarySelectorCacheKey","readTransformCache","getBasePlugins","resolveQualifiedDictionary","getContent","writeTransformCache"],"sources":["../../../src/interpreter/getDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n QualifiedDictionaryGroup,\n ResolveQualifiedDictionaryContent,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n getDictionarySelectorCacheKey,\n parseDictionarySelector,\n resolveQualifiedDictionary,\n} from '../dictionaryManipulator/qualifiedDictionary';\nimport {\n getDictionaryTransformCacheKey,\n readTransformCache,\n writeTransformCache,\n} from './dictionaryTransformCache';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n NodeProps,\n Plugins,\n} from './getContent';\nimport { getBasePlugins, getContent } from './getContent/getContent';\nimport { resolveInterpreterLocale } from './resolveInterpreterLocale';\n\n/**\n * Dictionaries whose transform is running. Content is transformed eagerly, so a\n * dictionary reached again through a `nest()` cycle is transformed lazily\n * instead: its nodes then resolve on read, and the cycle unwinds.\n */\nconst transformsInProgress = new WeakSet<object>();\n\n/**\n * Transforms a dictionary in a single pass, applying each plugin as needed.\n *\n * @param dictionary The dictionary (or qualified dictionary group) to transform.\n * @param localeOrSelector The locale, or a selector object (`{ item }`,\n * `{ variant }`, optionally with `locale`).\n * @param plugins An array of NodeTransformer that define how to transform recognized nodes.\n * If omitted, we’ll use a default set of plugins.\n */\nexport const getDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n> => {\n // The selector checks stay inline so bundlers can drop the whole\n // qualified-dictionary module when no dictionary declares a qualifier.\n const { locale: requestedLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector(localeOrSelector)\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n const locale = resolveInterpreterLocale(requestedLocale);\n\n // The base plugins are rebuilt on every call, so they cannot identify\n // themselves — but they are fully determined by the locale, which the key\n // already carries. Only an explicitly passed array needs its own identity.\n const cacheKey = getDictionaryTransformCacheKey(\n locale,\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? getDictionarySelectorCacheKey(selector)\n : '',\n plugins\n );\n\n const cached = readTransformCache<any>(dictionary, cacheKey);\n if (cached.hit) return cached.content;\n\n const appliedPlugins = plugins ?? getBasePlugins(locale);\n\n const resolved =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? resolveQualifiedDictionary(dictionary, selector)\n : (dictionary as Dictionary);\n\n const transformDictionary = (resolvedDictionary: Dictionary) => {\n const props: NodeProps = {\n dictionaryKey: resolvedDictionary.key,\n dictionaryPath: resolvedDictionary.filePath,\n keyPath: [],\n plugins: appliedPlugins,\n // Attached by the build optimization so `nest()` resolves without the\n // global registry. Undefined in unoptimized builds, where the\n // registry-based resolver is used instead.\n nestedDictionaries: resolvedDictionary.nestedDictionaries,\n eager: !transformsInProgress.has(resolvedDictionary),\n };\n\n transformsInProgress.add(resolvedDictionary);\n\n try {\n return getContent(resolvedDictionary.content, props, appliedPlugins);\n } finally {\n if (props.eager) transformsInProgress.delete(resolvedDictionary);\n }\n };\n\n if (resolved === null)\n return writeTransformCache(dictionary, cacheKey, null)!;\n\n if (Array.isArray(resolved)) {\n return writeTransformCache(\n dictionary,\n cacheKey,\n resolved.map(transformDictionary)\n ) as any;\n }\n\n return writeTransformCache(\n dictionary,\n cacheKey,\n transformDictionary(resolved)\n ) as any;\n};\n"],"mappings":";;;;;;;;;;;;AAmCA,MAAM,uCAAuB,IAAI,QAAgB;;;;;;;;;;AAWjD,MAAa,iBAIX,YACA,kBACA,YAKG;CAGH,MAAM,EAAE,QAAQ,iBAAiB,aAC/B,QAAQ,IAAI,iCAAiC,UACzCA,0EAAwB,gBAAgB,IACxC;EACE,QAAQ;EACR,UAAU;CACZ;CACN,MAAM,SAASC,sEAAyB,eAAe;CAKvD,MAAM,WAAWC,4EACf,QACA,QAAQ,IAAI,iCAAiC,UACzCC,gFAA8B,QAAQ,IACtC,IACJ,OACF;CAEA,MAAM,SAASC,gEAAwB,YAAY,QAAQ;CAC3D,IAAI,OAAO,KAAK,OAAO,OAAO;CAE9B,MAAM,iBAAiB,WAAWC,yDAAe,MAAM;CAEvD,MAAM,WACJ,QAAQ,IAAI,iCAAiC,UACzCC,6EAA2B,YAAY,QAAQ,IAC9C;CAEP,MAAM,uBAAuB,uBAAmC;EAC9D,MAAM,QAAmB;GACvB,eAAe,mBAAmB;GAClC,gBAAgB,mBAAmB;GACnC,SAAS,CAAC;GACV,SAAS;GAIT,oBAAoB,mBAAmB;GACvC,OAAO,CAAC,qBAAqB,IAAI,kBAAkB;EACrD;EAEA,qBAAqB,IAAI,kBAAkB;EAE3C,IAAI;GACF,OAAOC,qDAAW,mBAAmB,SAAS,OAAO,cAAc;EACrE,UAAU;GACR,IAAI,MAAM,OAAO,qBAAqB,OAAO,kBAAkB;EACjE;CACF;CAEA,IAAI,aAAa,MACf,OAAOC,iEAAoB,YAAY,UAAU,IAAI;CAEvD,IAAI,MAAM,QAAQ,QAAQ,GACxB,OAAOA,iEACL,YACA,UACA,SAAS,IAAI,mBAAmB,CAClC;CAGF,OAAOA,iEACL,YACA,UACA,oBAAoB,QAAQ,CAC9B;AACF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_interpreter_dictionaryTransformCache = require('./dictionaryTransformCache.cjs');
|
|
3
3
|
const require_dictionaryManipulator_qualifiedDictionary = require('../dictionaryManipulator/qualifiedDictionary.cjs');
|
|
4
|
+
const require_interpreter_resolveInterpreterLocale = require('./resolveInterpreterLocale.cjs');
|
|
4
5
|
const require_interpreter_getDictionary = require('./getDictionary.cjs');
|
|
5
6
|
const require_dictionaryManipulator_qualifiedDynamicLoader = require('../dictionaryManipulator/qualifiedDynamicLoader.cjs');
|
|
6
7
|
const require_dictionaryManipulator_plainDynamicLoader = require('../dictionaryManipulator/plainDynamicLoader.cjs');
|
|
7
|
-
let _intlayer_config_built = require("@intlayer/config/built");
|
|
8
8
|
|
|
9
9
|
//#region src/interpreter/getDictionaryAsync.ts
|
|
10
10
|
/**
|
|
@@ -57,7 +57,7 @@ const getDictionaryAsync = async (dictionaryLoaders, key, localeOrSelector, plug
|
|
|
57
57
|
locale = parsed.locale;
|
|
58
58
|
selector = parsed.selector;
|
|
59
59
|
} else locale = localeOrSelector;
|
|
60
|
-
const localeTarget = locale ??
|
|
60
|
+
const localeTarget = locale ?? await require_interpreter_resolveInterpreterLocale.resolveInterpreterLocaleAsync();
|
|
61
61
|
const cacheKey = `${key}_${localeTarget}_${require_dictionaryManipulator_qualifiedDictionary.getDictionarySelectorCacheKey(selector)}_${require_interpreter_dictionaryTransformCache.getPluginsCacheKey(plugins)}`;
|
|
62
62
|
const cachedContent = contentPromiseCache.get(cacheKey);
|
|
63
63
|
if (cachedContent) return cachedContent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionaryAsync.cjs","names":["findPlainDynamicLoader","parseDictionarySelector","
|
|
1
|
+
{"version":3,"file":"getDictionaryAsync.cjs","names":["findPlainDynamicLoader","parseDictionarySelector","resolveInterpreterLocaleAsync","getDictionarySelectorCacheKey","getPluginsCacheKey","getDictionary","isQualifiedDynamicLoaderMap","resolveQualifiedDynamicContentAsync"],"sources":["../../../src/interpreter/getDictionaryAsync.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport {\n findPlainDynamicLoader,\n type PlainDynamicLoaderMap,\n} from '../dictionaryManipulator/plainDynamicLoader';\nimport {\n getDictionarySelectorCacheKey,\n parseDictionarySelector,\n} from '../dictionaryManipulator/qualifiedDictionary';\nimport {\n isQualifiedDynamicLoaderMap,\n type QualifiedDynamicLoaderMap,\n resolveQualifiedDynamicContentAsync,\n} from '../dictionaryManipulator/qualifiedDynamicLoader';\nimport { getPluginsCacheKey } from './dictionaryTransformCache';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\nimport { resolveInterpreterLocaleAsync } from './resolveInterpreterLocale';\n\n/**\n * Content already resolved for a `key + locale + selector` triple, or the\n * in-flight promise resolving it. Storing the promise itself makes the cache\n * double as an in-flight deduplication table: concurrent calls for the same\n * chunk await one single load.\n */\nconst contentPromiseCache = new Map<string, Promise<unknown>>();\n\n/**\n * Awaits the chunk a plain loader map holds for `locale` — walking the same\n * fallback chain as static mode — and transforms it.\n *\n * Returns `null` when the map emitted no chunk for the locale nor for any of\n * its fallbacks, mirroring how a missing qualified coordinate resolves.\n */\nconst loadPlainChunk = async <T extends Dictionary, Content>(\n dictionaryLoaders: PlainDynamicLoaderMap<T>,\n locale: LocalesValues,\n transform: (dictionary: Dictionary) => Content\n): Promise<Content | null> => {\n const resolved = findPlainDynamicLoader<T>(dictionaryLoaders, locale);\n\n if (!resolved) return null;\n\n return transform(await resolved.loader());\n};\n\n/**\n * Loads a single locale chunk of a dictionary and returns its transformed\n * content.\n *\n * Counterpart of {@link getDictionary} for the per-locale loader maps emitted\n * in `.intlayer/dynamic_dictionaries/`: instead of receiving a dictionary\n * holding every locale, it receives the loader map and awaits only the chunk\n * the requested locale needs.\n *\n * The loader map is either plain (`locale → loader`) or qualified\n * (`locale → qualifierId → loader`, for collections and variants). For a\n * qualified map, only the chunk(s) the selector targets are loaded.\n *\n * Build plugins rewrite every `getIntlayerAsync('key', locale)` call into a\n * `getDictionaryAsync(loaderMap, 'key', locale)` one, so applications call\n * {@link getIntlayerAsync} and never this function directly.\n *\n * @param dictionaryLoaders - Plain or qualified per-locale loader map.\n * @param key - Dictionary key, used to namespace the chunk cache.\n * @param localeOrSelector - The locale, or a selector object (`{ item }`,\n * `{ variant }`, optionally with `locale`).\n * @param plugins - Node transformers. Defaults to the base interpreter set.\n */\nexport const getDictionaryAsync = async <\n const T extends Dictionary,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n dictionaryLoaders: PlainDynamicLoaderMap<T> | QualifiedDynamicLoaderMap,\n key: string,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): Promise<\n DeepTransformContent<\n T['content'],\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n >\n> => {\n let locale: LocalesValues | undefined;\n let selector: DictionarySelector | undefined;\n\n if (process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false') {\n const parsed = parseDictionarySelector<LocalesValues>(localeOrSelector);\n locale = parsed.locale;\n selector = parsed.selector;\n } else {\n // Selectors are unused in this project (build-time flag): the argument can\n // only be a locale, so the selector parsing is dead code.\n locale = localeOrSelector as LocalesValues | undefined;\n }\n\n const localeTarget = locale ?? (await resolveInterpreterLocaleAsync());\n\n const cacheKey = `${key}_${localeTarget}_${getDictionarySelectorCacheKey(\n selector\n )}_${getPluginsCacheKey(plugins)}`;\n\n const cachedContent = contentPromiseCache.get(cacheKey);\n if (cachedContent) return cachedContent as Promise<any>;\n\n const transform = (dictionary: Dictionary) =>\n getDictionary(dictionary, localeTarget, plugins);\n\n const contentPromise =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryLoaders)\n ? resolveQualifiedDynamicContentAsync({\n loaderMap: dictionaryLoaders,\n key,\n locale: localeTarget,\n selector,\n transform,\n })\n : loadPlainChunk(\n dictionaryLoaders as PlainDynamicLoaderMap<T>,\n localeTarget,\n transform\n );\n\n contentPromiseCache.set(cacheKey, contentPromise);\n\n // A rejected load must not stay cached, or every later call replays the\n // same failure without ever retrying the chunk.\n contentPromise.catch(() => contentPromiseCache.delete(cacheKey));\n\n return contentPromise as Promise<any>;\n};\n"],"mappings":";;;;;;;;;;;;;;;AAqCA,MAAM,sCAAsB,IAAI,IAA8B;;;;;;;;AAS9D,MAAM,iBAAiB,OACrB,mBACA,QACA,cAC4B;CAC5B,MAAM,WAAWA,wEAA0B,mBAAmB,MAAM;CAEpE,IAAI,CAAC,UAAU,OAAO;CAEtB,OAAO,UAAU,MAAM,SAAS,OAAO,CAAC;AAC1C;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,qBAAqB,OAIhC,mBACA,KACA,kBACA,YAOG;CACH,IAAI;CACJ,IAAI;CAEJ,IAAI,QAAQ,IAAI,iCAAiC,SAAS;EACxD,MAAM,SAASC,0EAAuC,gBAAgB;EACtE,SAAS,OAAO;EAChB,WAAW,OAAO;CACpB,OAGE,SAAS;CAGX,MAAM,eAAe,UAAW,MAAMC,2EAA8B;CAEpE,MAAM,WAAW,GAAG,IAAI,GAAG,aAAa,GAAGC,gFACzC,QACF,EAAE,GAAGC,gEAAmB,OAAO;CAE/B,MAAM,gBAAgB,oBAAoB,IAAI,QAAQ;CACtD,IAAI,eAAe,OAAO;CAE1B,MAAM,aAAa,eACjBC,gDAAc,YAAY,cAAc,OAAO;CAEjD,MAAM,iBACJ,QAAQ,IAAI,iCAAiC,WAC7CC,iFAA4B,iBAAiB,IACzCC,yFAAoC;EAClC,WAAW;EACX;EACA,QAAQ;EACR;EACA;CACF,CAAC,IACD,eACE,mBACA,cACA,SACF;CAEN,oBAAoB,IAAI,UAAU,cAAc;CAIhD,eAAe,YAAY,oBAAoB,OAAO,QAAQ,CAAC;CAE/D,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.cjs","names":["getDictionaries","getAppLogger","colorizeKey","getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Object.prototype methods libraries call on arbitrary values while inspecting\n * them — TanStack Router's `isPlainObject` reaches for `hasOwnProperty` on\n * every value it deep-compares. Answering them with another path proxy turns\n * a missing dictionary into `hasOwnProperty is not a function`, thrown deep\n * inside the consumer, so they are forwarded to the real implementations.\n */\nconst PROTOTYPE_METHOD_NAMES = new Set<string | symbol>([\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n]);\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n *\n * The proxy wraps a function so that calling any leaf — `keywords.join(', ')`,\n * `title.trim()` — resolves to the path too, instead of throwing\n * `join is not a function`. Being callable also keeps structural checks\n * (`Object.prototype.toString`) from mistaking it for a plain object worth\n * walking.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy((() => path) as Record<string | symbol, any>, {\n get: (target, prop) => {\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString' ||\n prop === 'valueOf'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (PROTOTYPE_METHOD_NAMES.has(prop)) {\n return (Object.prototype as Record<string | symbol, any>)[prop].bind(\n target\n );\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n });\n};\n\nconst warnedMissingDictionaries = new Set<string>();\n\n/**\n * Picks one dictionary by its key and returns its content for the given\n * locale or selector.\n *\n * The second argument is either a locale (`'fr'`) or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ variant: { id: 'prod_abc', userId: '123' } }` — structured variant\n * - `locale` can be combined with any selector: `{ item: 2, locale: 'fr' }`\n */\nexport const getIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T]!;\n\n if (!dictionary && process.env.NODE_ENV === 'development') {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n typeof window === 'undefined'\n ? `Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`\n : `Dictionary ${key} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n return getDictionary(dictionary, localeOrSelector, plugins) as any;\n};\n"],"mappings":";;;;;;;;;;;;;;AAyBA,MAAM,yCAAyB,IAAI,IAAqB;CACtD;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;AAYD,MAAM,sBAAsB,OAAO,OAAY;CAC7C,OAAO,IAAI,aAAa,OAAuC,EAC7D,MAAM,QAAQ,SAAS;EACrB,IACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,cACT,SAAS,WAET,aAAa;EAEf,IAAI,SAAS,QACX;EAEF,IAAI,uBAAuB,IAAI,IAAI,GACjC,OAAQ,OAAO,UAA2C,KAAK,CAAC,KAC9D,MACF;EAEF,IAAI,SAAS,OAAO,UAClB,OAAO,aAAa;GAClB,MAAM;EACR;EAIF,MAAM,WAAW,OAAO,GAAG,KAAK,GAAG,OAAO,IAAI,MAAM,OAAO,IAAI;EAC/D,OAAO,mBAAmB,QAAQ;CACpC,EACF,CAAC;AACH;AAEA,MAAM,4CAA4B,IAAI,IAAY;;;;;;;;;;;AAYlD,MAAa,eAIX,KACA,kBACA,YAKG;CAEH,MAAM,iBADeA,8CACS,CAAC,CAAC;CAEhC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"getIntlayer.cjs","names":["getDictionaries","getAppLogger","colorizeKey","getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import { log } from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\n\n/**\n * Object.prototype methods libraries call on arbitrary values while inspecting\n * them — TanStack Router's `isPlainObject` reaches for `hasOwnProperty` on\n * every value it deep-compares. Answering them with another path proxy turns\n * a missing dictionary into `hasOwnProperty is not a function`, thrown deep\n * inside the consumer, so they are forwarded to the real implementations.\n */\nconst PROTOTYPE_METHOD_NAMES = new Set<string | symbol>([\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'toLocaleString',\n]);\n\n/**\n * Creates a Recursive Proxy that returns the path of the accessed key\n * stringified. This prevents the app from crashing on undefined access.\n *\n * The proxy wraps a function so that calling any leaf — `keywords.join(', ')`,\n * `title.trim()` — resolves to the path too, instead of throwing\n * `join is not a function`. Being callable also keeps structural checks\n * (`Object.prototype.toString`) from mistaking it for a plain object worth\n * walking.\n */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy((() => path) as Record<string | symbol, any>, {\n get: (target, prop) => {\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString' ||\n prop === 'valueOf'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\n }\n if (PROTOTYPE_METHOD_NAMES.has(prop)) {\n return (Object.prototype as Record<string | symbol, any>)[prop].bind(\n target\n );\n }\n if (prop === Symbol.iterator) {\n return function* () {\n yield path;\n };\n }\n\n // Recursively build the path (e.g., \"myDictionary.home.title\")\n const nextPath = path ? `${path}.${String(prop)}` : String(prop);\n return createSafeFallback(nextPath);\n },\n });\n};\n\nconst warnedMissingDictionaries = new Set<string>();\n\n/**\n * Picks one dictionary by its key and returns its content for the given\n * locale or selector.\n *\n * The second argument is either a locale (`'fr'`) or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ variant: { id: 'prod_abc', userId: '123' } }` — structured variant\n * - `locale` can be combined with any selector: `{ item: 2, locale: 'fr' }`\n */\nexport const getIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T]!;\n\n if (!dictionary && process.env.NODE_ENV === 'development') {\n if (!warnedMissingDictionaries.has(key as string)) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger({ log });\n logger(\n typeof window === 'undefined'\n ? `Dictionary ${colorizeKey(key)} was not found. Using fallback proxy.`\n : `Dictionary ${key} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n }\n );\n warnedMissingDictionaries.add(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n return getDictionary(dictionary, localeOrSelector, plugins) as any;\n};\n"],"mappings":";;;;;;;;;;;;;;AAyBA,MAAM,yCAAyB,IAAI,IAAqB;CACtD;CACA;CACA;CACA;AACF,CAAC;;;;;;;;;;;AAYD,MAAM,sBAAsB,OAAO,OAAY;CAC7C,OAAO,IAAI,aAAa,OAAuC,EAC7D,MAAM,QAAQ,SAAS;EACrB,IACE,SAAS,YACT,SAAS,OAAO,eAChB,SAAS,cACT,SAAS,WAET,aAAa;EAEf,IAAI,SAAS,QACX;EAEF,IAAI,uBAAuB,IAAI,IAAI,GACjC,OAAQ,OAAO,UAA2C,KAAK,CAAC,KAC9D,MACF;EAEF,IAAI,SAAS,OAAO,UAClB,OAAO,aAAa;GAClB,MAAM;EACR;EAIF,MAAM,WAAW,OAAO,GAAG,KAAK,GAAG,OAAO,IAAI,MAAM,OAAO,IAAI;EAC/D,OAAO,mBAAmB,QAAQ;CACpC,EACF,CAAC;AACH;AAEA,MAAM,4CAA4B,IAAI,IAAY;;;;;;;;;;;AAYlD,MAAa,eAIX,KACA,kBACA,YAKG;CAEH,MAAM,iBADeA,8CACS,CAAC,CAAC;CAEhC,IAAI,CAAC,uCAAuC,eAAe;EACzD,IAAI,CAAC,0BAA0B,IAAI,GAAa,GAAG;GAGjD,IADeC,sCAAa,EAAE,gCAAI,CAC7B,CAAC,CACJ,OAAO,WAAW,cACd,kBAAcC,qCAAY,GAAG,EAAE,yCAC/B,cAAc,IAAI,wCACtB,EACE,OAAO,OACT,CACF;GACA,0BAA0B,IAAI,GAAa;EAC7C;EAEA,OAAO,mBAAmB,GAAa;CACzC;CAEA,OAAOC,gDAAc,YAAY,kBAAkB,OAAO;AAC5D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_interpreter_resolveInterpreterLocale = require('./resolveInterpreterLocale.cjs');
|
|
2
3
|
const require_interpreter_getIntlayer = require('./getIntlayer.cjs');
|
|
3
4
|
|
|
4
5
|
//#region src/interpreter/getIntlayerAsync.ts
|
|
@@ -29,7 +30,15 @@ const require_interpreter_getIntlayer = require('./getIntlayer.cjs');
|
|
|
29
30
|
* const { title } = await getIntlayerAsync('home-metadata', locale);
|
|
30
31
|
* ```
|
|
31
32
|
*/
|
|
32
|
-
const getIntlayerAsync = async (key, localeOrSelector, plugins) =>
|
|
33
|
+
const getIntlayerAsync = async (key, localeOrSelector, plugins) => {
|
|
34
|
+
const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
|
|
35
|
+
if (isSelector ? localeOrSelector.locale : localeOrSelector) return require_interpreter_getIntlayer.getIntlayer(key, localeOrSelector, plugins);
|
|
36
|
+
const locale = await require_interpreter_resolveInterpreterLocale.resolveInterpreterLocaleAsync();
|
|
37
|
+
return require_interpreter_getIntlayer.getIntlayer(key, isSelector ? {
|
|
38
|
+
...localeOrSelector,
|
|
39
|
+
locale
|
|
40
|
+
} : locale, plugins);
|
|
41
|
+
};
|
|
33
42
|
|
|
34
43
|
//#endregion
|
|
35
44
|
exports.getIntlayerAsync = getIntlayerAsync;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayerAsync.cjs","names":["getIntlayer"],"sources":["../../../src/interpreter/getIntlayerAsync.ts"],"sourcesContent":["import type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getIntlayer } from './getIntlayer';\n\n/**\n * Picks one dictionary by its key and resolves its content for the given\n * locale or selector, loading that locale alone.\n *\n * Async counterpart of {@link getIntlayer}, meant for the places a dictionary\n * is read outside of rendering — route `head` / metadata builders, loaders,\n * server functions. Where `getIntlayer` pulls in the merged dictionary holding\n * every locale, the build plugins (`@intlayer/babel`, `@intlayer/swc`) rewrite\n * this call into `getDictionaryAsync(loaderMap, key, locale)`, pointing it at\n * the per-locale chunks in `.intlayer/dynamic_dictionaries/`, so the bundle\n * only ever carries the locale actually requested.\n *\n * Without those plugins — an unoptimized build — the call resolves through the\n * synchronous dictionary registry instead: the same content, without the\n * per-locale split.\n *\n * The second argument is either a locale (`'fr'`) or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ variant: { id: 'prod_abc', userId: '123' } }` — structured variant\n * - `locale` can be combined with any selector: `{ item: 2, locale: 'fr' }`\n *\n * @example\n * ```ts\n * const { title } = await getIntlayerAsync('home-metadata', locale);\n * ```\n */\nexport const getIntlayerAsync = async <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): Promise<\n DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n >\n> => getIntlayer<T, A>(key, localeOrSelector, plugins);\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"getIntlayerAsync.cjs","names":["getIntlayer","resolveInterpreterLocaleAsync"],"sources":["../../../src/interpreter/getIntlayerAsync.ts"],"sourcesContent":["import type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getIntlayer } from './getIntlayer';\nimport { resolveInterpreterLocaleAsync } from './resolveInterpreterLocale';\n\n/**\n * Picks one dictionary by its key and resolves its content for the given\n * locale or selector, loading that locale alone.\n *\n * Async counterpart of {@link getIntlayer}, meant for the places a dictionary\n * is read outside of rendering — route `head` / metadata builders, loaders,\n * server functions. Where `getIntlayer` pulls in the merged dictionary holding\n * every locale, the build plugins (`@intlayer/babel`, `@intlayer/swc`) rewrite\n * this call into `getDictionaryAsync(loaderMap, key, locale)`, pointing it at\n * the per-locale chunks in `.intlayer/dynamic_dictionaries/`, so the bundle\n * only ever carries the locale actually requested.\n *\n * Without those plugins — an unoptimized build — the call resolves through the\n * synchronous dictionary registry instead: the same content, without the\n * per-locale split.\n *\n * The second argument is either a locale (`'fr'`) or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ variant: { id: 'prod_abc', userId: '123' } }` — structured variant\n * - `locale` can be combined with any selector: `{ item: 2, locale: 'fr' }`\n *\n * @example\n * ```ts\n * const { title } = await getIntlayerAsync('home-metadata', locale);\n * ```\n */\nexport const getIntlayerAsync = async <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelector = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A,\n plugins?: Plugins[]\n): Promise<\n DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n IInterpreterPluginState,\n ExtractSelectorLocale<A>\n >\n> => {\n const isSelector =\n typeof localeOrSelector === 'object' && localeOrSelector !== null;\n const requestedLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n if (requestedLocale) return getIntlayer<T, A>(key, localeOrSelector, plugins);\n\n // Only the async read can await request-bound locale sources\n const locale = await resolveInterpreterLocaleAsync();\n\n return getIntlayer<T, A>(\n key,\n (isSelector ? { ...localeOrSelector, locale } : locale) as A,\n plugins\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,mBAAmB,OAI9B,KACA,kBACA,YAOG;CACH,MAAM,aACJ,OAAO,qBAAqB,YAAY,qBAAqB;CAK/D,IAJwB,aACnB,iBAAwC,SACxC,kBAEgB,OAAOA,4CAAkB,KAAK,kBAAkB,OAAO;CAG5E,MAAM,SAAS,MAAMC,2EAA8B;CAEnD,OAAOD,4CACL,KACC,aAAa;EAAE,GAAG;EAAkB;CAAO,IAAI,QAChD,OACF;AACF"}
|
|
@@ -5,6 +5,7 @@ const require_interpreter_getContent_deepTransform = require('./getContent/deepT
|
|
|
5
5
|
const require_interpreter_getEnumeration = require('./getEnumeration.cjs');
|
|
6
6
|
const require_interpreter_getGender = require('./getGender.cjs');
|
|
7
7
|
const require_interpreter_getInsertion = require('./getInsertion.cjs');
|
|
8
|
+
const require_interpreter_resolveInterpreterLocale = require('./resolveInterpreterLocale.cjs');
|
|
8
9
|
const require_interpreter_getDictionary = require('./getDictionary.cjs');
|
|
9
10
|
const require_interpreter_getIntlayer = require('./getIntlayer.cjs');
|
|
10
11
|
const require_interpreter_getNesting = require('./getNesting.cjs');
|
|
@@ -51,7 +52,11 @@ exports.nestedPlugin = require_interpreter_getContent_plugins.nestedPlugin;
|
|
|
51
52
|
exports.pluralPlugin = require_interpreter_getContent_plugins.pluralPlugin;
|
|
52
53
|
exports.readTransformCache = require_interpreter_dictionaryTransformCache.readTransformCache;
|
|
53
54
|
exports.rebuildInterpolableContent = require_interpreter_interpolableNode.rebuildInterpolableContent;
|
|
55
|
+
exports.registerAmbientLocaleResolver = require_interpreter_resolveInterpreterLocale.registerAmbientLocaleResolver;
|
|
56
|
+
exports.registerAsyncAmbientLocaleResolver = require_interpreter_resolveInterpreterLocale.registerAsyncAmbientLocaleResolver;
|
|
54
57
|
exports.resolveInsertedSelector = require_interpreter_getContent_plugins.resolveInsertedSelector;
|
|
58
|
+
exports.resolveInterpreterLocale = require_interpreter_resolveInterpreterLocale.resolveInterpreterLocale;
|
|
59
|
+
exports.resolveInterpreterLocaleAsync = require_interpreter_resolveInterpreterLocale.resolveInterpreterLocaleAsync;
|
|
55
60
|
exports.selectPlugin = require_interpreter_getContent_plugins.selectPlugin;
|
|
56
61
|
exports.splitInsertionTemplate = require_interpreter_splitAndJoinInsertion.splitInsertionTemplate;
|
|
57
62
|
exports.transformInterpolableNode = require_interpreter_interpolableNode.transformInterpolableNode;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_utils_localeStorage = require('../utils/localeStorage.cjs');
|
|
3
|
+
let _intlayer_config_built = require("@intlayer/config/built");
|
|
4
|
+
|
|
5
|
+
//#region src/interpreter/resolveInterpreterLocale.ts
|
|
6
|
+
/**
|
|
7
|
+
* Held on `globalThis` so that every copy of this module (CJS and ESM builds,
|
|
8
|
+
* duplicated installs) shares the resolvers an integration registered.
|
|
9
|
+
*/
|
|
10
|
+
const getGlobalSet = (key) => {
|
|
11
|
+
const globalScope = globalThis;
|
|
12
|
+
globalScope[key] ??= /* @__PURE__ */ new Set();
|
|
13
|
+
return globalScope[key];
|
|
14
|
+
};
|
|
15
|
+
const getAmbientLocaleResolvers = () => getGlobalSet(Symbol.for("intlayer.ambientLocaleResolvers"));
|
|
16
|
+
const getAsyncAmbientLocaleResolvers = () => getGlobalSet(Symbol.for("intlayer.asyncAmbientLocaleResolvers"));
|
|
17
|
+
/**
|
|
18
|
+
* Registers a resolver giving the locale of the current context, consulted by
|
|
19
|
+
* `getIntlayer` / `getDictionary` when the call site passes no locale.
|
|
20
|
+
*
|
|
21
|
+
* Integrations owning a request scope (server middlewares keeping the request
|
|
22
|
+
* in `AsyncLocalStorage`) register one so that a bare `getIntlayer('key')`
|
|
23
|
+
* answers in the request locale.
|
|
24
|
+
*
|
|
25
|
+
* @param resolver - Returns the current locale, or `undefined` when unknown.
|
|
26
|
+
* @returns A function unregistering the resolver.
|
|
27
|
+
*/
|
|
28
|
+
const registerAmbientLocaleResolver = (resolver) => {
|
|
29
|
+
const resolvers = getAmbientLocaleResolvers();
|
|
30
|
+
resolvers.add(resolver);
|
|
31
|
+
return () => {
|
|
32
|
+
resolvers.delete(resolver);
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Registers an {@link AsyncAmbientLocaleResolver}, consulted only by the
|
|
37
|
+
* asynchronous reads (`getIntlayerAsync` / `getDictionaryAsync`), after the
|
|
38
|
+
* synchronous resolvers.
|
|
39
|
+
*
|
|
40
|
+
* Unlike synchronous resolvers, its errors propagate: frameworks rely on them
|
|
41
|
+
* for control flow (Next.js marks a route dynamic by throwing from
|
|
42
|
+
* `headers()`). A resolver returns `undefined` for errors meaning "unknown".
|
|
43
|
+
*
|
|
44
|
+
* @param resolver - Resolves the current locale, or `undefined` when unknown.
|
|
45
|
+
* @returns A function unregistering the resolver.
|
|
46
|
+
*/
|
|
47
|
+
const registerAsyncAmbientLocaleResolver = (resolver) => {
|
|
48
|
+
const resolvers = getAsyncAmbientLocaleResolvers();
|
|
49
|
+
resolvers.add(resolver);
|
|
50
|
+
return () => {
|
|
51
|
+
resolvers.delete(resolver);
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Returns the first locale a registered resolver knows, if any.
|
|
56
|
+
*/
|
|
57
|
+
const getAmbientLocale = () => {
|
|
58
|
+
for (const resolver of getAmbientLocaleResolvers()) try {
|
|
59
|
+
const locale = resolver();
|
|
60
|
+
if (locale) return locale;
|
|
61
|
+
} catch {}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Resolves the locale a dictionary is read in when the call site gives none:
|
|
65
|
+
*
|
|
66
|
+
* 1. the locale of the current context, from the registered resolvers
|
|
67
|
+
* (e.g. the request being handled by a server middleware);
|
|
68
|
+
* 2. in the browser, the locale persisted in storage (cookie, localStorage,
|
|
69
|
+
* sessionStorage), cached until the next `setLocaleInStorageClient`;
|
|
70
|
+
* 3. the default locale.
|
|
71
|
+
*
|
|
72
|
+
* Browser storage is never read off-browser: the server shares module state
|
|
73
|
+
* across requests, and the request cookie is only known to its integration.
|
|
74
|
+
*
|
|
75
|
+
* @param locale - Locale passed by the call site, if any.
|
|
76
|
+
* @returns The resolved locale.
|
|
77
|
+
*/
|
|
78
|
+
const resolveInterpreterLocale = (locale) => locale ?? getAmbientLocale() ?? (typeof window === "undefined" ? void 0 : require_utils_localeStorage.getCachedLocaleFromStorageClient()) ?? _intlayer_config_built.internationalization.defaultLocale;
|
|
79
|
+
/**
|
|
80
|
+
* Asynchronous twin of {@link resolveInterpreterLocale}: the asynchronous
|
|
81
|
+
* resolvers are awaited after the synchronous ones, before browser storage.
|
|
82
|
+
*
|
|
83
|
+
* @param locale - Locale passed by the call site, if any.
|
|
84
|
+
* @returns The resolved locale.
|
|
85
|
+
*/
|
|
86
|
+
const resolveInterpreterLocaleAsync = async (locale) => {
|
|
87
|
+
const knownLocale = locale ?? getAmbientLocale();
|
|
88
|
+
if (knownLocale) return knownLocale;
|
|
89
|
+
for (const resolver of getAsyncAmbientLocaleResolvers()) {
|
|
90
|
+
const resolvedLocale = await resolver();
|
|
91
|
+
if (resolvedLocale) return resolvedLocale;
|
|
92
|
+
}
|
|
93
|
+
return resolveInterpreterLocale();
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
97
|
+
exports.registerAmbientLocaleResolver = registerAmbientLocaleResolver;
|
|
98
|
+
exports.registerAsyncAmbientLocaleResolver = registerAsyncAmbientLocaleResolver;
|
|
99
|
+
exports.resolveInterpreterLocale = resolveInterpreterLocale;
|
|
100
|
+
exports.resolveInterpreterLocaleAsync = resolveInterpreterLocaleAsync;
|
|
101
|
+
//# sourceMappingURL=resolveInterpreterLocale.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveInterpreterLocale.cjs","names":["getCachedLocaleFromStorageClient","internationalization"],"sources":["../../../src/interpreter/resolveInterpreterLocale.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { getCachedLocaleFromStorageClient } from '../utils/localeStorage';\n\n/**\n * Returns the locale of the context the code runs in (typically the request\n * being handled on the server), or `undefined` outside of such a context.\n */\nexport type AmbientLocaleResolver = () => LocalesValues | undefined;\n\n/**\n * Asynchronous {@link AmbientLocaleResolver}, for sources that can only be read\n * by awaiting them (e.g. Next.js `headers()` / `cookies()`).\n */\nexport type AsyncAmbientLocaleResolver = () => Promise<\n LocalesValues | undefined\n>;\n\n/**\n * Held on `globalThis` so that every copy of this module (CJS and ESM builds,\n * duplicated installs) shares the resolvers an integration registered.\n */\nconst getGlobalSet = <T>(key: symbol): Set<T> => {\n const globalScope = globalThis as typeof globalThis & {\n [key: symbol]: Set<T> | undefined;\n };\n\n globalScope[key] ??= new Set<T>();\n\n return globalScope[key];\n};\n\nconst getAmbientLocaleResolvers = (): Set<AmbientLocaleResolver> =>\n getGlobalSet(Symbol.for('intlayer.ambientLocaleResolvers'));\n\nconst getAsyncAmbientLocaleResolvers = (): Set<AsyncAmbientLocaleResolver> =>\n getGlobalSet(Symbol.for('intlayer.asyncAmbientLocaleResolvers'));\n\n/**\n * Registers a resolver giving the locale of the current context, consulted by\n * `getIntlayer` / `getDictionary` when the call site passes no locale.\n *\n * Integrations owning a request scope (server middlewares keeping the request\n * in `AsyncLocalStorage`) register one so that a bare `getIntlayer('key')`\n * answers in the request locale.\n *\n * @param resolver - Returns the current locale, or `undefined` when unknown.\n * @returns A function unregistering the resolver.\n */\nexport const registerAmbientLocaleResolver = (\n resolver: AmbientLocaleResolver\n): (() => void) => {\n const resolvers = getAmbientLocaleResolvers();\n\n resolvers.add(resolver);\n\n return () => {\n resolvers.delete(resolver);\n };\n};\n\n/**\n * Registers an {@link AsyncAmbientLocaleResolver}, consulted only by the\n * asynchronous reads (`getIntlayerAsync` / `getDictionaryAsync`), after the\n * synchronous resolvers.\n *\n * Unlike synchronous resolvers, its errors propagate: frameworks rely on them\n * for control flow (Next.js marks a route dynamic by throwing from\n * `headers()`). A resolver returns `undefined` for errors meaning \"unknown\".\n *\n * @param resolver - Resolves the current locale, or `undefined` when unknown.\n * @returns A function unregistering the resolver.\n */\nexport const registerAsyncAmbientLocaleResolver = (\n resolver: AsyncAmbientLocaleResolver\n): (() => void) => {\n const resolvers = getAsyncAmbientLocaleResolvers();\n\n resolvers.add(resolver);\n\n return () => {\n resolvers.delete(resolver);\n };\n};\n\n/**\n * Returns the first locale a registered resolver knows, if any.\n */\nconst getAmbientLocale = (): LocalesValues | undefined => {\n for (const resolver of getAmbientLocaleResolvers()) {\n try {\n const locale = resolver();\n if (locale) return locale;\n } catch {}\n }\n};\n\n/**\n * Resolves the locale a dictionary is read in when the call site gives none:\n *\n * 1. the locale of the current context, from the registered resolvers\n * (e.g. the request being handled by a server middleware);\n * 2. in the browser, the locale persisted in storage (cookie, localStorage,\n * sessionStorage), cached until the next `setLocaleInStorageClient`;\n * 3. the default locale.\n *\n * Browser storage is never read off-browser: the server shares module state\n * across requests, and the request cookie is only known to its integration.\n *\n * @param locale - Locale passed by the call site, if any.\n * @returns The resolved locale.\n */\nexport const resolveInterpreterLocale = (\n locale?: LocalesValues\n): LocalesValues =>\n locale ??\n getAmbientLocale() ??\n (typeof window === 'undefined'\n ? undefined\n : getCachedLocaleFromStorageClient()) ??\n internationalization.defaultLocale;\n\n/**\n * Asynchronous twin of {@link resolveInterpreterLocale}: the asynchronous\n * resolvers are awaited after the synchronous ones, before browser storage.\n *\n * @param locale - Locale passed by the call site, if any.\n * @returns The resolved locale.\n */\nexport const resolveInterpreterLocaleAsync = async (\n locale?: LocalesValues\n): Promise<LocalesValues> => {\n const knownLocale = locale ?? getAmbientLocale();\n if (knownLocale) return knownLocale;\n\n for (const resolver of getAsyncAmbientLocaleResolvers()) {\n const resolvedLocale = await resolver();\n if (resolvedLocale) return resolvedLocale;\n }\n\n return resolveInterpreterLocale();\n};\n"],"mappings":";;;;;;;;;AAsBA,MAAM,gBAAmB,QAAwB;CAC/C,MAAM,cAAc;CAIpB,YAAY,yBAAS,IAAI,IAAO;CAEhC,OAAO,YAAY;AACrB;AAEA,MAAM,kCACJ,aAAa,OAAO,IAAI,iCAAiC,CAAC;AAE5D,MAAM,uCACJ,aAAa,OAAO,IAAI,sCAAsC,CAAC;;;;;;;;;;;;AAajE,MAAa,iCACX,aACiB;CACjB,MAAM,YAAY,0BAA0B;CAE5C,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;;;;;;;;;;;;;AAcA,MAAa,sCACX,aACiB;CACjB,MAAM,YAAY,+BAA+B;CAEjD,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;;;;AAKA,MAAM,yBAAoD;CACxD,KAAK,MAAM,YAAY,0BAA0B,GAC/C,IAAI;EACF,MAAM,SAAS,SAAS;EACxB,IAAI,QAAQ,OAAO;CACrB,QAAQ,CAAC;AAEb;;;;;;;;;;;;;;;;AAiBA,MAAa,4BACX,WAEA,UACA,iBAAiB,MAChB,OAAO,WAAW,cACf,SACAA,6DAAiC,MACrCC,4CAAqB;;;;;;;;AASvB,MAAa,gCAAgC,OAC3C,WAC2B;CAC3B,MAAM,cAAc,UAAU,iBAAiB;CAC/C,IAAI,aAAa,OAAO;CAExB,KAAK,MAAM,YAAY,+BAA+B,GAAG;EACvD,MAAM,iBAAiB,MAAM,SAAS;EACtC,IAAI,gBAAgB,OAAO;CAC7B;CAEA,OAAO,yBAAyB;AAClC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_localization_getPrefix = require('./getPrefix.cjs');
|
|
3
2
|
const require_utils_getCookie = require('../utils/getCookie.cjs');
|
|
3
|
+
const require_localization_getPrefix = require('./getPrefix.cjs');
|
|
4
4
|
const require_localization_getLocale = require('./getLocale.cjs');
|
|
5
5
|
const require_localization_getLocaleFromPath = require('./getLocaleFromPath.cjs');
|
|
6
6
|
let _intlayer_config_built = require("@intlayer/config/built");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_utils_localeStorage = require('../utils/localeStorage.cjs');
|
|
2
3
|
const require_localization_domainUtils = require('./domainUtils.cjs');
|
|
3
4
|
const require_localization_getPrefix = require('./getPrefix.cjs');
|
|
4
|
-
const require_utils_localeStorage = require('../utils/localeStorage.cjs');
|
|
5
5
|
const require_localization_getLocaleFromPath = require('./getLocaleFromPath.cjs');
|
|
6
6
|
|
|
7
7
|
//#region src/localization/resolveBrowserLocale.ts
|
|
@@ -18,6 +18,12 @@ const getRewriteRules = (rewrite, context = "url") => {
|
|
|
18
18
|
})) };
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
|
+
* Compiled regexes by pattern. Patterns come from the finite set of rewrite
|
|
22
|
+
* rules, while URL localization runs per link, so compiling once pays off.
|
|
23
|
+
* The regexes have no `g` flag, so sharing them is stateless.
|
|
24
|
+
*/
|
|
25
|
+
const patternRegexCache = /* @__PURE__ */ new Map();
|
|
26
|
+
/**
|
|
21
27
|
* Converts normalized pattern to Regex.
|
|
22
28
|
* Internal syntax supports:
|
|
23
29
|
* - :param -> ([^/]+) (one segment)
|
|
@@ -26,8 +32,12 @@ const getRewriteRules = (rewrite, context = "url") => {
|
|
|
26
32
|
* - :param? -> ([^/]*) (zero or one segment)
|
|
27
33
|
*/
|
|
28
34
|
const patternToRegex = (pattern) => {
|
|
35
|
+
const cachedRegex = patternRegexCache.get(pattern);
|
|
36
|
+
if (cachedRegex) return cachedRegex;
|
|
29
37
|
const regexString = pattern.replace(/\//g, "\\/").replace(/\\\/:(?:[^/\\*+?]+)\*/g, "(?:\\/(.*))?").replace(/\\\/:(?:[^/\\*+?]+)\?/g, "(?:\\/([^\\/]+))?").replace(/:([^/\\*+?]+)\*/g, "(.*)").replace(/:([^/\\*+?]+)\?/g, "([^\\/]*)").replace(/:([^/\\*+?]+)\+/g, "(.+)").replace(/:([^/\\*+?]+)/g, "([^\\/]+)");
|
|
30
|
-
|
|
38
|
+
const regex = new RegExp(`^${regexString}$`);
|
|
39
|
+
patternRegexCache.set(pattern, regex);
|
|
40
|
+
return regex;
|
|
31
41
|
};
|
|
32
42
|
/**
|
|
33
43
|
* Replaces route parameters in a path with provided values.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rewriteMatch.cjs","names":["legacyRules"],"sources":["../../../src/localization/rewriteMatch.ts"],"sourcesContent":["import type {\n RewriteObject,\n RewriteRules,\n RoutingConfig,\n} from '@intlayer/types/config';\n\n/**\n * Normalizes legacy Record format or extracts specialized rules from RewriteObject.\n *\n * Idempotent: already-normalized rules are handed back untouched, so a caller\n * holding resolved rules can pass them on without re-normalizing.\n */\nexport const getRewriteRules = <\n const Context extends keyof RewriteObject = 'url',\n>(\n rewrite: RoutingConfig['rewrite'] | RewriteRules,\n context: Context = 'url' as Context\n): RewriteRules | undefined => {\n if (\n !rewrite ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return undefined;\n\n if (Array.isArray((rewrite as RewriteRules).rules)) {\n return rewrite as RewriteRules;\n }\n\n if ('url' in rewrite) {\n return (rewrite as RewriteObject)[context];\n }\n\n // Normalize legacy format\n const legacyRules = rewrite as Record<string, Record<string, string>>;\n\n return {\n rules: Object.entries(legacyRules).map(([canonical, localized]) => ({\n // Normalize canonical path\n canonical: canonical.startsWith('/')\n ? canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')}`,\n\n // Normalize localized path\n localized: Object.fromEntries(\n Object.entries(localized).map(([locale, pattern]) => {\n const normalizedPattern = pattern?.startsWith('/')\n ? pattern.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${(pattern || '').replace(/\\[([^\\]]+)\\]/g, ':$1')}`;\n return [locale, normalizedPattern];\n })\n ),\n })),\n };\n};\n\n/**\n * Converts normalized pattern to Regex.\n * Internal syntax supports:\n * - :param -> ([^/]+) (one segment)\n * - :param* -> (.*) (zero or more segments)\n * - :param+ -> (.+) (one or more segments)\n * - :param? -> ([^/]*) (zero or one segment)\n */\nconst patternToRegex = (pattern: string) => {\n const regexString = pattern\n .replace(/\\//g, '\\\\/') // Escape slashes\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\*/g, '(?:\\\\/(.*))?') // /:param*\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\?/g, '(?:\\\\/([^\\\\/]+))?') // /:param?\n .replace(/:([^/\\\\*+?]+)\\*/g, '(.*)') // :param* (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\?/g, '([^\\\\/]*)') // :param? (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\+/g, '(.+)') // :param+\n .replace(/:([^/\\\\*+?]+)/g, '([^\\\\/]+)'); // :param\n\n
|
|
1
|
+
{"version":3,"file":"rewriteMatch.cjs","names":["legacyRules"],"sources":["../../../src/localization/rewriteMatch.ts"],"sourcesContent":["import type {\n RewriteObject,\n RewriteRules,\n RoutingConfig,\n} from '@intlayer/types/config';\n\n/**\n * Normalizes legacy Record format or extracts specialized rules from RewriteObject.\n *\n * Idempotent: already-normalized rules are handed back untouched, so a caller\n * holding resolved rules can pass them on without re-normalizing.\n */\nexport const getRewriteRules = <\n const Context extends keyof RewriteObject = 'url',\n>(\n rewrite: RoutingConfig['rewrite'] | RewriteRules,\n context: Context = 'url' as Context\n): RewriteRules | undefined => {\n if (\n !rewrite ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return undefined;\n\n if (Array.isArray((rewrite as RewriteRules).rules)) {\n return rewrite as RewriteRules;\n }\n\n if ('url' in rewrite) {\n return (rewrite as RewriteObject)[context];\n }\n\n // Normalize legacy format\n const legacyRules = rewrite as Record<string, Record<string, string>>;\n\n return {\n rules: Object.entries(legacyRules).map(([canonical, localized]) => ({\n // Normalize canonical path\n canonical: canonical.startsWith('/')\n ? canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')}`,\n\n // Normalize localized path\n localized: Object.fromEntries(\n Object.entries(localized).map(([locale, pattern]) => {\n const normalizedPattern = pattern?.startsWith('/')\n ? pattern.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${(pattern || '').replace(/\\[([^\\]]+)\\]/g, ':$1')}`;\n return [locale, normalizedPattern];\n })\n ),\n })),\n };\n};\n\n/**\n * Compiled regexes by pattern. Patterns come from the finite set of rewrite\n * rules, while URL localization runs per link, so compiling once pays off.\n * The regexes have no `g` flag, so sharing them is stateless.\n */\nconst patternRegexCache = new Map<string, RegExp>();\n\n/**\n * Converts normalized pattern to Regex.\n * Internal syntax supports:\n * - :param -> ([^/]+) (one segment)\n * - :param* -> (.*) (zero or more segments)\n * - :param+ -> (.+) (one or more segments)\n * - :param? -> ([^/]*) (zero or one segment)\n */\nconst patternToRegex = (pattern: string): RegExp => {\n const cachedRegex = patternRegexCache.get(pattern);\n\n if (cachedRegex) return cachedRegex;\n\n const regexString = pattern\n .replace(/\\//g, '\\\\/') // Escape slashes\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\*/g, '(?:\\\\/(.*))?') // /:param*\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\?/g, '(?:\\\\/([^\\\\/]+))?') // /:param?\n .replace(/:([^/\\\\*+?]+)\\*/g, '(.*)') // :param* (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\?/g, '([^\\\\/]*)') // :param? (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\+/g, '(.+)') // :param+\n .replace(/:([^/\\\\*+?]+)/g, '([^\\\\/]+)'); // :param\n\n const regex = new RegExp(`^${regexString}$`);\n patternRegexCache.set(pattern, regex);\n\n return regex;\n};\n\n/**\n * Replaces route parameters in a path with provided values.\n */\nexport const fillPath = (pattern: string, params: string[]) => {\n let index = 0;\n return (\n pattern\n .replace(/:([^/\\\\*+?]+)[*+?]?/g, () => params[index++] ?? '')\n .replace(/\\/+/g, '/')\n .replace(/\\/$/, '') || '/'\n );\n};\n\n/**\n * Extract values from a URL based on a pattern.\n */\nexport const extractParams = (\n url: string,\n pattern: string\n): string[] | null => {\n const regex = patternToRegex(pattern);\n const match = url.match(regex);\n return match ? match.slice(1) : null;\n};\n"],"mappings":";;;;;;;;AAYA,MAAa,mBAGX,SACA,UAAmB,UACU;CAC7B,IACE,CAAC,WACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,IAAI,MAAM,QAAS,QAAyB,KAAK,GAC/C,OAAO;CAGT,IAAI,SAAS,SACX,OAAQ,QAA0B;CAMpC,OAAO,EACL,OAAO,OAAO,QAAQA,OAAW,CAAC,CAAC,KAAK,CAAC,WAAW,gBAAgB;EAElE,WAAW,UAAU,WAAW,GAAG,IAC/B,UAAU,QAAQ,iBAAiB,KAAK,IACxC,IAAI,UAAU,QAAQ,iBAAiB,KAAK;EAGhD,WAAW,OAAO,YAChB,OAAO,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,aAAa;GAInD,OAAO,CAAC,QAHkB,SAAS,WAAW,GAAG,IAC7C,QAAQ,QAAQ,iBAAiB,KAAK,IACtC,KAAK,WAAW,GAAE,CAAE,QAAQ,iBAAiB,KAAK,GACrB;EACnC,CAAC,CACH;CACF,EAAE,EACJ;AACF;;;;;;AAOA,MAAM,oCAAoB,IAAI,IAAoB;;;;;;;;;AAUlD,MAAM,kBAAkB,YAA4B;CAClD,MAAM,cAAc,kBAAkB,IAAI,OAAO;CAEjD,IAAI,aAAa,OAAO;CAExB,MAAM,cAAc,QACjB,QAAQ,OAAO,KAAK,CAAC,CACrB,QAAQ,0BAA0B,cAAc,CAAC,CACjD,QAAQ,0BAA0B,mBAAmB,CAAC,CACtD,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,oBAAoB,WAAW,CAAC,CACxC,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,kBAAkB,WAAW;CAExC,MAAM,QAAQ,IAAI,OAAO,IAAI,YAAY,EAAE;CAC3C,kBAAkB,IAAI,SAAS,KAAK;CAEpC,OAAO;AACT;;;;AAKA,MAAa,YAAY,SAAiB,WAAqB;CAC7D,IAAI,QAAQ;CACZ,OACE,QACG,QAAQ,8BAA8B,OAAO,YAAY,EAAE,CAAC,CAC5D,QAAQ,QAAQ,GAAG,CAAC,CACpB,QAAQ,OAAO,EAAE,KAAK;AAE7B;;;;AAKA,MAAa,iBACX,KACA,YACoB;CACpB,MAAM,QAAQ,eAAe,OAAO;CACpC,MAAM,QAAQ,IAAI,MAAM,KAAK;CAC7B,OAAO,QAAQ,MAAM,MAAM,CAAC,IAAI;AAClC"}
|