preact-intlayer 9.5.11 → 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/client/useDictionaryAsync.cjs +2 -2
- package/dist/cjs/client/useDictionaryAsync.cjs.map +1 -1
- package/dist/cjs/client/useDictionaryDynamic.cjs +2 -2
- package/dist/cjs/client/useDictionaryDynamic.cjs.map +1 -1
- package/dist/cjs/plugins.cjs +7 -5
- package/dist/cjs/plugins.cjs.map +1 -1
- package/dist/esm/client/useDictionaryAsync.mjs +2 -2
- package/dist/esm/client/useDictionaryAsync.mjs.map +1 -1
- package/dist/esm/client/useDictionaryDynamic.mjs +6 -6
- package/dist/esm/client/useDictionaryDynamic.mjs.map +1 -1
- package/dist/esm/plugins.mjs +8 -6
- package/dist/esm/plugins.mjs.map +1 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_client_IntlayerProvider = require('./IntlayerProvider.cjs');
|
|
3
3
|
const require_client_useDictionary = require('./useDictionary.cjs');
|
|
4
|
-
let
|
|
4
|
+
let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
|
|
5
5
|
let preact_hooks = require("preact/hooks");
|
|
6
6
|
|
|
7
7
|
//#region src/client/useDictionaryAsync.ts
|
|
@@ -12,7 +12,7 @@ let preact_hooks = require("preact/hooks");
|
|
|
12
12
|
*/
|
|
13
13
|
const useDictionaryAsync = async (dictionaryPromise, locale) => {
|
|
14
14
|
const { locale: currentLocale } = (0, preact_hooks.useContext)(require_client_IntlayerProvider.IntlayerClientContext) ?? {};
|
|
15
|
-
const localeTarget = (0, preact_hooks.useMemo)(() => locale ?? currentLocale ??
|
|
15
|
+
const localeTarget = (0, preact_hooks.useMemo)(() => locale ?? currentLocale ?? (0, _intlayer_core_interpreter.resolveInterpreterLocale)(), [currentLocale, locale]);
|
|
16
16
|
const dictionary = await (0, preact_hooks.useMemo)(async () => await dictionaryPromise[localeTarget]?.(), [dictionaryPromise, localeTarget]);
|
|
17
17
|
return require_client_useDictionary.useDictionary(dictionary, localeTarget);
|
|
18
18
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryAsync.cjs","names":["useContext","IntlayerClientContext","useMemo","
|
|
1
|
+
{"version":3,"file":"useDictionaryAsync.cjs","names":["useContext","IntlayerClientContext","useMemo","resolveInterpreterLocale","useDictionary"],"sources":["../../../src/client/useDictionaryAsync.ts"],"sourcesContent":["import { resolveInterpreterLocale } from '@intlayer/core/interpreter';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext, useMemo } from 'preact/hooks';\nimport { IntlayerClientContext } from './IntlayerProvider';\nimport { useDictionary } from './useDictionary';\n\n/**\n * On the server side, Hook that transform a dictionary and return the content\n *\n * If the locale is not provided, it will use the locale from the client context\n */\nexport const useDictionaryAsync = async <const T extends Dictionary>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n locale?: LocalesValues\n): Promise<T> => {\n const { locale: currentLocale } = useContext(IntlayerClientContext) ?? {};\n\n const localeTarget = useMemo(\n () => locale ?? currentLocale ?? resolveInterpreterLocale(),\n [currentLocale, locale]\n );\n\n const dictionary = await useMemo(\n async () =>\n (await dictionaryPromise[\n localeTarget as keyof typeof dictionaryPromise\n ]?.()) as T,\n [dictionaryPromise, localeTarget]\n );\n\n return useDictionary(dictionary, localeTarget) as any;\n};\n"],"mappings":";;;;;;;;;;;;AAeA,MAAa,qBAAqB,OAChC,mBACA,WACe;CACf,MAAM,EAAE,QAAQ,sBAAkBA,yBAAWC,qDAAqB,KAAK,CAAC;CAExE,MAAM,mBAAeC,4BACb,UAAU,qBAAiBC,qDAAyB,GAC1D,CAAC,eAAe,MAAM,CACxB;CAEA,MAAM,aAAa,UAAMD,sBACvB,YACG,MAAM,kBACL,aACD,GAAG,GACN,CAAC,mBAAmB,YAAY,CAClC;CAEA,OAAOE,2CAAc,YAAY,YAAY;AAC/C"}
|
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
const require_getDictionary = require('../getDictionary.cjs');
|
|
3
3
|
const require_client_IntlayerProvider = require('./IntlayerProvider.cjs');
|
|
4
4
|
const require_client_useLoadDynamic = require('./useLoadDynamic.cjs');
|
|
5
|
-
let
|
|
5
|
+
let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
|
|
6
6
|
let preact_hooks = require("preact/hooks");
|
|
7
7
|
let _intlayer_core_dictionaryManipulator = require("@intlayer/core/dictionaryManipulator");
|
|
8
8
|
|
|
@@ -29,7 +29,7 @@ const useDictionaryDynamic = (dictionaryPromise, key, localeOrSelector) => {
|
|
|
29
29
|
locale: localeOrSelector,
|
|
30
30
|
selector: void 0
|
|
31
31
|
};
|
|
32
|
-
const localeTarget = selectorLocale ?? currentLocale ??
|
|
32
|
+
const localeTarget = selectorLocale ?? currentLocale ?? (0, _intlayer_core_interpreter.resolveInterpreterLocale)();
|
|
33
33
|
if (process.env.INTLAYER_DICTIONARY_SELECTOR !== "false" && (0, _intlayer_core_dictionaryManipulator.isQualifiedDynamicLoaderMap)(dictionaryPromise)) return (0, _intlayer_core_dictionaryManipulator.resolveQualifiedDynamicContent)({
|
|
34
34
|
loaderMap: dictionaryPromise,
|
|
35
35
|
key: String(key),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.cjs","names":["useContext","IntlayerClientContext","parseDictionarySelector","resolveDictionaryArgument","
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.cjs","names":["useContext","IntlayerClientContext","parseDictionarySelector","resolveDictionaryArgument","resolveInterpreterLocale","isQualifiedDynamicLoaderMap","resolveQualifiedDynamicContent","loadDynamicChunk","getDictionary","getPreloadedDictionary"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import {\n getPreloadedDictionary,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveDictionaryArgument,\n resolveQualifiedDynamicContent,\n} from '@intlayer/core/dictionaryManipulator';\nimport { resolveInterpreterLocale } from '@intlayer/core/interpreter';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext } from 'preact/hooks';\nimport { getDictionary } from '../getDictionary';\nimport { IntlayerClientContext } from './IntlayerProvider';\n// `useLoadDynamic` is a suspender cache, not a hook — aliased to a non-hook\n// name so it can be invoked in loops / conditionally (collection chunks).\nimport { useLoadDynamic as loadDynamicChunk } from './useLoadDynamic';\n\n/**\n * Preact hook that lazily loads a dictionary and returns its content.\n *\n * The dictionary entry is either a plain dynamic loader map\n * (`locale → loader`) or a qualified one (`locale → …qualifier → loader`,\n * tagged with the qualifier dimensions). For qualified maps, only the chunk(s)\n * the selector targets are loaded.\n *\n * If the locale is not provided (directly or through the selector), the client\n * context locale is used.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n) => {\n const { locale: currentLocale, variant: contextVariant } =\n useContext(IntlayerClientContext) ?? {};\n\n const { locale: selectorLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector<LocalesValues>(\n // Layers the provider's ambient variant under the call-site argument\n // before the chunk walk, so only the targeted chunk is loaded.\n resolveDictionaryArgument({\n localeOrSelector,\n contextLocale: currentLocale,\n contextVariant,\n dictionaryKey: String(key),\n })\n )\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n\n const localeTarget =\n selectorLocale ?? currentLocale ?? resolveInterpreterLocale();\n\n if (\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryPromise)\n ) {\n return resolveQualifiedDynamicContent({\n loaderMap: dictionaryPromise,\n key: String(key),\n locale: localeTarget,\n selector,\n loadChunk: (cacheKey, promise) => loadDynamicChunk(cacheKey, promise),\n transform: (dictionary) => getDictionary(dictionary, localeTarget),\n });\n }\n\n // A build-tool plugin may have started this locale's chunk while the entry\n // point itself was evaluating, in which case the content is already here and\n // reading it must not go through the suspender — see `getPreloadedDictionary`.\n const preloadedDictionary = getPreloadedDictionary(\n dictionaryPromise,\n localeTarget\n );\n if (preloadedDictionary) {\n return getDictionary(preloadedDictionary as T, localeTarget);\n }\n\n const plainLoaders = dictionaryPromise as StrictModeLocaleMap<\n () => Promise<T>\n >;\n\n const dictionary = loadDynamicChunk<T>(\n `${String(key)}.${localeTarget}`,\n plainLoaders[localeTarget as keyof typeof plainLoaders]?.() as Promise<T>\n );\n\n return getDictionary(dictionary, localeTarget);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmCA,MAAa,wBAKX,mBAGA,KACA,qBACG;CACH,MAAM,EAAE,QAAQ,eAAe,SAAS,uBACtCA,yBAAWC,qDAAqB,KAAK,CAAC;CAExC,MAAM,EAAE,QAAQ,gBAAgB,aAC9B,QAAQ,IAAI,iCAAiC,cACzCC,kEAGEC,gEAA0B;EACxB;EACA,eAAe;EACf;EACA,eAAe,OAAO,GAAG;CAC3B,CAAC,CACH,IACA;EACE,QAAQ;EACR,UAAU;CACZ;CAEN,MAAM,eACJ,kBAAkB,qBAAiBC,qDAAyB;CAE9D,IACE,QAAQ,IAAI,iCAAiC,eAC7CC,kEAA4B,iBAAiB,GAE7C,WAAOC,qEAA+B;EACpC,WAAW;EACX,KAAK,OAAO,GAAG;EACf,QAAQ;EACR;EACA,YAAY,UAAU,YAAYC,6CAAiB,UAAU,OAAO;EACpE,YAAY,eAAeC,oCAAc,YAAY,YAAY;CACnE,CAAC;CAMH,MAAM,0BAAsBC,6DAC1B,mBACA,YACF;CACA,IAAI,qBACF,OAAOD,oCAAc,qBAA0B,YAAY;CAG7D,MAAM,eAAe;CAIrB,MAAM,aAAaD,6CACjB,GAAG,OAAO,GAAG,EAAE,GAAG,gBAClB,aAAa,aAA0C,GAAG,CAC5D;CAEA,OAAOC,oCAAc,YAAY,YAAY;AAC/C"}
|
package/dist/cjs/plugins.cjs
CHANGED
|
@@ -88,7 +88,8 @@ const splitAndJoinInsertion = (template, values) => {
|
|
|
88
88
|
let match = regex.exec(template);
|
|
89
89
|
while (match !== null) {
|
|
90
90
|
if (match.index > lastIndex) parts.push(template.substring(lastIndex, match.index));
|
|
91
|
-
const
|
|
91
|
+
const key = match[1]?.trim();
|
|
92
|
+
const value = key && values[key];
|
|
92
93
|
if (value !== void 0 && value !== null) parts.push(typeof value === "number" ? String(value) : value);
|
|
93
94
|
lastIndex = match.index + match[0].length;
|
|
94
95
|
match = regex.exec(template);
|
|
@@ -240,15 +241,16 @@ const pluginsCache = /* @__PURE__ */ new Map();
|
|
|
240
241
|
* This function is used by both getIntlayer and getDictionary to ensure consistent plugin configuration.
|
|
241
242
|
*/
|
|
242
243
|
const getPlugins = (locale, fallback = true) => {
|
|
243
|
-
const
|
|
244
|
+
const currentLocale = (0, _intlayer_core_interpreter.resolveInterpreterLocale)(locale);
|
|
245
|
+
const cacheKey = `${currentLocale}_${fallback}`;
|
|
244
246
|
if (pluginsCache.has(cacheKey)) return pluginsCache.get(cacheKey);
|
|
245
247
|
const enabledPlugins = [
|
|
246
248
|
intlayerNodePlugins,
|
|
247
|
-
(0, _intlayer_core_interpreter.translationPlugin)(
|
|
249
|
+
(0, _intlayer_core_interpreter.translationPlugin)(currentLocale, fallback ? _intlayer_config_built.internationalization.defaultLocale : void 0),
|
|
248
250
|
_intlayer_core_interpreter.enumerationPlugin,
|
|
249
|
-
(0, _intlayer_core_interpreter.pluralPlugin)(
|
|
251
|
+
(0, _intlayer_core_interpreter.pluralPlugin)(currentLocale),
|
|
250
252
|
_intlayer_core_interpreter.conditionPlugin,
|
|
251
|
-
(0, _intlayer_core_interpreter.nestedPlugin)(
|
|
253
|
+
(0, _intlayer_core_interpreter.nestedPlugin)(currentLocale),
|
|
252
254
|
_intlayer_core_interpreter.filePlugin,
|
|
253
255
|
_intlayer_core_interpreter.genderPlugin,
|
|
254
256
|
_intlayer_core_interpreter.selectPlugin,
|
package/dist/cjs/plugins.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.cjs","names":["editor","renderIntlayerNode","ContentSelector","fallbackPlugin","renderPreactElement","h","Fragment","NodeTypes","isInterpolableWrapperNode","transformInterpolableNode","resolveInsertedSelector","lazy","getMarkdownMetadata","internationalization","translationPlugin","enumerationPlugin","pluralPlugin","conditionPlugin","nestedPlugin","filePlugin","genderPlugin","selectPlugin"],"sources":["../../src/plugins.tsx"],"sourcesContent":["import { editor, internationalization } from '@intlayer/config/built';\nimport {\n conditionPlugin,\n type DeepTransformContent as DeepTransformContentCore,\n enumerationPlugin,\n fallbackPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState as IInterpreterPluginStateCore,\n isInterpolableWrapperNode,\n nestedPlugin,\n type Plugins,\n pluralPlugin,\n resolveInsertedSelector,\n selectPlugin,\n transformInterpolableNode,\n translationPlugin,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { Fragment, type FunctionComponent, h, type VNode } from 'preact';\nimport { lazy } from 'preact/compat';\nimport { reportExposure } from './analytics/exposureSink';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then((m) => ({\n MarkdownRendererPlugin: m.MarkdownRendererPlugin,\n MarkdownMetadataRenderer: m.MarkdownMetadataRenderer,\n }))\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRenderer').then((m) => m.HTMLRenderer)\n : null;\n\n// These preloads are read later by `useLoadDynamic`, so the rejection must stay\n// on the promise: a `.catch()` chained into it would resolve with `undefined`\n// and be mistaken for a loaded module. Handle it on the side instead, so an\n// aborted chunk load never escapes as an unhandled rejection.\nmarkdownRendererModulePromise?.catch(() => {});\nhtmlRendererModulePromise?.catch(() => {});\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (_node, props) => {\n // Node-level analytics: record which content is resolved for display.\n // No-op (and dead-code-eliminated) when analytics is disabled.\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: props.dictionaryKey,\n keyPath: props.keyPath,\n locale: props.locale,\n nodeType: 'text',\n });\n }\n\n // Props are only forwarded to the editor selector: copying them for every\n // leaf would cost an allocation per rendered string\n if (process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled) {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n return renderIntlayerNode({\n value: rest.children,\n children: (\n <ContentSelector {...rest} key={rest.children}>\n {rest.children}\n </ContentSelector>\n ),\n });\n }\n\n return renderIntlayerNode({\n value: props.children,\n children: props.children,\n });\n },\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_PREACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'preact-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderPreactElement(node)}\n </ContentSelector>\n ) : (\n renderPreactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I; // Accept strings OR nested nodes like enumerations\n fields: readonly (infer F)[]; // Infer the exact string literals in the array\n}\n ? <V extends { [K in Extract<F, string>]: string | number | VNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : DeepTransformContent<I, L> // Delegate nested nodes (like enumerations) back to the core\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1].trim();\n const value = values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_INSERTION === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{ … }}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n // VNodes cannot be injected into a raw markup string, so string\n // interpolation (not `splitAndJoinInsertion`) is used here.\n if (isInterpolableWrapperNode(node)) {\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]:\n | string\n | number\n | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n const result = deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n\n return resolveInsertedSelector(children, result);\n },\n };\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/**\n * Code-split renderers are loaded with `lazy` rather than a hand-rolled\n * suspender. A node that suspended on the hand-rolled one never recovered once\n * the chunk landed, so every markdown node present on the first paint stayed\n * blank forever; `lazy` implements the suspend/retry handshake correctly.\n */\nconst MarkdownSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownRendererPlugin as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\nconst MarkdownMetadataSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownMetadataRenderer as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node) ?? {};\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n use: render,\n },\n });\n\n return render() as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.MARKDOWN,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.MARKDOWN,\n },\n ];\n\n const children = node[NodeTypes.MARKDOWN];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\nconst HTMLSuspenseRenderer = lazy(() =>\n htmlRendererModulePromise!.then((HTMLRenderer) => ({\n default: HTMLRenderer as FunctionComponent<Record<string, any>>,\n }))\n);\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_HTML === 'false'\n ? fallbackPlugin\n : {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const _tags = node.tags ?? [];\n // `children` is dropped deliberately: `HTMLRenderer` resolves its\n // content as `children || html`, so forwarding the raw node here would\n // shadow the HTML string and render nothing.\n const { plugins, children: _nodeChildren, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled\n ? h(\n ContentSelector,\n { ...rest },\n h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n })\n )\n : h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n }),\n additionalProps: { use: render },\n }) as any;\n\n return render();\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, S, L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T, S, L>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n\nconst pluginsCache = new Map<string, Plugins[]>();\n\n/**\n * Get the plugins array for Preact content transformation.\n * This function is used by both getIntlayer and getDictionary to ensure consistent plugin configuration.\n */\nexport const getPlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] => {\n const currentLocale = locale ?? internationalization.defaultLocale;\n const cacheKey = `${currentLocale}_${fallback}`;\n\n if (pluginsCache.has(cacheKey)) {\n return pluginsCache.get(cacheKey)!;\n }\n\n const plugins = [\n // First: most nodes are plain strings, which every other plugin rejects\n intlayerNodePlugins,\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n pluralPlugin(locale ?? internationalization.defaultLocale),\n conditionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n preactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n // Plugins disabled at build time never match: skip them on every node\n const enabledPlugins = plugins.filter((plugin) => plugin !== fallbackPlugin);\n\n pluginsCache.set(cacheKey, enabledPlugins);\n\n return enabledPlugins;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAuCA,MAAM,gCACJ,QAAQ,IAAI,gCAAgC,+CACxC,0CAA4C,MAAM,OAAO;CACvD,wBAAwB,EAAE;CAC1B,0BAA0B,EAAE;AAC9B,EAAE,IACF;AAEN,MAAM,4BACJ,QAAQ,IAAI,4BAA4B,+CACpC,4BAA8B,MAAM,MAAM,EAAE,YAAY,IACxD;AAMN,+BAA+B,YAAY,CAAC,CAAC;AAC7C,2BAA2B,YAAY,CAAC,CAAC;;AAWzC,MAAa,sBAA+B;CAC1C,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAChB,OAAO,SAAS,YAChB,OAAO,SAAS;CAClB,YAAY,OAAO,UAAU;EAG3B,IAAI,QAAQ,IAAI,+BAA+B,SAC7C,8CAAe;GACb,eAAe,MAAM;GACrB,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,UAAU;EACZ,CAAC;EAKH,IAAI,QAAQ,IAAI,4BAA4B,WAAWA,8BAAO,SAAS;GACrE,MAAM,EACJ,SACA,GAAG,SACD;GAEJ,OAAOC,wCAAmB;IACxB,OAAO,KAAK;IACZ,UACE,0CAACC,gDAAD;KAAiB,GAAI;KAAM,KAAK,KAAK;IAEpB,GADd,KAAK,QACS;GAErB,CAAC;EACH;EAEA,OAAOD,wCAAmB;GACxB,OAAO,MAAM;GACb,UAAU,MAAM;EAClB,CAAC;CACH;AACF;;AAcA,MAAa,oBACX,QAAQ,IAAI,mCAAmC,UAC3CE,4CACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAChB,OAAO,KAAK,UAAU,eACtB,OAAO,KAAK,QAAQ;CAEtB,YACE,MACA,EACE,SACA,GAAG,WAEF;EACH,IAAI,QAAQ,IAAI,+BAA+B,SAC7C,8CAAe;GACb,eAAe,KAAK;GACpB,SAAS,KAAK;GACd,QAAQ,KAAK;GACb,UAAU;EACZ,CAAC;EAGH,OAAOF,wCAAmB;GACxB,GAAG;GACH,OAAO;GACP,UACE,QAAQ,IAAI,4BAA4B,WACxCD,8BAAO,UACL,4CAACE,gDAAD;IAAiB,GAAI;cAClBE,8DAAoB,IAAI;GACV,KAEjBA,8DAAoB,IAAI;EAE9B,CAAC;CACH;AACF;;;;AAuBN,MAAM,WAAW,UAA+B;CAC9C,OACE,UAAU,QACV,UAAU,UACV,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU;AAErB;;;;AAKA,MAAM,yBACJ,UACA,WACU;CAIV,IAAI,CAFa,OAAO,OAAO,MAAM,CAAC,CAAC,KAAK,OAEhC,GAEV,OAAO,SAAS,QAAQ,yBAAyB,GAAG,QAAQ;EAE1D,QAAQ,OADW,IAAI,KACC,MAAM,GAAE,CAAE,SAAS;CAC7C,CAAC;CAIH,MAAM,QAA4B,CAAC;CACnC,IAAI,YAAY;CAChB,MAAM,QAAQ;CACd,IAAI,QAAgC,MAAM,KAAK,QAAQ;CAEvD,OAAO,UAAU,MAAM;EAErB,IAAI,MAAM,QAAQ,WAChB,MAAM,KAAK,SAAS,UAAU,WAAW,MAAM,KAAK,CAAC;EAKvD,MAAM,QAAQ,OADF,MAAM,EAAE,CAAC,KACE;EACvB,IAAI,UAAU,UAAa,UAAU,MACnC,MAAM,KAAK,OAAO,UAAU,WAAW,OAAO,KAAK,IAAI,KAAK;EAG9D,YAAY,MAAM,QAAQ,MAAM,EAAE,CAAC;EACnC,QAAQ,MAAM,KAAK,QAAQ;CAC7B;CAGA,IAAI,YAAY,SAAS,QACvB,MAAM,KAAK,SAAS,UAAU,SAAS,CAAC;CAI1C,WAAOC,UACLC,iBACA,MACA,GAAG,MAAM,KAAK,MAAM,cAAUD,UAAEC,iBAAU,EAAE,KAAK,MAAM,GAAG,IAAI,CAAC,CACjE;AACF;;AAGA,MAAa,kBACX,QAAQ,IAAI,iCAAiC,UACzCH,4CACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaI,yBAAU;CAC3D,YAAY,MAAwB,OAAO,sBAAsB;EAC/D,MAAM,aAAwB,CAC5B,GAAG,MAAM,SACT,EACE,MAAMA,yBAAU,UAClB,CACF;EAEA,MAAM,WAAW,KAAKA,yBAAU;;EAGhC,MAAM,wBAAiC;GACrC,IAAI;GACJ,YAAY,SACV,OAAO,SAAS,gBAAYC,sDAA0B,IAAI;GAC5D,YAAY,MAAM,UAAU,sBAAsB;IAMhD,QAAIA,sDAA0B,IAAI,GAChC,QACE,eAIAC,sDACE,MACA,QACA,UACA,MAAM,SACN,iBACF;IAGJ,MAAM,oBAAoB,kBAAkB,MAAM;KAChD,GAAG;KACH,UAAU;KACV,SAAS,CACP,IAAI,MAAM,WAAY,CAAC,EAAe,CAAE,QACrC,WAAW,OAAO,OAAO,sBAC5B,CACF;IACF,CAAC;IAED,QACE,WAMG;KACH,MAAM,SAAS,sBAAsB,mBAAmB,MAAM;KAE9D,OAAO,kBAAkB,QAAQ;MAC/B,GAAG;MACH,SAAS,MAAM;MACf,UAAU;KACZ,CAAC;IACH;GACF;EACF;EAEA,MAAM,SAAS,kBAAkB,UAAU;GACzC,GAAG;GACH;GACA,SAAS;GACT,SAAS,CAAC,uBAAuB,GAAI,MAAM,WAAW,CAAC,CAAE;EAC3D,CAAC;EAED,WAAOC,oDAAwB,UAAU,MAAM;CACjD;AACF;;;;;;;AAsBN,MAAM,+BAA2BC,0BAC/B,8BAA+B,MAAM,aAAa,EAChD,SAAS,QAAQ,uBAGnB,EAAE,CACJ;AAEA,MAAM,uCAAmCA,0BACvC,8BAA+B,MAAM,aAAa,EAChD,SAAS,QAAQ,yBAGnB,EAAE,CACJ;;AAGA,MAAa,uBACX,QAAQ,IAAI,gCAAgC,UACxCR,4CACA;CACE,IAAI;CACJ,YAAY,SAAS,OAAO,SAAS;CACrC,YAAY,MAAc,OAAO,sBAAsB;EACrD,MAAM,EACJ,SACA,GAAG,SACD;EAsCJ,MAAM,gBAAgB,sBApCLS,6CAAoB,IAAI,KAAK,CAAC,GAoCG;GAChD,SAAS,CAAC;IAlCV,IAAI;IACJ,YAAY,iBACV,OAAO,iBAAiB,YACxB,OAAO,iBAAiB,YACxB,OAAO,iBAAiB,aACxB,CAAC;IACH,YAAY,cAAc,UACxBX,wCAAmB;KACjB,GAAG;KACH,OAAO;KACP,UACE,QAAQ,IAAI,4BAA4B,WACxCD,8BAAO,UACL,4CAACE,gDAAD;MAAiB,GAAI;gBACnB,4CAAC,kCAAD;OACE,GAAI;OACJ,iBAAiB,MAAM;iBAEtB;MAC+B;KACnB,KAEjB,4CAAC,kCAAD;MACE,GAAI;MACJ,iBAAiB,MAAM;gBAEtB;KAC+B;IAExC,CAAC;GAKqB,CAAC;GACzB,eAAe,KAAK;GACpB,SAAS,CAAC;EACZ,CAAC;EAED,MAAM,UAAU,eACdD,wCAAmB;GACjB,GAAG;GACH,OAAO;GACP,UACE,QAAQ,IAAI,4BAA4B,WACxCD,8BAAO,UACL,4CAACE,gDAAD;IAAiB,GAAI;cACnB,4CAAC,0BAAD;KAA0B,GAAI;KAAkB;eAC7C;IACuB;GACX,KAEjB,4CAAC,0BAAD;IAA0B,GAAI;IAAkB;cAC7C;GACuB;GAE9B,iBAAiB;IACf,UAAU;IACV,KAAK;GACP;EACF,CAAC;EAEH,OAAO,OAAO;CAChB;AACF;AAcN,MAAa,iBACX,QAAQ,IAAI,gCAAgC,UACxCC,4CACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaI,yBAAU;CAC3D,YAAY,MAAuB,OAAO,sBAAsB;EAC9D,MAAM,aAAwB,CAC5B,GAAG,MAAM,SACT,EACE,MAAMA,yBAAU,SAClB,CACF;EAEA,MAAM,WAAW,KAAKA,yBAAU;EAEhC,OAAO,kBAAkB,UAAU;GACjC,GAAG;GACH;GACA,SAAS;GACT,SAAS,CAAC,sBAAsB,GAAI,MAAM,WAAW,CAAC,CAAE;EAC1D,CAAC;CACH;AACF;AAgBN,MAAM,2BAAuBI,0BAC3B,0BAA2B,MAAM,kBAAkB,EACjD,SAAS,aACX,EAAE,CACJ;;AAGA,MAAa,aACX,QAAQ,IAAI,4BAA4B,UACpCR,4CACA;CACE,IAAI;CACJ,YAAY,SACV,OAAO,SAAS,YAAY,MAAM,aAAaI,yBAAU;CAC3D,YAAY,MAA2B,UAAU;EAC/C,MAAM,OAAO,KAAKA,yBAAU;EACd,KAAK;EAInB,MAAM,EAAE,SAAS,UAAU,eAAe,GAAG,SAAS;EAGtD,MAAM,UAAU,mBACdN,wCAAmB;GACjB,GAAG;GACH,OAAO;GACP,UACE,QAAQ,IAAI,4BAA4B,WACxCD,8BAAO,cACHK,UACEH,gDACA,EAAE,GAAG,KAAK,OACVG,UAAE,sBAAsB;IACtB,GAAG;IACH;IACA,YAAY;GACd,CAAC,CACH,QACAA,UAAE,sBAAsB;IACtB,GAAG;IACH;IACA,YAAY;GACd,CAAC;GACP,iBAAiB,EAAE,KAAK,OAAO;EACjC,CAAC;EAEH,OAAO,OAAO;CAChB;AACF;AAmCN,MAAM,+BAAe,IAAI,IAAuB;;;;;AAMhD,MAAa,cACX,QACA,WAAoB,SACN;CAEd,MAAM,WAAW,GADK,UAAUQ,4CAAqB,cACnB,GAAG;CAErC,IAAI,aAAa,IAAI,QAAQ,GAC3B,OAAO,aAAa,IAAI,QAAQ;CAyBlC,MAAM,iBAAiB;EApBrB;MACAC,8CACE,UAAUD,4CAAqB,eAC/B,WAAWA,4CAAqB,gBAAgB,MAClD;EACAE;MACAC,yCAAa,UAAUH,4CAAqB,aAAa;EACzDI;MACAC,yCAAa,UAAUL,4CAAqB,aAAa;EACzDM;EACAC;EACAC;EAEA;EACA;EACA;EACA;CAI2B,CAAC,CAAC,QAAQ,WAAW,WAAWlB,yCAAc;CAE3E,aAAa,IAAI,UAAU,cAAc;CAEzC,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"plugins.cjs","names":["editor","renderIntlayerNode","ContentSelector","fallbackPlugin","renderPreactElement","h","Fragment","NodeTypes","isInterpolableWrapperNode","transformInterpolableNode","resolveInsertedSelector","lazy","getMarkdownMetadata","resolveInterpreterLocale","translationPlugin","internationalization","enumerationPlugin","pluralPlugin","conditionPlugin","nestedPlugin","filePlugin","genderPlugin","selectPlugin"],"sources":["../../src/plugins.tsx"],"sourcesContent":["import { editor, internationalization } from '@intlayer/config/built';\nimport {\n conditionPlugin,\n type DeepTransformContent as DeepTransformContentCore,\n enumerationPlugin,\n fallbackPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState as IInterpreterPluginStateCore,\n isInterpolableWrapperNode,\n nestedPlugin,\n type Plugins,\n pluralPlugin,\n resolveInsertedSelector,\n resolveInterpreterLocale,\n selectPlugin,\n transformInterpolableNode,\n translationPlugin,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { Fragment, type FunctionComponent, h, type VNode } from 'preact';\nimport { lazy } from 'preact/compat';\nimport { reportExposure } from './analytics/exposureSink';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then((m) => ({\n MarkdownRendererPlugin: m.MarkdownRendererPlugin,\n MarkdownMetadataRenderer: m.MarkdownMetadataRenderer,\n }))\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRenderer').then((m) => m.HTMLRenderer)\n : null;\n\n// These preloads are read later by `useLoadDynamic`, so the rejection must stay\n// on the promise: a `.catch()` chained into it would resolve with `undefined`\n// and be mistaken for a loaded module. Handle it on the side instead, so an\n// aborted chunk load never escapes as an unhandled rejection.\nmarkdownRendererModulePromise?.catch(() => {});\nhtmlRendererModulePromise?.catch(() => {});\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (_node, props) => {\n // Node-level analytics: record which content is resolved for display.\n // No-op (and dead-code-eliminated) when analytics is disabled.\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: props.dictionaryKey,\n keyPath: props.keyPath,\n locale: props.locale,\n nodeType: 'text',\n });\n }\n\n // Props are only forwarded to the editor selector: copying them for every\n // leaf would cost an allocation per rendered string\n if (process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled) {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n return renderIntlayerNode({\n value: rest.children,\n children: (\n <ContentSelector {...rest} key={rest.children}>\n {rest.children}\n </ContentSelector>\n ),\n });\n }\n\n return renderIntlayerNode({\n value: props.children,\n children: props.children,\n });\n },\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_PREACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'preact-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderPreactElement(node)}\n </ContentSelector>\n ) : (\n renderPreactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I; // Accept strings OR nested nodes like enumerations\n fields: readonly (infer F)[]; // Infer the exact string literals in the array\n}\n ? <V extends { [K in Extract<F, string>]: string | number | VNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : DeepTransformContent<I, L> // Delegate nested nodes (like enumerations) back to the core\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1]?.trim();\n const value = key && values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_INSERTION === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{ … }}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n // VNodes cannot be injected into a raw markup string, so string\n // interpolation (not `splitAndJoinInsertion`) is used here.\n if (isInterpolableWrapperNode(node)) {\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]:\n | string\n | number\n | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n const result = deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n\n return resolveInsertedSelector(children, result);\n },\n };\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/**\n * Code-split renderers are loaded with `lazy` rather than a hand-rolled\n * suspender. A node that suspended on the hand-rolled one never recovered once\n * the chunk landed, so every markdown node present on the first paint stayed\n * blank forever; `lazy` implements the suspend/retry handshake correctly.\n */\nconst MarkdownSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownRendererPlugin as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\nconst MarkdownMetadataSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownMetadataRenderer as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node) ?? {};\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n use: render,\n },\n });\n\n return render() as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.MARKDOWN,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.MARKDOWN,\n },\n ];\n\n const children = node[NodeTypes.MARKDOWN];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\nconst HTMLSuspenseRenderer = lazy(() =>\n htmlRendererModulePromise!.then((HTMLRenderer) => ({\n default: HTMLRenderer as FunctionComponent<Record<string, any>>,\n }))\n);\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_HTML === 'false'\n ? fallbackPlugin\n : {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const _tags = node.tags ?? [];\n // `children` is dropped deliberately: `HTMLRenderer` resolves its\n // content as `children || html`, so forwarding the raw node here would\n // shadow the HTML string and render nothing.\n const { plugins, children: _nodeChildren, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled\n ? h(\n ContentSelector,\n { ...rest },\n h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n })\n )\n : h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n }),\n additionalProps: { use: render },\n }) as any;\n\n return render();\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, S, L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T, S, L>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n\nconst pluginsCache = new Map<string, Plugins[]>();\n\n/**\n * Get the plugins array for Preact content transformation.\n * This function is used by both getIntlayer and getDictionary to ensure consistent plugin configuration.\n */\nexport const getPlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] => {\n const currentLocale = resolveInterpreterLocale(locale);\n const cacheKey = `${currentLocale}_${fallback}`;\n\n if (pluginsCache.has(cacheKey)) {\n return pluginsCache.get(cacheKey)!;\n }\n\n const plugins = [\n // First: most nodes are plain strings, which every other plugin rejects\n intlayerNodePlugins,\n translationPlugin(\n currentLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n pluralPlugin(currentLocale),\n conditionPlugin,\n nestedPlugin(currentLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n preactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n // Plugins disabled at build time never match: skip them on every node\n const enabledPlugins = plugins.filter((plugin) => plugin !== fallbackPlugin);\n\n pluginsCache.set(cacheKey, enabledPlugins);\n\n return enabledPlugins;\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IntlayerClientContext } from "./IntlayerProvider.mjs";
|
|
2
2
|
import { useDictionary } from "./useDictionary.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveInterpreterLocale } from "@intlayer/core/interpreter";
|
|
4
4
|
import { useContext, useMemo } from "preact/hooks";
|
|
5
5
|
|
|
6
6
|
//#region src/client/useDictionaryAsync.ts
|
|
@@ -11,7 +11,7 @@ import { useContext, useMemo } from "preact/hooks";
|
|
|
11
11
|
*/
|
|
12
12
|
const useDictionaryAsync = async (dictionaryPromise, locale) => {
|
|
13
13
|
const { locale: currentLocale } = useContext(IntlayerClientContext) ?? {};
|
|
14
|
-
const localeTarget = useMemo(() => locale ?? currentLocale ??
|
|
14
|
+
const localeTarget = useMemo(() => locale ?? currentLocale ?? resolveInterpreterLocale(), [currentLocale, locale]);
|
|
15
15
|
const dictionary = await useMemo(async () => await dictionaryPromise[localeTarget]?.(), [dictionaryPromise, localeTarget]);
|
|
16
16
|
return useDictionary(dictionary, localeTarget);
|
|
17
17
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryAsync.mjs","names":[],"sources":["../../../src/client/useDictionaryAsync.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useDictionaryAsync.mjs","names":[],"sources":["../../../src/client/useDictionaryAsync.ts"],"sourcesContent":["import { resolveInterpreterLocale } from '@intlayer/core/interpreter';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext, useMemo } from 'preact/hooks';\nimport { IntlayerClientContext } from './IntlayerProvider';\nimport { useDictionary } from './useDictionary';\n\n/**\n * On the server side, Hook that transform a dictionary and return the content\n *\n * If the locale is not provided, it will use the locale from the client context\n */\nexport const useDictionaryAsync = async <const T extends Dictionary>(\n dictionaryPromise: StrictModeLocaleMap<() => Promise<T>>,\n locale?: LocalesValues\n): Promise<T> => {\n const { locale: currentLocale } = useContext(IntlayerClientContext) ?? {};\n\n const localeTarget = useMemo(\n () => locale ?? currentLocale ?? resolveInterpreterLocale(),\n [currentLocale, locale]\n );\n\n const dictionary = await useMemo(\n async () =>\n (await dictionaryPromise[\n localeTarget as keyof typeof dictionaryPromise\n ]?.()) as T,\n [dictionaryPromise, localeTarget]\n );\n\n return useDictionary(dictionary, localeTarget) as any;\n};\n"],"mappings":";;;;;;;;;;;AAeA,MAAa,qBAAqB,OAChC,mBACA,WACe;CACf,MAAM,EAAE,QAAQ,kBAAkB,WAAW,qBAAqB,KAAK,CAAC;CAExE,MAAM,eAAe,cACb,UAAU,iBAAiB,yBAAyB,GAC1D,CAAC,eAAe,MAAM,CACxB;CAEA,MAAM,aAAa,MAAM,QACvB,YACG,MAAM,kBACL,aACD,GAAG,GACN,CAAC,mBAAmB,YAAY,CAClC;CAEA,OAAO,cAAc,YAAY,YAAY;AAC/C"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getDictionary } from "../getDictionary.mjs";
|
|
1
|
+
import { getDictionary as getDictionary$1 } from "../getDictionary.mjs";
|
|
2
2
|
import { IntlayerClientContext } from "./IntlayerProvider.mjs";
|
|
3
3
|
import { useLoadDynamic } from "./useLoadDynamic.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveInterpreterLocale } from "@intlayer/core/interpreter";
|
|
5
5
|
import { useContext } from "preact/hooks";
|
|
6
6
|
import { getPreloadedDictionary, isQualifiedDynamicLoaderMap, parseDictionarySelector, resolveDictionaryArgument, resolveQualifiedDynamicContent } from "@intlayer/core/dictionaryManipulator";
|
|
7
7
|
|
|
@@ -28,20 +28,20 @@ const useDictionaryDynamic = (dictionaryPromise, key, localeOrSelector) => {
|
|
|
28
28
|
locale: localeOrSelector,
|
|
29
29
|
selector: void 0
|
|
30
30
|
};
|
|
31
|
-
const localeTarget = selectorLocale ?? currentLocale ??
|
|
31
|
+
const localeTarget = selectorLocale ?? currentLocale ?? resolveInterpreterLocale();
|
|
32
32
|
if (process.env.INTLAYER_DICTIONARY_SELECTOR !== "false" && isQualifiedDynamicLoaderMap(dictionaryPromise)) return resolveQualifiedDynamicContent({
|
|
33
33
|
loaderMap: dictionaryPromise,
|
|
34
34
|
key: String(key),
|
|
35
35
|
locale: localeTarget,
|
|
36
36
|
selector,
|
|
37
37
|
loadChunk: (cacheKey, promise) => useLoadDynamic(cacheKey, promise),
|
|
38
|
-
transform: (dictionary) => getDictionary(dictionary, localeTarget)
|
|
38
|
+
transform: (dictionary) => getDictionary$1(dictionary, localeTarget)
|
|
39
39
|
});
|
|
40
40
|
const preloadedDictionary = getPreloadedDictionary(dictionaryPromise, localeTarget);
|
|
41
|
-
if (preloadedDictionary) return getDictionary(preloadedDictionary, localeTarget);
|
|
41
|
+
if (preloadedDictionary) return getDictionary$1(preloadedDictionary, localeTarget);
|
|
42
42
|
const plainLoaders = dictionaryPromise;
|
|
43
43
|
const dictionary = useLoadDynamic(`${String(key)}.${localeTarget}`, plainLoaders[localeTarget]?.());
|
|
44
|
-
return getDictionary(dictionary, localeTarget);
|
|
44
|
+
return getDictionary$1(dictionary, localeTarget);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.mjs","names":["loadDynamicChunk"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.mjs","names":["loadDynamicChunk","getDictionary"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import {\n getPreloadedDictionary,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveDictionaryArgument,\n resolveQualifiedDynamicContent,\n} from '@intlayer/core/dictionaryManipulator';\nimport { resolveInterpreterLocale } from '@intlayer/core/interpreter';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext } from 'preact/hooks';\nimport { getDictionary } from '../getDictionary';\nimport { IntlayerClientContext } from './IntlayerProvider';\n// `useLoadDynamic` is a suspender cache, not a hook — aliased to a non-hook\n// name so it can be invoked in loops / conditionally (collection chunks).\nimport { useLoadDynamic as loadDynamicChunk } from './useLoadDynamic';\n\n/**\n * Preact hook that lazily loads a dictionary and returns its content.\n *\n * The dictionary entry is either a plain dynamic loader map\n * (`locale → loader`) or a qualified one (`locale → …qualifier → loader`,\n * tagged with the qualifier dimensions). For qualified maps, only the chunk(s)\n * the selector targets are loaded.\n *\n * If the locale is not provided (directly or through the selector), the client\n * context locale is used.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n) => {\n const { locale: currentLocale, variant: contextVariant } =\n useContext(IntlayerClientContext) ?? {};\n\n const { locale: selectorLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector<LocalesValues>(\n // Layers the provider's ambient variant under the call-site argument\n // before the chunk walk, so only the targeted chunk is loaded.\n resolveDictionaryArgument({\n localeOrSelector,\n contextLocale: currentLocale,\n contextVariant,\n dictionaryKey: String(key),\n })\n )\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n\n const localeTarget =\n selectorLocale ?? currentLocale ?? resolveInterpreterLocale();\n\n if (\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryPromise)\n ) {\n return resolveQualifiedDynamicContent({\n loaderMap: dictionaryPromise,\n key: String(key),\n locale: localeTarget,\n selector,\n loadChunk: (cacheKey, promise) => loadDynamicChunk(cacheKey, promise),\n transform: (dictionary) => getDictionary(dictionary, localeTarget),\n });\n }\n\n // A build-tool plugin may have started this locale's chunk while the entry\n // point itself was evaluating, in which case the content is already here and\n // reading it must not go through the suspender — see `getPreloadedDictionary`.\n const preloadedDictionary = getPreloadedDictionary(\n dictionaryPromise,\n localeTarget\n );\n if (preloadedDictionary) {\n return getDictionary(preloadedDictionary as T, localeTarget);\n }\n\n const plainLoaders = dictionaryPromise as StrictModeLocaleMap<\n () => Promise<T>\n >;\n\n const dictionary = loadDynamicChunk<T>(\n `${String(key)}.${localeTarget}`,\n plainLoaders[localeTarget as keyof typeof plainLoaders]?.() as Promise<T>\n );\n\n return getDictionary(dictionary, localeTarget);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmCA,MAAa,wBAKX,mBAGA,KACA,qBACG;CACH,MAAM,EAAE,QAAQ,eAAe,SAAS,mBACtC,WAAW,qBAAqB,KAAK,CAAC;CAExC,MAAM,EAAE,QAAQ,gBAAgB,aAC9B,QAAQ,IAAI,iCAAiC,UACzC,wBAGE,0BAA0B;EACxB;EACA,eAAe;EACf;EACA,eAAe,OAAO,GAAG;CAC3B,CAAC,CACH,IACA;EACE,QAAQ;EACR,UAAU;CACZ;CAEN,MAAM,eACJ,kBAAkB,iBAAiB,yBAAyB;CAE9D,IACE,QAAQ,IAAI,iCAAiC,WAC7C,4BAA4B,iBAAiB,GAE7C,OAAO,+BAA+B;EACpC,WAAW;EACX,KAAK,OAAO,GAAG;EACf,QAAQ;EACR;EACA,YAAY,UAAU,YAAYA,eAAiB,UAAU,OAAO;EACpE,YAAY,eAAeC,gBAAc,YAAY,YAAY;CACnE,CAAC;CAMH,MAAM,sBAAsB,uBAC1B,mBACA,YACF;CACA,IAAI,qBACF,OAAOA,gBAAc,qBAA0B,YAAY;CAG7D,MAAM,eAAe;CAIrB,MAAM,aAAaD,eACjB,GAAG,OAAO,GAAG,EAAE,GAAG,gBAClB,aAAa,aAA0C,GAAG,CAC5D;CAEA,OAAOC,gBAAc,YAAY,YAAY;AAC/C"}
|
package/dist/esm/plugins.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { reportExposure } from "./analytics/exposureSink.mjs";
|
|
|
2
2
|
import { ContentSelector } from "./editor/ContentSelector.mjs";
|
|
3
3
|
import { renderIntlayerNode } from "./IntlayerNode.mjs";
|
|
4
4
|
import { renderPreactElement } from "./preactElement/renderPreactElement.mjs";
|
|
5
|
-
import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, isInterpolableWrapperNode, nestedPlugin, pluralPlugin, resolveInsertedSelector, selectPlugin, transformInterpolableNode, translationPlugin } from "@intlayer/core/interpreter";
|
|
5
|
+
import { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, isInterpolableWrapperNode, nestedPlugin, pluralPlugin, resolveInsertedSelector, resolveInterpreterLocale, selectPlugin, transformInterpolableNode, translationPlugin } from "@intlayer/core/interpreter";
|
|
6
6
|
import { editor, internationalization } from "@intlayer/config/built";
|
|
7
7
|
import { getMarkdownMetadata } from "@intlayer/core/markdown";
|
|
8
8
|
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
@@ -85,7 +85,8 @@ const splitAndJoinInsertion = (template, values) => {
|
|
|
85
85
|
let match = regex.exec(template);
|
|
86
86
|
while (match !== null) {
|
|
87
87
|
if (match.index > lastIndex) parts.push(template.substring(lastIndex, match.index));
|
|
88
|
-
const
|
|
88
|
+
const key = match[1]?.trim();
|
|
89
|
+
const value = key && values[key];
|
|
89
90
|
if (value !== void 0 && value !== null) parts.push(typeof value === "number" ? String(value) : value);
|
|
90
91
|
lastIndex = match.index + match[0].length;
|
|
91
92
|
match = regex.exec(template);
|
|
@@ -237,15 +238,16 @@ const pluginsCache = /* @__PURE__ */ new Map();
|
|
|
237
238
|
* This function is used by both getIntlayer and getDictionary to ensure consistent plugin configuration.
|
|
238
239
|
*/
|
|
239
240
|
const getPlugins = (locale, fallback = true) => {
|
|
240
|
-
const
|
|
241
|
+
const currentLocale = resolveInterpreterLocale(locale);
|
|
242
|
+
const cacheKey = `${currentLocale}_${fallback}`;
|
|
241
243
|
if (pluginsCache.has(cacheKey)) return pluginsCache.get(cacheKey);
|
|
242
244
|
const enabledPlugins = [
|
|
243
245
|
intlayerNodePlugins,
|
|
244
|
-
translationPlugin(
|
|
246
|
+
translationPlugin(currentLocale, fallback ? internationalization.defaultLocale : void 0),
|
|
245
247
|
enumerationPlugin,
|
|
246
|
-
pluralPlugin(
|
|
248
|
+
pluralPlugin(currentLocale),
|
|
247
249
|
conditionPlugin,
|
|
248
|
-
nestedPlugin(
|
|
250
|
+
nestedPlugin(currentLocale),
|
|
249
251
|
filePlugin,
|
|
250
252
|
genderPlugin,
|
|
251
253
|
selectPlugin,
|
package/dist/esm/plugins.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.mjs","names":[],"sources":["../../src/plugins.tsx"],"sourcesContent":["import { editor, internationalization } from '@intlayer/config/built';\nimport {\n conditionPlugin,\n type DeepTransformContent as DeepTransformContentCore,\n enumerationPlugin,\n fallbackPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState as IInterpreterPluginStateCore,\n isInterpolableWrapperNode,\n nestedPlugin,\n type Plugins,\n pluralPlugin,\n resolveInsertedSelector,\n selectPlugin,\n transformInterpolableNode,\n translationPlugin,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { Fragment, type FunctionComponent, h, type VNode } from 'preact';\nimport { lazy } from 'preact/compat';\nimport { reportExposure } from './analytics/exposureSink';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then((m) => ({\n MarkdownRendererPlugin: m.MarkdownRendererPlugin,\n MarkdownMetadataRenderer: m.MarkdownMetadataRenderer,\n }))\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRenderer').then((m) => m.HTMLRenderer)\n : null;\n\n// These preloads are read later by `useLoadDynamic`, so the rejection must stay\n// on the promise: a `.catch()` chained into it would resolve with `undefined`\n// and be mistaken for a loaded module. Handle it on the side instead, so an\n// aborted chunk load never escapes as an unhandled rejection.\nmarkdownRendererModulePromise?.catch(() => {});\nhtmlRendererModulePromise?.catch(() => {});\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (_node, props) => {\n // Node-level analytics: record which content is resolved for display.\n // No-op (and dead-code-eliminated) when analytics is disabled.\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: props.dictionaryKey,\n keyPath: props.keyPath,\n locale: props.locale,\n nodeType: 'text',\n });\n }\n\n // Props are only forwarded to the editor selector: copying them for every\n // leaf would cost an allocation per rendered string\n if (process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled) {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n return renderIntlayerNode({\n value: rest.children,\n children: (\n <ContentSelector {...rest} key={rest.children}>\n {rest.children}\n </ContentSelector>\n ),\n });\n }\n\n return renderIntlayerNode({\n value: props.children,\n children: props.children,\n });\n },\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_PREACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'preact-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderPreactElement(node)}\n </ContentSelector>\n ) : (\n renderPreactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I; // Accept strings OR nested nodes like enumerations\n fields: readonly (infer F)[]; // Infer the exact string literals in the array\n}\n ? <V extends { [K in Extract<F, string>]: string | number | VNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : DeepTransformContent<I, L> // Delegate nested nodes (like enumerations) back to the core\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1].trim();\n const value = values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_INSERTION === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{ … }}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n // VNodes cannot be injected into a raw markup string, so string\n // interpolation (not `splitAndJoinInsertion`) is used here.\n if (isInterpolableWrapperNode(node)) {\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]:\n | string\n | number\n | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n const result = deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n\n return resolveInsertedSelector(children, result);\n },\n };\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/**\n * Code-split renderers are loaded with `lazy` rather than a hand-rolled\n * suspender. A node that suspended on the hand-rolled one never recovered once\n * the chunk landed, so every markdown node present on the first paint stayed\n * blank forever; `lazy` implements the suspend/retry handshake correctly.\n */\nconst MarkdownSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownRendererPlugin as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\nconst MarkdownMetadataSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownMetadataRenderer as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node) ?? {};\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n use: render,\n },\n });\n\n return render() as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.MARKDOWN,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.MARKDOWN,\n },\n ];\n\n const children = node[NodeTypes.MARKDOWN];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\nconst HTMLSuspenseRenderer = lazy(() =>\n htmlRendererModulePromise!.then((HTMLRenderer) => ({\n default: HTMLRenderer as FunctionComponent<Record<string, any>>,\n }))\n);\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_HTML === 'false'\n ? fallbackPlugin\n : {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const _tags = node.tags ?? [];\n // `children` is dropped deliberately: `HTMLRenderer` resolves its\n // content as `children || html`, so forwarding the raw node here would\n // shadow the HTML string and render nothing.\n const { plugins, children: _nodeChildren, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled\n ? h(\n ContentSelector,\n { ...rest },\n h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n })\n )\n : h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n }),\n additionalProps: { use: render },\n }) as any;\n\n return render();\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, S, L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T, S, L>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n\nconst pluginsCache = new Map<string, Plugins[]>();\n\n/**\n * Get the plugins array for Preact content transformation.\n * This function is used by both getIntlayer and getDictionary to ensure consistent plugin configuration.\n */\nexport const getPlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] => {\n const currentLocale = locale ?? internationalization.defaultLocale;\n const cacheKey = `${currentLocale}_${fallback}`;\n\n if (pluginsCache.has(cacheKey)) {\n return pluginsCache.get(cacheKey)!;\n }\n\n const plugins = [\n // First: most nodes are plain strings, which every other plugin rejects\n intlayerNodePlugins,\n translationPlugin(\n locale ?? internationalization.defaultLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n pluralPlugin(locale ?? internationalization.defaultLocale),\n conditionPlugin,\n nestedPlugin(locale ?? internationalization.defaultLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n preactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n // Plugins disabled at build time never match: skip them on every node\n const enabledPlugins = plugins.filter((plugin) => plugin !== fallbackPlugin);\n\n pluginsCache.set(cacheKey, enabledPlugins);\n\n return enabledPlugins;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.mjs","names":[],"sources":["../../src/plugins.tsx"],"sourcesContent":["import { editor, internationalization } from '@intlayer/config/built';\nimport {\n conditionPlugin,\n type DeepTransformContent as DeepTransformContentCore,\n enumerationPlugin,\n fallbackPlugin,\n filePlugin,\n genderPlugin,\n type IInterpreterPluginState as IInterpreterPluginStateCore,\n isInterpolableWrapperNode,\n nestedPlugin,\n type Plugins,\n pluralPlugin,\n resolveInsertedSelector,\n resolveInterpreterLocale,\n selectPlugin,\n transformInterpolableNode,\n translationPlugin,\n} from '@intlayer/core/interpreter';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\nimport type {\n HTMLContent,\n InsertionContent,\n MarkdownContent,\n} from '@intlayer/core/transpiler';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport type {\n DeclaredLocales,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport type { NodeType } from '@intlayer/types/nodeType';\nimport * as NodeTypes from '@intlayer/types/nodeType';\nimport { Fragment, type FunctionComponent, h, type VNode } from 'preact';\nimport { lazy } from 'preact/compat';\nimport { reportExposure } from './analytics/exposureSink';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/types';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderPreactElement } from './preactElement/renderPreactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then((m) => ({\n MarkdownRendererPlugin: m.MarkdownRendererPlugin,\n MarkdownMetadataRenderer: m.MarkdownMetadataRenderer,\n }))\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRenderer').then((m) => m.HTMLRenderer)\n : null;\n\n// These preloads are read later by `useLoadDynamic`, so the rejection must stay\n// on the promise: a `.catch()` chained into it would resolve with `undefined`\n// and be mistaken for a loaded module. Handle it on the side instead, so an\n// aborted chunk load never escapes as an unhandled rejection.\nmarkdownRendererModulePromise?.catch(() => {});\nhtmlRendererModulePromise?.catch(() => {});\n\n/** ---------------------------------------------\n * INTLAYER NODE PLUGIN\n * --------------------------------------------- */\n\nexport type IntlayerNodeCond<T> = T extends number | string\n ? IntlayerNode<T>\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const intlayerNodePlugins: Plugins = {\n id: 'intlayer-node-plugin',\n canHandle: (node) =>\n typeof node === 'bigint' ||\n typeof node === 'string' ||\n typeof node === 'number',\n transform: (_node, props) => {\n // Node-level analytics: record which content is resolved for display.\n // No-op (and dead-code-eliminated) when analytics is disabled.\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: props.dictionaryKey,\n keyPath: props.keyPath,\n locale: props.locale,\n nodeType: 'text',\n });\n }\n\n // Props are only forwarded to the editor selector: copying them for every\n // leaf would cost an allocation per rendered string\n if (process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled) {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n return renderIntlayerNode({\n value: rest.children,\n children: (\n <ContentSelector {...rest} key={rest.children}>\n {rest.children}\n </ContentSelector>\n ),\n });\n }\n\n return renderIntlayerNode({\n value: props.children,\n children: props.children,\n });\n },\n};\n\n/** ---------------------------------------------\n * PREACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type PreactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? VNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const preactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_PREACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'preact-node-plugin',\n canHandle: (node) =>\n typeof node === 'object' &&\n typeof node.props !== 'undefined' &&\n typeof node.key !== 'undefined',\n\n transform: (\n node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\n if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {\n reportExposure({\n dictionaryKey: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'preact-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[preact-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderPreactElement(node)}\n </ContentSelector>\n ) : (\n renderPreactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T, _S, L extends LocalesValues> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I; // Accept strings OR nested nodes like enumerations\n fields: readonly (infer F)[]; // Infer the exact string literals in the array\n}\n ? <V extends { [K in Extract<F, string>]: string | number | VNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<VNode>\n : DeepTransformContent<I, L> // Delegate nested nodes (like enumerations) back to the core\n : never;\n\n/**\n * Check if a value is a Preact VNode\n */\nconst isVNode = (value: any): value is VNode => {\n return (\n value !== null &&\n value !== undefined &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n );\n};\n\n/**\n * Split insertion string and join with Preact VNodes\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | VNode>\n): VNode => {\n // Check if any value is a VNode\n const hasVNode = Object.values(values).some(isVNode);\n\n if (!hasVNode) {\n // Simple string replacement\n return template.replace(/\\{\\{\\s*(.*?)\\s*\\}\\}/g, (_, key) => {\n const trimmedKey = key.trim();\n return (values[trimmedKey] ?? '').toString();\n }) as any;\n }\n\n // Split the template by placeholders while keeping the structure\n const parts: (string | VNode)[] = [];\n let lastIndex = 0;\n const regex = /\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n let match: RegExpExecArray | null = regex.exec(template);\n\n while (match !== null) {\n // Add text before the placeholder\n if (match.index > lastIndex) {\n parts.push(template.substring(lastIndex, match.index));\n }\n\n // Add the replaced value\n const key = match[1]?.trim();\n const value = key && values[key];\n if (value !== undefined && value !== null) {\n parts.push(typeof value === 'number' ? String(value) : value);\n }\n\n lastIndex = match.index + match[0].length;\n match = regex.exec(template);\n }\n\n // Add remaining text\n if (lastIndex < template.length) {\n parts.push(template.substring(lastIndex));\n }\n\n // Return as Fragment\n return h(\n Fragment,\n null,\n ...parts.map((part, index) => h(Fragment, { key: index }, part))\n );\n};\n\n/** Insertion plugin for Preact. Handles component/node insertion. */\nexport const insertionPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_INSERTION === 'false'\n ? fallbackPlugin\n : {\n id: 'insertion-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.INSERTION,\n transform: (node: InsertionContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.INSERTION,\n },\n ];\n\n const children = node[NodeTypes.INSERTION];\n\n /** Insertion string plugin. Replaces string node with a component that render the insertion. */\n const insertionStringPlugin: Plugins = {\n id: 'insertion-string-plugin',\n canHandle: (node) =>\n typeof node === 'string' || isInterpolableWrapperNode(node),\n transform: (node, subProps, deepTransformNode) => {\n // `html()`/`markdown()` nodes carry their `{{ … }}` placeholders\n // inside a raw string. Interpolate into that string, then re-run\n // the transform so the html/markdown renderer applies afterwards.\n // VNodes cannot be injected into a raw markup string, so string\n // interpolation (not `splitAndJoinInsertion`) is used here.\n if (isInterpolableWrapperNode(node)) {\n return (\n values: {\n [K in InsertionContent['fields'][number]]: string | number;\n }\n ) =>\n transformInterpolableNode(\n node,\n values,\n subProps,\n props.plugins,\n deepTransformNode\n );\n }\n\n const transformedResult = deepTransformNode(node, {\n ...subProps,\n children: node,\n plugins: [\n ...(props.plugins ?? ([] as Plugins[])).filter(\n (plugin) => plugin.id !== 'intlayer-node-plugin'\n ),\n ],\n });\n\n return (\n values: {\n [K in InsertionContent['fields'][number]]:\n | string\n | number\n | VNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result as any,\n });\n };\n },\n };\n\n const result = deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [insertionStringPlugin, ...(props.plugins ?? [])],\n });\n\n return resolveInsertedSelector(children, result);\n },\n };\n\n/**\n * MARKDOWN PLUGIN\n */\n\nexport type MarkdownStringCond<T> = T extends string\n ? IntlayerNode<\n string,\n {\n metadata: DeepTransformContent<string>;\n use: (components?: HTMLComponents<'permissive', {}>) => VNode;\n }\n >\n : never;\n\n/**\n * Code-split renderers are loaded with `lazy` rather than a hand-rolled\n * suspender. A node that suspended on the hand-rolled one never recovered once\n * the chunk landed, so every markdown node present on the first paint stayed\n * blank forever; `lazy` implements the suspend/retry handshake correctly.\n */\nconst MarkdownSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownRendererPlugin as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\nconst MarkdownMetadataSuspenseRenderer = lazy(() =>\n markdownRendererModulePromise!.then((modules) => ({\n default: modules.MarkdownMetadataRenderer as FunctionComponent<\n Record<string, any>\n >,\n }))\n);\n\n/** Markdown string plugin. Replaces string node with a component that render the markdown. */\nexport const markdownStringPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-string-plugin',\n canHandle: (node) => typeof node === 'string',\n transform: (node: string, props, deepTransformNode) => {\n const {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n } = props;\n\n const metadata = getMarkdownMetadata(node) ?? {};\n\n const metadataPlugins: Plugins = {\n id: 'markdown-metadata-plugin',\n canHandle: (metadataNode) =>\n typeof metadataNode === 'string' ||\n typeof metadataNode === 'number' ||\n typeof metadataNode === 'boolean' ||\n !metadataNode,\n transform: (metadataNode, props) =>\n renderIntlayerNode({\n ...props,\n value: metadataNode,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownMetadataSuspenseRenderer\n {...rest}\n metadataKeyPath={props.keyPath}\n >\n {node}\n </MarkdownMetadataSuspenseRenderer>\n ),\n }),\n };\n\n // Transform metadata while keeping the same structure\n const metadataNodes = deepTransformNode(metadata, {\n plugins: [metadataPlugins],\n dictionaryKey: rest.dictionaryKey,\n keyPath: [],\n });\n\n const render = (components?: any) =>\n renderIntlayerNode({\n ...props,\n value: node,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n </ContentSelector>\n ) : (\n <MarkdownSuspenseRenderer {...rest} components={components}>\n {node}\n </MarkdownSuspenseRenderer>\n ),\n additionalProps: {\n metadata: metadataNodes,\n use: render,\n },\n });\n\n return render() as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer _M;\n metadata?: infer U;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => VNode;\n metadata: DeepTransformContent<U>;\n }\n : never;\n\nexport const markdownPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN === 'false'\n ? fallbackPlugin\n : {\n id: 'markdown-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.MARKDOWN,\n transform: (node: MarkdownContent, props, deepTransformNode) => {\n const newKeyPath: KeyPath[] = [\n ...props.keyPath,\n {\n type: NodeTypes.MARKDOWN,\n },\n ];\n\n const children = node[NodeTypes.MARKDOWN];\n\n return deepTransformNode(children, {\n ...props,\n children,\n keyPath: newKeyPath,\n plugins: [markdownStringPlugin, ...(props.plugins ?? [])],\n });\n },\n };\n\n/** ---------------------------------------------\n * HTML PLUGIN\n * --------------------------------------------- */\n\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? {\n use: (components?: HTMLComponents<'permissive', U>) => IntlayerNode<I>;\n }\n : never;\n\nconst HTMLSuspenseRenderer = lazy(() =>\n htmlRendererModulePromise!.then((HTMLRenderer) => ({\n default: HTMLRenderer as FunctionComponent<Record<string, any>>,\n }))\n);\n\n/** HTML plugin. Replaces node with a function that takes components => VNode. */\nexport const htmlPlugin: Plugins =\n process.env.INTLAYER_NODE_TYPE_HTML === 'false'\n ? fallbackPlugin\n : {\n id: 'html-plugin',\n canHandle: (node) =>\n typeof node === 'object' && node?.nodeType === NodeTypes.HTML,\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const _tags = node.tags ?? [];\n // `children` is dropped deliberately: `HTMLRenderer` resolves its\n // content as `children || html`, so forwarding the raw node here would\n // shadow the HTML string and render nothing.\n const { plugins, children: _nodeChildren, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): VNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled\n ? h(\n ContentSelector,\n { ...rest },\n h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n })\n )\n : h(HTMLSuspenseRenderer, {\n ...rest,\n html,\n components: userComponents,\n }),\n additionalProps: { use: render },\n }) as any;\n\n return render();\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport interface IInterpreterPluginPreact<T, S, L extends LocalesValues> {\n preactNode: PreactNodeCond<T>;\n preactIntlayerNode: IntlayerNodeCond<T>;\n preactInsertion: InsertionCond<T, S, L>;\n preactMarkdown: MarkdownCond<T>;\n preactHtml: HTMLPluginCond<T>;\n}\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `preact-intlayer` plugins will override the types of `intlayer` functions.\n */\nexport type IInterpreterPluginState = Omit<\n IInterpreterPluginStateCore,\n 'insertion' // Remove insertion type from core package\n> & {\n preactNode: true;\n preactIntlayerNode: true;\n preactInsertion: true;\n preactMarkdown: true;\n preactHtml: true;\n};\n\nexport type DeepTransformContent<\n T,\n L extends LocalesValues = DeclaredLocales,\n> = DeepTransformContentCore<T, IInterpreterPluginState, L>;\n\nconst pluginsCache = new Map<string, Plugins[]>();\n\n/**\n * Get the plugins array for Preact content transformation.\n * This function is used by both getIntlayer and getDictionary to ensure consistent plugin configuration.\n */\nexport const getPlugins = (\n locale?: LocalesValues,\n fallback: boolean = true\n): Plugins[] => {\n const currentLocale = resolveInterpreterLocale(locale);\n const cacheKey = `${currentLocale}_${fallback}`;\n\n if (pluginsCache.has(cacheKey)) {\n return pluginsCache.get(cacheKey)!;\n }\n\n const plugins = [\n // First: most nodes are plain strings, which every other plugin rejects\n intlayerNodePlugins,\n translationPlugin(\n currentLocale,\n fallback ? internationalization.defaultLocale : undefined\n ),\n enumerationPlugin,\n pluralPlugin(currentLocale),\n conditionPlugin,\n nestedPlugin(currentLocale),\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n preactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n // Plugins disabled at build time never match: skip them on every node\n const enabledPlugins = plugins.filter((plugin) => plugin !== fallbackPlugin);\n\n pluginsCache.set(cacheKey, enabledPlugins);\n\n return enabledPlugins;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.ts","names":[],"sources":["../../src/plugins.tsx"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","names":[],"sources":["../../src/plugins.tsx"],"mappings":";;;;;;;;;;;YAgEY,iBAAiB,KAAK,4BAC9B,aAAa;;qBAIJ,qBAAqB;;;;YA+CtB,eAAe,KAAK;EAC9B;EACA;IAEE;;qBAIS,mBAAmB;;;;YA8CpB,cAAc,GAAG,IAAI,UAAU,iBAAiB;EAC1D,UAAU;GACT,UAAU,kBAAkB;EAC7B,wBAAwB;KAErB,aAAa,KAAK,QAAQ,+BAA+B,UACxD,QAAQ,MACL,mBACD,QAAQ,6BACN,uBACA,aAAa,SACf,qBAAqB,GAAG;;qBAuEnB,iBAAiB;;;;YAuFlB,mBAAmB,KAAK,mBAChC;EAGI,UAAU;EACV,MAAM,aAAa,qCAAqC;;;qBA4BnD,sBAAsB;YAiFvB,aAAa,KAAK;EAC5B,UAAU;GACT,UAAU,iBAAiB;EAC5B,iBAAiB;EACjB,aAAa;;EAGT,MAAM,aAAa,6BAA6B,OAAO;EACvD,UAAU,qBAAqB;;qBAIxB,gBAAgB;;;;YA8BjB,eAAe,KAAK;EAC9B,UAAU;GACT,UAAU,aAAa;EACxB,aAAa;;EAGT,MAAM,aAAa,6BAA6B,OAAO,aAAa;;;qBAW7D,YAAY;;;;iBAgDR,yBAAyB,GAAG,GAAG,UAAU;EACxD,YAAY,eAAe;EAC3B,oBAAoB,iBAAiB;EACrC,iBAAiB,cAAc,GAAG,GAAG;EACrC,gBAAgB,aAAa;EAC7B,YAAY,eAAe;;;;;;;YAQjB,0BAA0B,KACpC;EAGA;EACA;EACA;EACA;EACA;;YAGU,qBACV,GACA,UAAU,gBAAgB,mBACxB,uBAAyB,GAAG,yBAAyB;;;;;qBAQ5C,aAAU,SACZ,eAAa,uBAErB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "preact-intlayer",
|
|
3
|
-
"version": "9.5.
|
|
3
|
+
"version": "9.5.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Easily internationalize i18n your Preact applications with type-safe multilingual content management.",
|
|
6
6
|
"keywords": [
|
|
@@ -101,12 +101,12 @@
|
|
|
101
101
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
102
102
|
},
|
|
103
103
|
"dependencies": {
|
|
104
|
-
"@intlayer/api": "9.5.
|
|
105
|
-
"@intlayer/config": "9.5.
|
|
106
|
-
"@intlayer/core": "9.5.
|
|
107
|
-
"@intlayer/editor": "9.5.
|
|
108
|
-
"@intlayer/engine": "9.5.
|
|
109
|
-
"@intlayer/types": "9.5.
|
|
104
|
+
"@intlayer/api": "9.5.12",
|
|
105
|
+
"@intlayer/config": "9.5.12",
|
|
106
|
+
"@intlayer/core": "9.5.12",
|
|
107
|
+
"@intlayer/editor": "9.5.12",
|
|
108
|
+
"@intlayer/engine": "9.5.12",
|
|
109
|
+
"@intlayer/types": "9.5.12"
|
|
110
110
|
},
|
|
111
111
|
"devDependencies": {
|
|
112
112
|
"@types/node": "^22",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"preact": ">=8.0.0"
|
|
124
124
|
},
|
|
125
125
|
"optionalDependencies": {
|
|
126
|
-
"@intlayer/analytics": "9.5.
|
|
126
|
+
"@intlayer/analytics": "9.5.12"
|
|
127
127
|
},
|
|
128
128
|
"engines": {
|
|
129
129
|
"node": ">=14.18"
|