react-intlayer 9.3.1 → 9.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/editor/useEditor.cjs +2 -2
- package/dist/cjs/editor/useEditor.cjs.map +1 -1
- package/dist/cjs/plugins.cjs +2 -0
- package/dist/cjs/plugins.cjs.map +1 -1
- package/dist/esm/editor/useEditor.mjs +2 -2
- package/dist/esm/editor/useEditor.mjs.map +1 -1
- package/dist/esm/plugins.mjs +2 -0
- package/dist/esm/plugins.mjs.map +1 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -20,12 +20,12 @@ const useEditor = () => {
|
|
|
20
20
|
const manager = initEditorClient();
|
|
21
21
|
managerRef.current = manager;
|
|
22
22
|
if (locale) manager.currentLocale.set(locale);
|
|
23
|
-
});
|
|
23
|
+
}).catch(() => {});
|
|
24
24
|
return () => {
|
|
25
25
|
managerRef.current = null;
|
|
26
26
|
import("@intlayer/editor").then(({ stopEditorClient }) => {
|
|
27
27
|
stopEditorClient();
|
|
28
|
-
});
|
|
28
|
+
}).catch(() => {});
|
|
29
29
|
};
|
|
30
30
|
}, []);
|
|
31
31
|
(0, react.useEffect)(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditor.cjs","names":["useContext","IntlayerClientContext","useRef","isEnabled"],"sources":["../../../src/editor/useEditor.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorStateManager } from '@intlayer/editor';\nimport { isEnabled } from '@intlayer/editor/isEnabled';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\n\n/**\n * Initializes the Intlayer editor client singleton when the editor is enabled.\n * Syncs the current locale from the Intlayer context into the editor manager so\n * the editor always knows which locale the app is displaying.\n */\nexport const useEditor = () => {\n const { locale } = useContext(IntlayerClientContext) ?? {};\n const managerRef = useRef<EditorStateManager | null>(null);\n\n useEffect(() => {\n if (process.env.INTLAYER_EDITOR_ENABLED === 'false' || !isEnabled) return;\n\n import('@intlayer/editor').then(({ initEditorClient }) => {\n
|
|
1
|
+
{"version":3,"file":"useEditor.cjs","names":["useContext","IntlayerClientContext","useRef","isEnabled"],"sources":["../../../src/editor/useEditor.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorStateManager } from '@intlayer/editor';\nimport { isEnabled } from '@intlayer/editor/isEnabled';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\n\n/**\n * Initializes the Intlayer editor client singleton when the editor is enabled.\n * Syncs the current locale from the Intlayer context into the editor manager so\n * the editor always knows which locale the app is displaying.\n */\nexport const useEditor = () => {\n const { locale } = useContext(IntlayerClientContext) ?? {};\n const managerRef = useRef<EditorStateManager | null>(null);\n\n useEffect(() => {\n if (process.env.INTLAYER_EDITOR_ENABLED === 'false' || !isEnabled) return;\n\n import('@intlayer/editor')\n .then(({ initEditorClient }) => {\n const manager = initEditorClient();\n managerRef.current = manager;\n\n if (locale) manager.currentLocale.set(locale as Locale);\n })\n .catch(() => {});\n\n return () => {\n managerRef.current = null;\n import('@intlayer/editor')\n .then(({ stopEditorClient }) => {\n stopEditorClient();\n })\n .catch(() => {});\n };\n }, []);\n\n useEffect(() => {\n if (!locale || !managerRef.current) return;\n\n managerRef.current.currentLocale.set(locale as Locale);\n }, [locale]);\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,kBAAkB;CAC7B,MAAM,EAAE,eAAWA,kBAAWC,qDAAqB,KAAK,CAAC;CACzD,MAAM,iBAAaC,cAAkC,IAAI;CAEzD,2BAAgB;EACd,IAAI,QAAQ,IAAI,4BAA4B,WAAW,CAACC,sCAAW;EAEnE,OAAO,mBAAmB,CACvB,MAAM,EAAE,uBAAuB;GAC9B,MAAM,UAAU,iBAAiB;GACjC,WAAW,UAAU;GAErB,IAAI,QAAQ,QAAQ,cAAc,IAAI,MAAgB;EACxD,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EAEjB,aAAa;GACX,WAAW,UAAU;GACrB,OAAO,mBAAmB,CACvB,MAAM,EAAE,uBAAuB;IAC9B,iBAAiB;GACnB,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EACnB;CACF,GAAG,CAAC,CAAC;CAEL,2BAAgB;EACd,IAAI,CAAC,UAAU,CAAC,WAAW,SAAS;EAEpC,WAAW,QAAQ,cAAc,IAAI,MAAgB;CACvD,GAAG,CAAC,MAAM,CAAC;AACb"}
|
package/dist/cjs/plugins.cjs
CHANGED
|
@@ -16,6 +16,8 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
16
16
|
//#region src/plugins.tsx
|
|
17
17
|
const markdownRendererModulePromise = process.env.INTLAYER_NODE_TYPE_MARKDOWN !== "false" ? Promise.resolve().then(() => require("./markdown/MarkdownRendererPlugin.cjs")).then((m) => m.MarkdownRendererPlugin) : null;
|
|
18
18
|
const htmlRendererModulePromise = process.env.INTLAYER_NODE_TYPE_HTML !== "false" ? Promise.resolve().then(() => require("./html/HTMLRendererPlugin.cjs")).then((m) => m.HTMLRendererPlugin) : null;
|
|
19
|
+
markdownRendererModulePromise?.catch(() => {});
|
|
20
|
+
htmlRendererModulePromise?.catch(() => {});
|
|
19
21
|
/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
|
|
20
22
|
const intlayerNodePlugins = {
|
|
21
23
|
id: "intlayer-node-plugin",
|
package/dist/cjs/plugins.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.cjs","names":["renderIntlayerNode","editor","ContentSelector","fallbackPlugin","renderReactElement","splitInsertionTemplate","createElement","Fragment","NodeTypes","isInterpolableWrapperNode","transformInterpolableNode","func","useLoadDynamic","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 selectPlugin,\n splitInsertionTemplate,\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 {\n createElement,\n type FC,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { reportExposure } from './analytics/exposureSink';\nimport { useLoadDynamic } from './client/useLoadDynamic';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/HTMLComponentTypes';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderReactElement } from './reactElement/renderReactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then(\n (m) => m.MarkdownRendererPlugin\n )\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRendererPlugin').then((m) => m.HTMLRendererPlugin)\n : null;\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: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\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: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'text',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: rest.children,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled ? (\n <ContentSelector {...rest}>{rest.children}</ContentSelector>\n ) : (\n rest.children\n ),\n });\n },\n};\n\n/** ---------------------------------------------\n * REACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type ReactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? ReactNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const reactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_REACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'react-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: 'react-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[react-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderReactElement(node)}\n </ContentSelector>\n ) : (\n renderReactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: ReactNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<ReactNode>\n : DeepTransformContent<I>\n : never;\n\n/**\n * Split insertion string and join with React nodes using shared core logic\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | ReactNode>\n): ReactNode => {\n const result = splitInsertionTemplate(template, values);\n\n if (result.isSimple) {\n // Simple string replacement\n return result.parts as string;\n }\n\n // Return as Fragment with proper keys\n return createElement(\n Fragment,\n null,\n ...(result.parts as any[]).map((part, index) =>\n createElement(Fragment, { key: index }, part)\n )\n );\n};\n\n/** Insertion plugin for React. 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 // React nodes cannot be injected into a raw markup string, so\n // string 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 | ReactNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result,\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 if (\n typeof children === 'object' &&\n children !== null &&\n 'nodeType' in children &&\n [NodeTypes.ENUMERATION, NodeTypes.CONDITION].includes(\n children.nodeType as\n | typeof NodeTypes.ENUMERATION\n | typeof NodeTypes.CONDITION\n )\n ) {\n return (values: any) => (arg: any) => {\n const func = result as Function;\n const inner = func(arg);\n\n if (typeof inner === 'function') {\n return inner(values);\n }\n return inner;\n };\n }\n\n return 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', {}>) => ReactNode;\n }\n >\n : never;\n\nconst MarkdownSuspenseRenderer: FC<Record<string, any>> = ({\n children,\n ...props\n}) => {\n const MarkdownRendererPlugin = useLoadDynamic(\n 'markdown-renderer-plugin',\n markdownRendererModulePromise!\n );\n return createElement(MarkdownRendererPlugin as any, { ...props, children });\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}>{node}</ContentSelector>\n ) : (\n node\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?: HTMLComponents) =>\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 },\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return node;\n if (prop === Symbol.toPrimitive) return () => node;\n if (prop === 'toString') return () => node;\n if (prop === 'valueOf') return () => node;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(node);\n }\n if (prop === 'metadata') return metadataNodes;\n if (prop === 'use')\n return (components?: HTMLComponents) => render(components);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer M;\n tags?: infer U;\n metadata?: infer V;\n}\n ? IntlayerNode<\n M,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n metadata: DeepTransformContent<V>;\n }\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\n/**\n * HTML conditional type that enforces:\n * - All components (Standard or Custom) are OPTIONAL in the `use()` method.\n * - Custom components props are strictly inferred from the dictionary definition.\n *\n * This ensures type safety:\n * - `html('<div>Hello <CustomComponent /></div>').use({ CustomComponent: ... })` - optional but typed\n */\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? IntlayerNode<\n I,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n }\n >\n : never;\n\nconst HTMLSuspenseRenderer: FC<Record<string, any>> = (props) => {\n const HTMLRendererPlugin = useLoadDynamic(\n 'html-renderer-plugin',\n htmlRendererModulePromise!\n );\n return createElement(HTMLRendererPlugin as any, props);\n};\n\n/** HTML plugin. Replaces node with a function that takes components => ReactNode. */\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\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): ReactNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n </ContentSelector>\n ) : (\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n ),\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return html;\n if (prop === Symbol.toPrimitive) return () => html;\n if (prop === 'toString') return () => html;\n if (prop === 'valueOf') return () => html;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(html);\n }\n if (prop === 'use')\n return (userComponents?: HTMLComponents) =>\n render(userComponents);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport type IInterpreterPluginReact<T, _S, _L extends LocalesValues> = {\n reactNode: ReactNodeCond<T>;\n reactIntlayerNode: IntlayerNodeCond<T>;\n reactInsertion: InsertionCond<T>;\n reactMarkdown: MarkdownCond<T>;\n reactHtml: HTMLPluginCond<T>;\n};\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `react-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 reactNode: true;\n reactIntlayerNode: true;\n reactMarkdown: true;\n reactHtml: true;\n reactInsertion: 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 React 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 // Env var allows the bundler to to remove the plugin if not used to make the bundle smaller\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\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n intlayerNodePlugins,\n reactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n pluginsCache.set(cacheKey, plugins);\n\n return plugins;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.cjs","names":["renderIntlayerNode","editor","ContentSelector","fallbackPlugin","renderReactElement","splitInsertionTemplate","createElement","Fragment","NodeTypes","isInterpolableWrapperNode","transformInterpolableNode","func","useLoadDynamic","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 selectPlugin,\n splitInsertionTemplate,\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 {\n createElement,\n type FC,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { reportExposure } from './analytics/exposureSink';\nimport { useLoadDynamic } from './client/useLoadDynamic';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/HTMLComponentTypes';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderReactElement } from './reactElement/renderReactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then(\n (m) => m.MarkdownRendererPlugin\n )\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRendererPlugin').then((m) => m.HTMLRendererPlugin)\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: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\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: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'text',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: rest.children,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled ? (\n <ContentSelector {...rest}>{rest.children}</ContentSelector>\n ) : (\n rest.children\n ),\n });\n },\n};\n\n/** ---------------------------------------------\n * REACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type ReactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? ReactNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const reactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_REACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'react-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: 'react-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[react-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderReactElement(node)}\n </ContentSelector>\n ) : (\n renderReactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: ReactNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<ReactNode>\n : DeepTransformContent<I>\n : never;\n\n/**\n * Split insertion string and join with React nodes using shared core logic\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | ReactNode>\n): ReactNode => {\n const result = splitInsertionTemplate(template, values);\n\n if (result.isSimple) {\n // Simple string replacement\n return result.parts as string;\n }\n\n // Return as Fragment with proper keys\n return createElement(\n Fragment,\n null,\n ...(result.parts as any[]).map((part, index) =>\n createElement(Fragment, { key: index }, part)\n )\n );\n};\n\n/** Insertion plugin for React. 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 // React nodes cannot be injected into a raw markup string, so\n // string 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 | ReactNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result,\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 if (\n typeof children === 'object' &&\n children !== null &&\n 'nodeType' in children &&\n [NodeTypes.ENUMERATION, NodeTypes.CONDITION].includes(\n children.nodeType as\n | typeof NodeTypes.ENUMERATION\n | typeof NodeTypes.CONDITION\n )\n ) {\n return (values: any) => (arg: any) => {\n const func = result as Function;\n const inner = func(arg);\n\n if (typeof inner === 'function') {\n return inner(values);\n }\n return inner;\n };\n }\n\n return 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', {}>) => ReactNode;\n }\n >\n : never;\n\nconst MarkdownSuspenseRenderer: FC<Record<string, any>> = ({\n children,\n ...props\n}) => {\n const MarkdownRendererPlugin = useLoadDynamic(\n 'markdown-renderer-plugin',\n markdownRendererModulePromise!\n );\n return createElement(MarkdownRendererPlugin as any, { ...props, children });\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}>{node}</ContentSelector>\n ) : (\n node\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?: HTMLComponents) =>\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 },\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return node;\n if (prop === Symbol.toPrimitive) return () => node;\n if (prop === 'toString') return () => node;\n if (prop === 'valueOf') return () => node;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(node);\n }\n if (prop === 'metadata') return metadataNodes;\n if (prop === 'use')\n return (components?: HTMLComponents) => render(components);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer M;\n tags?: infer U;\n metadata?: infer V;\n}\n ? IntlayerNode<\n M,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n metadata: DeepTransformContent<V>;\n }\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\n/**\n * HTML conditional type that enforces:\n * - All components (Standard or Custom) are OPTIONAL in the `use()` method.\n * - Custom components props are strictly inferred from the dictionary definition.\n *\n * This ensures type safety:\n * - `html('<div>Hello <CustomComponent /></div>').use({ CustomComponent: ... })` - optional but typed\n */\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? IntlayerNode<\n I,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n }\n >\n : never;\n\nconst HTMLSuspenseRenderer: FC<Record<string, any>> = (props) => {\n const HTMLRendererPlugin = useLoadDynamic(\n 'html-renderer-plugin',\n htmlRendererModulePromise!\n );\n return createElement(HTMLRendererPlugin as any, props);\n};\n\n/** HTML plugin. Replaces node with a function that takes components => ReactNode. */\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\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): ReactNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n </ContentSelector>\n ) : (\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n ),\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return html;\n if (prop === Symbol.toPrimitive) return () => html;\n if (prop === 'toString') return () => html;\n if (prop === 'valueOf') return () => html;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(html);\n }\n if (prop === 'use')\n return (userComponents?: HTMLComponents) =>\n render(userComponents);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport type IInterpreterPluginReact<T, _S, _L extends LocalesValues> = {\n reactNode: ReactNodeCond<T>;\n reactIntlayerNode: IntlayerNodeCond<T>;\n reactInsertion: InsertionCond<T>;\n reactMarkdown: MarkdownCond<T>;\n reactHtml: HTMLPluginCond<T>;\n};\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `react-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 reactNode: true;\n reactIntlayerNode: true;\n reactMarkdown: true;\n reactHtml: true;\n reactInsertion: 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 React 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 // Env var allows the bundler to to remove the plugin if not used to make the bundle smaller\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\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n intlayerNodePlugins,\n reactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n pluginsCache.set(cacheKey, plugins);\n\n return plugins;\n};\n"],"mappings":"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"}
|
|
@@ -19,12 +19,12 @@ const useEditor = () => {
|
|
|
19
19
|
const manager = initEditorClient();
|
|
20
20
|
managerRef.current = manager;
|
|
21
21
|
if (locale) manager.currentLocale.set(locale);
|
|
22
|
-
});
|
|
22
|
+
}).catch(() => {});
|
|
23
23
|
return () => {
|
|
24
24
|
managerRef.current = null;
|
|
25
25
|
import("@intlayer/editor").then(({ stopEditorClient }) => {
|
|
26
26
|
stopEditorClient();
|
|
27
|
-
});
|
|
27
|
+
}).catch(() => {});
|
|
28
28
|
};
|
|
29
29
|
}, []);
|
|
30
30
|
useEffect(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditor.mjs","names":[],"sources":["../../../src/editor/useEditor.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorStateManager } from '@intlayer/editor';\nimport { isEnabled } from '@intlayer/editor/isEnabled';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\n\n/**\n * Initializes the Intlayer editor client singleton when the editor is enabled.\n * Syncs the current locale from the Intlayer context into the editor manager so\n * the editor always knows which locale the app is displaying.\n */\nexport const useEditor = () => {\n const { locale } = useContext(IntlayerClientContext) ?? {};\n const managerRef = useRef<EditorStateManager | null>(null);\n\n useEffect(() => {\n if (process.env.INTLAYER_EDITOR_ENABLED === 'false' || !isEnabled) return;\n\n import('@intlayer/editor').then(({ initEditorClient }) => {\n
|
|
1
|
+
{"version":3,"file":"useEditor.mjs","names":[],"sources":["../../../src/editor/useEditor.tsx"],"sourcesContent":["'use client';\n\nimport type { EditorStateManager } from '@intlayer/editor';\nimport { isEnabled } from '@intlayer/editor/isEnabled';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\n\n/**\n * Initializes the Intlayer editor client singleton when the editor is enabled.\n * Syncs the current locale from the Intlayer context into the editor manager so\n * the editor always knows which locale the app is displaying.\n */\nexport const useEditor = () => {\n const { locale } = useContext(IntlayerClientContext) ?? {};\n const managerRef = useRef<EditorStateManager | null>(null);\n\n useEffect(() => {\n if (process.env.INTLAYER_EDITOR_ENABLED === 'false' || !isEnabled) return;\n\n import('@intlayer/editor')\n .then(({ initEditorClient }) => {\n const manager = initEditorClient();\n managerRef.current = manager;\n\n if (locale) manager.currentLocale.set(locale as Locale);\n })\n .catch(() => {});\n\n return () => {\n managerRef.current = null;\n import('@intlayer/editor')\n .then(({ stopEditorClient }) => {\n stopEditorClient();\n })\n .catch(() => {});\n };\n }, []);\n\n useEffect(() => {\n if (!locale || !managerRef.current) return;\n\n managerRef.current.currentLocale.set(locale as Locale);\n }, [locale]);\n};\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,kBAAkB;CAC7B,MAAM,EAAE,WAAW,WAAW,qBAAqB,KAAK,CAAC;CACzD,MAAM,aAAa,OAAkC,IAAI;CAEzD,gBAAgB;EACd,IAAI,QAAQ,IAAI,4BAA4B,WAAW,CAAC,WAAW;EAEnE,OAAO,mBAAmB,CACvB,MAAM,EAAE,uBAAuB;GAC9B,MAAM,UAAU,iBAAiB;GACjC,WAAW,UAAU;GAErB,IAAI,QAAQ,QAAQ,cAAc,IAAI,MAAgB;EACxD,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EAEjB,aAAa;GACX,WAAW,UAAU;GACrB,OAAO,mBAAmB,CACvB,MAAM,EAAE,uBAAuB;IAC9B,iBAAiB;GACnB,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EACnB;CACF,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,IAAI,CAAC,UAAU,CAAC,WAAW,SAAS;EAEpC,WAAW,QAAQ,cAAc,IAAI,MAAgB;CACvD,GAAG,CAAC,MAAM,CAAC;AACb"}
|
package/dist/esm/plugins.mjs
CHANGED
|
@@ -13,6 +13,8 @@ import { jsx } from "react/jsx-runtime";
|
|
|
13
13
|
//#region src/plugins.tsx
|
|
14
14
|
const markdownRendererModulePromise = process.env.INTLAYER_NODE_TYPE_MARKDOWN !== "false" ? import("./markdown/MarkdownRendererPlugin.mjs").then((m) => m.MarkdownRendererPlugin) : null;
|
|
15
15
|
const htmlRendererModulePromise = process.env.INTLAYER_NODE_TYPE_HTML !== "false" ? import("./html/HTMLRendererPlugin.mjs").then((m) => m.HTMLRendererPlugin) : null;
|
|
16
|
+
markdownRendererModulePromise?.catch(() => {});
|
|
17
|
+
htmlRendererModulePromise?.catch(() => {});
|
|
16
18
|
/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
|
|
17
19
|
const intlayerNodePlugins = {
|
|
18
20
|
id: "intlayer-node-plugin",
|
package/dist/esm/plugins.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.mjs","names":["func"],"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 selectPlugin,\n splitInsertionTemplate,\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 {\n createElement,\n type FC,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { reportExposure } from './analytics/exposureSink';\nimport { useLoadDynamic } from './client/useLoadDynamic';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/HTMLComponentTypes';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderReactElement } from './reactElement/renderReactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then(\n (m) => m.MarkdownRendererPlugin\n )\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRendererPlugin').then((m) => m.HTMLRendererPlugin)\n : null;\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: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\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: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'text',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: rest.children,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled ? (\n <ContentSelector {...rest}>{rest.children}</ContentSelector>\n ) : (\n rest.children\n ),\n });\n },\n};\n\n/** ---------------------------------------------\n * REACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type ReactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? ReactNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const reactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_REACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'react-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: 'react-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[react-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderReactElement(node)}\n </ContentSelector>\n ) : (\n renderReactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: ReactNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<ReactNode>\n : DeepTransformContent<I>\n : never;\n\n/**\n * Split insertion string and join with React nodes using shared core logic\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | ReactNode>\n): ReactNode => {\n const result = splitInsertionTemplate(template, values);\n\n if (result.isSimple) {\n // Simple string replacement\n return result.parts as string;\n }\n\n // Return as Fragment with proper keys\n return createElement(\n Fragment,\n null,\n ...(result.parts as any[]).map((part, index) =>\n createElement(Fragment, { key: index }, part)\n )\n );\n};\n\n/** Insertion plugin for React. 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 // React nodes cannot be injected into a raw markup string, so\n // string 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 | ReactNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result,\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 if (\n typeof children === 'object' &&\n children !== null &&\n 'nodeType' in children &&\n [NodeTypes.ENUMERATION, NodeTypes.CONDITION].includes(\n children.nodeType as\n | typeof NodeTypes.ENUMERATION\n | typeof NodeTypes.CONDITION\n )\n ) {\n return (values: any) => (arg: any) => {\n const func = result as Function;\n const inner = func(arg);\n\n if (typeof inner === 'function') {\n return inner(values);\n }\n return inner;\n };\n }\n\n return 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', {}>) => ReactNode;\n }\n >\n : never;\n\nconst MarkdownSuspenseRenderer: FC<Record<string, any>> = ({\n children,\n ...props\n}) => {\n const MarkdownRendererPlugin = useLoadDynamic(\n 'markdown-renderer-plugin',\n markdownRendererModulePromise!\n );\n return createElement(MarkdownRendererPlugin as any, { ...props, children });\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}>{node}</ContentSelector>\n ) : (\n node\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?: HTMLComponents) =>\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 },\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return node;\n if (prop === Symbol.toPrimitive) return () => node;\n if (prop === 'toString') return () => node;\n if (prop === 'valueOf') return () => node;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(node);\n }\n if (prop === 'metadata') return metadataNodes;\n if (prop === 'use')\n return (components?: HTMLComponents) => render(components);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer M;\n tags?: infer U;\n metadata?: infer V;\n}\n ? IntlayerNode<\n M,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n metadata: DeepTransformContent<V>;\n }\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\n/**\n * HTML conditional type that enforces:\n * - All components (Standard or Custom) are OPTIONAL in the `use()` method.\n * - Custom components props are strictly inferred from the dictionary definition.\n *\n * This ensures type safety:\n * - `html('<div>Hello <CustomComponent /></div>').use({ CustomComponent: ... })` - optional but typed\n */\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? IntlayerNode<\n I,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n }\n >\n : never;\n\nconst HTMLSuspenseRenderer: FC<Record<string, any>> = (props) => {\n const HTMLRendererPlugin = useLoadDynamic(\n 'html-renderer-plugin',\n htmlRendererModulePromise!\n );\n return createElement(HTMLRendererPlugin as any, props);\n};\n\n/** HTML plugin. Replaces node with a function that takes components => ReactNode. */\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\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): ReactNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n </ContentSelector>\n ) : (\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n ),\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return html;\n if (prop === Symbol.toPrimitive) return () => html;\n if (prop === 'toString') return () => html;\n if (prop === 'valueOf') return () => html;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(html);\n }\n if (prop === 'use')\n return (userComponents?: HTMLComponents) =>\n render(userComponents);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport type IInterpreterPluginReact<T, _S, _L extends LocalesValues> = {\n reactNode: ReactNodeCond<T>;\n reactIntlayerNode: IntlayerNodeCond<T>;\n reactInsertion: InsertionCond<T>;\n reactMarkdown: MarkdownCond<T>;\n reactHtml: HTMLPluginCond<T>;\n};\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `react-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 reactNode: true;\n reactIntlayerNode: true;\n reactMarkdown: true;\n reactHtml: true;\n reactInsertion: 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 React 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 // Env var allows the bundler to to remove the plugin if not used to make the bundle smaller\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\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n intlayerNodePlugins,\n reactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n pluginsCache.set(cacheKey, plugins);\n\n return plugins;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugins.mjs","names":["func"],"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 selectPlugin,\n splitInsertionTemplate,\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 {\n createElement,\n type FC,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { reportExposure } from './analytics/exposureSink';\nimport { useLoadDynamic } from './client/useLoadDynamic';\nimport { ContentSelector } from './editor/ContentSelector';\nimport type { HTMLComponents } from './html/HTMLComponentTypes';\nimport { type IntlayerNode, renderIntlayerNode } from './IntlayerNode';\nimport { renderReactElement } from './reactElement/renderReactElement';\n\nconst markdownRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_MARKDOWN !== 'false'\n ? import('./markdown/MarkdownRendererPlugin').then(\n (m) => m.MarkdownRendererPlugin\n )\n : null;\n\nconst htmlRendererModulePromise =\n process.env.INTLAYER_NODE_TYPE_HTML !== 'false'\n ? import('./html/HTMLRendererPlugin').then((m) => m.HTMLRendererPlugin)\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: (\n _node,\n {\n plugins, // Removed to avoid next error - Functions cannot be passed directly to Client Components\n ...rest\n }\n ) => {\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: rest.dictionaryKey,\n keyPath: rest.keyPath,\n locale: rest.locale,\n nodeType: 'text',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: rest.children,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled ? (\n <ContentSelector {...rest}>{rest.children}</ContentSelector>\n ) : (\n rest.children\n ),\n });\n },\n};\n\n/** ---------------------------------------------\n * REACT NODE PLUGIN\n * --------------------------------------------- */\n\nexport type ReactNodeCond<T> = T extends {\n props: any;\n key: any;\n}\n ? ReactNode\n : never;\n\n/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */\nexport const reactNodePlugins: Plugins =\n process.env.INTLAYER_NODE_TYPE_REACT_NODE === 'false'\n ? fallbackPlugin\n : {\n id: 'react-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: 'react-node',\n });\n }\n\n return renderIntlayerNode({\n ...rest,\n value: '[[react-element]]',\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n {renderReactElement(node)}\n </ContentSelector>\n ) : (\n renderReactElement(node)\n ),\n });\n },\n };\n\n/** ---------------------------------------------\n * INSERTION PLUGIN\n * --------------------------------------------- */\n\nexport type InsertionCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.INSERTION]: infer I;\n fields: readonly string[];\n}\n ? <V extends { [K in T['fields'][number]]: ReactNode }>(\n values: V\n ) => I extends string\n ? V[keyof V] extends string | number\n ? IntlayerNode<string>\n : IntlayerNode<ReactNode>\n : DeepTransformContent<I>\n : never;\n\n/**\n * Split insertion string and join with React nodes using shared core logic\n */\nconst splitAndJoinInsertion = (\n template: string,\n values: Record<string, string | number | ReactNode>\n): ReactNode => {\n const result = splitInsertionTemplate(template, values);\n\n if (result.isSimple) {\n // Simple string replacement\n return result.parts as string;\n }\n\n // Return as Fragment with proper keys\n return createElement(\n Fragment,\n null,\n ...(result.parts as any[]).map((part, index) =>\n createElement(Fragment, { key: index }, part)\n )\n );\n};\n\n/** Insertion plugin for React. 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 // React nodes cannot be injected into a raw markup string, so\n // string 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 | ReactNode;\n }\n ) => {\n const result = splitAndJoinInsertion(transformedResult, values);\n\n return deepTransformNode(result, {\n ...subProps,\n plugins: props.plugins,\n children: result,\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 if (\n typeof children === 'object' &&\n children !== null &&\n 'nodeType' in children &&\n [NodeTypes.ENUMERATION, NodeTypes.CONDITION].includes(\n children.nodeType as\n | typeof NodeTypes.ENUMERATION\n | typeof NodeTypes.CONDITION\n )\n ) {\n return (values: any) => (arg: any) => {\n const func = result as Function;\n const inner = func(arg);\n\n if (typeof inner === 'function') {\n return inner(values);\n }\n return inner;\n };\n }\n\n return 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', {}>) => ReactNode;\n }\n >\n : never;\n\nconst MarkdownSuspenseRenderer: FC<Record<string, any>> = ({\n children,\n ...props\n}) => {\n const MarkdownRendererPlugin = useLoadDynamic(\n 'markdown-renderer-plugin',\n markdownRendererModulePromise!\n );\n return createElement(MarkdownRendererPlugin as any, { ...props, children });\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}>{node}</ContentSelector>\n ) : (\n node\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?: HTMLComponents) =>\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 },\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return node;\n if (prop === Symbol.toPrimitive) return () => node;\n if (prop === 'toString') return () => node;\n if (prop === 'valueOf') return () => node;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(node);\n }\n if (prop === 'metadata') return metadataNodes;\n if (prop === 'use')\n return (components?: HTMLComponents) => render(components);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\nexport type MarkdownCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.MARKDOWN]: infer M;\n tags?: infer U;\n metadata?: infer V;\n}\n ? IntlayerNode<\n M,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n metadata: DeepTransformContent<V>;\n }\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\n/**\n * HTML conditional type that enforces:\n * - All components (Standard or Custom) are OPTIONAL in the `use()` method.\n * - Custom components props are strictly inferred from the dictionary definition.\n *\n * This ensures type safety:\n * - `html('<div>Hello <CustomComponent /></div>').use({ CustomComponent: ... })` - optional but typed\n */\nexport type HTMLPluginCond<T> = T extends {\n nodeType: NodeType | string;\n [NodeTypes.HTML]: infer I;\n tags?: infer U;\n}\n ? IntlayerNode<\n I,\n {\n use: (components?: HTMLComponents<'permissive', U>) => ReactNode;\n }\n >\n : never;\n\nconst HTMLSuspenseRenderer: FC<Record<string, any>> = (props) => {\n const HTMLRendererPlugin = useLoadDynamic(\n 'html-renderer-plugin',\n htmlRendererModulePromise!\n );\n return createElement(HTMLRendererPlugin as any, props);\n};\n\n/** HTML plugin. Replaces node with a function that takes components => ReactNode. */\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\n transform: (node: HTMLContent<string>, props) => {\n const html = node[NodeTypes.HTML];\n const { plugins, ...rest } = props;\n\n // Type-safe render function that accepts properly typed components\n const render = (userComponents?: HTMLComponents): ReactNode =>\n renderIntlayerNode({\n ...rest,\n value: html,\n children:\n process.env.INTLAYER_EDITOR_ENABLED !== 'false' &&\n editor.enabled ? (\n <ContentSelector {...rest}>\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n </ContentSelector>\n ) : (\n <HTMLSuspenseRenderer\n {...rest}\n html={html}\n userComponents={userComponents}\n />\n ),\n });\n\n const element = render() as unknown as ReactElement;\n\n return new Proxy(element, {\n get(target, prop, receiver) {\n if (prop === 'value') return html;\n if (prop === Symbol.toPrimitive) return () => html;\n if (prop === 'toString') return () => html;\n if (prop === 'valueOf') return () => html;\n if (typeof prop === 'string' && prop !== 'constructor') {\n const method = (String.prototype as any)[prop];\n if (typeof method === 'function') return method.bind(html);\n }\n if (prop === 'use')\n return (userComponents?: HTMLComponents) =>\n render(userComponents);\n return Reflect.get(target, prop, receiver);\n },\n }) as any;\n },\n };\n\n/** ---------------------------------------------\n * PLUGINS RESULT\n * --------------------------------------------- */\n\nexport type IInterpreterPluginReact<T, _S, _L extends LocalesValues> = {\n reactNode: ReactNodeCond<T>;\n reactIntlayerNode: IntlayerNodeCond<T>;\n reactInsertion: InsertionCond<T>;\n reactMarkdown: MarkdownCond<T>;\n reactHtml: HTMLPluginCond<T>;\n};\n\n/**\n * Insert this type as param of `DeepTransformContent` to avoid `intlayer` package pollution.\n *\n * Otherwise the the `react-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 reactNode: true;\n reactIntlayerNode: true;\n reactMarkdown: true;\n reactHtml: true;\n reactInsertion: 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 React 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 // Env var allows the bundler to to remove the plugin if not used to make the bundle smaller\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\n filePlugin,\n genderPlugin,\n selectPlugin,\n // Always include: handle plain strings/numbers and React elements\n intlayerNodePlugins,\n reactNodePlugins,\n insertionPlugin,\n markdownPlugin,\n htmlPlugin,\n ] as Plugins[];\n\n pluginsCache.set(cacheKey, plugins);\n\n return plugins;\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":";;;;;;;;;;;KAoEY,iBAAiB,KAAK,4BAC9B,aAAa;;cAIJ,qBAAqB;;;;KAyCtB,cAAc,KAAK;EAC7B;EACA;IAEE;;cAIS,kBAAkB;;;;KA8CnB,cAAc,KAAK;EAC7B,UAAU;GACT,UAAU,kBAAkB;EAC7B;KAEG,aAAa,KAAK,sBAAsB,cACvC,QAAQ,MACL,mBACD,QAAQ,6BACN,uBACA,aAAa,aACf,qBAAqB;;cA4BhB,iBAAiB;;;;KA4GlB,mBAAmB,KAAK,mBAChC;EAGI,UAAU;EACV,MAAM,YAAY,qCAAqC;;;cAiBlD,sBAAsB;KAqFvB,aAAa,KAAK;EAC5B,UAAU;GACT,UAAU,iBAAiB;EAC5B,aAAa;EACb,iBAAiB;IAEf,aACE;EAEE,MAAM,aAAa,6BAA6B,OAAO;EACvD,UAAU,qBAAqB;;cAK1B,gBAAgB;;;;;;;;;;;;KAsCjB,eAAe,KAAK;EAC9B,UAAU;GACT,UAAU,aAAa;EACxB,aAAa;IAEX,aACE;EAEE,MAAM,aAAa,6BAA6B,OAAO;;;cAclD,YAAY;;;;KA6Db,wBAAwB,GAAG,IAAI,WAAW;EACpD,WAAW,cAAc;EACzB,mBAAmB,iBAAiB;EACpC,gBAAgB,cAAc;EAC9B,eAAe,aAAa;EAC5B,WAAW,eAAe;;;;;;;KAQhB,0BAA0B,KACpC;EAGA;EACA;EACA;EACA;EACA;;KAGU,qBACV,GACA,UAAU,gBAAgB,mBACxB,uBAAyB,GAAG,yBAAyB;;;;;cAQ5C,aAAU,SACZ,eAAa,uBAErB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-intlayer",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Easily internationalize i18n your React applications with type-safe multilingual content management.",
|
|
6
6
|
"keywords": [
|
|
@@ -132,12 +132,12 @@
|
|
|
132
132
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
133
133
|
},
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"@intlayer/api": "9.3.
|
|
136
|
-
"@intlayer/config": "9.3.
|
|
137
|
-
"@intlayer/core": "9.3.
|
|
138
|
-
"@intlayer/dictionaries-entry": "9.3.
|
|
139
|
-
"@intlayer/editor": "9.3.
|
|
140
|
-
"@intlayer/types": "9.3.
|
|
135
|
+
"@intlayer/api": "9.3.2",
|
|
136
|
+
"@intlayer/config": "9.3.2",
|
|
137
|
+
"@intlayer/core": "9.3.2",
|
|
138
|
+
"@intlayer/dictionaries-entry": "9.3.2",
|
|
139
|
+
"@intlayer/editor": "9.3.2",
|
|
140
|
+
"@intlayer/types": "9.3.2"
|
|
141
141
|
},
|
|
142
142
|
"devDependencies": {
|
|
143
143
|
"@craco/types": "7.1.0",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"react-dom": ">=16.0.0"
|
|
159
159
|
},
|
|
160
160
|
"optionalDependencies": {
|
|
161
|
-
"@intlayer/analytics": "9.3.
|
|
161
|
+
"@intlayer/analytics": "9.3.2"
|
|
162
162
|
},
|
|
163
163
|
"engines": {
|
|
164
164
|
"node": ">=14.18"
|