svelte-intlayer 9.5.9-canary.0 → 9.5.10

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.
@@ -26,7 +26,7 @@ import type { LocalesValues, ProviderVariant } from '@intlayer/types/module_augm
26
26
  * ```
27
27
  */
28
28
  export declare const setupIntlayer: (initialLocale?: LocalesValues, initialVariant?: ProviderVariant) => {
29
- readonly locale: "id" | "cy" | "hr" | "th" | "tr" | "tt" | "mi" | "mn" | "ms" | "af" | "af-ZA" | "ar" | "ar-AE" | "ar-BH" | "ar-DZ" | "ar-EG" | "ar-IQ" | "ar-JO" | "ar-KW" | "ar-LB" | "ar-LY" | "ar-MA" | "ar-OM" | "ar-QA" | "ar-SA" | "ar-SY" | "ar-TN" | "ar-YE" | "az" | "az-AZ" | "be" | "be-BY" | "bg" | "bg-BG" | "bs" | "bs-BA" | "ca" | "ca-ES" | "cs" | "cs-CZ" | "cy-GB" | "da" | "da-DK" | "de" | "de-AT" | "de-CH" | "de-DE" | "de-LI" | "de-LU" | "dv" | "dv-MV" | "el" | "el-GR" | "en" | "en-AU" | "en-BZ" | "en-CA" | "en-CB" | "en-GB" | "en-IE" | "en-JM" | "en-NZ" | "en-PH" | "en-TT" | "en-US" | "en-ZA" | "en-ZW" | "eo" | "es" | "es-AR" | "es-BO" | "es-CL" | "es-CO" | "es-CR" | "es-DO" | "es-EC" | "es-ES" | "es-GT" | "es-HN" | "es-MX" | "es-NI" | "es-PA" | "es-PE" | "es-PR" | "es-PY" | "es-SV" | "es-UY" | "es-VE" | "et" | "et-EE" | "eu" | "eu-ES" | "fa" | "fa-IR" | "fi" | "fi-FI" | "fo" | "fo-FO" | "fr" | "fr-BE" | "fr-CA" | "fr-CH" | "fr-FR" | "fr-LU" | "fr-MC" | "ga" | "ga-IE" | "gd" | "gd-GB" | "gl" | "gl-ES" | "gu" | "gu-IN" | "he" | "he-IL" | "hi" | "hi-IN" | "hr-BA" | "hr-HR" | "hu" | "hu-HU" | "hy" | "hy-AM" | "id-ID" | "is" | "is-IS" | "it" | "it-CH" | "it-IT" | "ja" | "ja-JP" | "ka" | "ka-GE" | "kk" | "kk-KZ" | "kn" | "kn-IN" | "ko" | "ko-KR" | "kok" | "kok-IN" | "ku" | "ku-TR" | "ky" | "ky-KG" | "lt" | "lt-LT" | "lv" | "lv-LV" | "mi-NZ" | "mk" | "mk-MK" | "mn-MN" | "mr" | "mr-IN" | "ms-BN" | "ms-MY" | "mt" | "mt-MT" | "ml" | "ml-IN" | "no" | "nb" | "nb-NO" | "nl" | "nl-BE" | "nl-NL" | "nn" | "nn-NO" | "ns" | "ns-ZA" | "pa" | "pa-IN" | "pl" | "pl-PL" | "ps" | "ps-AR" | "pt" | "pt-BR" | "pt-PT" | "qu" | "qu-BO" | "qu-EC" | "qu-PE" | "ro" | "ro-RO" | "ro-MD" | "rm" | "rm-CH" | "ru" | "ru-RU" | "ru-MD" | "sa" | "sa-IN" | "se" | "se-FI" | "se-NO" | "se-SE" | "hsb" | "hsb-DE" | "dsb" | "dsb-DE" | "sk" | "sk-SK" | "sl" | "sl-SI" | "sq" | "sq-AL" | "sr" | "sr-BA" | "sr-SP" | "sv" | "sv-FI" | "sv-SE" | "sw" | "sw-KE" | "syr" | "syr-SY" | "ta" | "ta-IN" | "te" | "te-IN" | "th-TH" | "tl" | "tl-PH" | "tn" | "tn-ZA" | "tr-TR" | "tt-RU" | "ts" | "uk" | "uk-UA" | "ur" | "ur-PK" | "uz" | "uz-UZ" | "vi" | "vi-VN" | "ve" | "ve-ZA" | "xh" | "xh-ZA" | "zh" | "zh-Hans" | "zh-CN" | "zh-HK" | "zh-MO" | "zh-SG" | "zh-Hant" | "zu" | "zu-ZA" | "bn" | "bn-BD" | "bn-IN" | "bn-MM" | "my" | "my-MM" | "km" | "km-KH" | "lo" | "lo-LA" | "yo" | "yo-NG" | "yi" | "yi-001" | "am" | "am-ET" | "ne" | "ne-NP" | "si" | "si-LK" | "sr-Cyrl" | "sr-RS" | "en-IN" | "en-SG" | "en-HK" | "en-NG" | "en-PK" | "en-MY" | "en-BW" | "en-KE" | "en-TZ" | "en-GH" | "en-UG" | "es-CU" | "es-US" | "pt-GW" | "pt-MZ" | "pt-ST" | "pt-CV" | "pt-TL" | "pt-MO" | "zh-TW" | "ar-MR" | "ar-PS" | "ar-SD" | "ar-DJ" | "ar-SO" | "ar-TD" | "ar-KM" | "mg-MG" | (string & {});
29
+ readonly locale: import("@intlayer/types").Locale | (string & {});
30
30
  setLocale: (newLocale: LocalesValues) => void;
31
31
  readonly variant: ProviderVariant | undefined;
32
32
  setVariant: (newVariant: ProviderVariant | undefined) => void;
@@ -4,6 +4,7 @@ import { useAnalytics } from '../analytics/useAnalytics';
4
4
  import { useEditor } from '../editor/useEditor';
5
5
  import { setIntlayerContext } from './intlayerContext';
6
6
  import { intlayerStore } from './intlayerStore';
7
+ import { getLocaleInStorage } from './useLocaleStorage';
7
8
  /**
8
9
  * Setups Intlayer in your Svelte application.
9
10
  *
@@ -31,16 +32,18 @@ import { intlayerStore } from './intlayerStore';
31
32
  * ```
32
33
  */
33
34
  export const setupIntlayer = (initialLocale, initialVariant) => {
35
+ // Returning visitors keep their language when no locale is passed
36
+ const startLocale = initialLocale ?? getLocaleInStorage();
34
37
  setIntlayerIdentifier();
35
38
  useEditor();
36
39
  useAnalytics();
37
40
  // Create Reactive State (Svelte 5)
38
41
  // We make the locale a "rune" so updates propagate
39
- let locale = $state(initialLocale);
42
+ let locale = $state(startLocale);
40
43
  let variant = $state(initialVariant);
41
44
  // Keep intlayerStore in sync so useEditor can subscribe to it
42
- if (initialLocale) {
43
- intlayerStore.setLocale(initialLocale);
45
+ if (startLocale) {
46
+ intlayerStore.setLocale(startLocale);
44
47
  }
45
48
  // Define the Context Object
46
49
  const contextValue = {
@@ -1,14 +1,24 @@
1
1
  import type { LocalesValues } from '@intlayer/types/module_augmentation';
2
+ /**
3
+ * Reads the locale persisted in the browser storage (cookie, localStorage…).
4
+ *
5
+ * Unlike `localeInStorage`, read on first call rather than at import, then
6
+ * cached until the next `setLocaleInStorage`. Never cached on the server.
7
+ */
8
+ export declare const getLocaleInStorage: () => import("@intlayer/types").Locale | undefined;
2
9
  /**
3
10
  * Get the locale cookie
11
+ *
12
+ * Read once at import time; marked pure so bundlers drop the read when nothing
13
+ * imports it.
4
14
  */
5
- export declare const localeInStorage: import("intlayer").Locale | undefined;
15
+ export declare const localeInStorage: import("@intlayer/types").Locale | undefined;
6
16
  /**
7
17
  * @deprecated Use localeInStorage instead
8
18
  *
9
19
  * Get the locale cookie
10
20
  */
11
- export declare const localeCookie: import("intlayer").Locale | undefined;
21
+ export declare const localeCookie: import("@intlayer/types").Locale | undefined;
12
22
  /**
13
23
  * Set the locale cookie
14
24
  */
@@ -1,9 +1,20 @@
1
- import { getLocaleFromStorageClient, LocaleStorageClient, localeStorageOptions, setLocaleInStorageClient as setLocaleInStorageCore, } from '@intlayer/core/utils';
1
+ import { getCachedLocaleFromStorageClient, getLocaleFromStorageClient, LocaleStorageClient, localeStorageOptions, setLocaleInStorageClient as setLocaleInStorageCore, } from '@intlayer/core/utils';
2
2
  import { readable } from 'svelte/store';
3
+ /**
4
+ * Reads the locale persisted in the browser storage (cookie, localStorage…).
5
+ *
6
+ * Unlike `localeInStorage`, read on first call rather than at import, then
7
+ * cached until the next `setLocaleInStorage`. Never cached on the server.
8
+ */
9
+ export const getLocaleInStorage = getCachedLocaleFromStorageClient;
3
10
  /**
4
11
  * Get the locale cookie
12
+ *
13
+ * Read once at import time; marked pure so bundlers drop the read when nothing
14
+ * imports it.
5
15
  */
6
- export const localeInStorage = getLocaleFromStorageClient(localeStorageOptions);
16
+ export const localeInStorage =
17
+ /* @__PURE__ */ getLocaleFromStorageClient(localeStorageOptions);
7
18
  /**
8
19
  * @deprecated Use localeInStorage instead
9
20
  *
@@ -1,3 +1,3 @@
1
1
  export declare const useCompact: () => import("svelte/store").Readable<(value: string | number, options?: (Intl.NumberFormatOptions & {
2
- locale?: import("intlayer").LocalesValues;
2
+ locale?: import("@intlayer/types").LocalesValues;
3
3
  }) | undefined) => string>;
@@ -1,3 +1,3 @@
1
1
  export declare const useCurrency: () => import("svelte/store").Readable<(value: string | number, options?: (Intl.NumberFormatOptions & {
2
- locale?: import("intlayer").LocalesValues;
2
+ locale?: import("@intlayer/types").LocalesValues;
3
3
  }) | undefined) => string>;
@@ -5,5 +5,5 @@
5
5
  * A store containing a date/time formatting function bound to the active locale.
6
6
  */
7
7
  export declare const useDate: () => import("svelte/store").Readable<(date: string | number | Date, options?: import("@intlayer/core/formatters").DateTimePreset | (Intl.DateTimeFormatOptions & {
8
- locale?: import("intlayer").LocalesValues;
8
+ locale?: import("@intlayer/types").LocalesValues;
9
9
  }) | undefined) => string>;
@@ -1,3 +1,3 @@
1
1
  export declare const useList: () => import("svelte/store").Readable<(values: (string | number)[], options?: (import("@intlayer/core/formatters").ListFormatOptions & {
2
- locale?: import("intlayer").LocalesValues;
2
+ locale?: import("@intlayer/types").LocalesValues;
3
3
  }) | undefined) => string>;
@@ -5,5 +5,5 @@
5
5
  * A store containing a number formatting function bound to the active locale.
6
6
  */
7
7
  export declare const useNumber: () => import("svelte/store").Readable<(value: string | number, args_1?: (Intl.NumberFormatOptions & {
8
- locale?: import("intlayer").LocalesValues;
8
+ locale?: import("@intlayer/types").LocalesValues;
9
9
  }) | undefined) => string>;
@@ -1,3 +1,3 @@
1
1
  export declare const usePercentage: () => import("svelte/store").Readable<(value: string | number, args_1?: (Intl.NumberFormatOptions & {
2
- locale?: import("intlayer").LocalesValues;
2
+ locale?: import("@intlayer/types").LocalesValues;
3
3
  }) | undefined) => string>;
@@ -1,4 +1,4 @@
1
1
  export declare const useRelativeTime: () => import("svelte/store").Readable<(from: string | number | Date, to?: string | number | Date | undefined, options?: (Intl.RelativeTimeFormatOptions & {
2
- locale?: import("intlayer").LocalesValues;
2
+ locale?: import("@intlayer/types").LocalesValues;
3
3
  unit?: Intl.RelativeTimeFormatUnit;
4
4
  }) | undefined) => string>;
@@ -1,3 +1,3 @@
1
1
  export declare const useUnit: () => import("svelte/store").Readable<(value: string | number, options?: (Intl.NumberFormatOptions & {
2
- locale?: import("intlayer").LocalesValues;
2
+ locale?: import("@intlayer/types").LocalesValues;
3
3
  }) | undefined) => string>;
@@ -1,10 +1,11 @@
1
- import { type ParsedMarkdown } from '@intlayer/core/markdown';
1
+ import { type CompileOptions, type ParsedMarkdown } from '@intlayer/core/markdown';
2
2
  /**
3
3
  * Intermediate AST produced by `parseMarkdown`.
4
4
  * Pass this to `compileMarkdown` to skip re-parsing when the same content is
5
5
  * rendered multiple times.
6
6
  */
7
7
  export type { ParsedMarkdown };
8
+ export type MarkdownCompilerOptions = CompileOptions;
8
9
  /**
9
10
  * **Step 1 of 2 — parse only.**
10
11
  * Converts a raw markdown string into a `ParsedMarkdown` AST without rendering
@@ -23,7 +24,7 @@ export type { ParsedMarkdown };
23
24
  * const html = compileMarkdown(ast);
24
25
  * ```
25
26
  */
26
- export declare const parseMarkdown: (markdown?: string, options?: any) => ParsedMarkdown;
27
+ export declare const parseMarkdown: (markdown?: string, options?: MarkdownCompilerOptions) => ParsedMarkdown;
27
28
  /**
28
29
  * **Steps 1 + 2 — parse and render in one shot.**
29
30
  * Accepts a raw markdown string or a pre-parsed `ParsedMarkdown` AST and
@@ -38,4 +39,4 @@ export declare const parseMarkdown: (markdown?: string, options?: any) => Parsed
38
39
  * <div>{@html compileMarkdown('# Hello **World**')}</div>
39
40
  * ```
40
41
  */
41
- export declare const compileMarkdown: (input?: string | ParsedMarkdown, options?: any) => unknown;
42
+ export declare const compileMarkdown: (input?: string | ParsedMarkdown, options?: MarkdownCompilerOptions) => string;
@@ -22,7 +22,7 @@ export const parseMarkdown = (markdown = '', options = {}) => {
22
22
  const { components, namedCodesToUnicode, sanitizer, slugify, ...compilerOptions } = options;
23
23
  const ctx = {
24
24
  runtime: svelteHtmlRuntime,
25
- components,
25
+ components: components,
26
26
  namedCodesToUnicode,
27
27
  sanitizer: sanitizer,
28
28
  slugify,
@@ -50,7 +50,7 @@ export const compileMarkdown = (input = '', options = {}) => {
50
50
  const { components, namedCodesToUnicode, sanitizer, slugify, ...compilerOptions } = options;
51
51
  const ctx = {
52
52
  runtime: svelteHtmlRuntime,
53
- components,
53
+ components: components,
54
54
  namedCodesToUnicode,
55
55
  sanitizer: sanitizer,
56
56
  slugify,
@@ -11,7 +11,7 @@ export type RenderMarkdownProps = RenderMarkdownOptions;
11
11
  * outside a `<MarkdownProvider>`; delegates to the provider's render function
12
12
  * when one is active.
13
13
  */
14
- export declare const renderMarkdown: (input?: string | ParsedMarkdown, options?: any) => unknown;
14
+ export declare const renderMarkdown: (input?: string | ParsedMarkdown, options?: import("./compiler").MarkdownCompilerOptions) => string;
15
15
  /**
16
16
  * Returns a render function bound to the current `<MarkdownProvider>` context.
17
17
  * The returned function forwards its call to whichever `renderMarkdown`
package/dist/plugins.js CHANGED
@@ -84,23 +84,31 @@ export const intlayerNodePlugins = {
84
84
  canHandle: (node) => typeof node === 'bigint' ||
85
85
  typeof node === 'string' ||
86
86
  typeof node === 'number',
87
- transform: (node, { children, ...rest }) => {
87
+ transform: (node, props) => {
88
88
  // Node-level analytics: record which content is resolved for display.
89
89
  // No-op (and dead-code-eliminated) when analytics is disabled.
90
90
  if (process.env.INTLAYER_ANALYTICS_ENABLED !== 'false') {
91
91
  reportExposure({
92
- dictionaryKey: rest.dictionaryKey,
93
- keyPath: rest.keyPath,
94
- locale: rest.locale,
92
+ dictionaryKey: props.dictionaryKey,
93
+ keyPath: props.keyPath,
94
+ locale: props.locale,
95
95
  nodeType: 'text',
96
96
  });
97
97
  }
98
+ // Props are only forwarded to the editor selector: copying them for every
99
+ // leaf would cost an allocation per rendered string
100
+ if (process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled) {
101
+ const { children, ...rest } = props;
102
+ return renderIntlayerNode({
103
+ value: children ?? node,
104
+ component: ContentSelector,
105
+ props: rest,
106
+ });
107
+ }
98
108
  return renderIntlayerNode({
99
- value: children ?? node,
100
- component: process.env.INTLAYER_EDITOR_ENABLED !== 'false' && editor.enabled
101
- ? ContentSelector
102
- : undefined,
103
- props: rest,
109
+ value: props.children ?? node,
110
+ component: undefined,
111
+ props: {},
104
112
  });
105
113
  },
106
114
  };
@@ -240,37 +248,20 @@ export const markdownStringPlugin = process.env.INTLAYER_NODE_TYPE_MARKDOWN ===
240
248
  dictionaryKey: rest.dictionaryKey,
241
249
  keyPath: [],
242
250
  }) ?? {};
243
- const render = (components) => {
244
- const nodeResult = renderIntlayerNode({
251
+ const render = (components) => renderIntlayerNode({
252
+ value: node,
253
+ component: resolveMarkdownRenderer(),
254
+ props: {
255
+ ...rest,
245
256
  value: node,
246
- component: resolveMarkdownRenderer(),
247
- props: {
248
- ...rest,
249
- value: node,
250
- ...components,
251
- },
252
- additionalProps: {
253
- metadata: metadataNodes,
254
- },
255
- });
256
- return new Proxy(nodeResult, {
257
- get(target, prop, receiver) {
258
- if (prop === 'value') {
259
- return node;
260
- }
261
- if (prop === 'metadata') {
262
- return metadataNodes;
263
- }
264
- if (prop === 'use') {
265
- return (newComponents) => render(newComponents);
266
- }
267
- if (prop === 'toString') {
268
- return () => _compile?.(node, { runtime: _svelteHtmlRuntime, components: components }, {}) ?? node;
269
- }
270
- return Reflect.get(target, prop, receiver);
271
- },
272
- });
273
- };
257
+ ...components,
258
+ },
259
+ additionalProps: {
260
+ metadata: metadataNodes,
261
+ use: render,
262
+ toString: () => _compile?.(node, { runtime: _svelteHtmlRuntime, components: components }, {}) ?? node,
263
+ },
264
+ });
274
265
  return render();
275
266
  },
276
267
  };
@@ -336,6 +327,8 @@ export const getPlugins = (locale, fallback = true) => {
336
327
  return pluginsCache.get(cacheKey);
337
328
  }
338
329
  const plugins = [
330
+ // First: most nodes are plain strings, which every other plugin rejects
331
+ intlayerNodePlugins,
339
332
  translationPlugin(locale ?? internationalization.defaultLocale, fallback ? internationalization.defaultLocale : undefined),
340
333
  enumerationPlugin,
341
334
  pluralPlugin(locale ?? internationalization.defaultLocale),
@@ -344,12 +337,13 @@ export const getPlugins = (locale, fallback = true) => {
344
337
  filePlugin,
345
338
  genderPlugin,
346
339
  selectPlugin,
347
- intlayerNodePlugins,
348
340
  svelteNodePlugins,
349
341
  insertionPlugin,
350
342
  markdownPlugin,
351
343
  htmlPlugin,
352
344
  ];
353
- pluginsCache.set(cacheKey, plugins);
354
- return plugins;
345
+ // Plugins disabled at build time never match: skip them on every node
346
+ const enabledPlugins = plugins.filter((plugin) => plugin !== fallbackPlugin);
347
+ pluginsCache.set(cacheKey, enabledPlugins);
348
+ return enabledPlugins;
355
349
  };
@@ -1,21 +1,23 @@
1
1
  // import type { ResolvedEditor } from '@intlayer/types/module_augmentation';
2
+ import { getIntlayerNodePrototype } from '@intlayer/core/utils';
2
3
  import IntlayerNodeWrapper from './IntlayerNodeWrapper.svelte';
3
4
  export const renderIntlayerNode = (args) => {
4
5
  const isClassComponent = Boolean(IntlayerNodeWrapper.prototype?.$destroy);
5
6
  let Node;
6
7
  if (isClassComponent) {
7
- Node = class extends IntlayerNodeWrapper {
8
- constructor(options) {
9
- super({
10
- ...options,
11
- props: {
12
- ...options.props,
13
- Renderer: args.component,
14
- rendererProps: args.props,
15
- value: args.value,
16
- },
17
- });
18
- }
8
+ // A constructor function returning the instance rather than a subclass:
9
+ // `super()` resolves through the constructor's prototype, which is
10
+ // replaced below
11
+ Node = function IntlayerNode(options) {
12
+ return new IntlayerNodeWrapper({
13
+ ...options,
14
+ props: {
15
+ ...options.props,
16
+ Renderer: args.component,
17
+ rendererProps: args.props,
18
+ value: args.value,
19
+ },
20
+ });
19
21
  };
20
22
  }
21
23
  else {
@@ -33,40 +35,11 @@ export const renderIntlayerNode = (args) => {
33
35
  writable: true,
34
36
  configurable: true,
35
37
  });
36
- Object.defineProperty(Node, 'toString', {
37
- value: () => String(args.value ?? ''),
38
- writable: true,
39
- configurable: true,
40
- });
41
- Object.defineProperty(Node, 'valueOf', {
42
- value: () => args.value,
43
- writable: true,
44
- configurable: true,
45
- });
46
- Object.defineProperty(Node, Symbol.toPrimitive, {
47
- value: () => args.value ?? '',
48
- writable: true,
49
- configurable: true,
50
- });
51
- // Delegate native methods from the underlying value to Node (any type).
52
- if (args.value !== null && args.value !== undefined) {
53
- const valObj = Object(args.value); // Safely boxes primitives (e.g., 50 -> Number object)
54
- const proto = Object.getPrototypeOf(valObj);
55
- for (const prop of Object.getOwnPropertyNames(proto)) {
56
- if (prop === 'constructor' || prop in Node)
57
- continue;
58
- const valProp = valObj[prop]; // read from instance so length/index values are correct
59
- if (typeof valProp === 'function') {
60
- Object.defineProperty(Node, prop, {
61
- value: valProp.bind(args.value),
62
- writable: true,
63
- configurable: true,
64
- });
65
- }
66
- }
67
- }
68
38
  if (args.additionalProps) {
69
39
  Object.assign(Node, args.additionalProps);
70
40
  }
41
+ // Serves the value's members (`node.toUpperCase()`), after the assignments
42
+ // above so they never walk a Proxy in the prototype chain
43
+ Object.setPrototypeOf(Node, getIntlayerNodePrototype(args.value, Function.prototype));
71
44
  return Node;
72
45
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,56 @@
1
+ import { cond, enu, insert, select } from '@intlayer/core/transpiler';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+ // ---------------------------------------------------------------------------
4
+ // Mocks – must be declared before any import that transitively loads them.
5
+ // ---------------------------------------------------------------------------
6
+ const mockConfig = vi.hoisted(() => ({
7
+ editor: { enabled: false },
8
+ internationalization: { defaultLocale: 'en', locales: ['en'] },
9
+ }));
10
+ vi.mock('@intlayer/config/built', () => ({
11
+ default: mockConfig,
12
+ editor: mockConfig.editor,
13
+ internationalization: mockConfig.internationalization,
14
+ }));
15
+ // Mock the Svelte wrapper component so vitest doesn't try to parse it.
16
+ vi.mock('./IntlayerNodeWrapper.svelte', () => ({
17
+ default: () => null,
18
+ }));
19
+ // Mock the editor module (exports Svelte components).
20
+ vi.mock('./editor', () => ({
21
+ ContentSelector: () => null,
22
+ }));
23
+ // Mock Svelte markdown components.
24
+ vi.mock('./markdown/MarkdownMetadataWithSelector.svelte', () => ({
25
+ default: () => null,
26
+ }));
27
+ vi.mock('./markdown/MarkdownWithSelector.svelte', () => ({
28
+ default: () => null,
29
+ }));
30
+ vi.mock('./markdown/runtime', () => ({
31
+ svelteHtmlRuntime: {},
32
+ }));
33
+ import { getDictionary } from './getDictionary';
34
+ const resolve = (node) => getDictionary({ key: 'selector-nodes', content: { node } }, 'en').node;
35
+ /**
36
+ * Svelte nodes are components (functions exposing `.value`): selector nodes
37
+ * must return them, never call them with the selector values.
38
+ */
39
+ describe('selector nodes with object selectors', () => {
40
+ it('should resolve an enumeration from { count }', () => {
41
+ const node = resolve(enu({ '1': 'One item', '>1': 'Many items' }));
42
+ expect(node({ count: 5 }).value).toBe('Many items');
43
+ });
44
+ it('should resolve a condition from { value }', () => {
45
+ const node = resolve(cond({ true: 'On', false: 'Off' }));
46
+ expect(node({ value: false }).value).toBe('Off');
47
+ });
48
+ it('should resolve a select from { value }', () => {
49
+ const node = resolve(select({ a: 'A', fallback: 'F' }));
50
+ expect(node({ value: 'a' }).value).toBe('A');
51
+ });
52
+ it('should resolve an inserted enumeration', () => {
53
+ const node = resolve(insert(enu({ '>1': '{{count}} items' })));
54
+ expect(node({ count: 5 })(5).value).toBe('5 items');
55
+ });
56
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-intlayer",
3
- "version": "9.5.9-canary.0",
3
+ "version": "9.5.10",
4
4
  "description": "Easily internationalize i18n your Svelte applications with type-safe multilingual content management.",
5
5
  "keywords": [
6
6
  "intlayer",
@@ -83,11 +83,11 @@
83
83
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
84
84
  },
85
85
  "dependencies": {
86
- "@intlayer/api": "9.5.8",
87
- "@intlayer/config": "9.5.8",
88
- "@intlayer/core": "9.5.8",
89
- "@intlayer/editor": "9.5.8",
90
- "@intlayer/types": "9.5.8"
86
+ "@intlayer/api": "9.5.10",
87
+ "@intlayer/config": "9.5.10",
88
+ "@intlayer/core": "9.5.10",
89
+ "@intlayer/editor": "9.5.10",
90
+ "@intlayer/types": "9.5.10"
91
91
  },
92
92
  "devDependencies": {
93
93
  "@sveltejs/adapter-auto": "7.0.1",
@@ -102,14 +102,14 @@
102
102
  "svelte-check": "4.7.5",
103
103
  "tsdown": "0.23.0",
104
104
  "typescript": "5.9.3",
105
- "vite": "8.3.0",
106
- "vitest": "5.0.1"
105
+ "vite": "8.3.1",
106
+ "vitest": "5.0.2"
107
107
  },
108
108
  "peerDependencies": {
109
109
  "svelte": ">=5.0.0"
110
110
  },
111
111
  "optionalDependencies": {
112
- "@intlayer/analytics": "9.5.8"
112
+ "@intlayer/analytics": "9.5.10"
113
113
  },
114
114
  "engines": {
115
115
  "node": ">=14.18"