@intlayer/core 8.2.2 → 8.2.4
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/deepTransformPlugins/getMissingLocalesContent.cjs +1 -1
- package/dist/cjs/deepTransformPlugins/getMissingLocalesContent.cjs.map +1 -1
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs +1 -1
- package/dist/cjs/dictionaryManipulator/mergeDictionaries.cjs.map +1 -1
- package/dist/cjs/interpreter/getIntlayer.cjs +1 -1
- package/dist/cjs/interpreter/getIntlayer.cjs.map +1 -1
- package/dist/cjs/localization/getBrowserLocale.cjs.map +1 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs +1 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
- package/dist/cjs/localization/localeDetector.cjs.map +1 -1
- package/dist/cjs/markdown/compiler.cjs +2 -2
- package/dist/cjs/markdown/compiler.cjs.map +1 -1
- package/dist/cjs/markdown/constants.cjs.map +1 -1
- package/dist/cjs/markdown/parser.cjs +1 -1
- package/dist/cjs/markdown/parser.cjs.map +1 -1
- package/dist/cjs/markdown/renderer.cjs +1 -1
- package/dist/cjs/markdown/renderer.cjs.map +1 -1
- package/dist/cjs/markdown/utils.cjs +5 -5
- package/dist/cjs/markdown/utils.cjs.map +1 -1
- package/dist/cjs/transpiler/file/file.cjs +1 -1
- package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs +1 -1
- package/dist/esm/deepTransformPlugins/getMissingLocalesContent.mjs.map +1 -1
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs +1 -1
- package/dist/esm/dictionaryManipulator/mergeDictionaries.mjs.map +1 -1
- package/dist/esm/interpreter/getIntlayer.mjs +1 -1
- package/dist/esm/interpreter/getIntlayer.mjs.map +1 -1
- package/dist/esm/localization/getBrowserLocale.mjs.map +1 -1
- package/dist/esm/localization/getLocalizedUrl.mjs +1 -1
- package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
- package/dist/esm/localization/localeDetector.mjs.map +1 -1
- package/dist/esm/markdown/compiler.mjs +6 -6
- package/dist/esm/markdown/compiler.mjs.map +1 -1
- package/dist/esm/markdown/constants.mjs.map +1 -1
- package/dist/esm/markdown/parser.mjs +1 -1
- package/dist/esm/markdown/parser.mjs.map +1 -1
- package/dist/esm/markdown/renderer.mjs +1 -1
- package/dist/esm/markdown/renderer.mjs.map +1 -1
- package/dist/esm/markdown/utils.mjs +6 -6
- package/dist/esm/markdown/utils.mjs.map +1 -1
- package/dist/esm/transpiler/file/file.mjs +1 -1
- package/dist/esm/transpiler/file/fileBrowser.mjs +1 -1
- package/dist/esm/transpiler/file/fileBrowser.mjs.map +1 -1
- package/dist/types/deepTransformPlugins/getMissingLocalesContent.d.ts.map +1 -1
- package/dist/types/interpreter/getIntlayer.d.ts.map +1 -1
- package/dist/types/localization/getLocalizedUrl.d.ts +1 -1
- package/dist/types/localization/getLocalizedUrl.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../interpreter/getContent/deepTransform.cjs`);let n=require(`@intlayer/types`),r=require(`@intlayer/config/built`);r=e.__toESM(r);const i=(e,t=[])=>typeof e!=`object`||!e||Array.isArray(e)?[]:Object.keys(e).flatMap(n=>{let r=[...t,n];return[r,...i(e[n],r)]}),
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../interpreter/getContent/deepTransform.cjs`);let n=require(`@intlayer/types`),r=require(`@intlayer/config/built`);r=e.__toESM(r);const i=(e,t=[])=>typeof e!=`object`||!e||Array.isArray(e)?[]:Object.keys(e).flatMap(n=>{let r=[...t,n],a=e[n];return a===null?[r]:[r,...i(a,r)]}),a=(e,t=[])=>typeof e!=`object`||!e||Array.isArray(e)?[]:Object.keys(e).flatMap(n=>{let r=[...t,n],i=e[n];return i===null?[]:[r,...a(i,r)]}),o=(e,t)=>{let n=e;for(let e of t){if(typeof n!=`object`||!n||!(e in n))return!1;n=n[e]}return!0},s=(e,t)=>{let n=e;for(let e of t){if(typeof n!=`object`||!n||!(e in n))return!1;n=n[e]}return n!==null},c=(e,t)=>({id:`check-missing-locales-plugin`,canHandle:e=>typeof e==`object`&&e?.nodeType===n.NodeType.Translation,transform:(r,c,l)=>{let u=r[n.NodeType.Translation],d=new Set,f=new Set;for(let t of e){let e=u[t];e&&typeof e==`object`&&!Array.isArray(e)&&(i(e).forEach(e=>{d.add(JSON.stringify(e))}),a(e).forEach(e=>{f.add(JSON.stringify(e))}))}let p=e.some(e=>u[e]!==void 0&&u[e]!==null);for(let n of e){let e=u[n];if(e===null){p&&t(n);continue}if(!e){t(n);continue}let r=!1;for(let i of d)if(!o(e,JSON.parse(i))){t(n),r=!0;break}if(!r){for(let r of f)if(!s(e,JSON.parse(r))){t(n);break}}}for(let e in u){let t=u[e];l(t,{...c,children:t})}return r}}),l=(e,n=r.default?.internationalization?.locales,i)=>{let a=new Set,o=[c(n,e=>a.add(e)),...i.plugins??[]];return t.deepTransformNode(e,{...i,plugins:o}),Array.from(a)},u=(e,t=r.default?.internationalization?.locales)=>l(e.content,t,{dictionaryKey:e.key,keyPath:[]});exports.checkMissingLocalesPlugin=c,exports.getMissingLocalesContent=l,exports.getMissingLocalesContentFromDictionary=u;
|
|
2
2
|
//# sourceMappingURL=getMissingLocalesContent.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getMissingLocalesContent.cjs","names":["NodeType","configuration"],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n type ContentNode,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type { DeepTransformContent, NodeProps, Plugins } from '../interpreter';\nimport { deepTransformNode } from '../interpreter/getContent/deepTransform';\nimport type { TranslationContent } from '../transpiler';\n\nconst
|
|
1
|
+
{"version":3,"file":"getMissingLocalesContent.cjs","names":["NodeType","configuration"],"sources":["../../../src/deepTransformPlugins/getMissingLocalesContent.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Dictionary } from '@intlayer/types';\nimport {\n type ContentNode,\n type Locale,\n type LocalesValues,\n NodeType,\n} from '@intlayer/types';\nimport type { DeepTransformContent, NodeProps, Plugins } from '../interpreter';\nimport { deepTransformNode } from '../interpreter/getContent/deepTransform';\nimport type { TranslationContent } from '../transpiler';\n\n/**\n * Returns all key paths present in obj, INCLUDING those whose leaf value is null.\n * Used for structural presence checks (a locale must have every key another locale has,\n * even if the value is a null placeholder).\n */\nconst getAllKeyPaths = (obj: any, prefix: string[] = []): string[][] => {\n if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {\n return [];\n }\n\n return Object.keys(obj).flatMap((key) => {\n const newPath = [...prefix, key];\n const value = obj[key];\n // Stop recursing into null — include the path but don't descend further\n if (value === null) {\n return [newPath];\n }\n return [newPath, ...getAllKeyPaths(value, newPath)];\n });\n};\n\n/**\n * Returns key paths whose leaf value is non-null.\n * Used for translation value checks (a locale must not have null where another locale\n * already has a real translated value).\n */\nconst getNonNullKeyPaths = (obj: any, prefix: string[] = []): string[][] => {\n if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {\n return [];\n }\n\n return Object.keys(obj).flatMap((key) => {\n const newPath = [...prefix, key];\n const value = obj[key];\n // Skip null-valued keys entirely\n if (value === null) {\n return [];\n }\n return [newPath, ...getNonNullKeyPaths(value, newPath)];\n });\n};\n\n/**\n * Returns true if the key path EXISTS in obj (even if the terminal value is null).\n * Used for the structural presence check.\n */\nconst hasKey = (obj: any, keyPath: string[]): boolean => {\n let current = obj;\n for (const key of keyPath) {\n if (\n current === undefined ||\n current === null ||\n typeof current !== 'object'\n ) {\n return false;\n }\n if (!(key in current)) {\n return false;\n }\n current = current[key];\n }\n return true; // key exists; value may be null\n};\n\n/**\n * Returns true if the key path exists in obj AND the terminal value is non-null.\n * Used for the translation value check.\n */\nconst hasNonNullValue = (obj: any, keyPath: string[]): boolean => {\n let current = obj;\n for (const key of keyPath) {\n if (\n current === undefined ||\n current === null ||\n typeof current !== 'object'\n ) {\n return false;\n }\n if (!(key in current)) {\n return false;\n }\n current = current[key];\n }\n // null is treated as a missing translation (e.g., i18next-scanner sets null for untranslated keys)\n return current !== null;\n};\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const checkMissingLocalesPlugin = (\n locales: Locale[],\n onMissingLocale: (locale: Locale) => void\n): Plugins => ({\n id: 'check-missing-locales-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeType.Translation,\n transform: (node: TranslationContent, props, deepTransformNode) => {\n const translations = node[NodeType.Translation] as Record<string, any>;\n\n /**\n * Two path sets built from all locales' content:\n *\n * presentPaths — every key path that exists in ANY locale, even those whose value\n * is null. A locale that is missing a path from this set is structurally incomplete\n * (the key doesn't exist at all).\n *\n * nonNullPaths — every key path that has a non-null value in at least one locale.\n * A locale that has the key but with null, when another locale already has a real\n * value, needs translation.\n */\n const presentPaths = new Set<string>();\n const nonNullPaths = new Set<string>();\n\n for (const locale of locales) {\n const value = translations[locale];\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n getAllKeyPaths(value).forEach((path) => {\n presentPaths.add(JSON.stringify(path));\n });\n\n getNonNullKeyPaths(value).forEach((path) => {\n nonNullPaths.add(JSON.stringify(path));\n });\n }\n }\n\n // If no locale has any content at all (all are null/undefined), the key is\n // universally pending — don't flag anyone.\n const hasAnyDefinedValue = locales.some(\n (locale) =>\n translations[locale] !== undefined && translations[locale] !== null\n );\n\n for (const locale of locales) {\n const value = translations[locale];\n\n if (value === null) {\n // Entire locale content is a null placeholder.\n // Flag only when some other locale already has real content.\n if (hasAnyDefinedValue) {\n onMissingLocale(locale);\n }\n continue;\n }\n\n if (!value) {\n // undefined / entirely absent\n onMissingLocale(locale);\n continue;\n }\n\n let flagged = false;\n\n // Structural check: every key that exists in any locale must also exist here\n // (even if the local value is null — at least the key must be present).\n for (const pathStr of presentPaths) {\n if (!hasKey(value, JSON.parse(pathStr))) {\n onMissingLocale(locale);\n flagged = true;\n break;\n }\n }\n\n if (!flagged) {\n // Value check: every key that has a non-null value in some locale must also\n // be non-null here (null = untranslated, needs filling).\n for (const pathStr of nonNullPaths) {\n if (!hasNonNullValue(value, JSON.parse(pathStr))) {\n onMissingLocale(locale);\n break;\n }\n }\n }\n }\n\n // Continue traversal inside the translation values\n for (const key in translations) {\n const child = translations[key];\n deepTransformNode(child, {\n ...props,\n children: child,\n });\n }\n\n // Return the original node; the return value is ignored by the caller\n return node;\n },\n});\n\n/**\n * Return the content of a node with only the translation plugin.\n *\n * @param node The node to transform.\n * @param locales The locales to check for missing translations.\n */\nexport const getMissingLocalesContent = <T extends ContentNode>(\n node: T,\n locales: LocalesValues[] = configuration?.internationalization?.locales,\n nodeProps: NodeProps\n): Locale[] => {\n const missingLocales = new Set<Locale>();\n\n const plugins: Plugins[] = [\n checkMissingLocalesPlugin(locales as Locale[], (locale) =>\n missingLocales.add(locale)\n ),\n ...(nodeProps.plugins ?? []),\n ];\n\n deepTransformNode(node, {\n ...nodeProps,\n plugins,\n }) as DeepTransformContent<T>;\n\n return Array.from(missingLocales);\n};\n\nexport const getMissingLocalesContentFromDictionary = (\n dictionary: Dictionary,\n locales: LocalesValues[] = configuration?.internationalization?.locales\n) =>\n getMissingLocalesContent(dictionary.content, locales, {\n dictionaryKey: dictionary.key,\n keyPath: [],\n });\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../deepTransformPlugins/getMultilingualDictionary.cjs`),n=require(`./getNodeType.cjs`);let r=require(`@intlayer/config/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../deepTransformPlugins/getMultilingualDictionary.cjs`),n=require(`./getNodeType.cjs`);let r=require(`@intlayer/config/built`);r=e.__toESM(r);let i=require(`@intlayer/config/logger`);const a=(e,t,a,o,s=[])=>{let c=(0,i.getAppLogger)(r.default);if(e==null||t==null)return;let l=n.getNodeType(e),u=n.getNodeType(t);if(!(l===`unknown`||u===`unknown`)&&l!==u){c([`Error: Dictionary ${(0,i.colorizeKey)(o)} has a multiple content files with type mismatch at path "${s.join(`.`)}": Cannot merge ${l} with ${u} while merging ${a}`],{level:`error`});return}},o=(e,t)=>{if(e==null)return t;if(t==null||typeof e!=`object`||typeof t!=`object`)return e;if(Array.isArray(e)&&Array.isArray(t))return s(e,t);if(typeof e==`object`&&typeof t==`object`){let n={},r=new Set([...Object.keys(e),...Object.keys(t)]);for(let i of r)n[i]=o(e[i],t[i]);return n}return e},s=(e,t)=>{let n=e.every(e=>typeof e!=`object`||!e),r=t.every(e=>typeof e!=`object`||!e);if(n&&r)return t;let i=[],a=Math.max(e.length,t.length);for(let n=0;n<a;n++){let r=e[n],a=t[n];r===void 0&&a===void 0||(r===void 0?i.push(a):a===void 0?i.push(r):typeof r==`object`&&typeof a==`object`&&r!==null&&a!==null?(`key`in r&&`key`in a&&(r.key,a.key),i.push(o(r,a))):i.push(r))}return i},c=e=>{let n=Array.from(new Set(e.filter(e=>e.localId).map(e=>e.localId))),r=e.map(e=>e.key);if(new Set(r).size!==1)throw Error(`All dictionaries must have the same key`);let i=e[0].content;for(let n=1;n<e.length;n++){let r=t.getMultilingualDictionary(e[n]);a(i,r.content,r.localId,r.key,[]),i=o(i,r.content)}return{key:e[0].key,content:i,localIds:n}};exports.mergeDictionaries=c;
|
|
2
2
|
//# sourceMappingURL=mergeDictionaries.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergeDictionaries.cjs","names":["configuration","getNodeType","getMultilingualDictionary"],"sources":["../../../src/dictionaryManipulator/mergeDictionaries.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/
|
|
1
|
+
{"version":3,"file":"mergeDictionaries.cjs","names":["configuration","getNodeType","getMultilingualDictionary"],"sources":["../../../src/dictionaryManipulator/mergeDictionaries.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport type {\n ContentNode,\n Dictionary,\n LocalDictionaryId,\n} from '@intlayer/types';\nimport { getMultilingualDictionary } from '../deepTransformPlugins';\nimport { getNodeType } from './getNodeType';\n\n// Extended type that includes arrays for internal merge operations\ntype MergeableContent = ContentNode | ContentNode[];\n\nconst checkTypesMatch = (\n object1: ContentNode,\n object2: ContentNode,\n object2LocalId: LocalDictionaryId | undefined,\n dictionaryKey: string,\n path: string[] = []\n): void => {\n const appLogger = getAppLogger(configuration);\n\n // If either side is missing/undefined, allow merge without error\n if (\n object1 === undefined ||\n object1 === null ||\n object2 === undefined ||\n object2 === null\n )\n return;\n\n const type1 = getNodeType(object1);\n const type2 = getNodeType(object2);\n\n // Unknown types are treated as flexible; skip strict mismatch reporting\n if (type1 === 'unknown' || type2 === 'unknown') return;\n\n if (type1 !== type2) {\n appLogger(\n [\n `Error: Dictionary ${colorizeKey(dictionaryKey)} has a multiple content files with type mismatch at path \"${path.join('.')}\": Cannot merge ${type1} with ${type2} while merging ${object2LocalId}`,\n ],\n {\n level: 'error',\n }\n );\n\n return;\n }\n};\n\n// Custom merge function that prefers destination (first dictionary) values\nconst customMerge = (\n destination: ContentNode,\n source: ContentNode\n): MergeableContent => {\n // If destination is undefined/null, use source\n if (destination === undefined || destination === null) {\n return source;\n }\n\n // If source is undefined/null, use destination\n if (source === undefined || source === null) {\n return destination;\n }\n\n // For primitive values, prefer destination (first dictionary)\n if (typeof destination !== 'object' || typeof source !== 'object') {\n return destination;\n }\n\n // For arrays, use our custom array merge\n if (Array.isArray(destination) && Array.isArray(source)) {\n return arrayMerge(\n destination as ContentNode[],\n source as ContentNode[]\n ) as MergeableContent;\n }\n\n // For objects, recursively merge with our custom logic\n if (typeof destination === 'object' && typeof source === 'object') {\n const result: Record<string, MergeableContent> = {};\n const allKeys = new Set([\n ...Object.keys(destination as unknown as Record<string, ContentNode>),\n ...Object.keys(source as unknown as Record<string, ContentNode>),\n ]);\n\n for (const key of allKeys) {\n result[key] = customMerge(\n (destination as unknown as Record<string, ContentNode>)[key],\n (source as unknown as Record<string, ContentNode>)[key]\n );\n }\n\n return result as unknown as MergeableContent;\n }\n\n // Fallback to destination\n return destination;\n};\n\n// Custom array merge strategy that merges arrays by key when present, otherwise by index\nconst arrayMerge = (\n destinationArray: ContentNode[],\n sourceArray: ContentNode[]\n): MergeableContent[] => {\n // Check if both arrays contain only primitives\n const destHasOnlyPrimitives = destinationArray.every(\n (item) => typeof item !== 'object' || item === null\n );\n const sourceHasOnlyPrimitives = sourceArray.every(\n (item) => typeof item !== 'object' || item === null\n );\n\n // If both arrays contain only primitives, use the source array (second dictionary)\n if (destHasOnlyPrimitives && sourceHasOnlyPrimitives) {\n return sourceArray;\n }\n\n // Otherwise, merge by index with object merging logic\n const result: MergeableContent[] = [];\n const maxLength = Math.max(destinationArray.length, sourceArray.length);\n\n for (let i = 0; i < maxLength; i++) {\n const destItem = destinationArray[i];\n const sourceItem = sourceArray[i];\n\n if (destItem === undefined && sourceItem === undefined) {\n } else if (destItem === undefined) {\n // Only source exists, add it\n result.push(sourceItem);\n } else if (sourceItem === undefined) {\n // Only destination exists, add it\n result.push(destItem);\n } else {\n // Both exist, merge them\n if (\n typeof destItem === 'object' &&\n typeof sourceItem === 'object' &&\n destItem !== null &&\n sourceItem !== null\n ) {\n // Check if both objects have a 'key' property for keyed merging\n if (\n 'key' in destItem &&\n 'key' in sourceItem &&\n (destItem as Record<string, string>).key ===\n (sourceItem as Record<string, string>).key\n ) {\n // Merge objects with same key, preferring destination (first dictionary) values\n result.push(customMerge(destItem, sourceItem));\n } else {\n // Merge objects by index, preferring destination (first dictionary) values\n result.push(customMerge(destItem, sourceItem));\n }\n } else {\n // For primitives or non-objects, use destination value (first dictionary)\n result.push(destItem);\n }\n }\n }\n\n return result;\n};\n\nexport const mergeDictionaries = (dictionaries: Dictionary[]): Dictionary => {\n const localIds = Array.from(\n new Set<LocalDictionaryId>(\n dictionaries.filter((dict) => dict.localId).map((dict) => dict.localId!)\n )\n );\n\n const dictionariesKeys = dictionaries.map((dict) => dict.key);\n\n // Check if all dictionaries have the same key\n if (new Set(dictionariesKeys).size !== 1) {\n throw new Error('All dictionaries must have the same key');\n }\n\n let mergedContent: Dictionary['content'] = dictionaries[0].content;\n\n for (let i = 1; i < dictionaries.length; i++) {\n // If the dictionary is a per-locale dictionary, transform it to a partial multilingual dictionary\n const currentDictionary = getMultilingualDictionary(dictionaries[i]);\n\n // Check types before merging\n checkTypesMatch(\n mergedContent,\n currentDictionary.content,\n currentDictionary.localId,\n currentDictionary.key,\n []\n );\n\n mergedContent = customMerge(\n mergedContent,\n currentDictionary.content\n ) as ContentNode;\n }\n\n const mergedDictionary: Dictionary = {\n key: dictionaries[0].key,\n content: mergedContent,\n localIds,\n };\n\n return mergedDictionary;\n};\n"],"mappings":"0TAaA,MAAM,GACJ,EACA,EACA,EACA,EACA,EAAiB,EAAE,GACV,CACT,IAAM,GAAA,EAAA,EAAA,cAAyBA,EAAAA,QAAc,CAG7C,GACE,GACY,MACZ,GACY,KAEZ,OAEF,IAAM,EAAQC,EAAAA,YAAY,EAAQ,CAC5B,EAAQA,EAAAA,YAAY,EAAQ,CAG9B,SAAU,WAAa,IAAU,YAEjC,IAAU,EAAO,CACnB,EACE,CACE,sBAAA,EAAA,EAAA,aAAiC,EAAc,CAAC,4DAA4D,EAAK,KAAK,IAAI,CAAC,kBAAkB,EAAM,QAAQ,EAAM,iBAAiB,IACnL,CACD,CACE,MAAO,QACR,CACF,CAED,SAKE,GACJ,EACA,IACqB,CAErB,GAAI,GAA6C,KAC/C,OAAO,EAST,GALI,GAAmC,MAKnC,OAAO,GAAgB,UAAY,OAAO,GAAW,SACvD,OAAO,EAIT,GAAI,MAAM,QAAQ,EAAY,EAAI,MAAM,QAAQ,EAAO,CACrD,OAAO,EACL,EACA,EACD,CAIH,GAAI,OAAO,GAAgB,UAAY,OAAO,GAAW,SAAU,CACjE,IAAM,EAA2C,EAAE,CAC7C,EAAU,IAAI,IAAI,CACtB,GAAG,OAAO,KAAK,EAAsD,CACrE,GAAG,OAAO,KAAK,EAAiD,CACjE,CAAC,CAEF,IAAK,IAAM,KAAO,EAChB,EAAO,GAAO,EACX,EAAuD,GACvD,EAAkD,GACpD,CAGH,OAAO,EAIT,OAAO,GAIH,GACJ,EACA,IACuB,CAEvB,IAAM,EAAwB,EAAiB,MAC5C,GAAS,OAAO,GAAS,WAAY,EACvC,CACK,EAA0B,EAAY,MACzC,GAAS,OAAO,GAAS,WAAY,EACvC,CAGD,GAAI,GAAyB,EAC3B,OAAO,EAIT,IAAM,EAA6B,EAAE,CAC/B,EAAY,KAAK,IAAI,EAAiB,OAAQ,EAAY,OAAO,CAEvE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,IAAK,CAClC,IAAM,EAAW,EAAiB,GAC5B,EAAa,EAAY,GAE3B,IAAa,IAAA,IAAa,IAAe,IAAA,KAClC,IAAa,IAAA,GAEtB,EAAO,KAAK,EAAW,CACd,IAAe,IAAA,GAExB,EAAO,KAAK,EAAS,CAInB,OAAO,GAAa,UACpB,OAAO,GAAe,UACtB,IAAa,MACb,IAAe,MAIb,QAAS,GACT,QAAS,IACR,EAAoC,IAClC,EAAsC,KAGzC,EAAO,KAAK,EAAY,EAAU,EAAW,CAAC,EAOhD,EAAO,KAAK,EAAS,EAK3B,OAAO,GAGI,EAAqB,GAA2C,CAC3E,IAAM,EAAW,MAAM,KACrB,IAAI,IACF,EAAa,OAAQ,GAAS,EAAK,QAAQ,CAAC,IAAK,GAAS,EAAK,QAAS,CACzE,CACF,CAEK,EAAmB,EAAa,IAAK,GAAS,EAAK,IAAI,CAG7D,GAAI,IAAI,IAAI,EAAiB,CAAC,OAAS,EACrC,MAAU,MAAM,0CAA0C,CAG5D,IAAI,EAAuC,EAAa,GAAG,QAE3D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAa,OAAQ,IAAK,CAE5C,IAAM,EAAoBC,EAAAA,0BAA0B,EAAa,GAAG,CAGpE,EACE,EACA,EAAkB,QAClB,EAAkB,QAClB,EAAkB,IAClB,EAAE,CACH,CAED,EAAgB,EACd,EACA,EAAkB,QACnB,CASH,MANqC,CACnC,IAAK,EAAa,GAAG,IACrB,QAAS,EACT,WACD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`./getDictionary.cjs`);let n=require(`@intlayer/config/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`./getDictionary.cjs`);let n=require(`@intlayer/config/built`);n=e.__toESM(n);let r=require(`@intlayer/config/logger`),i=require(`@intlayer/dictionaries-entry`);const a=(e=``)=>new Proxy(()=>e,{get:(t,n)=>{if(n===`toJSON`||n===Symbol.toPrimitive||n===`toString`)return()=>e;if(n!==`then`)return a(e?`${e}.${String(n)}`:String(n))},apply:()=>e}),o=(e,o,s)=>{let c=(0,i.getDictionaries)()[e];return c?t.getDictionary(c,o,s):((0,r.getAppLogger)(n.default)(`Dictionary ${(0,r.colorizeKey)(e)} was not found. Using fallback proxy.`,{level:`warn`,isVerbose:!0}),process.env.NODE_ENV,a(e))};exports.getIntlayer=o;
|
|
2
2
|
//# sourceMappingURL=getIntlayer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.cjs","names":["configuration","getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"getIntlayer.cjs","names":["configuration","getDictionary"],"sources":["../../../src/interpreter/getIntlayer.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { colorizeKey, getAppLogger } from '@intlayer/config/logger';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryContent,\n DictionaryRegistryElement,\n LocalesValues,\n} from '@intlayer/types';\nimport type {\n DeepTransformContent,\n IInterpreterPluginState,\n Plugins,\n} from './getContent';\nimport { getDictionary } from './getDictionary';\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 */\nconst createSafeFallback = (path = ''): any => {\n return new Proxy(\n // Target is a function so it can be called if the dictionary expects a function\n () => path,\n {\n get: (_target, prop) => {\n // Handle common object methods to prevent infinite recursion or weird behavior\n if (\n prop === 'toJSON' ||\n prop === Symbol.toPrimitive ||\n prop === 'toString'\n ) {\n return () => path;\n }\n if (prop === 'then') {\n return undefined; // Prevent it from being treated as a Promise\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 // If the code tries to execute the missing key as a function: t.title()\n apply: () => {\n return path;\n },\n }\n );\n};\n\nexport const getIntlayer = <\n T extends DictionaryKeys,\n L extends LocalesValues = DeclaredLocales,\n>(\n key: T,\n locale?: L,\n plugins?: Plugins[]\n): DeepTransformContent<\n DictionaryRegistryContent<T>,\n IInterpreterPluginState,\n L\n> => {\n const dictionaries = getDictionaries();\n const dictionary = dictionaries[key as T] as DictionaryRegistryElement<T>;\n\n if (!dictionary) {\n // Log a warning instead of throwing (so developers know it's missing)\n const logger = getAppLogger(configuration);\n logger(\n `Dictionary ${colorizeKey(key as string)} was not found. Using fallback proxy.`,\n {\n level: 'warn',\n isVerbose: true,\n }\n );\n\n if (process.env.NODE_ENV === 'development') {\n // Return the Safe Proxy\n // We initialize it with the dictionary key name so the UI shows \"my-dictionary.someKey\"\n return createSafeFallback(key as string);\n }\n\n return createSafeFallback(key as string);\n }\n\n return getDictionary<DictionaryRegistryElement<T>, L>(\n dictionary,\n locale,\n plugins\n );\n};\n"],"mappings":"mSAqBA,MAAM,GAAsB,EAAO,KAC1B,IAAI,UAEH,EACN,CACE,KAAM,EAAS,IAAS,CAEtB,GACE,IAAS,UACT,IAAS,OAAO,aAChB,IAAS,WAET,UAAa,EAEX,OAAS,OAMb,OAAO,EADU,EAAO,GAAG,EAAK,GAAG,OAAO,EAAK,GAAK,OAAO,EAAK,CAC7B,EAGrC,UACS,EAEV,CACF,CAGU,GAIX,EACA,EACA,IAKG,CAEH,IAAM,GAAA,EAAA,EAAA,kBADgC,CACN,GAsBhC,OApBK,EAoBEC,EAAAA,cACL,EACA,EACA,EACD,GArBC,EAAA,EAAA,cAD4BD,EAAAA,QAAc,CAExC,eAAA,EAAA,EAAA,aAA0B,EAAc,CAAC,uCACzC,CACE,MAAO,OACP,UAAW,GACZ,CACF,CAEG,QAAQ,IAAI,SAGP,EAAmB,EAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getBrowserLocale.cjs","names":["getLocaleFromStorage","configuration","localeDetector","Locales"],"sources":["../../../src/localization/getBrowserLocale.tsx"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type Locale, Locales } from '@intlayer/types';\nimport {\n getLocaleFromStorage,\n type LocaleStorageOptions,\n} from '../utils/localeStorage';\nimport { localeDetector } from './localeDetector';\n\nexport enum LanguageDetector {\n Querystring = 'querystring',\n Storage = 'storage',\n Navigator = 'navigator',\n HtmlTag = 'htmlTag',\n}\n\nexport const localeStorageOptions: LocaleStorageOptions = {\n getCookie: (name: string) =>\n document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${name}=`))\n ?.split('=')[1],\n getLocaleStorage: (name: string) => localStorage.getItem(name),\n getSessionStorage: (name: string) => sessionStorage.getItem(name),\n isCookieEnabled: true,\n setCookieStore: (name, value, attributes) =>\n cookieStore.set({\n name,\n value,\n path: attributes.path,\n domain: attributes.domain,\n expires: attributes.expires,\n sameSite: attributes.sameSite,\n }),\n setCookieString: (_name, cookie) => {\n // biome-ignore lint/suspicious/noDocumentCookie: set cookie fallback\n document.cookie = cookie;\n },\n setSessionStorage: (name, value) => sessionStorage.setItem(name, value),\n setLocaleStorage: (name, value) => localStorage.setItem(name, value),\n};\n\n// Default settings for the language detector\ntype LanguageDetectorOptions = {\n order?: LanguageDetector[];\n lookupQuerystring?: string;\n htmlTag?: HTMLElement | null;\n};\n\nconst getDefaultsOptions = (): LanguageDetectorOptions => {\n return {\n order: [\n LanguageDetector.Querystring,\n LanguageDetector.Storage,\n LanguageDetector.Navigator,\n LanguageDetector.HtmlTag,\n ],\n lookupQuerystring: 'locale',\n htmlTag: typeof document !== 'undefined' ? document.documentElement : null,\n };\n};\n\nconst detectLanguage = (\n order: string[],\n options: LanguageDetectorOptions\n): Record<LanguageDetector, Locale | undefined> => {\n const detected: Record<LanguageDetector, Locale | undefined> = {} as Record<\n LanguageDetector,\n Locale | undefined\n >;\n\n const queryStringDetector = () => {\n if (typeof window === 'undefined') return;\n const search = window.location.search || '';\n const params = new URLSearchParams(search);\n const value = params.get(options.lookupQuerystring ?? '');\n if (value) {\n detected[LanguageDetector.Querystring] = value as Locale;\n }\n };\n\n const storageDetector = () => {\n if (typeof window === 'undefined') return;\n\n const locale = getLocaleFromStorage({\n getCookie: (name: string) => {\n try {\n const cookies = document.cookie.split(';');\n const cookieName = `${name}=`;\n\n const cookie = cookies.find((cookie) =>\n cookie.trim().startsWith(cookieName)\n );\n\n if (cookie) {\n return cookie.split('=')[1].trim();\n }\n } catch {}\n return undefined;\n },\n getSessionStorage: (name: string) => {\n try {\n return window.sessionStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n getLocaleStorage: (name: string) => {\n try {\n return window.localStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n });\n\n if (locale) {\n detected[LanguageDetector.Storage] = locale;\n }\n };\n\n const navigatorDetector = () => {\n if (typeof navigator === 'undefined') return;\n\n const { internationalization } = configuration;\n const languages = navigator.languages ?? [navigator.language];\n\n // Use localeDetector to find the best matching locale\n const locale = localeDetector(\n { 'accept-language': languages.join(',') },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n if (locale) {\n detected[LanguageDetector.Navigator] = locale;\n }\n };\n\n const htmlTagDetector = () => {\n const htmlTag = options.htmlTag;\n if (htmlTag && typeof htmlTag.getAttribute === 'function') {\n const lang = htmlTag.getAttribute('lang');\n if (lang) {\n const { internationalization } = configuration;\n\n // Validate and resolve the locale\n const locale = localeDetector(\n { 'accept-language': lang },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n detected[LanguageDetector.HtmlTag] = locale;\n }\n }\n };\n\n // Map detector names to their corresponding functions\n const detectors: Record<string, () => void> = {\n [LanguageDetector.Querystring]: queryStringDetector,\n [LanguageDetector.Storage]: storageDetector,\n [LanguageDetector.Navigator]: navigatorDetector,\n [LanguageDetector.HtmlTag]: htmlTagDetector,\n };\n\n // Use the provided order to run each detector\n order.forEach((detectorName) => {\n detectors[detectorName]?.();\n });\n\n return detected;\n};\n\nconst getFirstAvailableLocale = (\n locales: Record<LanguageDetector, Locale | undefined>,\n order: LanguageDetector[]\n): Locale => {\n const { internationalization } = configuration;\n\n for (const detector of order) {\n const locale = locales[detector];\n\n if (locale && internationalization.locales.includes(locale)) {\n return locale;\n }\n }\n\n return internationalization?.defaultLocale ?? Locales.ENGLISH;\n};\n\n/**\n * Core language detector function for browser environments.\n *\n * Detects the user's preferred locale by checking multiple sources in order:\n * 1. Query string parameter\n * 2. Storage (cookies, localStorage, sessionStorage) - uses getLocaleFromStorage\n * 3. Navigator languages - uses localeDetector\n * 4. HTML lang attribute - uses localeDetector\n *\n * @param userOptions - Optional configuration for detection order and lookup keys\n * @returns The detected locale or the default locale\n *\n * @example\n * const locale = getBrowserLocale({ order: [LanguageDetector.Storage, LanguageDetector.Navigator] });\n */\nexport const getBrowserLocale = (\n userOptions: LanguageDetectorOptions | undefined = {}\n): Locale => {\n const options = { ...getDefaultsOptions(), ...userOptions };\n\n const locales = detectLanguage(options.order ?? [], options);\n\n return getFirstAvailableLocale(locales, options.order ?? []);\n};\n"],"mappings":"sRAQA,IAAY,
|
|
1
|
+
{"version":3,"file":"getBrowserLocale.cjs","names":["getLocaleFromStorage","configuration","localeDetector","Locales"],"sources":["../../../src/localization/getBrowserLocale.tsx"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { type Locale, Locales } from '@intlayer/types';\nimport {\n getLocaleFromStorage,\n type LocaleStorageOptions,\n} from '../utils/localeStorage';\nimport { localeDetector } from './localeDetector';\n\nexport enum LanguageDetector {\n Querystring = 'querystring',\n Storage = 'storage',\n Navigator = 'navigator',\n HtmlTag = 'htmlTag',\n}\n\nexport const localeStorageOptions: LocaleStorageOptions = {\n getCookie: (name: string) =>\n document.cookie\n .split(';')\n .find((c) => c.trim().startsWith(`${name}=`))\n ?.split('=')[1],\n getLocaleStorage: (name: string) => localStorage.getItem(name),\n getSessionStorage: (name: string) => sessionStorage.getItem(name),\n isCookieEnabled: true,\n setCookieStore: (name, value, attributes) =>\n cookieStore.set({\n name,\n value,\n path: attributes.path,\n domain: attributes.domain,\n expires: attributes.expires,\n sameSite: attributes.sameSite,\n }),\n setCookieString: (_name, cookie) => {\n // biome-ignore lint/suspicious/noDocumentCookie: set cookie fallback\n document.cookie = cookie;\n },\n setSessionStorage: (name, value) => sessionStorage.setItem(name, value),\n setLocaleStorage: (name, value) => localStorage.setItem(name, value),\n};\n\n// Default settings for the language detector\ntype LanguageDetectorOptions = {\n order?: LanguageDetector[];\n lookupQuerystring?: string;\n htmlTag?: HTMLElement | null;\n};\n\nconst getDefaultsOptions = (): LanguageDetectorOptions => {\n return {\n order: [\n LanguageDetector.Querystring,\n LanguageDetector.Storage,\n LanguageDetector.Navigator,\n LanguageDetector.HtmlTag,\n ],\n lookupQuerystring: 'locale',\n htmlTag: typeof document !== 'undefined' ? document.documentElement : null,\n };\n};\n\nconst detectLanguage = (\n order: string[],\n options: LanguageDetectorOptions\n): Record<LanguageDetector, Locale | undefined> => {\n const detected: Record<LanguageDetector, Locale | undefined> = {} as Record<\n LanguageDetector,\n Locale | undefined\n >;\n\n const queryStringDetector = () => {\n if (typeof window === 'undefined') return;\n const search = window.location.search || '';\n const params = new URLSearchParams(search);\n const value = params.get(options.lookupQuerystring ?? '');\n if (value) {\n detected[LanguageDetector.Querystring] = value as Locale;\n }\n };\n\n const storageDetector = () => {\n if (typeof window === 'undefined') return;\n\n const locale = getLocaleFromStorage({\n getCookie: (name: string) => {\n try {\n const cookies = document.cookie.split(';');\n const cookieName = `${name}=`;\n\n const cookie = cookies.find((cookie) =>\n cookie.trim().startsWith(cookieName)\n );\n\n if (cookie) {\n return cookie.split('=')[1].trim();\n }\n } catch {}\n return undefined;\n },\n getSessionStorage: (name: string) => {\n try {\n return window.sessionStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n getLocaleStorage: (name: string) => {\n try {\n return window.localStorage.getItem(name) ?? undefined;\n } catch {}\n return undefined;\n },\n });\n\n if (locale) {\n detected[LanguageDetector.Storage] = locale;\n }\n };\n\n const navigatorDetector = () => {\n if (typeof navigator === 'undefined') return;\n\n const { internationalization } = configuration;\n const languages = navigator.languages ?? [navigator.language];\n\n // Use localeDetector to find the best matching locale\n const locale = localeDetector(\n { 'accept-language': languages.join(',') },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n if (locale) {\n detected[LanguageDetector.Navigator] = locale;\n }\n };\n\n const htmlTagDetector = () => {\n const htmlTag = options.htmlTag;\n if (htmlTag && typeof htmlTag.getAttribute === 'function') {\n const lang = htmlTag.getAttribute('lang');\n if (lang) {\n const { internationalization } = configuration;\n\n // Validate and resolve the locale\n const locale = localeDetector(\n { 'accept-language': lang },\n internationalization.locales,\n internationalization.defaultLocale\n );\n\n detected[LanguageDetector.HtmlTag] = locale;\n }\n }\n };\n\n // Map detector names to their corresponding functions\n const detectors: Record<string, () => void> = {\n [LanguageDetector.Querystring]: queryStringDetector,\n [LanguageDetector.Storage]: storageDetector,\n [LanguageDetector.Navigator]: navigatorDetector,\n [LanguageDetector.HtmlTag]: htmlTagDetector,\n };\n\n // Use the provided order to run each detector\n order.forEach((detectorName) => {\n detectors[detectorName]?.();\n });\n\n return detected;\n};\n\nconst getFirstAvailableLocale = (\n locales: Record<LanguageDetector, Locale | undefined>,\n order: LanguageDetector[]\n): Locale => {\n const { internationalization } = configuration;\n\n for (const detector of order) {\n const locale = locales[detector];\n\n if (locale && internationalization.locales.includes(locale)) {\n return locale;\n }\n }\n\n return internationalization?.defaultLocale ?? Locales.ENGLISH;\n};\n\n/**\n * Core language detector function for browser environments.\n *\n * Detects the user's preferred locale by checking multiple sources in order:\n * 1. Query string parameter\n * 2. Storage (cookies, localStorage, sessionStorage) - uses getLocaleFromStorage\n * 3. Navigator languages - uses localeDetector\n * 4. HTML lang attribute - uses localeDetector\n *\n * @param userOptions - Optional configuration for detection order and lookup keys\n * @returns The detected locale or the default locale\n *\n * @example\n * const locale = getBrowserLocale({ order: [LanguageDetector.Storage, LanguageDetector.Navigator] });\n */\nexport const getBrowserLocale = (\n userOptions: LanguageDetectorOptions | undefined = {}\n): Locale => {\n const options = { ...getDefaultsOptions(), ...userOptions };\n\n const locales = detectLanguage(options.order ?? [], options);\n\n return getFirstAvailableLocale(locales, options.order ?? []);\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/checkIsURLAbsolute.cjs`),n=require(`./getPathWithoutLocale.cjs`),r=require(`./getPrefix.cjs`),i=require(`./rewriteUtils.cjs`);let a=require(`@intlayer/config/client`),o=require(`@intlayer/config/built`);o=e.__toESM(o);const s=(e,s,c={})=>{let{defaultLocale:l,mode:u,locales:d,rewrite:f}={defaultLocale:o.default?.internationalization?.defaultLocale??a.DefaultValues.Internationalization.DEFAULT_LOCALE,mode:o.default?.routing?.mode??a.DefaultValues.Routing.ROUTING_MODE,locales:o.default?.internationalization?.locales??a.DefaultValues.Internationalization.LOCALES,rewrite:o.default?.routing?.rewrite,...c},p=n.getPathWithoutLocale(e,d),m=i.getRewriteRules(f,`url`);if(u===`no-prefix`)return i.getLocalizedPath(i.getCanonicalPath(p,void 0,m),s,m).path;let h=t.checkIsURLAbsolute(p),g=h?new URL(p):new URL(p,`http://example.com`),_=h?`${g.protocol}//${g.host}`:``,v=i.getLocalizedPath(i.getCanonicalPath(g.pathname,void 0,m),s,m).path;if(u===`search-params`){let e=new URLSearchParams(g.search);e.set(`locale`,s.toString());let t=e.toString(),n=t?`${v}?${t}`:v;return h?`${_}${n}${g.hash}`:`${n}${g.hash}`}let{prefix:y}=r.getPrefix(s,{defaultLocale:l,mode:u,locales:d}),b=`/${y}${v}`;return b=b.replaceAll(/\/+/g,`/`),b.length>1&&b.endsWith(`/`)&&(b=b.slice(0,-1)),h?`${_}${b}${g.search}${g.hash}`:`${b}${g.search}${g.hash}`};exports.getLocalizedUrl=s;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/checkIsURLAbsolute.cjs`),n=require(`./getPathWithoutLocale.cjs`),r=require(`./getPrefix.cjs`),i=require(`./rewriteUtils.cjs`);let a=require(`@intlayer/config/client`),o=require(`@intlayer/config/built`);o=e.__toESM(o);const s=(e,s=o.default?.internationalization?.defaultLocale,c={})=>{let{defaultLocale:l,mode:u,locales:d,rewrite:f}={defaultLocale:o.default?.internationalization?.defaultLocale??a.DefaultValues.Internationalization.DEFAULT_LOCALE,mode:o.default?.routing?.mode??a.DefaultValues.Routing.ROUTING_MODE,locales:o.default?.internationalization?.locales??a.DefaultValues.Internationalization.LOCALES,rewrite:o.default?.routing?.rewrite,...c},p=n.getPathWithoutLocale(e,d),m=i.getRewriteRules(f,`url`);if(u===`no-prefix`)return i.getLocalizedPath(i.getCanonicalPath(p,void 0,m),s,m).path;let h=t.checkIsURLAbsolute(p),g=h?new URL(p):new URL(p,`http://example.com`),_=h?`${g.protocol}//${g.host}`:``,v=i.getLocalizedPath(i.getCanonicalPath(g.pathname,void 0,m),s,m).path;if(u===`search-params`){let e=new URLSearchParams(g.search);e.set(`locale`,s.toString());let t=e.toString(),n=t?`${v}?${t}`:v;return h?`${_}${n}${g.hash}`:`${n}${g.hash}`}let{prefix:y}=r.getPrefix(s,{defaultLocale:l,mode:u,locales:d}),b=`/${y}${v}`;return b=b.replaceAll(/\/+/g,`/`),b.length>1&&b.endsWith(`/`)&&(b=b.slice(0,-1)),h?`${_}${b}${g.search}${g.hash}`:`${b}${g.search}${g.hash}`};exports.getLocalizedUrl=s;
|
|
2
2
|
//# sourceMappingURL=getLocalizedUrl.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.cjs","names":["configuration","DefaultValues","getPathWithoutLocale","getRewriteRules","getLocalizedPath","getCanonicalPath","checkIsURLAbsolute","getPrefix"],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { Locale, LocalesValues, RoutingConfig } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport { getPrefix } from './getPrefix';\nimport {\n getCanonicalPath,\n getLocalizedPath,\n getRewriteRules,\n} from './rewriteUtils';\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n } = {}\n): string => {\n const { defaultLocale, mode, locales, rewrite } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n rewrite: configuration?.routing?.rewrite,\n ...options,\n };\n\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n\n const urlRewriteRules = getRewriteRules(rewrite, 'url');\n\n if (mode === 'no-prefix') {\n // Resolve to canonical path first from the potentially localized input URL\n const canonicalPathname = getCanonicalPath(\n urlWithoutLocale,\n undefined,\n urlRewriteRules\n );\n\n // Localize the canonical path for the target locale\n return getLocalizedPath(\n canonicalPathname,\n currentLocale as Locale,\n urlRewriteRules\n ).path;\n }\n\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n // Resolve to canonical path first\n const canonicalPathname = getCanonicalPath(\n parsedUrl.pathname,\n undefined,\n urlRewriteRules\n );\n\n // Localize the canonical path for the target locale\n const translatedPathname = getLocalizedPath(\n canonicalPathname,\n currentLocale as Locale,\n urlRewriteRules\n ).path;\n\n if (mode === 'search-params') {\n const searchParams = new URLSearchParams(parsedUrl.search);\n searchParams.set('locale', currentLocale.toString());\n\n const queryString = searchParams.toString();\n const pathWithQuery = queryString\n ? `${translatedPathname}?${queryString}`\n : translatedPathname;\n\n return isAbsoluteUrl\n ? `${baseUrl}${pathWithQuery}${parsedUrl.hash}`\n : `${pathWithQuery}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, {\n defaultLocale,\n mode,\n locales,\n });\n\n let localizedPath = `/${prefix}${translatedPathname}`;\n\n localizedPath = localizedPath.replaceAll(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n const finalUrl = isAbsoluteUrl\n ? `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`\n : `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n\n return finalUrl;\n};\n"],"mappings":"sWAgDA,MAAa,GACX,EACA,
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.cjs","names":["configuration","DefaultValues","getPathWithoutLocale","getRewriteRules","getLocalizedPath","getCanonicalPath","checkIsURLAbsolute","getPrefix"],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { Locale, LocalesValues, RoutingConfig } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport { getPrefix } from './getPrefix';\nimport {\n getCanonicalPath,\n getLocalizedPath,\n getRewriteRules,\n} from './rewriteUtils';\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues = configuration?.internationalization\n ?.defaultLocale,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n } = {}\n): string => {\n const { defaultLocale, mode, locales, rewrite } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n rewrite: configuration?.routing?.rewrite,\n ...options,\n };\n\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n\n const urlRewriteRules = getRewriteRules(rewrite, 'url');\n\n if (mode === 'no-prefix') {\n // Resolve to canonical path first from the potentially localized input URL\n const canonicalPathname = getCanonicalPath(\n urlWithoutLocale,\n undefined,\n urlRewriteRules\n );\n\n // Localize the canonical path for the target locale\n return getLocalizedPath(\n canonicalPathname,\n currentLocale as Locale,\n urlRewriteRules\n ).path;\n }\n\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n // Resolve to canonical path first\n const canonicalPathname = getCanonicalPath(\n parsedUrl.pathname,\n undefined,\n urlRewriteRules\n );\n\n // Localize the canonical path for the target locale\n const translatedPathname = getLocalizedPath(\n canonicalPathname,\n currentLocale as Locale,\n urlRewriteRules\n ).path;\n\n if (mode === 'search-params') {\n const searchParams = new URLSearchParams(parsedUrl.search);\n searchParams.set('locale', currentLocale.toString());\n\n const queryString = searchParams.toString();\n const pathWithQuery = queryString\n ? `${translatedPathname}?${queryString}`\n : translatedPathname;\n\n return isAbsoluteUrl\n ? `${baseUrl}${pathWithQuery}${parsedUrl.hash}`\n : `${pathWithQuery}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, {\n defaultLocale,\n mode,\n locales,\n });\n\n let localizedPath = `/${prefix}${translatedPathname}`;\n\n localizedPath = localizedPath.replaceAll(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n const finalUrl = isAbsoluteUrl\n ? `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`\n : `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n\n return finalUrl;\n};\n"],"mappings":"sWAgDA,MAAa,GACX,EACA,EAA+BA,EAAAA,SAAe,sBAC1C,cACJ,EAKI,EAAE,GACK,CACX,GAAM,CAAE,gBAAe,OAAM,UAAS,WAAY,CAChD,cACEA,EAAAA,SAAe,sBAAsB,eACrCC,EAAAA,cAAc,qBAAqB,eACrC,KAAMD,EAAAA,SAAe,SAAS,MAAQC,EAAAA,cAAc,QAAQ,aAC5D,QACED,EAAAA,SAAe,sBAAsB,SACrCC,EAAAA,cAAc,qBAAqB,QACrC,QAASD,EAAAA,SAAe,SAAS,QACjC,GAAG,EACJ,CAEK,EAAmBE,EAAAA,qBAAqB,EAAK,EAAQ,CAErD,EAAkBC,EAAAA,gBAAgB,EAAS,MAAM,CAEvD,GAAI,IAAS,YASX,OAAOC,EAAAA,iBAPmBC,EAAAA,iBACxB,EACA,IAAA,GACA,EACD,CAKC,EACA,EACD,CAAC,KAGJ,IAAM,EAAgBC,EAAAA,mBAAmB,EAAiB,CAEpD,EAAY,EACd,IAAI,IAAI,EAAiB,CACzB,IAAI,IAAI,EAAkB,qBAAqB,CAE7C,EAAU,EACZ,GAAG,EAAU,SAAS,IAAI,EAAU,OACpC,GAUE,EAAqBF,EAAAA,iBAPDC,EAAAA,iBACxB,EAAU,SACV,IAAA,GACA,EACD,CAKC,EACA,EACD,CAAC,KAEF,GAAI,IAAS,gBAAiB,CAC5B,IAAM,EAAe,IAAI,gBAAgB,EAAU,OAAO,CAC1D,EAAa,IAAI,SAAU,EAAc,UAAU,CAAC,CAEpD,IAAM,EAAc,EAAa,UAAU,CACrC,EAAgB,EAClB,GAAG,EAAmB,GAAG,IACzB,EAEJ,OAAO,EACH,GAAG,IAAU,IAAgB,EAAU,OACvC,GAAG,IAAgB,EAAU,OAGnC,GAAM,CAAE,UAAWE,EAAAA,UAAU,EAAe,CAC1C,gBACA,OACA,UACD,CAAC,CAEE,EAAgB,IAAI,IAAS,IAYjC,MAVA,GAAgB,EAAc,WAAW,OAAQ,IAAI,CAEjD,EAAc,OAAS,GAAK,EAAc,SAAS,IAAI,GACzD,EAAgB,EAAc,MAAM,EAAG,GAAG,EAG3B,EACb,GAAG,IAAU,IAAgB,EAAU,SAAS,EAAU,OAC1D,GAAG,IAAgB,EAAU,SAAS,EAAU"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localeDetector.cjs","names":["localeResolver"],"sources":["../../../src/localization/localeDetector.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types';\nimport { localeResolver } from './localeResolver';\n\n/**\n * Constants\n */\nconst LANGUAGE_FORMAT_REGULAR_EXPRESSION =\n /^\\s*([^\\s\\-;]+)(?:-([^\\s;]+))?\\s*(?:;(.*))?$/;\nconst DEFAULT_QUALITY_SCORE = 1;\n\n/**\n * Enumeration for specificity weights.\n * Higher values indicate a more precise match.\n */\nenum SpecificityWeight {\n None = 0,\n Broad = 1, // Matches prefix (e.g., 'en' matches 'en-US')\n Prefix = 2, // Matches prefix in reverse (e.g., 'en-US' matches 'en')\n Exact = 4, // Matches exact string (e.g., 'en-US' matches 'en-US')\n}\n\n/**\n * Represents a parsed language tag from the header.\n */\ntype LanguagePreference = {\n languageCode: string;\n regionCode?: string;\n fullLocale: string;\n qualityScore: number;\n originalIndex: number;\n};\n\n/**\n * Represents the result of matching a requested language against an available language.\n */\ntype MatchResult = {\n providedIndex: number;\n headerIndex: number;\n qualityScore: number;\n specificityScore: number;\n};\n\n/**\n * Parses a single language tag string from the Accept-Language header.\n * Example input: \"en-US;q=0.8\"\n */\nconst parseLanguageTag = (\n tagString: string,\n index: number\n): LanguagePreference | null => {\n const match = LANGUAGE_FORMAT_REGULAR_EXPRESSION.exec(tagString);\n if (!match) {\n return null;\n }\n\n const languageCode = match[1];\n const regionCode = match[2];\n const parameters = match[3];\n\n // Construct the full locale string (e.g., \"en-US\" or \"en\")\n const fullLocale = regionCode\n ? `${languageCode}-${regionCode}`\n : languageCode;\n\n let qualityScore = DEFAULT_QUALITY_SCORE;\n\n // Parse parameters to find the quality score (\"q\")\n if (parameters) {\n const parameterList = parameters.split(';');\n for (const parameter of parameterList) {\n const [key, value] = parameter.split('=');\n if (key === 'q') {\n qualityScore = parseFloat(value);\n }\n }\n }\n\n return {\n languageCode,\n regionCode,\n qualityScore,\n originalIndex: index,\n fullLocale,\n };\n};\n\n/**\n * Parses the entire Accept-Language header string into a list of preferences.\n */\nconst parseAcceptLanguageHeader = (\n headerValue: string\n): LanguagePreference[] => {\n const rawTags = headerValue.split(',');\n const preferences: LanguagePreference[] = [];\n\n for (let index = 0; index < rawTags.length; index++) {\n const tag = rawTags[index].trim();\n const parsedLanguage = parseLanguageTag(tag, index);\n\n if (parsedLanguage) {\n preferences.push(parsedLanguage);\n }\n }\n\n return preferences;\n};\n\n/**\n * Calculates the specificity of a match between a provided language and a requested preference.\n */\nconst calculateMatchSpecificity = (\n providedLanguage: string,\n preference: LanguagePreference,\n providedIndex: number\n): MatchResult | null => {\n const parsedProvided = parseLanguageTag(providedLanguage, providedIndex);\n if (!parsedProvided) {\n return null;\n }\n\n let specificityScore = SpecificityWeight.None;\n\n const preferenceFullLower = preference.fullLocale.toLowerCase();\n const preferencePrefixLower = preference.languageCode.toLowerCase();\n const providedFullLower = parsedProvided.fullLocale.toLowerCase();\n const providedPrefixLower = parsedProvided.languageCode.toLowerCase();\n\n if (preferenceFullLower === providedFullLower) {\n specificityScore |= SpecificityWeight.Exact;\n } else if (preferencePrefixLower === providedFullLower) {\n specificityScore |= SpecificityWeight.Prefix;\n } else if (preferenceFullLower === providedPrefixLower) {\n specificityScore |= SpecificityWeight.Broad;\n } else if (preference.fullLocale !== '*') {\n return null;\n }\n\n return {\n providedIndex,\n headerIndex: preference.originalIndex,\n qualityScore: preference.qualityScore,\n specificityScore,\n };\n};\n\n/**\n * Determines the best match for a specific available language against the list of user accepted languages.\n */\nconst getBestMatchForLanguage = (\n providedLanguage: string,\n acceptedPreferences: LanguagePreference[],\n providedIndex: number\n): MatchResult => {\n // Initialize with a non-match priority\n let bestMatch: MatchResult = {\n headerIndex: -1,\n qualityScore: 0,\n specificityScore: 0,\n providedIndex,\n };\n\n for (const preference of acceptedPreferences) {\n const matchSpec = calculateMatchSpecificity(\n providedLanguage,\n preference,\n providedIndex\n );\n\n if (matchSpec) {\n // Compare current best match with new match\n const scoreDifference =\n bestMatch.specificityScore - matchSpec.specificityScore ||\n bestMatch.qualityScore - matchSpec.qualityScore ||\n bestMatch.headerIndex - matchSpec.headerIndex;\n\n // If the new match is better (difference < 0), update priority\n if (scoreDifference < 0) {\n bestMatch = matchSpec;\n }\n }\n }\n\n return bestMatch;\n};\n\n/**\n * Comparator function to sort language matches.\n * Sorting order:\n * 1. Quality Score (Descending)\n * 2. Specificity Score (Descending)\n * 3. Order in Header (Ascending - lower index is better)\n * 4. Order in Provided List (Ascending)\n */\nconst compareMatchResults = (a: MatchResult, b: MatchResult): number => {\n return (\n b.qualityScore - a.qualityScore ||\n b.specificityScore - a.specificityScore ||\n a.headerIndex - b.headerIndex ||\n a.providedIndex - b.providedIndex ||\n 0\n );\n};\n\n/**\n * Derives the list of preferred languages based on the Accept-Language header\n * and an optional list of available languages.\n */\nexport const getPreferredLanguages = (\n acceptHeader: string | undefined,\n availableLanguages?: string[]\n): string[] => {\n // RFC 2616 sec 14.4: no header implies '*'\n const headerValue = acceptHeader === undefined ? '*' : acceptHeader || '';\n const acceptedPreferences = parseAcceptLanguageHeader(headerValue);\n\n // If no specific languages are provided to filter against, return the header languages sorted by quality\n if (!availableLanguages) {\n return acceptedPreferences\n .filter((preference) => preference.qualityScore > 0)\n .sort((a, b) => b.qualityScore - a.qualityScore) // Simple sort by quality\n .map((preference) => preference.fullLocale);\n }\n\n // Map available languages to their match priority against the header\n const matchResults = availableLanguages.map((language, index) =>\n getBestMatchForLanguage(language, acceptedPreferences, index)\n );\n\n return matchResults\n .filter((result) => result.qualityScore > 0)\n .sort(compareMatchResults)\n .map((result) => availableLanguages[result.providedIndex]);\n};\n\n/**\n * Detects the locale from the request headers.\n *\n * Headers are provided by the browser/client and can be used to determine the user's preferred language.\n * This function intersects the user's `Accept-Language` header with the application's available locales.\n */\nexport const localeDetector = (\n headers: Record<string, string | undefined>,\n availableLocales?: Locale[],\n defaultLocale?: Locale\n): Locale => {\n const acceptLanguageHeader = headers['accept-language'];\n\n const preferredLocaleStrings = getPreferredLanguages(\n acceptLanguageHeader,\n availableLocales as string[]\n );\n\n return localeResolver(\n preferredLocaleStrings as Locale[],\n availableLocales,\n defaultLocale\n );\n};\n"],"mappings":"2GAMM,EACJ,+CAOF,IAAK,
|
|
1
|
+
{"version":3,"file":"localeDetector.cjs","names":["localeResolver"],"sources":["../../../src/localization/localeDetector.ts"],"sourcesContent":["import type { Locale } from '@intlayer/types';\nimport { localeResolver } from './localeResolver';\n\n/**\n * Constants\n */\nconst LANGUAGE_FORMAT_REGULAR_EXPRESSION =\n /^\\s*([^\\s\\-;]+)(?:-([^\\s;]+))?\\s*(?:;(.*))?$/;\nconst DEFAULT_QUALITY_SCORE = 1;\n\n/**\n * Enumeration for specificity weights.\n * Higher values indicate a more precise match.\n */\nenum SpecificityWeight {\n None = 0,\n Broad = 1, // Matches prefix (e.g., 'en' matches 'en-US')\n Prefix = 2, // Matches prefix in reverse (e.g., 'en-US' matches 'en')\n Exact = 4, // Matches exact string (e.g., 'en-US' matches 'en-US')\n}\n\n/**\n * Represents a parsed language tag from the header.\n */\ntype LanguagePreference = {\n languageCode: string;\n regionCode?: string;\n fullLocale: string;\n qualityScore: number;\n originalIndex: number;\n};\n\n/**\n * Represents the result of matching a requested language against an available language.\n */\ntype MatchResult = {\n providedIndex: number;\n headerIndex: number;\n qualityScore: number;\n specificityScore: number;\n};\n\n/**\n * Parses a single language tag string from the Accept-Language header.\n * Example input: \"en-US;q=0.8\"\n */\nconst parseLanguageTag = (\n tagString: string,\n index: number\n): LanguagePreference | null => {\n const match = LANGUAGE_FORMAT_REGULAR_EXPRESSION.exec(tagString);\n if (!match) {\n return null;\n }\n\n const languageCode = match[1];\n const regionCode = match[2];\n const parameters = match[3];\n\n // Construct the full locale string (e.g., \"en-US\" or \"en\")\n const fullLocale = regionCode\n ? `${languageCode}-${regionCode}`\n : languageCode;\n\n let qualityScore = DEFAULT_QUALITY_SCORE;\n\n // Parse parameters to find the quality score (\"q\")\n if (parameters) {\n const parameterList = parameters.split(';');\n for (const parameter of parameterList) {\n const [key, value] = parameter.split('=');\n if (key === 'q') {\n qualityScore = parseFloat(value);\n }\n }\n }\n\n return {\n languageCode,\n regionCode,\n qualityScore,\n originalIndex: index,\n fullLocale,\n };\n};\n\n/**\n * Parses the entire Accept-Language header string into a list of preferences.\n */\nconst parseAcceptLanguageHeader = (\n headerValue: string\n): LanguagePreference[] => {\n const rawTags = headerValue.split(',');\n const preferences: LanguagePreference[] = [];\n\n for (let index = 0; index < rawTags.length; index++) {\n const tag = rawTags[index].trim();\n const parsedLanguage = parseLanguageTag(tag, index);\n\n if (parsedLanguage) {\n preferences.push(parsedLanguage);\n }\n }\n\n return preferences;\n};\n\n/**\n * Calculates the specificity of a match between a provided language and a requested preference.\n */\nconst calculateMatchSpecificity = (\n providedLanguage: string,\n preference: LanguagePreference,\n providedIndex: number\n): MatchResult | null => {\n const parsedProvided = parseLanguageTag(providedLanguage, providedIndex);\n if (!parsedProvided) {\n return null;\n }\n\n let specificityScore = SpecificityWeight.None;\n\n const preferenceFullLower = preference.fullLocale.toLowerCase();\n const preferencePrefixLower = preference.languageCode.toLowerCase();\n const providedFullLower = parsedProvided.fullLocale.toLowerCase();\n const providedPrefixLower = parsedProvided.languageCode.toLowerCase();\n\n if (preferenceFullLower === providedFullLower) {\n specificityScore |= SpecificityWeight.Exact;\n } else if (preferencePrefixLower === providedFullLower) {\n specificityScore |= SpecificityWeight.Prefix;\n } else if (preferenceFullLower === providedPrefixLower) {\n specificityScore |= SpecificityWeight.Broad;\n } else if (preference.fullLocale !== '*') {\n return null;\n }\n\n return {\n providedIndex,\n headerIndex: preference.originalIndex,\n qualityScore: preference.qualityScore,\n specificityScore,\n };\n};\n\n/**\n * Determines the best match for a specific available language against the list of user accepted languages.\n */\nconst getBestMatchForLanguage = (\n providedLanguage: string,\n acceptedPreferences: LanguagePreference[],\n providedIndex: number\n): MatchResult => {\n // Initialize with a non-match priority\n let bestMatch: MatchResult = {\n headerIndex: -1,\n qualityScore: 0,\n specificityScore: 0,\n providedIndex,\n };\n\n for (const preference of acceptedPreferences) {\n const matchSpec = calculateMatchSpecificity(\n providedLanguage,\n preference,\n providedIndex\n );\n\n if (matchSpec) {\n // Compare current best match with new match\n const scoreDifference =\n bestMatch.specificityScore - matchSpec.specificityScore ||\n bestMatch.qualityScore - matchSpec.qualityScore ||\n bestMatch.headerIndex - matchSpec.headerIndex;\n\n // If the new match is better (difference < 0), update priority\n if (scoreDifference < 0) {\n bestMatch = matchSpec;\n }\n }\n }\n\n return bestMatch;\n};\n\n/**\n * Comparator function to sort language matches.\n * Sorting order:\n * 1. Quality Score (Descending)\n * 2. Specificity Score (Descending)\n * 3. Order in Header (Ascending - lower index is better)\n * 4. Order in Provided List (Ascending)\n */\nconst compareMatchResults = (a: MatchResult, b: MatchResult): number => {\n return (\n b.qualityScore - a.qualityScore ||\n b.specificityScore - a.specificityScore ||\n a.headerIndex - b.headerIndex ||\n a.providedIndex - b.providedIndex ||\n 0\n );\n};\n\n/**\n * Derives the list of preferred languages based on the Accept-Language header\n * and an optional list of available languages.\n */\nexport const getPreferredLanguages = (\n acceptHeader: string | undefined,\n availableLanguages?: string[]\n): string[] => {\n // RFC 2616 sec 14.4: no header implies '*'\n const headerValue = acceptHeader === undefined ? '*' : acceptHeader || '';\n const acceptedPreferences = parseAcceptLanguageHeader(headerValue);\n\n // If no specific languages are provided to filter against, return the header languages sorted by quality\n if (!availableLanguages) {\n return acceptedPreferences\n .filter((preference) => preference.qualityScore > 0)\n .sort((a, b) => b.qualityScore - a.qualityScore) // Simple sort by quality\n .map((preference) => preference.fullLocale);\n }\n\n // Map available languages to their match priority against the header\n const matchResults = availableLanguages.map((language, index) =>\n getBestMatchForLanguage(language, acceptedPreferences, index)\n );\n\n return matchResults\n .filter((result) => result.qualityScore > 0)\n .sort(compareMatchResults)\n .map((result) => availableLanguages[result.providedIndex]);\n};\n\n/**\n * Detects the locale from the request headers.\n *\n * Headers are provided by the browser/client and can be used to determine the user's preferred language.\n * This function intersects the user's `Accept-Language` header with the application's available locales.\n */\nexport const localeDetector = (\n headers: Record<string, string | undefined>,\n availableLocales?: Locale[],\n defaultLocale?: Locale\n): Locale => {\n const acceptLanguageHeader = headers['accept-language'];\n\n const preferredLocaleStrings = getPreferredLanguages(\n acceptLanguageHeader,\n availableLocales as string[]\n );\n\n return localeResolver(\n preferredLocaleStrings as Locale[],\n availableLocales,\n defaultLocale\n );\n};\n"],"mappings":"2GAMM,EACJ,+CAOF,IAAK,EAAL,SAAA,EAAA,OACE,GAAA,EAAA,KAAA,GAAA,OACA,EAAA,EAAA,MAAA,GAAA,QACA,EAAA,EAAA,OAAA,GAAA,SACA,EAAA,EAAA,MAAA,GAAA,WAJG,GAAA,EAAA,CAKJ,CA2BD,MAAM,GACJ,EACA,IAC8B,CAC9B,IAAM,EAAQ,EAAmC,KAAK,EAAU,CAChE,GAAI,CAAC,EACH,OAAO,KAGT,IAAM,EAAe,EAAM,GACrB,EAAa,EAAM,GACnB,EAAa,EAAM,GAGnB,EAAa,EACf,GAAG,EAAa,GAAG,IACnB,EAEA,EAAe,EAGnB,GAAI,EAAY,CACd,IAAM,EAAgB,EAAW,MAAM,IAAI,CAC3C,IAAK,IAAM,KAAa,EAAe,CACrC,GAAM,CAAC,EAAK,GAAS,EAAU,MAAM,IAAI,CACrC,IAAQ,MACV,EAAe,WAAW,EAAM,GAKtC,MAAO,CACL,eACA,aACA,eACA,cAAe,EACf,aACD,EAMG,EACJ,GACyB,CACzB,IAAM,EAAU,EAAY,MAAM,IAAI,CAChC,EAAoC,EAAE,CAE5C,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAQ,OAAQ,IAAS,CAEnD,IAAM,EAAiB,EADX,EAAQ,GAAO,MAAM,CACY,EAAM,CAE/C,GACF,EAAY,KAAK,EAAe,CAIpC,OAAO,GAMH,GACJ,EACA,EACA,IACuB,CACvB,IAAM,EAAiB,EAAiB,EAAkB,EAAc,CACxE,GAAI,CAAC,EACH,OAAO,KAGT,IAAI,EAAmB,EAAkB,KAEnC,EAAsB,EAAW,WAAW,aAAa,CACzD,EAAwB,EAAW,aAAa,aAAa,CAC7D,EAAoB,EAAe,WAAW,aAAa,CAC3D,EAAsB,EAAe,aAAa,aAAa,CAErE,GAAI,IAAwB,EAC1B,GAAoB,EAAkB,cAC7B,IAA0B,EACnC,GAAoB,EAAkB,eAC7B,IAAwB,EACjC,GAAoB,EAAkB,cAC7B,EAAW,aAAe,IACnC,OAAO,KAGT,MAAO,CACL,gBACA,YAAa,EAAW,cACxB,aAAc,EAAW,aACzB,mBACD,EAMG,GACJ,EACA,EACA,IACgB,CAEhB,IAAI,EAAyB,CAC3B,YAAa,GACb,aAAc,EACd,iBAAkB,EAClB,gBACD,CAED,IAAK,IAAM,KAAc,EAAqB,CAC5C,IAAM,EAAY,EAChB,EACA,EACA,EACD,CAEG,IAGA,EAAU,iBAAmB,EAAU,kBACvC,EAAU,aAAe,EAAU,cACnC,EAAU,YAAc,EAAU,aAGd,IACpB,EAAY,GAKlB,OAAO,GAWH,GAAuB,EAAgB,IAEzC,EAAE,aAAe,EAAE,cACnB,EAAE,iBAAmB,EAAE,kBACvB,EAAE,YAAc,EAAE,aAClB,EAAE,cAAgB,EAAE,eACpB,EAQS,GACX,EACA,IACa,CAGb,IAAM,EAAsB,EADR,IAAiB,IAAA,GAAY,IAAM,GAAgB,GACL,CAelE,OAZK,EAQgB,EAAmB,KAAK,EAAU,IACrD,EAAwB,EAAU,EAAqB,EAAM,CAC9D,CAGE,OAAQ,GAAW,EAAO,aAAe,EAAE,CAC3C,KAAK,EAAoB,CACzB,IAAK,GAAW,EAAmB,EAAO,eAAe,CAdnD,EACJ,OAAQ,GAAe,EAAW,aAAe,EAAE,CACnD,MAAM,EAAG,IAAM,EAAE,aAAe,EAAE,aAAa,CAC/C,IAAK,GAAe,EAAW,WAAW,EAoBpC,GACX,EACA,EACA,IACW,CACX,IAAM,EAAuB,EAAQ,mBAOrC,OAAOA,EAAAA,eALwB,EAC7B,EACA,EACD,CAIC,EACA,EACD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./constants.cjs`),t=require(`./utils.cjs`),n=require(`./parser.cjs`),r=require(`./renderer.cjs`),i=/^!\[(.*?)\]\( *((?:\([^)]*\)|[^() ])*) *"?([^)"]*)?"?\)/,a=RegExp(`^\\[((?:\\[[^\\[\\]]*(?:\\[[^\\[\\]]*\\][^\\[\\]]*)*\\]|[^\\[\\]])*)\\]\\(\\s*<?((?:\\([^)]*\\)|[^\\s\\\\]|\\\\.)*?)>?(?:\\s+['"]([\\s\\S]*?)['"])?\\s*\\)`),o=(e,n)=>{if(typeof e!=`string`)return e;let r=t.get(n,e);if(!r&&typeof e==`string`){let i=e.toLowerCase(),a=Object.keys(n).find(e=>e.toLowerCase()===i);a&&(r=t.get(n,a))}return r||e},s=(e,n)=>{let{runtime:r,components:i={}}=e,a=n.tagfilter?[`title`,`textarea`,`style`,`xmp`,`iframe`,`noembed`,`noframes`,`script`,`plaintext`]:[];return(e,n,...s)=>{if(typeof e==`string`&&a.includes(e.toLowerCase()))return null;let c=typeof e==`string`,l=t.cx(n?.className,n?.class),u={},d=!1;if(n)for(let e in n){let t=n[e];t!=null&&(e===`className`||e===`class`?d||=(l&&(u.className=l),!0):u[e]=t)}!d&&l&&(u.className=l);let f=u;r.normalizeProps&&c&&(f=r.normalizeProps(e,u));let p=o(e,i);return r.createElement(p,f,...s.length===1?[s[0]]:s)}},c=(n,r,o,s,c,l,u,d)=>{let f=e=>{if(process.env.NODE_ENV===`test`&&e===`中文`){let n=t.slugify(e);console.log(`Slug check:`,{input:e,ctxSlugify:!!r.slugify,defaultSlugifyResult:n})}return r.slugify?r.slugify(e,t.slugify):t.slugify(e)},p=r.sanitizer??t.sanitizer,m=r.namedCodesToUnicode?{...e.NAMED_CODES_TO_UNICODE,...r.namedCodesToUnicode}:e.NAMED_CODES_TO_UNICODE,h=r=>{let i=r===
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./constants.cjs`),t=require(`./utils.cjs`),n=require(`./parser.cjs`),r=require(`./renderer.cjs`),i=/^!\[(.*?)\]\( *((?:\([^)]*\)|[^() ])*) *"?([^)"]*)?"?\)/,a=RegExp(`^\\[((?:\\[[^\\[\\]]*(?:\\[[^\\[\\]]*\\][^\\[\\]]*)*\\]|[^\\[\\]])*)\\]\\(\\s*<?((?:\\([^)]*\\)|[^\\s\\\\]|\\\\.)*?)>?(?:\\s+['"]([\\s\\S]*?)['"])?\\s*\\)`),o=(e,n)=>{if(typeof e!=`string`)return e;let r=t.get(n,e);if(!r&&typeof e==`string`){let i=e.toLowerCase(),a=Object.keys(n).find(e=>e.toLowerCase()===i);a&&(r=t.get(n,a))}return r||e},s=(e,n)=>{let{runtime:r,components:i={}}=e,a=n.tagfilter?[`title`,`textarea`,`style`,`xmp`,`iframe`,`noembed`,`noframes`,`script`,`plaintext`]:[];return(e,n,...s)=>{if(typeof e==`string`&&a.includes(e.toLowerCase()))return null;let c=typeof e==`string`,l=t.cx(n?.className,n?.class),u={},d=!1;if(n)for(let e in n){let t=n[e];t!=null&&(e===`className`||e===`class`?d||=(l&&(u.className=l),!0):u[e]=t)}!d&&l&&(u.className=l);let f=u;r.normalizeProps&&c&&(f=r.normalizeProps(e,u));let p=o(e,i);return r.createElement(p,f,...s.length===1?[s[0]]:s)}},c=(n,r,o,s,c,l,u,d)=>{let f=e=>{if(process.env.NODE_ENV===`test`&&e===`中文`){let n=t.slugify(e);console.log(`Slug check:`,{input:e,ctxSlugify:!!r.slugify,defaultSlugifyResult:n})}return r.slugify?r.slugify(e,t.slugify):t.slugify(e)},p=r.sanitizer??t.sanitizer,m=r.namedCodesToUnicode?{...e.NAMED_CODES_TO_UNICODE,...r.namedCodesToUnicode}:e.NAMED_CODES_TO_UNICODE,h=r=>{let i=r===1,a=i?e.ORDERED_LIST_R:e.UNORDERED_LIST_R,o=i?e.ORDERED_LIST_ITEM_R:e.UNORDERED_LIST_ITEM_R,s=i?e.ORDERED_LIST_ITEM_PREFIX_R:e.UNORDERED_LIST_ITEM_PREFIX_R;return{_qualify:e=>s.test(e),_match:t.allowInline((t,n)=>{let r=e.LIST_LOOKBEHIND_R.exec(n.prevCapture??``),i=n.list??(!n.inline&&!n.simple);if(r&&i){let e=(r[1]||``)+t;return a.exec(e)}return null}),_order:e.Priority.HIGH,_parse(n,r,a){let c=n[2],l=i?+c.slice(0,-1):void 0,u=n[0].replace(e.BLOCK_END_R,`
|
|
2
2
|
`).match(o);if(!u)return{items:[],ordered:i,start:l};let d=!1;return{items:u.map((e,n)=>{let i=s.exec(e),o=i?i[0].length:0,c=RegExp(`^ {1,${o}}`,`gm`),l=e.replace(c,``).replace(s,``),f=n===u.length-1,p=l.indexOf(`
|
|
3
3
|
|
|
4
4
|
`)!==-1||f&&d;d=p;let m=a.inline,h=a.list;a.list=!0;let g;p?(a.inline=!1,g=`${t.trimEnd(l)}\n\n`):(a.inline=!0,g=t.trimEnd(l));let _=r(g,a);return a.inline=m,a.list=h,_}),ordered:i,start:l}},_render(e,t,r={}){let i=e.ordered?`ol`:`ul`,a={key:r.key};return e.ordered&&e.start!=null&&(a.start=e.start),n(i,a,...e.items.map((e,i)=>n(`li`,{key:i},t(e,r))))}}},g=(e,n)=>{if(n.inline||n.simple||n.inHTML&&e.indexOf(`
|
|
@@ -9,5 +9,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
|
|
|
9
9
|
`,r),i=e.slice(r,n===-1?void 0:n+1);if(t.some(d,i)||n===-1||!i.trim())break;r=n+1}let i=e.slice(0,r);if(i===``)return null;let a=t.trimEnd(i);return a===``?null:[i,void 0,a]};return{[e.RuleType.blockQuote]:{_qualify:[`>`],_match:t.blockRegex(e.BLOCKQUOTE_R),_order:e.Priority.HIGH,_parse(n,r,i){let a=n[0].replace(e.BLOCKQUOTE_TRIM_LEFT_MULTILINE_R,``).match(e.BLOCKQUOTE_ALERT_R),o=a?.[1],s=a?.[2]??``;return{alert:o,children:s.indexOf(`
|
|
10
10
|
`)===-1?t.parseInline(r,s,i):t.parseBlock(r,s,i)}},_render(t,r,i={}){let a={key:i.key};return t.alert&&(a.className=`markdown-alert-${f(t.alert.toLowerCase())}`,t.children.unshift({attrs:{},children:[{type:e.RuleType.text,text:t.alert}],noInnerParse:!0,type:e.RuleType.htmlBlock,tag:`header`})),n(`blockquote`,a,r(t.children,i))}},[e.RuleType.breakLine]:{_qualify:[` `],_match:t.anyScopeRegex(e.BREAK_LINE_R),_order:e.Priority.HIGH,_parse:t.captureNothing,_render(e,t,r={}){return n(`br`,{key:r.key})}},[e.RuleType.breakThematic]:{_qualify:[`--`,`__`,`**`,`- `,`* `,`_ `],_match:t.blockRegex(e.BREAK_THEMATIC_R),_order:e.Priority.HIGH,_parse:t.captureNothing,_render(e,t,r={}){return n(`hr`,{key:r.key})}},[e.RuleType.codeBlock]:{_qualify:[` `],_match:t.blockRegex(e.CODE_BLOCK_R),_order:e.Priority.MAX,_parse(n){return{type:e.RuleType.codeBlock,lang:void 0,text:t.unescapeString(t.trimEnd(n[0].replace(/^ {4}/gm,``)))}},_render(e,t,r={}){let i={...e.attrs??{}},a=e.lang?`lang-${e.lang}`:`lang-plaintext`;return i.className=i.className?`${i.className} ${a}`:a,e.lang&&!i.lang&&(i.lang=e.lang),n(`pre`,{key:r.key},n(`code`,i,e.text))}},[e.RuleType.codeFenced]:{_qualify:["```",`~~~`],_match:t.blockRegex(e.CODE_BLOCK_FENCED_R),_order:e.Priority.MAX,_parse(t){return{attrs:l(`code`,t[3]??``),lang:t[2]||void 0,text:t[4],type:e.RuleType.codeBlock}}},[e.RuleType.codeInline]:{_qualify:["`"],_match:t.simpleInlineRegex(e.CODE_INLINE_R),_order:e.Priority.LOW,_parse(e){return{text:t.unescapeString(e[2])}},_render(e,t,r={}){return n(`code`,{key:r.key},e.text)}},[e.RuleType.footnote]:{_qualify:[`[^`],_match:t.blockRegex(e.FOOTNOTE_R),_order:e.Priority.MAX,_parse(e){return s.push({footnote:e[2],identifier:e[1]}),{}},_render:t.renderNothing},[e.RuleType.footnoteReference]:{_qualify:[`[^`],_match:t.inlineRegex(e.FOOTNOTE_REFERENCE_R),_order:e.Priority.HIGH,_parse(e){return{target:`#${f(e[1])}`,text:e[1]}},_render(e,t,r={}){return n(`a`,{key:r.key,href:p(e.target,`a`,`href`)??void 0},n(`sup`,{key:r.key},e.text))}},[e.RuleType.gfmTask]:{_qualify:[`[ ]`,`[x]`],_match:t.inlineRegex(e.GFM_TASK_R),_order:e.Priority.HIGH,_parse(e){return{completed:e[1].toLowerCase()===`x`}},_render(e,t,r={}){return n(`input`,{checked:e.completed,key:r.key,readOnly:!0,type:`checkbox`})}},[e.RuleType.heading]:{_qualify:[`#`],_match:t.blockRegex(o.enforceAtxHeadings?e.HEADING_ATX_COMPLIANT_R:e.HEADING_R),_order:e.Priority.HIGH,_parse(e,n,r){return{children:t.parseInline(n,e[2],r),id:f(e[2]),level:e[1].length}},_render(e,t,r={}){return n(`h${e.level}`,{id:e.id,key:r.key},t(e.children,r))}},[e.RuleType.headingSetext]:{_qualify:e=>{let t=e.indexOf(`
|
|
11
11
|
`);return t>0&&t<e.length-1&&(e[t+1]===`=`||e[t+1]===`-`)},_match:t.blockRegex(e.HEADING_SETEXT_R),_order:e.Priority.MAX,_parse(n,r,i){return{children:t.parseInline(r,n[1],i),level:n[2]===`=`?1:2,type:e.RuleType.heading}}},[e.RuleType.htmlBlock]:{_qualify:e=>{if(o.disableParsingRawHTML)return!1;let t=e.match(/^ *<([a-z][a-z0-9:-]*)\b/i);if(!t)return!1;let n=t[1];return e.toLowerCase().indexOf(`</${n.toLowerCase()}>`)!==-1},_match:t.anyScopeRegex(e.HTML_BLOCK_ELEMENT_R),_order:e.Priority.HIGH,_parse(n,r,i){let a=n[3].match(e.HTML_LEFT_TRIM_AMOUNT_R)?.[1]??``,o=t.trimLeadingWhitespaceOutsideFences(n[3],a),s=u(o)?t.parseBlock:t.parseInline,c=n[1].trim(),d=e.DO_NOT_PROCESS_HTML_ELEMENTS.indexOf(c.toLowerCase())!==-1,f=d?c.toLowerCase():c,p={attrs:l(f,n[2]??``),noInnerParse:d,tag:f};if(i.inAnchor=i.inAnchor||c.toLowerCase()===`a`,d)p.text=n[3];else{let e=i.inHTML;i.inHTML=!0,p.children=s(r,o,i),i.inHTML=e}return i.inAnchor=!1,p},_render(e,t,r={}){return n(e.tag,{key:r.key,...e.attrs??{}},e.text??(e.children?t(e.children,r):``))}},[e.RuleType.htmlComment]:{_qualify:[`<!`],_match:t.anyScopeRegex(e.HTML_COMMENT_R),_order:e.Priority.HIGH,_parse:t.captureNothing,_render:t.renderNothing},[e.RuleType.htmlSelfClosing]:{_qualify:e=>o.disableParsingRawHTML?!1:/^ *<([a-zA-Z][a-zA-Z0-9:]*)[\s>/]/.test(e),_match:t.anyScopeRegex(e.HTML_SELF_CLOSING_ELEMENT_R),_order:e.Priority.HIGH,_parse(e){let t=e[1].trim();return{attrs:l(t,e[2]||``),tag:t}},_render(e,t,r={}){return n(e.tag,{key:r.key,...e.attrs??{}})}},[e.RuleType.customComponent]:{_qualify:e=>/^ *<([A-Z][a-zA-Z0-9]*)/.test(e),_match:t.anyScopeRegex(e.CUSTOM_COMPONENT_R),_order:e.Priority.MAX,_parse(n,r,i){let a=n[3].match(e.HTML_LEFT_TRIM_AMOUNT_R)?.[1]??``,o=t.trimLeadingWhitespaceOutsideFences(n[3],a),s=u(o)?t.parseBlock:t.parseInline,c=n[1].trim(),d={attrs:l(c,n[2]??``),noInnerParse:!1,tag:c},f=i.inHTML;return i.inHTML=!0,d.children=s(r,o,i),i.inHTML=f,d},_render(e,t,r={}){return n(e.tag,{key:r.key,...e.attrs??{}},e.text??(e.children?t(e.children,r):``))}},[e.RuleType.paragraph]:{_match:g,_order:e.Priority.LOW,_parse:t.parseCaptureInline,_render(e,t,r={}){return n(`p`,{key:r.key},t(e.children,r))}},[e.RuleType.image]:{_qualify:[`![`],_match:t.simpleInlineRegex(i),_order:e.Priority.HIGH,_parse(e){return{alt:t.unescapeString(e[1]),target:t.unescapeString(e[2]),title:t.unescapeString(e[3])}},_render(e,t,r={}){return n(`img`,{key:r.key,alt:e.alt??void 0,title:e.title??void 0,src:p(e.target,`img`,`src`)??void 0})}},[e.RuleType.link]:{_qualify:[`[`],_match:t.inlineRegex(a),_order:e.Priority.LOW,_parse(e,n,r){return{children:t.parseSimpleInline(n,e[1],r),target:t.unescapeString(e[2]),title:t.unescapeString(e[3])}},_render(e,t,r={}){let i=p(e.target,`a`,`href`);return process.env.NODE_ENV===`test`&&e.target.includes(`javascript:`)&&console.log(`Compiler sanitize result:`,{target:e.target,sanitizedHref:i,finalHref:i??void 0}),n(`a`,{key:r.key,href:i??void 0,title:e.title??void 0},t(e.children,r))}},[e.RuleType.linkAngleBraceStyleDetector]:{_qualify:[`<`],_match:t.inlineRegex(e.LINK_AUTOLINK_R),_order:e.Priority.MAX,_parse(t){let n=t[1],r=!1;return n.indexOf(`@`)!==-1&&n.indexOf(`//`)===-1&&(r=!0,n=n.replace(`mailto:`,``)),{children:[{text:n,type:e.RuleType.text}],target:r?`mailto:${n}`:n,type:e.RuleType.link}}},[e.RuleType.linkBareUrlDetector]:{_qualify:(e,n)=>!!(n.inline&&!n.inAnchor&&!o.disableAutoLink&&(t.startsWith(e,`http://`)||t.startsWith(e,`https://`))),_match:t.inlineRegex(e.LINK_AUTOLINK_BARE_URL_R),_order:e.Priority.MAX,_parse(t){return{children:[{text:t[1],type:e.RuleType.text}],target:t[1],type:e.RuleType.link}}},[e.RuleType.newlineCoalescer]:{_match:t.blockRegex(e.CONSECUTIVE_NEWLINE_R),_order:e.Priority.LOW,_parse:t.captureNothing,_render(){return`
|
|
12
|
-
`}},[e.RuleType.orderedList]:h(
|
|
12
|
+
`}},[e.RuleType.orderedList]:h(1),[e.RuleType.unorderedList]:h(2),[e.RuleType.ref]:{_qualify:[`[`],_match:t.anyScopeRegex(e.REFERENCE_IMAGE_OR_LINK),_order:e.Priority.MAX,_parse(e){return c[e[1]]={target:e[2],title:e[4]},{}},_render:t.renderNothing},[e.RuleType.refImage]:{_qualify:[`![`],_match:t.simpleInlineRegex(e.REFERENCE_IMAGE_R),_order:e.Priority.MAX,_parse(e){return{alt:e[1]?t.unescapeString(e[1]):void 0,ref:e[2]}},_render(e,t,r={}){let i=c[e.ref];return i?n(`img`,{key:r.key,alt:e.alt,src:p(i.target,`img`,`src`)??void 0,title:i.title}):null}},[e.RuleType.refLink]:{_qualify:e=>e[0]===`[`&&e.indexOf(`](`)===-1,_match:t.inlineRegex(e.REFERENCE_LINK_R),_order:e.Priority.MAX,_parse(e,n,r){return{children:t.parseSimpleInline(n,e[1],r),fallbackChildren:e[0],ref:e[2]}},_render(e,t,r={}){let i=c[e.ref];return i?n(`a`,{key:r.key,href:p(i.target,`a`,`href`)??void 0,title:i.title},t(e.children,r)):n(`span`,{key:r.key},e.fallbackChildren)}},[e.RuleType.table]:{_qualify:[`|`],_match:t.blockRegex(e.NP_TABLE_R),_order:e.Priority.HIGH,_parse(n,r,i){i.inline=!0;let a=n[2]?t.parseTableAlign(n[2]):[],o=n[3]?t.parseTableCells(n[3],r,i):[],s=t.parseTableRow(n[1],r,i,!!o.length);return i.inline=!1,o.length?{align:a,cells:o,header:s,type:e.RuleType.table}:{children:s.flat(),type:e.RuleType.paragraph}},_render(e,t,r={}){let i=e,a=e=>i.align[e]?{textAlign:i.align[e]}:{};return n(`table`,{key:r.key},n(`thead`,null,n(`tr`,null,...i.header.map((e,i)=>n(`th`,{key:i,style:a(i)},t(e,r))))),n(`tbody`,null,...i.cells.map((e,i)=>n(`tr`,{key:i},...e.map((e,i)=>n(`td`,{key:i,style:a(i)},t(e,r)))))))}},[e.RuleType.tableSeparator]:{_match:(e,t)=>t.inTable&&e[0]===`|`?/^\|/.exec(e):null,_order:e.Priority.HIGH,_parse(){return{type:e.RuleType.tableSeparator}},_render(){return` | `}},[e.RuleType.text]:{_match:t.allowInline((t,n)=>e.SHORTCODE_R.exec(t)||e.TEXT_PLAIN_R.exec(t)||/^[\s\S]/.exec(t)),_order:e.Priority.MIN,_parse(t){let n=t[0];return{text:n.indexOf(`&`)===-1?n:n.replace(e.HTML_CHAR_CODE_R,(e,t)=>m[t]||e)}},_render(e){return e.text}},[e.RuleType.textBolded]:{_qualify:[`**`,`__`],_match:t.simpleInlineRegex(e.TEXT_BOLD_R),_order:e.Priority.MED,_parse(e,t,n){return{children:t(e[2],n)}},_render(e,t,r={}){return n(`strong`,{key:r.key},t(e.children,r))}},[e.RuleType.textEmphasized]:{_qualify:[`*`,`_`],_match:t.simpleInlineRegex(e.TEXT_EMPHASIZED_R),_order:e.Priority.LOW,_parse(e,t,n){return{children:t(e[2],n)}},_render(e,t,r={}){return n(`em`,{key:r.key},t(e.children,r))}},[e.RuleType.textEscaped]:{_qualify:[`\\`],_match:t.simpleInlineRegex(e.TEXT_ESCAPED_R),_order:e.Priority.HIGH,_parse(t){return{text:t[1],type:e.RuleType.text}}},[e.RuleType.textMarked]:{_qualify:[`==`],_match:t.simpleInlineRegex(e.TEXT_MARKED_R),_order:e.Priority.LOW,_parse:t.parseCaptureInline,_render(e,t,r={}){return n(`mark`,{key:r.key},t(e.children,r))}},[e.RuleType.textStrikethroughed]:{_qualify:[`~~`],_match:t.simpleInlineRegex(e.TEXT_STRIKETHROUGHED_R),_order:e.Priority.LOW,_parse:t.parseCaptureInline,_render(e,t,r={}){return n(`del`,{key:r.key},t(e.children,r))}}}},l=(i=``,a,o={})=>{let l=a.components??{},u=e=>{if(process.env.NODE_ENV===`test`&&e===`中文`){let n=t.slugify(e);console.log(`Slug check:`,{input:e,ctxSlugify:!!a.slugify,defaultSlugifyResult:n})}return a.slugify?a.slugify(e,t.slugify):t.slugify(e)},d=s(a,o),f=[],p={},m=(n,r)=>{if(!r||!r.trim())return null;let i=r.match(e.ATTR_EXTRACTOR_R);return i?i.reduce((r,i)=>{let o=i.indexOf(`=`);if(o!==-1){let s=t.normalizeAttributeKey(i.slice(0,o)).trim(),c=t.unquote(i.slice(o+1).trim()),l=e.ATTRIBUTE_TO_NODE_PROP_MAP[s]??s;if(l===`ref`)return r;r[l]=t.attributeValueToNodePropValue(n,s,c,a.sanitizer??t.sanitizer),typeof r[l]==`string`&&(e.HTML_BLOCK_ELEMENT_R.test(r[l])||e.HTML_SELF_CLOSING_ELEMENT_R.test(r[l]))&&(r[l]=b(r[l].trim()))}else i!==`style`&&(r[e.ATTRIBUTE_TO_NODE_PROP_MAP[i]??i]=!0);return r},{}):null},h=[e.BLOCKQUOTE_R,e.CODE_BLOCK_FENCED_R,e.CODE_BLOCK_R,o.enforceAtxHeadings?e.HEADING_ATX_COMPLIANT_R:e.HEADING_R,e.HEADING_SETEXT_R,e.NP_TABLE_R,e.ORDERED_LIST_R,e.UNORDERED_LIST_R,e.CUSTOM_COMPONENT_R],g=c(d,a,o,f,p,m,n=>{let r=n.replace(e.TRIM_STARTING_NEWLINES,``),i=r.length>2048?r.slice(0,2048):r;return t.some(o.disableParsingRawHTML?h:[...h,e.PARAGRAPH_R,e.HTML_BLOCK_ELEMENT_R,e.HTML_COMMENT_R,e.HTML_SELF_CLOSING_ELEMENT_R,e.CUSTOM_COMPONENT_R],i)},h),_=o.disableParsingRawHTML?Object.keys(g).reduce((t,n)=>(n!==e.RuleType.htmlBlock&&n!==e.RuleType.htmlSelfClosing&&(t[n]=g[n]),t),{}):g,v=n.parserFor(_),y=r.renderFor(r.createRenderer(_,o.renderRule)),b=n=>{let r=o.preserveFrontmatter?n:n.replace(e.FRONT_MATTER_R,``),i=o.forceInline||!o.forceBlock&&e.SHOULD_RENDER_AS_BLOCK_R.test(r.replace(e.TRIM_STARTING_NEWLINES,``))===!1,a=y(v(i?r:`${t.trimEnd(r).replace(e.TRIM_STARTING_NEWLINES,``)}\n\n`,{inline:i}),{inline:i});for(;typeof a[a.length-1]==`string`&&!a[a.length-1].trim();)a.pop();if(o.wrapper===null)return a;let s=o.wrapper??(i?`span`:`div`);if(a.length>1||o.forceWrapper)return d(s,{key:`outer`},a);if(a.length===1){let e=a[0];if(typeof e==`string`){let n={key:`outer`};if(!i&&l){let r=t.get(l,`p.props`,{})??{},i=t.cx(n.className,r.className),a={...n,...r};return i&&(a.className=i),d(`span`,a,e)}return d(`span`,n,e)}return e}return d(s,{key:`outer`},null)};if(typeof i!=`string`)throw process.env.NODE_ENV!==`production`&&console.error(`intlayer: the first argument must be a string. Received`,typeof i),Error(`intlayer: the first argument must be a string`);let x=b(i);return f.length?d(`div`,null,x,d(`footer`,{key:`footer`},...f.map(e=>d(`div`,{id:u(e.identifier),key:e.identifier},e.identifier,y(v(e.footnote,{inline:!0}),{inline:!0}))))):x},u=e=>(t,n)=>l(t,e,n),d=(e,t,n={})=>{let{components:r,namedCodesToUnicode:i,sanitizer:a,slugify:o,...s}=n;return l(e,{runtime:t,components:r,namedCodesToUnicode:i,sanitizer:a,slugify:o},s)};exports.compile=l,exports.compileWithOptions=d,exports.createCompiler=u;
|
|
13
13
|
//# sourceMappingURL=compiler.cjs.map
|