@intlayer/core 9.0.0-canary.0 → 9.0.0-canary.1

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.
Files changed (99) hide show
  1. package/dist/cjs/localization/getPrefix.cjs.map +1 -1
  2. package/dist/cjs/transpiler/markdown/validateMarkdown.cjs +6 -6
  3. package/dist/cjs/transpiler/markdown/validateMarkdown.cjs.map +1 -1
  4. package/dist/esm/localization/getPrefix.mjs.map +1 -1
  5. package/dist/esm/transpiler/markdown/validateMarkdown.mjs +6 -6
  6. package/dist/esm/transpiler/markdown/validateMarkdown.mjs.map +1 -1
  7. package/dist/types/interpreter/getPlural.d.ts +1 -1
  8. package/dist/types/localization/getPrefix.d.ts +4 -18
  9. package/dist/types/localization/getPrefix.d.ts.map +1 -1
  10. package/dist/types/transpiler/markdown/validateMarkdown.d.ts.map +1 -1
  11. package/package.json +7 -7
  12. package/dist/cjs/interpreter/getCollection.cjs +0 -25
  13. package/dist/cjs/interpreter/getCollection.cjs.map +0 -1
  14. package/dist/cjs/interpreter/getVariant.cjs +0 -30
  15. package/dist/cjs/interpreter/getVariant.cjs.map +0 -1
  16. package/dist/cjs/transpiler/collection/collection.cjs +0 -32
  17. package/dist/cjs/transpiler/collection/collection.cjs.map +0 -1
  18. package/dist/cjs/transpiler/collection/index.cjs +0 -4
  19. package/dist/cjs/transpiler/variant/index.cjs +0 -4
  20. package/dist/cjs/transpiler/variant/variant.cjs +0 -35
  21. package/dist/cjs/transpiler/variant/variant.cjs.map +0 -1
  22. package/dist/esm/interpreter/getCollection.mjs +0 -23
  23. package/dist/esm/interpreter/getCollection.mjs.map +0 -1
  24. package/dist/esm/interpreter/getVariant.mjs +0 -28
  25. package/dist/esm/interpreter/getVariant.mjs.map +0 -1
  26. package/dist/esm/transpiler/collection/collection.mjs +0 -30
  27. package/dist/esm/transpiler/collection/collection.mjs.map +0 -1
  28. package/dist/esm/transpiler/collection/index.mjs +0 -3
  29. package/dist/esm/transpiler/variant/index.mjs +0 -3
  30. package/dist/esm/transpiler/variant/variant.mjs +0 -33
  31. package/dist/esm/transpiler/variant/variant.mjs.map +0 -1
  32. package/dist/types/@intlayer/core/dist/types/formatters/compact.d.ts +0 -1
  33. package/dist/types/@intlayer/core/dist/types/formatters/currency.d.ts +0 -1
  34. package/dist/types/@intlayer/core/dist/types/formatters/date.d.ts +0 -1
  35. package/dist/types/@intlayer/core/dist/types/formatters/index.d.ts +0 -1
  36. package/dist/types/@intlayer/core/dist/types/formatters/list.d.ts +0 -1
  37. package/dist/types/@intlayer/core/dist/types/formatters/number.d.ts +0 -1
  38. package/dist/types/@intlayer/core/dist/types/formatters/percentage.d.ts +0 -1
  39. package/dist/types/@intlayer/core/dist/types/formatters/relativeTime.d.ts +0 -1
  40. package/dist/types/@intlayer/core/dist/types/formatters/units.d.ts +0 -1
  41. package/dist/types/@intlayer/core/dist/types/interpreter/getCondition.d.ts +0 -1
  42. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/deepTransform.d.ts +0 -1
  43. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/getContent.d.ts +0 -2
  44. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/plugins.d.ts +0 -4
  45. package/dist/types/@intlayer/core/dist/types/interpreter/getDictionary.d.ts +0 -2
  46. package/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +0 -1
  47. package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayer.d.ts +0 -2
  48. package/dist/types/@intlayer/core/dist/types/interpreter/getNesting.d.ts +0 -2
  49. package/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +0 -1
  50. package/dist/types/@intlayer/core/dist/types/interpreter/getTranslation.d.ts +0 -1
  51. package/dist/types/@intlayer/core/dist/types/interpreter/getVariant.d.ts +0 -1
  52. package/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +0 -1
  53. package/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +0 -1
  54. package/dist/types/@intlayer/core/dist/types/localization/generateSitemap.d.ts +0 -2
  55. package/dist/types/@intlayer/core/dist/types/localization/getBrowserLocale.d.ts +0 -1
  56. package/dist/types/@intlayer/core/dist/types/localization/getHTMLTextDir.d.ts +0 -1
  57. package/dist/types/@intlayer/core/dist/types/localization/getLocale.d.ts +0 -1
  58. package/dist/types/@intlayer/core/dist/types/localization/getLocaleFromPath.d.ts +0 -1
  59. package/dist/types/@intlayer/core/dist/types/localization/getLocaleLang.d.ts +0 -1
  60. package/dist/types/@intlayer/core/dist/types/localization/getLocaleName.d.ts +0 -1
  61. package/dist/types/@intlayer/core/dist/types/localization/getLocalizedUrl.d.ts +0 -1
  62. package/dist/types/@intlayer/core/dist/types/localization/getMultilingualUrls.d.ts +0 -1
  63. package/dist/types/@intlayer/core/dist/types/localization/getPathWithoutLocale.d.ts +0 -1
  64. package/dist/types/@intlayer/core/dist/types/localization/getPrefix.d.ts +0 -3
  65. package/dist/types/@intlayer/core/dist/types/localization/index.d.ts +0 -1
  66. package/dist/types/@intlayer/core/dist/types/localization/localeDetector.d.ts +0 -1
  67. package/dist/types/@intlayer/core/dist/types/localization/localeMapper.d.ts +0 -2
  68. package/dist/types/@intlayer/core/dist/types/localization/localeResolver.d.ts +0 -2
  69. package/dist/types/@intlayer/core/dist/types/localization/rewriteUtils.d.ts +0 -3
  70. package/dist/types/@intlayer/core/dist/types/localization/validatePrefix.d.ts +0 -1
  71. package/dist/types/@intlayer/core/dist/types/markdown/index.d.ts +0 -1
  72. package/dist/types/@intlayer/core/dist/types/transpiler/collection/collection.d.ts +0 -1
  73. package/dist/types/@intlayer/core/dist/types/transpiler/condition/condition.d.ts +0 -1
  74. package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/enumeration.d.ts +0 -1
  75. package/dist/types/@intlayer/core/dist/types/transpiler/file/file.d.ts +0 -1
  76. package/dist/types/@intlayer/core/dist/types/transpiler/gender/gender.d.ts +0 -1
  77. package/dist/types/@intlayer/core/dist/types/transpiler/html/html.d.ts +0 -1
  78. package/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +0 -1
  79. package/dist/types/@intlayer/core/dist/types/transpiler/insertion/insertion.d.ts +0 -1
  80. package/dist/types/@intlayer/core/dist/types/transpiler/markdown/markdown.d.ts +0 -1
  81. package/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +0 -2
  82. package/dist/types/@intlayer/core/dist/types/transpiler/plural/plural.d.ts +0 -1
  83. package/dist/types/@intlayer/core/dist/types/transpiler/translation/translation.d.ts +0 -2
  84. package/dist/types/@intlayer/core/dist/types/transpiler/variant/variant.d.ts +0 -1
  85. package/dist/types/@intlayer/core/dist/types/utils/index.d.ts +0 -1
  86. package/dist/types/@intlayer/core/dist/types/utils/intl.d.ts +0 -1
  87. package/dist/types/@intlayer/core/dist/types/utils/isSameKeyPath.d.ts +0 -1
  88. package/dist/types/@intlayer/core/dist/types/utils/localeStorage.d.ts +0 -2
  89. package/dist/types/interpreter/getCollection.d.ts +0 -19
  90. package/dist/types/interpreter/getCollection.d.ts.map +0 -1
  91. package/dist/types/interpreter/getVariant.d.ts +0 -26
  92. package/dist/types/interpreter/getVariant.d.ts.map +0 -1
  93. package/dist/types/intlayer/dist/types/index.d.ts +0 -4
  94. package/dist/types/transpiler/collection/collection.d.ts +0 -34
  95. package/dist/types/transpiler/collection/collection.d.ts.map +0 -1
  96. package/dist/types/transpiler/collection/index.d.ts +0 -2
  97. package/dist/types/transpiler/variant/index.d.ts +0 -2
  98. package/dist/types/transpiler/variant/variant.d.ts +0 -43
  99. package/dist/types/transpiler/variant/variant.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"getPrefix.cjs","names":["internationalization","DEFAULT_LOCALE","routing","ROUTING_MODE","LOCALES"],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Shared routing options used across all URL localization functions.\n */\nexport type RoutingOptions = {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n domains?: RoutingConfig['domains'];\n /**\n * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).\n * When provided, `getLocalizedUrl` returns a relative URL for locales whose\n * configured domain matches `currentDomain`, and an absolute URL only when\n * the target locale lives on a different domain.\n *\n * When omitted the function tries to infer it from:\n * 1. The domain of an absolute input URL.\n * 2. `window.location.hostname` in browser environments.\n * Falls back to always generating absolute URLs when neither is available.\n */\n currentDomain?: string;\n};\n\n/**\n * Resolves routing configuration by merging provided options with configuration defaults.\n * Single source of truth for default routing config resolution across all localization functions.\n */\nexport const resolveRoutingConfig = (options: RoutingOptions = {}) => ({\n defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,\n mode: routing?.mode ?? ROUTING_MODE,\n locales: internationalization?.locales ?? LOCALES,\n rewrite: routing?.rewrite,\n domains: routing?.domains,\n ...options,\n});\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The locale path segment appended to `/`, with a trailing slash (e.g. `'fr/'`).\n * Empty string when no prefix is needed.\n */\n prefix: string;\n /**\n * The bare locale identifier (e.g. `'fr'`), or `undefined` when no prefix is applied.\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Narrowed return type for {@link getPrefix} that carries the locale literal through.\n *\n * Distributes over union locales — calling `getPrefix('fr')` in `prefix-no-default`\n * mode with `defaultLocale = 'en'` resolves to `{ prefix: 'fr/'; localePrefix: 'fr' }`.\n *\n * Note: domain-based routing and \"locale not in locales\" edge cases may return an\n * empty result at runtime regardless of what this type reports.\n */\nexport type GetPrefixResultNarrowed<\n L extends LocalesValues | undefined,\n Mode extends string = ResolvedRoutingMode,\n Default extends LocalesValues = ResolvedDefaultLocale,\n> = L extends string\n ? [string] extends [L] // L is wide (string / LocalesValues) → distribute over declared locales\n ? GetPrefixResultNarrowed<DeclaredLocales, Mode, Default>\n : [string] extends [Mode]\n ? GetPrefixResult // mode is wide → fall back to generic result\n : Mode extends 'prefix-all'\n ? { prefix: `${L}/`; localePrefix: L }\n : Mode extends 'prefix-no-default'\n ? L extends Default\n ? { prefix: ''; localePrefix: undefined }\n : { prefix: `${L}/`; localePrefix: L }\n : { prefix: ''; localePrefix: undefined } // no-prefix / search-params\n : { prefix: ''; localePrefix: undefined }; // locale is undefined\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = <const L extends LocalesValues | undefined>(\n locale: L,\n options: RoutingOptions = {}\n): GetPrefixResultNarrowed<L> => {\n const { defaultLocale, mode, locales, domains } =\n resolveRoutingConfig(options);\n\n if (\n (process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default') ||\n !locale ||\n !locales.includes(locale)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n\n // If this locale is the only one assigned to its domain, no URL prefix is needed\n // (the domain itself identifies the locale). Shared domains use normal prefix logic.\n if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && domains) {\n const localeDomain = domains[locale as LocalesValues];\n\n if (localeDomain) {\n const localesOnSameDomain = Object.values(domains).filter(\n (domain) => domain === localeDomain\n ).length;\n\n if (localesOnSameDomain === 1) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n }\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n } as GetPrefixResultNarrowed<L>;\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n};\n"],"mappings":";;;;;;;;;;AA+CA,MAAa,wBAAwB,UAA0B,EAAE,MAAM;CACrE,eAAeA,6CAAsB,iBAAiBC;CACtD,MAAMC,gCAAS,QAAQC;CACvB,SAASH,6CAAsB,WAAWI;CAC1C,SAASF,gCAAS;CAClB,SAASA,gCAAS;CAClB,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+ED,MAAa,aACX,QACA,UAA0B,EAAE,KACG;CAC/B,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;AAE/B,KACG,QAAQ,IAAI,4BACX,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B,uBAC3C,CAAC,UACD,CAAC,QAAQ,SAAS,OAAO,CAEzB,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAKH,KAAI,QAAQ,IAAI,gCAAgC,WAAW,SAAS;EAClE,MAAM,eAAe,QAAQ;AAE7B,MAAI,cAKF;OAJ4B,OAAO,OAAO,QAAQ,CAAC,QAChD,WAAW,WAAW,aACxB,CAAC,WAE0B,EAC1B,QAAO;IACL,QAAQ;IACR,cAAc;IACf;;;AAUP,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
1
+ {"version":3,"file":"getPrefix.cjs","names":["internationalization","DEFAULT_LOCALE","routing","ROUTING_MODE","LOCALES"],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Shared routing options used across all URL localization functions.\n */\nexport type RoutingOptions = {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n domains?: RoutingConfig['domains'];\n /**\n * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).\n * When provided, `getLocalizedUrl` returns a relative URL for locales whose\n * configured domain matches `currentDomain`, and an absolute URL only when\n * the target locale lives on a different domain.\n *\n * When omitted the function tries to infer it from:\n * 1. The domain of an absolute input URL.\n * 2. `window.location.hostname` in browser environments.\n * Falls back to always generating absolute URLs when neither is available.\n */\n currentDomain?: string;\n};\n\n/**\n * Resolves routing configuration by merging provided options with configuration defaults.\n * Single source of truth for default routing config resolution across all localization functions.\n */\nexport const resolveRoutingConfig = (\n options: RoutingOptions = {}\n): Omit<RoutingOptions, 'defaultLocale' | 'mode' | 'locales'> & {\n defaultLocale: LocalesValues;\n mode: RoutingConfig['mode'];\n locales: LocalesValues[];\n} => ({\n defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,\n mode: routing?.mode ?? ROUTING_MODE,\n locales: internationalization?.locales ?? LOCALES,\n rewrite: routing?.rewrite,\n domains: routing?.domains,\n ...options,\n});\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The locale path segment appended to `/`, with a trailing slash (e.g. `'fr/'`).\n * Empty string when no prefix is needed.\n */\n prefix: string;\n /**\n * The bare locale identifier (e.g. `'fr'`), or `undefined` when no prefix is applied.\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Narrowed return type for {@link getPrefix} that carries the locale literal through.\n *\n * Distributes over union locales — calling `getPrefix('fr')` in `prefix-no-default`\n * mode with `defaultLocale = 'en'` resolves to `{ prefix: 'fr/'; localePrefix: 'fr' }`.\n *\n * Note: domain-based routing and \"locale not in locales\" edge cases may return an\n * empty result at runtime regardless of what this type reports.\n */\nexport type GetPrefixResultNarrowed<\n L extends LocalesValues | undefined,\n Mode extends string = ResolvedRoutingMode,\n Default extends LocalesValues = ResolvedDefaultLocale,\n> = L extends string\n ? [string] extends [L] // L is wide (string / LocalesValues) → distribute over declared locales\n ? GetPrefixResultNarrowed<DeclaredLocales, Mode, Default>\n : [string] extends [Mode]\n ? GetPrefixResult // mode is wide → fall back to generic result\n : Mode extends 'prefix-all'\n ? { prefix: `${L}/`; localePrefix: L }\n : Mode extends 'prefix-no-default'\n ? L extends Default\n ? { prefix: ''; localePrefix: undefined }\n : { prefix: `${L}/`; localePrefix: L }\n : { prefix: ''; localePrefix: undefined } // no-prefix / search-params\n : { prefix: ''; localePrefix: undefined }; // locale is undefined\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = <const L extends LocalesValues | undefined>(\n locale: L,\n options: RoutingOptions = {}\n): GetPrefixResultNarrowed<L> => {\n const { defaultLocale, mode, locales, domains } =\n resolveRoutingConfig(options);\n\n if (\n (process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default') ||\n !locale ||\n !locales.includes(locale)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n\n // If this locale is the only one assigned to its domain, no URL prefix is needed\n // (the domain itself identifies the locale). Shared domains use normal prefix logic.\n if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && domains) {\n const localeDomain = domains[locale as LocalesValues];\n\n if (localeDomain) {\n const localesOnSameDomain = Object.values(domains).filter(\n (domain) => domain === localeDomain\n ).length;\n\n if (localesOnSameDomain === 1) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n }\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n } as GetPrefixResultNarrowed<L>;\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n};\n"],"mappings":";;;;;;;;;;AA+CA,MAAa,wBACX,UAA0B,EAAE,MAKxB;CACJ,eAAeA,6CAAsB,iBAAiBC;CACtD,MAAMC,gCAAS,QAAQC;CACvB,SAASH,6CAAsB,WAAWI;CAC1C,SAASF,gCAAS;CAClB,SAASA,gCAAS;CAClB,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+ED,MAAa,aACX,QACA,UAA0B,EAAE,KACG;CAC/B,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;AAE/B,KACG,QAAQ,IAAI,4BACX,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B,uBAC3C,CAAC,UACD,CAAC,QAAQ,SAAS,OAAO,CAEzB,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAKH,KAAI,QAAQ,IAAI,gCAAgC,WAAW,SAAS;EAClE,MAAM,eAAe,QAAQ;AAE7B,MAAI,cAKF;OAJ4B,OAAO,OAAO,QAAQ,CAAC,QAChD,WAAW,WAAW,aACxB,CAAC,WAE0B,EAC1B,QAAO;IACL,QAAQ;IACR,cAAc;IACf;;;AAUP,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
@@ -13,13 +13,13 @@ const stripCode = (content) => {
13
13
  let openFence = null;
14
14
  for (const line of lines) {
15
15
  const fence = line.match(/^[\s>]*(`{3,}|~{3,})/);
16
- if (!inCodeBlock) if (fence) {
16
+ if (!inCodeBlock) if (fence?.[1]) {
17
17
  inCodeBlock = true;
18
18
  openFence = fence[1];
19
19
  result.push("");
20
- } else result.push(line.replace(/`[^`\n]+`/g, (m) => " ".repeat(m.length)));
20
+ } else result.push(line.replace(/(`+)(?:(?!\1).)+?\1/g, (m) => " ".repeat(m.length)));
21
21
  else {
22
- if (fence && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
22
+ if (fence?.[1]?.[0] && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
23
23
  inCodeBlock = false;
24
24
  openFence = null;
25
25
  }
@@ -35,14 +35,14 @@ const validateCodeBlocks = (content) => {
35
35
  let openFence = null;
36
36
  let openLineNumber = -1;
37
37
  for (let i = 0; i < lines.length; i++) {
38
- const fence = lines[i].match(/^[\s>]*(`{3,}|~{3,})/);
38
+ const fence = lines[i]?.match(/^[\s>]*(`{3,}|~{3,})/);
39
39
  if (!inCodeBlock) {
40
- if (fence) {
40
+ if (fence?.[1]) {
41
41
  inCodeBlock = true;
42
42
  openFence = fence[1];
43
43
  openLineNumber = i + 1;
44
44
  }
45
- } else if (fence && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
45
+ } else if (fence?.[1] && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
46
46
  inCodeBlock = false;
47
47
  openFence = null;
48
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validateMarkdown.cjs","names":["validateHTML"],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inCodeBlock = false;\n let openFence: string | null = null;\n\n for (const line of lines) {\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n if (!inCodeBlock) {\n if (fence) {\n inCodeBlock = true;\n openFence = fence[1];\n result.push('');\n } else {\n // Also strip inline code spans on this line\n result.push(line.replace(/`[^`\\n]+`/g, (m) => ' '.repeat(m.length)));\n }\n } else {\n if (\n fence &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n result.push('');\n }\n }\n\n return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n const issues: HTMLValidationIssue[] = [];\n const lines = content.split('\\n');\n let inCodeBlock = false;\n let openFence: string | null = null;\n let openLineNumber = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n if (!inCodeBlock) {\n if (fence) {\n inCodeBlock = true;\n openFence = fence[1];\n openLineNumber = i + 1;\n }\n } else {\n if (\n fence &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n }\n }\n\n if (inCodeBlock) {\n issues.push({\n type: 'error',\n message: `Unclosed code block (opened at line ${openLineNumber})`,\n });\n }\n\n return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n const codeIssues = validateCodeBlocks(content);\n const htmlIssues = validateHTML(stripCode(content)).issues;\n const issues = [...codeIssues, ...htmlIssues];\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,SAAmB,EAAE;CAC3B,IAAI,cAAc;CAClB,IAAI,YAA2B;AAE/B,MAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,MAAI,CAAC,YACH,KAAI,OAAO;AACT,iBAAc;AACd,eAAY,MAAM;AAClB,UAAO,KAAK,GAAG;QAGf,QAAO,KAAK,KAAK,QAAQ,eAAe,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,CAAC;OAEjE;AACL,OACE,SACA,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,kBAAc;AACd,gBAAY;;AAEd,UAAO,KAAK,GAAG;;;AAInB,QAAO,OAAO,KAAK,KAAK;;AAG1B,MAAM,sBAAsB,YAA2C;CACrE,MAAM,SAAgC,EAAE;CACxC,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,IAAI,cAAc;CAClB,IAAI,YAA2B;CAC/B,IAAI,iBAAiB;AAErB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EAGrC,MAAM,QAFO,MAAM,GAEA,MAAM,uBAAuB;AAEhD,MAAI,CAAC,aACH;OAAI,OAAO;AACT,kBAAc;AACd,gBAAY,MAAM;AAClB,qBAAiB,IAAI;;aAIrB,SACA,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,iBAAc;AACd,eAAY;;;AAKlB,KAAI,YACF,QAAO,KAAK;EACV,MAAM;EACN,SAAS,uCAAuC,eAAe;EAChE,CAAC;AAGJ,QAAO;;;;;;;;;AAUT,MAAa,oBAAoB,YAA8C;CAC7E,MAAM,aAAa,mBAAmB,QAAQ;CAC9C,MAAM,aAAaA,kDAAa,UAAU,QAAQ,CAAC,CAAC;CACpD,MAAM,SAAS,CAAC,GAAG,YAAY,GAAG,WAAW;AAE7C,QAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC,WAAW;EAC3D;EACD"}
1
+ {"version":3,"file":"validateMarkdown.cjs","names":["validateHTML"],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inCodeBlock = false;\n let openFence: string | null = null;\n\n for (const line of lines) {\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n result.push('');\n } else {\n // Also strip inline code spans on this line. Code spans may be\n // delimited by a run of one or more backticks and end with a matching\n // run of the same length (CommonMark), allowing shorter backtick runs\n // inside (e.g. `` t`Hello ${name}` ``).\n result.push(\n line.replace(/(`+)(?:(?!\\1).)+?\\1/g, (m) => ' '.repeat(m.length))\n );\n }\n } else {\n if (\n fence?.[1]?.[0] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n result.push('');\n }\n }\n\n return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n const issues: HTMLValidationIssue[] = [];\n const lines = content.split('\\n');\n let inCodeBlock = false;\n let openFence: string | null = null;\n let openLineNumber = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line?.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n openLineNumber = i + 1;\n }\n } else {\n if (\n fence?.[1] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n }\n }\n\n if (inCodeBlock) {\n issues.push({\n type: 'error',\n message: `Unclosed code block (opened at line ${openLineNumber})`,\n });\n }\n\n return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n const codeIssues = validateCodeBlocks(content);\n const htmlIssues = validateHTML(stripCode(content)).issues;\n const issues = [...codeIssues, ...htmlIssues];\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,SAAmB,EAAE;CAC3B,IAAI,cAAc;CAClB,IAAI,YAA2B;AAE/B,MAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,MAAI,CAAC,YACH,KAAI,QAAQ,IAAI;AACd,iBAAc;AACd,eAAY,MAAM;AAClB,UAAO,KAAK,GAAG;QAMf,QAAO,KACL,KAAK,QAAQ,yBAAyB,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,CAClE;OAEE;AACL,OACE,QAAQ,KAAK,MACb,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,kBAAc;AACd,gBAAY;;AAEd,UAAO,KAAK,GAAG;;;AAInB,QAAO,OAAO,KAAK,KAAK;;AAG1B,MAAM,sBAAsB,YAA2C;CACrE,MAAM,SAAgC,EAAE;CACxC,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,IAAI,cAAc;CAClB,IAAI,YAA2B;CAC/B,IAAI,iBAAiB;AAErB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EAGrC,MAAM,QAFO,MAAM,IAEC,MAAM,uBAAuB;AAEjD,MAAI,CAAC,aACH;OAAI,QAAQ,IAAI;AACd,kBAAc;AACd,gBAAY,MAAM;AAClB,qBAAiB,IAAI;;aAIrB,QAAQ,MACR,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,iBAAc;AACd,eAAY;;;AAKlB,KAAI,YACF,QAAO,KAAK;EACV,MAAM;EACN,SAAS,uCAAuC,eAAe;EAChE,CAAC;AAGJ,QAAO;;;;;;;;;AAUT,MAAa,oBAAoB,YAA8C;CAC7E,MAAM,aAAa,mBAAmB,QAAQ;CAC9C,MAAM,aAAaA,kDAAa,UAAU,QAAQ,CAAC,CAAC;CACpD,MAAM,SAAS,CAAC,GAAG,YAAY,GAAG,WAAW;AAE7C,QAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC,WAAW;EAC3D;EACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"getPrefix.mjs","names":[],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Shared routing options used across all URL localization functions.\n */\nexport type RoutingOptions = {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n domains?: RoutingConfig['domains'];\n /**\n * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).\n * When provided, `getLocalizedUrl` returns a relative URL for locales whose\n * configured domain matches `currentDomain`, and an absolute URL only when\n * the target locale lives on a different domain.\n *\n * When omitted the function tries to infer it from:\n * 1. The domain of an absolute input URL.\n * 2. `window.location.hostname` in browser environments.\n * Falls back to always generating absolute URLs when neither is available.\n */\n currentDomain?: string;\n};\n\n/**\n * Resolves routing configuration by merging provided options with configuration defaults.\n * Single source of truth for default routing config resolution across all localization functions.\n */\nexport const resolveRoutingConfig = (options: RoutingOptions = {}) => ({\n defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,\n mode: routing?.mode ?? ROUTING_MODE,\n locales: internationalization?.locales ?? LOCALES,\n rewrite: routing?.rewrite,\n domains: routing?.domains,\n ...options,\n});\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The locale path segment appended to `/`, with a trailing slash (e.g. `'fr/'`).\n * Empty string when no prefix is needed.\n */\n prefix: string;\n /**\n * The bare locale identifier (e.g. `'fr'`), or `undefined` when no prefix is applied.\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Narrowed return type for {@link getPrefix} that carries the locale literal through.\n *\n * Distributes over union locales — calling `getPrefix('fr')` in `prefix-no-default`\n * mode with `defaultLocale = 'en'` resolves to `{ prefix: 'fr/'; localePrefix: 'fr' }`.\n *\n * Note: domain-based routing and \"locale not in locales\" edge cases may return an\n * empty result at runtime regardless of what this type reports.\n */\nexport type GetPrefixResultNarrowed<\n L extends LocalesValues | undefined,\n Mode extends string = ResolvedRoutingMode,\n Default extends LocalesValues = ResolvedDefaultLocale,\n> = L extends string\n ? [string] extends [L] // L is wide (string / LocalesValues) → distribute over declared locales\n ? GetPrefixResultNarrowed<DeclaredLocales, Mode, Default>\n : [string] extends [Mode]\n ? GetPrefixResult // mode is wide → fall back to generic result\n : Mode extends 'prefix-all'\n ? { prefix: `${L}/`; localePrefix: L }\n : Mode extends 'prefix-no-default'\n ? L extends Default\n ? { prefix: ''; localePrefix: undefined }\n : { prefix: `${L}/`; localePrefix: L }\n : { prefix: ''; localePrefix: undefined } // no-prefix / search-params\n : { prefix: ''; localePrefix: undefined }; // locale is undefined\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = <const L extends LocalesValues | undefined>(\n locale: L,\n options: RoutingOptions = {}\n): GetPrefixResultNarrowed<L> => {\n const { defaultLocale, mode, locales, domains } =\n resolveRoutingConfig(options);\n\n if (\n (process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default') ||\n !locale ||\n !locales.includes(locale)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n\n // If this locale is the only one assigned to its domain, no URL prefix is needed\n // (the domain itself identifies the locale). Shared domains use normal prefix logic.\n if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && domains) {\n const localeDomain = domains[locale as LocalesValues];\n\n if (localeDomain) {\n const localesOnSameDomain = Object.values(domains).filter(\n (domain) => domain === localeDomain\n ).length;\n\n if (localesOnSameDomain === 1) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n }\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n } as GetPrefixResultNarrowed<L>;\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n};\n"],"mappings":";;;;;;;;AA+CA,MAAa,wBAAwB,UAA0B,EAAE,MAAM;CACrE,eAAe,sBAAsB,iBAAiB;CACtD,MAAM,SAAS,QAAQ;CACvB,SAAS,sBAAsB,WAAW;CAC1C,SAAS,SAAS;CAClB,SAAS,SAAS;CAClB,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+ED,MAAa,aACX,QACA,UAA0B,EAAE,KACG;CAC/B,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;AAE/B,KACG,QAAQ,IAAI,4BACX,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B,uBAC3C,CAAC,UACD,CAAC,QAAQ,SAAS,OAAO,CAEzB,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAKH,KAAI,QAAQ,IAAI,gCAAgC,WAAW,SAAS;EAClE,MAAM,eAAe,QAAQ;AAE7B,MAAI,cAKF;OAJ4B,OAAO,OAAO,QAAQ,CAAC,QAChD,WAAW,WAAW,aACxB,CAAC,WAE0B,EAC1B,QAAO;IACL,QAAQ;IACR,cAAc;IACf;;;AAUP,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
1
+ {"version":3,"file":"getPrefix.mjs","names":[],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import { internationalization, routing } from '@intlayer/config/built';\nimport {\n DEFAULT_LOCALE,\n LOCALES,\n ROUTING_MODE,\n} from '@intlayer/config/defaultValues';\n\n// ── Tree-shake constants ──────────────────────────────────────────────────────\n// When these env vars are injected at build time, bundlers eliminate the\n// branches guarded by these constants.\n\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { RoutingConfig } from '@intlayer/types/config';\nimport type {\n DeclaredLocales,\n LocalesValues,\n ResolvedDefaultLocale,\n ResolvedRoutingMode,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Shared routing options used across all URL localization functions.\n */\nexport type RoutingOptions = {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n rewrite?: RoutingConfig['rewrite'];\n domains?: RoutingConfig['domains'];\n /**\n * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).\n * When provided, `getLocalizedUrl` returns a relative URL for locales whose\n * configured domain matches `currentDomain`, and an absolute URL only when\n * the target locale lives on a different domain.\n *\n * When omitted the function tries to infer it from:\n * 1. The domain of an absolute input URL.\n * 2. `window.location.hostname` in browser environments.\n * Falls back to always generating absolute URLs when neither is available.\n */\n currentDomain?: string;\n};\n\n/**\n * Resolves routing configuration by merging provided options with configuration defaults.\n * Single source of truth for default routing config resolution across all localization functions.\n */\nexport const resolveRoutingConfig = (\n options: RoutingOptions = {}\n): Omit<RoutingOptions, 'defaultLocale' | 'mode' | 'locales'> & {\n defaultLocale: LocalesValues;\n mode: RoutingConfig['mode'];\n locales: LocalesValues[];\n} => ({\n defaultLocale: internationalization?.defaultLocale ?? DEFAULT_LOCALE,\n mode: routing?.mode ?? ROUTING_MODE,\n locales: internationalization?.locales ?? LOCALES,\n rewrite: routing?.rewrite,\n domains: routing?.domains,\n ...options,\n});\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: RoutingConfig['mode'];\n};\n\nexport type GetPrefixResult = {\n /**\n * The locale path segment appended to `/`, with a trailing slash (e.g. `'fr/'`).\n * Empty string when no prefix is needed.\n */\n prefix: string;\n /**\n * The bare locale identifier (e.g. `'fr'`), or `undefined` when no prefix is applied.\n */\n localePrefix: Locale | undefined;\n};\n\n/**\n * Narrowed return type for {@link getPrefix} that carries the locale literal through.\n *\n * Distributes over union locales — calling `getPrefix('fr')` in `prefix-no-default`\n * mode with `defaultLocale = 'en'` resolves to `{ prefix: 'fr/'; localePrefix: 'fr' }`.\n *\n * Note: domain-based routing and \"locale not in locales\" edge cases may return an\n * empty result at runtime regardless of what this type reports.\n */\nexport type GetPrefixResultNarrowed<\n L extends LocalesValues | undefined,\n Mode extends string = ResolvedRoutingMode,\n Default extends LocalesValues = ResolvedDefaultLocale,\n> = L extends string\n ? [string] extends [L] // L is wide (string / LocalesValues) → distribute over declared locales\n ? GetPrefixResultNarrowed<DeclaredLocales, Mode, Default>\n : [string] extends [Mode]\n ? GetPrefixResult // mode is wide → fall back to generic result\n : Mode extends 'prefix-all'\n ? { prefix: `${L}/`; localePrefix: L }\n : Mode extends 'prefix-no-default'\n ? L extends Default\n ? { prefix: ''; localePrefix: undefined }\n : { prefix: `${L}/`; localePrefix: L }\n : { prefix: ''; localePrefix: undefined } // no-prefix / search-params\n : { prefix: ''; localePrefix: undefined }; // locale is undefined\n\n/**\n * Determines the URL prefix for a given locale based on the routing mode configuration.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode with default locale\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // prefix-no-default mode with non-default locale\n * getPrefix('fr', { defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { prefix: '/fr', localePrefix: 'fr' }\n *\n * // prefix-all mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { prefix: '/en', localePrefix: locale }\n *\n * // search-params mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'search-params' })\n * // Returns { prefix: '', localePrefix: undefined }\n *\n * // no-prefix mode\n * getPrefix('en', { defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { prefix: '', localePrefix: undefined }\n * ```\n *\n * @param locale - The locale to check for prefix. If not provided, uses configured default locale.\n * @param options - Configuration options\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.\n */\nexport const getPrefix = <const L extends LocalesValues | undefined>(\n locale: L,\n options: RoutingOptions = {}\n): GetPrefixResultNarrowed<L> => {\n const { defaultLocale, mode, locales, domains } =\n resolveRoutingConfig(options);\n\n if (\n (process.env['INTLAYER_ROUTING_MODE'] &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-all' &&\n process.env['INTLAYER_ROUTING_MODE'] !== 'prefix-no-default') ||\n !locale ||\n !locales.includes(locale)\n ) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n\n // If this locale is the only one assigned to its domain, no URL prefix is needed\n // (the domain itself identifies the locale). Shared domains use normal prefix logic.\n if (process.env['INTLAYER_ROUTING_DOMAINS'] !== 'false' && domains) {\n const localeDomain = domains[locale as LocalesValues];\n\n if (localeDomain) {\n const localesOnSameDomain = Object.values(domains).filter(\n (domain) => domain === localeDomain\n ).length;\n\n if (localesOnSameDomain === 1) {\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n }\n }\n }\n\n // Handle prefix-based modes (prefix-all or prefix-no-default)\n const shouldPrefix =\n mode === 'prefix-all' ||\n (mode === 'prefix-no-default' && defaultLocale !== locale);\n\n if (shouldPrefix) {\n return {\n prefix: `${locale}/`,\n localePrefix: locale as Locale,\n } as GetPrefixResultNarrowed<L>;\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n } as GetPrefixResultNarrowed<L>;\n};\n"],"mappings":";;;;;;;;AA+CA,MAAa,wBACX,UAA0B,EAAE,MAKxB;CACJ,eAAe,sBAAsB,iBAAiB;CACtD,MAAM,SAAS,QAAQ;CACvB,SAAS,sBAAsB,WAAW;CAC1C,SAAS,SAAS;CAClB,SAAS,SAAS;CAClB,GAAG;CACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+ED,MAAa,aACX,QACA,UAA0B,EAAE,KACG;CAC/B,MAAM,EAAE,eAAe,MAAM,SAAS,YACpC,qBAAqB,QAAQ;AAE/B,KACG,QAAQ,IAAI,4BACX,QAAQ,IAAI,6BAA6B,gBACzC,QAAQ,IAAI,6BAA6B,uBAC3C,CAAC,UACD,CAAC,QAAQ,SAAS,OAAO,CAEzB,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAKH,KAAI,QAAQ,IAAI,gCAAgC,WAAW,SAAS;EAClE,MAAM,eAAe,QAAQ;AAE7B,MAAI,cAKF;OAJ4B,OAAO,OAAO,QAAQ,CAAC,QAChD,WAAW,WAAW,aACxB,CAAC,WAE0B,EAC1B,QAAO;IACL,QAAQ;IACR,cAAc;IACf;;;AAUP,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
@@ -12,13 +12,13 @@ const stripCode = (content) => {
12
12
  let openFence = null;
13
13
  for (const line of lines) {
14
14
  const fence = line.match(/^[\s>]*(`{3,}|~{3,})/);
15
- if (!inCodeBlock) if (fence) {
15
+ if (!inCodeBlock) if (fence?.[1]) {
16
16
  inCodeBlock = true;
17
17
  openFence = fence[1];
18
18
  result.push("");
19
- } else result.push(line.replace(/`[^`\n]+`/g, (m) => " ".repeat(m.length)));
19
+ } else result.push(line.replace(/(`+)(?:(?!\1).)+?\1/g, (m) => " ".repeat(m.length)));
20
20
  else {
21
- if (fence && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
21
+ if (fence?.[1]?.[0] && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
22
22
  inCodeBlock = false;
23
23
  openFence = null;
24
24
  }
@@ -34,14 +34,14 @@ const validateCodeBlocks = (content) => {
34
34
  let openFence = null;
35
35
  let openLineNumber = -1;
36
36
  for (let i = 0; i < lines.length; i++) {
37
- const fence = lines[i].match(/^[\s>]*(`{3,}|~{3,})/);
37
+ const fence = lines[i]?.match(/^[\s>]*(`{3,}|~{3,})/);
38
38
  if (!inCodeBlock) {
39
- if (fence) {
39
+ if (fence?.[1]) {
40
40
  inCodeBlock = true;
41
41
  openFence = fence[1];
42
42
  openLineNumber = i + 1;
43
43
  }
44
- } else if (fence && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
44
+ } else if (fence?.[1] && fence[1][0] === openFence[0] && fence[1].length >= openFence.length) {
45
45
  inCodeBlock = false;
46
46
  openFence = null;
47
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validateMarkdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inCodeBlock = false;\n let openFence: string | null = null;\n\n for (const line of lines) {\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n if (!inCodeBlock) {\n if (fence) {\n inCodeBlock = true;\n openFence = fence[1];\n result.push('');\n } else {\n // Also strip inline code spans on this line\n result.push(line.replace(/`[^`\\n]+`/g, (m) => ' '.repeat(m.length)));\n }\n } else {\n if (\n fence &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n result.push('');\n }\n }\n\n return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n const issues: HTMLValidationIssue[] = [];\n const lines = content.split('\\n');\n let inCodeBlock = false;\n let openFence: string | null = null;\n let openLineNumber = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n if (!inCodeBlock) {\n if (fence) {\n inCodeBlock = true;\n openFence = fence[1];\n openLineNumber = i + 1;\n }\n } else {\n if (\n fence &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n }\n }\n\n if (inCodeBlock) {\n issues.push({\n type: 'error',\n message: `Unclosed code block (opened at line ${openLineNumber})`,\n });\n }\n\n return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n const codeIssues = validateCodeBlocks(content);\n const htmlIssues = validateHTML(stripCode(content)).issues;\n const issues = [...codeIssues, ...htmlIssues];\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,SAAmB,EAAE;CAC3B,IAAI,cAAc;CAClB,IAAI,YAA2B;AAE/B,MAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,MAAI,CAAC,YACH,KAAI,OAAO;AACT,iBAAc;AACd,eAAY,MAAM;AAClB,UAAO,KAAK,GAAG;QAGf,QAAO,KAAK,KAAK,QAAQ,eAAe,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,CAAC;OAEjE;AACL,OACE,SACA,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,kBAAc;AACd,gBAAY;;AAEd,UAAO,KAAK,GAAG;;;AAInB,QAAO,OAAO,KAAK,KAAK;;AAG1B,MAAM,sBAAsB,YAA2C;CACrE,MAAM,SAAgC,EAAE;CACxC,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,IAAI,cAAc;CAClB,IAAI,YAA2B;CAC/B,IAAI,iBAAiB;AAErB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EAGrC,MAAM,QAFO,MAAM,GAEA,MAAM,uBAAuB;AAEhD,MAAI,CAAC,aACH;OAAI,OAAO;AACT,kBAAc;AACd,gBAAY,MAAM;AAClB,qBAAiB,IAAI;;aAIrB,SACA,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,iBAAc;AACd,eAAY;;;AAKlB,KAAI,YACF,QAAO,KAAK;EACV,MAAM;EACN,SAAS,uCAAuC,eAAe;EAChE,CAAC;AAGJ,QAAO;;;;;;;;;AAUT,MAAa,oBAAoB,YAA8C;CAC7E,MAAM,aAAa,mBAAmB,QAAQ;CAC9C,MAAM,aAAa,aAAa,UAAU,QAAQ,CAAC,CAAC;CACpD,MAAM,SAAS,CAAC,GAAG,YAAY,GAAG,WAAW;AAE7C,QAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC,WAAW;EAC3D;EACD"}
1
+ {"version":3,"file":"validateMarkdown.mjs","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"sourcesContent":["import { type HTMLValidationIssue, validateHTML } from '../html/validateHTML';\n\nexport type { HTMLValidationIssue as MarkdownValidationIssue } from '../html/validateHTML';\n\nexport type MarkdownValidationResult = {\n valid: boolean;\n issues: HTMLValidationIssue[];\n};\n\n/**\n * Strips fenced code blocks and inline code from markdown content so that\n * HTML-like syntax inside code is not mistakenly validated.\n */\nconst stripCode = (content: string): string => {\n const lines = content.split('\\n');\n const result: string[] = [];\n let inCodeBlock = false;\n let openFence: string | null = null;\n\n for (const line of lines) {\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line.match(/^[\\s>]*(`{3,}|~{3,})/);\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n result.push('');\n } else {\n // Also strip inline code spans on this line. Code spans may be\n // delimited by a run of one or more backticks and end with a matching\n // run of the same length (CommonMark), allowing shorter backtick runs\n // inside (e.g. `` t`Hello ${name}` ``).\n result.push(\n line.replace(/(`+)(?:(?!\\1).)+?\\1/g, (m) => ' '.repeat(m.length))\n );\n }\n } else {\n if (\n fence?.[1]?.[0] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n result.push('');\n }\n }\n\n return result.join('\\n');\n};\n\nconst validateCodeBlocks = (content: string): HTMLValidationIssue[] => {\n const issues: HTMLValidationIssue[] = [];\n const lines = content.split('\\n');\n let inCodeBlock = false;\n let openFence: string | null = null;\n let openLineNumber = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Allow leading whitespace and blockquote markers before the fence characters\n const fence = line?.match(/^[\\s>]*(`{3,}|~{3,})/);\n\n if (!inCodeBlock) {\n if (fence?.[1]) {\n inCodeBlock = true;\n openFence = fence[1];\n openLineNumber = i + 1;\n }\n } else {\n if (\n fence?.[1] &&\n fence[1][0] === openFence![0] &&\n fence[1].length >= openFence!.length\n ) {\n inCodeBlock = false;\n openFence = null;\n }\n }\n }\n\n if (inCodeBlock) {\n issues.push({\n type: 'error',\n message: `Unclosed code block (opened at line ${openLineNumber})`,\n });\n }\n\n return issues;\n};\n\n/**\n * Validates markdown content for structural correctness:\n * - All fenced code blocks are properly closed\n * - HTML tags are properly nested and closed\n *\n * HTML inside code blocks is excluded from HTML validation.\n */\nexport const validateMarkdown = (content: string): MarkdownValidationResult => {\n const codeIssues = validateCodeBlocks(content);\n const htmlIssues = validateHTML(stripCode(content)).issues;\n const issues = [...codeIssues, ...htmlIssues];\n\n return {\n valid: issues.filter((i) => i.type === 'error').length === 0,\n issues,\n };\n};\n"],"mappings":";;;;;;;AAaA,MAAM,aAAa,YAA4B;CAC7C,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,SAAmB,EAAE;CAC3B,IAAI,cAAc;CAClB,IAAI,YAA2B;AAE/B,MAAK,MAAM,QAAQ,OAAO;EAExB,MAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,MAAI,CAAC,YACH,KAAI,QAAQ,IAAI;AACd,iBAAc;AACd,eAAY,MAAM;AAClB,UAAO,KAAK,GAAG;QAMf,QAAO,KACL,KAAK,QAAQ,yBAAyB,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,CAClE;OAEE;AACL,OACE,QAAQ,KAAK,MACb,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,kBAAc;AACd,gBAAY;;AAEd,UAAO,KAAK,GAAG;;;AAInB,QAAO,OAAO,KAAK,KAAK;;AAG1B,MAAM,sBAAsB,YAA2C;CACrE,MAAM,SAAgC,EAAE;CACxC,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,IAAI,cAAc;CAClB,IAAI,YAA2B;CAC/B,IAAI,iBAAiB;AAErB,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EAGrC,MAAM,QAFO,MAAM,IAEC,MAAM,uBAAuB;AAEjD,MAAI,CAAC,aACH;OAAI,QAAQ,IAAI;AACd,kBAAc;AACd,gBAAY,MAAM;AAClB,qBAAiB,IAAI;;aAIrB,QAAQ,MACR,MAAM,GAAG,OAAO,UAAW,MAC3B,MAAM,GAAG,UAAU,UAAW,QAC9B;AACA,iBAAc;AACd,eAAY;;;AAKlB,KAAI,YACF,QAAO,KAAK;EACV,MAAM;EACN,SAAS,uCAAuC,eAAe;EAChE,CAAC;AAGJ,QAAO;;;;;;;;;AAUT,MAAa,oBAAoB,YAA8C;CAC7E,MAAM,aAAa,mBAAmB,QAAQ;CAC9C,MAAM,aAAa,aAAa,UAAU,QAAQ,CAAC,CAAC;CACpD,MAAM,SAAS,CAAC,GAAG,YAAY,GAAG,WAAW;AAE7C,QAAO;EACL,OAAO,OAAO,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC,WAAW;EAC3D;EACD"}
@@ -1,6 +1,6 @@
1
1
  import { PluralContentState } from "../transpiler/plural/plural.js";
2
- import { LocalesValues } from "../intlayer/dist/types/index.js";
3
2
  import { DeclaredLocales } from "@intlayer/types";
3
+ import { LocalesValues } from "intlayer";
4
4
 
5
5
  //#region src/interpreter/getPlural.d.ts
6
6
  /**
@@ -29,24 +29,10 @@ type RoutingOptions = {
29
29
  * Resolves routing configuration by merging provided options with configuration defaults.
30
30
  * Single source of truth for default routing config resolution across all localization functions.
31
31
  */
32
- declare const resolveRoutingConfig: (options?: RoutingOptions) => {
33
- locales: any;
34
- defaultLocale: any;
35
- mode: any;
36
- rewrite: any;
37
- domains: any;
38
- /**
39
- * The hostname of the page currently being rendered (e.g. `'intlayer.org'`).
40
- * When provided, `getLocalizedUrl` returns a relative URL for locales whose
41
- * configured domain matches `currentDomain`, and an absolute URL only when
42
- * the target locale lives on a different domain.
43
- *
44
- * When omitted the function tries to infer it from:
45
- * 1. The domain of an absolute input URL.
46
- * 2. `window.location.hostname` in browser environments.
47
- * Falls back to always generating absolute URLs when neither is available.
48
- */
49
- currentDomain?: string;
32
+ declare const resolveRoutingConfig: (options?: RoutingOptions) => Omit<RoutingOptions, "defaultLocale" | "mode" | "locales"> & {
33
+ defaultLocale: LocalesValues;
34
+ mode: RoutingConfig["mode"];
35
+ locales: LocalesValues[];
50
36
  };
51
37
  type GetPrefixOptions = {
52
38
  defaultLocale?: LocalesValues;
@@ -1 +1 @@
1
- {"version":3,"file":"getPrefix.d.ts","names":[],"sources":["../../../src/localization/getPrefix.ts"],"mappings":";;;;;;;AAuBA;KAAY,cAAA;EACV,OAAA,GAAU,aAAA;EACV,aAAA,GAAgB,aAAA;EAChB,IAAA,GAAO,aAAA;EACP,OAAA,GAAU,aAAA;EACV,OAAA,GAAU,aAAA;EAAA;;;;;;;;;;;EAYV,aAAA;AAAA;;;;AAOF;cAAa,oBAAA,GAAwB,OAAA,GAAS,cAAA;;;;;;;;;;;;;AAS9C;;;;;;KAAY,gBAAA;EACV,aAAA,GAAgB,aAAA;EAChB,IAAA,GAAO,aAAA;AAAA;AAAA,KAGG,eAAA;EAAe;;;;EAKzB,MAAA;EAIc;;;EAAd,YAAA,EAAc,MAAA;AAAA;;;;;;;;;;KAYJ,uBAAA,WACA,aAAA,oCACY,mBAAA,kBACN,aAAA,GAAgB,qBAAA,IAC9B,CAAA,oCACkB,CAAA,IAChB,uBAAA,CAAwB,eAAA,EAAiB,IAAA,EAAM,OAAA,sBAC7B,IAAA,IAChB,eAAA,GACA,IAAA;EACI,MAAA,KAAW,CAAA;EAAM,YAAA,EAAc,CAAA;AAAA,IACjC,IAAA,+BACE,CAAA,SAAU,OAAA;EACN,MAAA;EAAY,YAAA;AAAA;EACZ,MAAA,KAAW,CAAA;EAAM,YAAA,EAAc,CAAA;AAAA;EACjC,MAAA;EAAY,YAAA;AAAA;EACpB,MAAA;EAAY,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmCL,SAAA,mBAA6B,aAAA,cACxC,MAAA,EAAQ,CAAA,EACR,OAAA,GAAS,cAAA,KACR,uBAAA,CAAwB,CAAA"}
1
+ {"version":3,"file":"getPrefix.d.ts","names":[],"sources":["../../../src/localization/getPrefix.ts"],"mappings":";;;;;;;AAuBA;KAAY,cAAA;EACV,OAAA,GAAU,aAAA;EACV,aAAA,GAAgB,aAAA;EAChB,IAAA,GAAO,aAAA;EACP,OAAA,GAAU,aAAA;EACV,OAAA,GAAU,aAAA;EAAA;;;;;;;;;;;EAYV,aAAA;AAAA;;;;AAOF;cAAa,oBAAA,GACX,OAAA,GAAS,cAAA,KACR,IAAA,CAAK,cAAA;EACN,aAAA,EAAe,aAAA;EACf,IAAA,EAAM,aAAA;EACN,OAAA,EAAS,aAAA;AAAA;AAAA,KAUC,gBAAA;EACV,aAAA,GAAgB,aAAA;EAChB,IAAA,GAAO,aAAA;AAAA;AAAA,KAGG,eAAA;EAnBD;;;;EAwBT,MAAA;EAtBe;;;EA0Bf,YAAA,EAAc,MAAA;AAAA;;;AAdhB;;;;;;;KA0BY,uBAAA,WACA,aAAA,oCACY,mBAAA,kBACN,aAAA,GAAgB,qBAAA,IAC9B,CAAA,oCACkB,CAAA,IAChB,uBAAA,CAAwB,eAAA,EAAiB,IAAA,EAAM,OAAA,sBAC7B,IAAA,IAChB,eAAA,GACA,IAAA;EACI,MAAA,KAAW,CAAA;EAAM,YAAA,EAAc,CAAA;AAAA,IACjC,IAAA,+BACE,CAAA,SAAU,OAAA;EACN,MAAA;EAAY,YAAA;AAAA;EACZ,MAAA,KAAW,CAAA;EAAM,YAAA,EAAc,CAAA;AAAA;EACjC,MAAA;EAAY,YAAA;AAAA;EACpB,MAAA;EAAY,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmCL,SAAA,mBAA6B,aAAA,cACxC,MAAA,EAAQ,CAAA,EACR,OAAA,GAAS,cAAA,KACR,uBAAA,CAAwB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"validateMarkdown.d.ts","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"mappings":";;;KAIY,wBAAA;EACV,KAAA;EACA,MAAA,EAAQ,mBAAA;AAAA;;;;;;;AAwFV;cAAa,gBAAA,GAAoB,OAAA,aAAkB,wBAAA"}
1
+ {"version":3,"file":"validateMarkdown.d.ts","names":[],"sources":["../../../../src/transpiler/markdown/validateMarkdown.ts"],"mappings":";;;KAIY,wBAAA;EACV,KAAA;EACA,MAAA,EAAQ,mBAAA;AAAA;;;;;;;AA6FV;cAAa,gBAAA,GAAoB,OAAA,aAAkB,wBAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/core",
3
- "version": "9.0.0-canary.0",
3
+ "version": "9.0.0-canary.1",
4
4
  "private": false,
5
5
  "description": "Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.",
6
6
  "keywords": [
@@ -172,11 +172,11 @@
172
172
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
173
173
  },
174
174
  "dependencies": {
175
- "@intlayer/api": "9.0.0-canary.0",
176
- "@intlayer/config": "9.0.0-canary.0",
177
- "@intlayer/dictionaries-entry": "9.0.0-canary.0",
178
- "@intlayer/types": "9.0.0-canary.0",
179
- "@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.0",
175
+ "@intlayer/api": "9.0.0-canary.1",
176
+ "@intlayer/config": "9.0.0-canary.1",
177
+ "@intlayer/dictionaries-entry": "9.0.0-canary.1",
178
+ "@intlayer/types": "9.0.0-canary.1",
179
+ "@intlayer/unmerged-dictionaries-entry": "9.0.0-canary.1",
180
180
  "defu": "6.1.7"
181
181
  },
182
182
  "devDependencies": {
@@ -187,7 +187,7 @@
187
187
  "rimraf": "6.1.3",
188
188
  "tsdown": "0.21.10",
189
189
  "typescript": "6.0.3",
190
- "vitest": "4.1.8"
190
+ "vitest": "4.1.9"
191
191
  },
192
192
  "engines": {
193
193
  "node": ">=14.18"
@@ -1,25 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
-
3
- //#region src/interpreter/getCollection.ts
4
- /**
5
- * Picks a single item from a resolved collection array, or returns the full
6
- * array when no index is requested.
7
- *
8
- * @param items - The already-resolved collection items.
9
- * @param itemIndex - Optional 0-based index of the item to retrieve.
10
- * @returns The item at `itemIndex`, or the full array when no index is given.
11
- *
12
- * @example
13
- * ```ts
14
- * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']
15
- * const one = getCollection(['a', 'b', 'c'], 1); // 'b'
16
- * ```
17
- */
18
- const getCollection = (items, itemIndex) => {
19
- if (itemIndex === void 0 || itemIndex === null) return items;
20
- return items[itemIndex];
21
- };
22
-
23
- //#endregion
24
- exports.getCollection = getCollection;
25
- //# sourceMappingURL=getCollection.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getCollection.cjs","names":[],"sources":["../../../src/interpreter/getCollection.ts"],"sourcesContent":["/**\n * Picks a single item from a resolved collection array, or returns the full\n * array when no index is requested.\n *\n * @param items - The already-resolved collection items.\n * @param itemIndex - Optional 0-based index of the item to retrieve.\n * @returns The item at `itemIndex`, or the full array when no index is given.\n *\n * @example\n * ```ts\n * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']\n * const one = getCollection(['a', 'b', 'c'], 1); // 'b'\n * ```\n */\nexport const getCollection = <T>(items: T[], itemIndex?: number): T | T[] => {\n if (itemIndex === undefined || itemIndex === null) {\n return items;\n }\n\n return items[itemIndex] as T;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAcA,MAAa,iBAAoB,OAAY,cAAgC;AAC3E,KAAI,cAAc,UAAa,cAAc,KAC3C,QAAO;AAGT,QAAO,MAAM"}
@@ -1,30 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
-
3
- //#region src/interpreter/getVariant.ts
4
- /**
5
- * Resolves a variant node to its selected alternative.
6
- *
7
- * Falls back to `control` when the requested `variantKey` does not exist in
8
- * the node or when no key is specified.
9
- *
10
- * @param variantContent - The map of variant alternatives.
11
- * @param variantKey - Optional name of the alternative to select.
12
- * @returns The resolved content for the requested variant.
13
- *
14
- * @example
15
- * ```ts
16
- * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };
17
- *
18
- * getVariant(node); // 'Welcome'
19
- * getVariant(node, 'black_friday'); // 'Up to 50% off'
20
- * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)
21
- * ```
22
- */
23
- const getVariant = (variantContent, variantKey) => {
24
- if (variantKey && variantKey in variantContent) return variantContent[variantKey];
25
- return variantContent.control;
26
- };
27
-
28
- //#endregion
29
- exports.getVariant = getVariant;
30
- //# sourceMappingURL=getVariant.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getVariant.cjs","names":[],"sources":["../../../src/interpreter/getVariant.ts"],"sourcesContent":["import type { VariantContentState } from '../transpiler/variant/variant';\n\n/**\n * Resolves a variant node to its selected alternative.\n *\n * Falls back to `control` when the requested `variantKey` does not exist in\n * the node or when no key is specified.\n *\n * @param variantContent - The map of variant alternatives.\n * @param variantKey - Optional name of the alternative to select.\n * @returns The resolved content for the requested variant.\n *\n * @example\n * ```ts\n * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };\n *\n * getVariant(node); // 'Welcome'\n * getVariant(node, 'black_friday'); // 'Up to 50% off'\n * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)\n * ```\n */\nexport const getVariant = <T>(\n variantContent: VariantContentState<T>,\n variantKey?: string\n): T => {\n if (variantKey && variantKey in variantContent) {\n return variantContent[variantKey] as T;\n }\n\n return variantContent.control as T;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,cACX,gBACA,eACM;AACN,KAAI,cAAc,cAAc,eAC9B,QAAO,eAAe;AAGxB,QAAO,eAAe"}
@@ -1,32 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
3
- let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
4
-
5
- //#region src/transpiler/collection/collection.ts
6
- /**
7
- * Declares an ordered list of content items inside a dictionary.
8
- *
9
- * At runtime, `useIntlayer('my-key')` returns all items as an array.
10
- * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.
11
- *
12
- * @example
13
- * ```ts
14
- * import { t, collection } from 'intlayer';
15
- *
16
- * export default {
17
- * key: 'faq',
18
- * content: collection([
19
- * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },
20
- * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },
21
- * ]),
22
- * } satisfies Dictionary;
23
- * ```
24
- */
25
- const collection = (items) => ({
26
- nodeType: _intlayer_types_nodeType.COLLECTION,
27
- collection: items
28
- });
29
-
30
- //#endregion
31
- exports.collection = collection;
32
- //# sourceMappingURL=collection.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection.cjs","names":["COLLECTION"],"sources":["../../../../src/transpiler/collection/collection.ts"],"sourcesContent":["import { COLLECTION } from '@intlayer/types/nodeType';\n\n/**\n * Shape of a collection node stored in the dictionary JSON.\n * Items may contain any other node type (translations, conditions, etc.).\n */\nexport type CollectionContent<T = unknown> = {\n nodeType: typeof COLLECTION;\n collection: T[];\n};\n\n/**\n * Declares an ordered list of content items inside a dictionary.\n *\n * At runtime, `useIntlayer('my-key')` returns all items as an array.\n * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.\n *\n * @example\n * ```ts\n * import { t, collection } from 'intlayer';\n *\n * export default {\n * key: 'faq',\n * content: collection([\n * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },\n * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },\n * ]),\n * } satisfies Dictionary;\n * ```\n */\nexport const collection = <T>(items: T[]): CollectionContent<T> => ({\n nodeType: COLLECTION,\n collection: items,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,cAAiB,WAAsC;CAClE,UAAUA;CACV,YAAY;CACb"}
@@ -1,4 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_transpiler_collection_collection = require('./collection.cjs');
3
-
4
- exports.collection = require_transpiler_collection_collection.collection;
@@ -1,4 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_transpiler_variant_variant = require('./variant.cjs');
3
-
4
- exports.variant = require_transpiler_variant_variant.variant;
@@ -1,35 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
3
- let _intlayer_types_nodeType = require("@intlayer/types/nodeType");
4
-
5
- //#region src/transpiler/variant/variant.ts
6
- /**
7
- * Declares a set of named content alternatives for A/B testing or feature flags.
8
- *
9
- * The `control` key is mandatory and acts as the default when no variant is
10
- * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.
11
- * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.
12
- *
13
- * @example
14
- * ```ts
15
- * import { t, variant } from 'intlayer';
16
- *
17
- * export default {
18
- * key: 'hero-banner',
19
- * content: {
20
- * headline: variant({
21
- * control: t({ en: 'Welcome', fr: 'Bienvenue' }),
22
- * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\'à -50 %' }),
23
- * }),
24
- * },
25
- * } satisfies Dictionary;
26
- * ```
27
- */
28
- const variant = (variants) => ({
29
- nodeType: _intlayer_types_nodeType.VARIANT,
30
- variant: variants
31
- });
32
-
33
- //#endregion
34
- exports.variant = variant;
35
- //# sourceMappingURL=variant.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variant.cjs","names":["VARIANT"],"sources":["../../../../src/transpiler/variant/variant.ts"],"sourcesContent":["import { VARIANT } from '@intlayer/types/nodeType';\n\n/**\n * Shape of a variant node stored in the dictionary JSON.\n * `control` is the mandatory default/fallback key; all other keys are\n * optional named experiment branches.\n */\nexport type VariantContentState<T = unknown> = { control: T } & Record<\n string,\n T\n>;\n\nexport type VariantContent<T = unknown> = {\n nodeType: typeof VARIANT;\n variant: VariantContentState<T>;\n};\n\n/**\n * Declares a set of named content alternatives for A/B testing or feature flags.\n *\n * The `control` key is mandatory and acts as the default when no variant is\n * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.\n * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.\n *\n * @example\n * ```ts\n * import { t, variant } from 'intlayer';\n *\n * export default {\n * key: 'hero-banner',\n * content: {\n * headline: variant({\n * control: t({ en: 'Welcome', fr: 'Bienvenue' }),\n * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\\'à -50 %' }),\n * }),\n * },\n * } satisfies Dictionary;\n * ```\n */\nexport const variant = <T>(\n variants: { control: T } & Partial<Record<string, T>>\n): VariantContent<T> => ({\n nodeType: VARIANT,\n variant: variants as VariantContentState<T>,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,WACX,cACuB;CACvB,UAAUA;CACV,SAAS;CACV"}
@@ -1,23 +0,0 @@
1
- //#region src/interpreter/getCollection.ts
2
- /**
3
- * Picks a single item from a resolved collection array, or returns the full
4
- * array when no index is requested.
5
- *
6
- * @param items - The already-resolved collection items.
7
- * @param itemIndex - Optional 0-based index of the item to retrieve.
8
- * @returns The item at `itemIndex`, or the full array when no index is given.
9
- *
10
- * @example
11
- * ```ts
12
- * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']
13
- * const one = getCollection(['a', 'b', 'c'], 1); // 'b'
14
- * ```
15
- */
16
- const getCollection = (items, itemIndex) => {
17
- if (itemIndex === void 0 || itemIndex === null) return items;
18
- return items[itemIndex];
19
- };
20
-
21
- //#endregion
22
- export { getCollection };
23
- //# sourceMappingURL=getCollection.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getCollection.mjs","names":[],"sources":["../../../src/interpreter/getCollection.ts"],"sourcesContent":["/**\n * Picks a single item from a resolved collection array, or returns the full\n * array when no index is requested.\n *\n * @param items - The already-resolved collection items.\n * @param itemIndex - Optional 0-based index of the item to retrieve.\n * @returns The item at `itemIndex`, or the full array when no index is given.\n *\n * @example\n * ```ts\n * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']\n * const one = getCollection(['a', 'b', 'c'], 1); // 'b'\n * ```\n */\nexport const getCollection = <T>(items: T[], itemIndex?: number): T | T[] => {\n if (itemIndex === undefined || itemIndex === null) {\n return items;\n }\n\n return items[itemIndex] as T;\n};\n"],"mappings":";;;;;;;;;;;;;;;AAcA,MAAa,iBAAoB,OAAY,cAAgC;AAC3E,KAAI,cAAc,UAAa,cAAc,KAC3C,QAAO;AAGT,QAAO,MAAM"}
@@ -1,28 +0,0 @@
1
- //#region src/interpreter/getVariant.ts
2
- /**
3
- * Resolves a variant node to its selected alternative.
4
- *
5
- * Falls back to `control` when the requested `variantKey` does not exist in
6
- * the node or when no key is specified.
7
- *
8
- * @param variantContent - The map of variant alternatives.
9
- * @param variantKey - Optional name of the alternative to select.
10
- * @returns The resolved content for the requested variant.
11
- *
12
- * @example
13
- * ```ts
14
- * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };
15
- *
16
- * getVariant(node); // 'Welcome'
17
- * getVariant(node, 'black_friday'); // 'Up to 50% off'
18
- * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)
19
- * ```
20
- */
21
- const getVariant = (variantContent, variantKey) => {
22
- if (variantKey && variantKey in variantContent) return variantContent[variantKey];
23
- return variantContent.control;
24
- };
25
-
26
- //#endregion
27
- export { getVariant };
28
- //# sourceMappingURL=getVariant.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getVariant.mjs","names":[],"sources":["../../../src/interpreter/getVariant.ts"],"sourcesContent":["import type { VariantContentState } from '../transpiler/variant/variant';\n\n/**\n * Resolves a variant node to its selected alternative.\n *\n * Falls back to `control` when the requested `variantKey` does not exist in\n * the node or when no key is specified.\n *\n * @param variantContent - The map of variant alternatives.\n * @param variantKey - Optional name of the alternative to select.\n * @returns The resolved content for the requested variant.\n *\n * @example\n * ```ts\n * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };\n *\n * getVariant(node); // 'Welcome'\n * getVariant(node, 'black_friday'); // 'Up to 50% off'\n * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)\n * ```\n */\nexport const getVariant = <T>(\n variantContent: VariantContentState<T>,\n variantKey?: string\n): T => {\n if (variantKey && variantKey in variantContent) {\n return variantContent[variantKey] as T;\n }\n\n return variantContent.control as T;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,cACX,gBACA,eACM;AACN,KAAI,cAAc,cAAc,eAC9B,QAAO,eAAe;AAGxB,QAAO,eAAe"}
@@ -1,30 +0,0 @@
1
- import { COLLECTION } from "@intlayer/types/nodeType";
2
-
3
- //#region src/transpiler/collection/collection.ts
4
- /**
5
- * Declares an ordered list of content items inside a dictionary.
6
- *
7
- * At runtime, `useIntlayer('my-key')` returns all items as an array.
8
- * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.
9
- *
10
- * @example
11
- * ```ts
12
- * import { t, collection } from 'intlayer';
13
- *
14
- * export default {
15
- * key: 'faq',
16
- * content: collection([
17
- * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },
18
- * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },
19
- * ]),
20
- * } satisfies Dictionary;
21
- * ```
22
- */
23
- const collection = (items) => ({
24
- nodeType: COLLECTION,
25
- collection: items
26
- });
27
-
28
- //#endregion
29
- export { collection };
30
- //# sourceMappingURL=collection.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection.mjs","names":[],"sources":["../../../../src/transpiler/collection/collection.ts"],"sourcesContent":["import { COLLECTION } from '@intlayer/types/nodeType';\n\n/**\n * Shape of a collection node stored in the dictionary JSON.\n * Items may contain any other node type (translations, conditions, etc.).\n */\nexport type CollectionContent<T = unknown> = {\n nodeType: typeof COLLECTION;\n collection: T[];\n};\n\n/**\n * Declares an ordered list of content items inside a dictionary.\n *\n * At runtime, `useIntlayer('my-key')` returns all items as an array.\n * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.\n *\n * @example\n * ```ts\n * import { t, collection } from 'intlayer';\n *\n * export default {\n * key: 'faq',\n * content: collection([\n * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },\n * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },\n * ]),\n * } satisfies Dictionary;\n * ```\n */\nexport const collection = <T>(items: T[]): CollectionContent<T> => ({\n nodeType: COLLECTION,\n collection: items,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,cAAiB,WAAsC;CAClE,UAAU;CACV,YAAY;CACb"}
@@ -1,3 +0,0 @@
1
- import { collection } from "./collection.mjs";
2
-
3
- export { collection };
@@ -1,3 +0,0 @@
1
- import { variant } from "./variant.mjs";
2
-
3
- export { variant };
@@ -1,33 +0,0 @@
1
- import { VARIANT } from "@intlayer/types/nodeType";
2
-
3
- //#region src/transpiler/variant/variant.ts
4
- /**
5
- * Declares a set of named content alternatives for A/B testing or feature flags.
6
- *
7
- * The `control` key is mandatory and acts as the default when no variant is
8
- * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.
9
- * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.
10
- *
11
- * @example
12
- * ```ts
13
- * import { t, variant } from 'intlayer';
14
- *
15
- * export default {
16
- * key: 'hero-banner',
17
- * content: {
18
- * headline: variant({
19
- * control: t({ en: 'Welcome', fr: 'Bienvenue' }),
20
- * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\'à -50 %' }),
21
- * }),
22
- * },
23
- * } satisfies Dictionary;
24
- * ```
25
- */
26
- const variant = (variants) => ({
27
- nodeType: VARIANT,
28
- variant: variants
29
- });
30
-
31
- //#endregion
32
- export { variant };
33
- //# sourceMappingURL=variant.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variant.mjs","names":[],"sources":["../../../../src/transpiler/variant/variant.ts"],"sourcesContent":["import { VARIANT } from '@intlayer/types/nodeType';\n\n/**\n * Shape of a variant node stored in the dictionary JSON.\n * `control` is the mandatory default/fallback key; all other keys are\n * optional named experiment branches.\n */\nexport type VariantContentState<T = unknown> = { control: T } & Record<\n string,\n T\n>;\n\nexport type VariantContent<T = unknown> = {\n nodeType: typeof VARIANT;\n variant: VariantContentState<T>;\n};\n\n/**\n * Declares a set of named content alternatives for A/B testing or feature flags.\n *\n * The `control` key is mandatory and acts as the default when no variant is\n * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.\n * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.\n *\n * @example\n * ```ts\n * import { t, variant } from 'intlayer';\n *\n * export default {\n * key: 'hero-banner',\n * content: {\n * headline: variant({\n * control: t({ en: 'Welcome', fr: 'Bienvenue' }),\n * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\\'à -50 %' }),\n * }),\n * },\n * } satisfies Dictionary;\n * ```\n */\nexport const variant = <T>(\n variants: { control: T } & Partial<Record<string, T>>\n): VariantContent<T> => ({\n nodeType: VARIANT,\n variant: variants as VariantContentState<T>,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,WACX,cACuB;CACvB,UAAU;CACV,SAAS;CACV"}
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1,2 +0,0 @@
1
- import { ContentNode } from "@intlayer/types/dictionary";
2
- import { DeclaredLocales, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1,4 +0,0 @@
1
- import { DeclaredLocales, DictionaryKeys, LocalesValues } from "@intlayer/types/module_augmentation";
2
- import { NodeType } from "@intlayer/types/nodeType";
3
- import { Locale } from "@intlayer/types/allLocales";
4
- import { KeyPath } from "@intlayer/types/keyPath";
@@ -1,2 +0,0 @@
1
- import { Dictionary, DictionarySelector, QualifiedDictionaryGroup, ResolveQualifiedDictionaryContent } from "@intlayer/types/dictionary";
2
- import { DeclaredLocales, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1,2 +0,0 @@
1
- import { DictionarySelector } from "@intlayer/types/dictionary";
2
- import { DeclaredLocales, DictionaryKeys, DictionaryRegistryResult, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1,2 +0,0 @@
1
- import { GetSubPath } from "@intlayer/types/dictionary";
2
- import { DictionaryKeys, DictionaryRegistryContent } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { DeclaredLocales } from "@intlayer/types";
@@ -1 +0,0 @@
1
- import { LocalesValues, StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
@@ -1,2 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
2
- import { RoutingConfig } from "@intlayer/types/config";
@@ -1 +0,0 @@
1
- import { Locale } from "@intlayer/types/allLocales";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { Locale } from "@intlayer/types/allLocales";
@@ -1 +0,0 @@
1
- import { Locale } from "@intlayer/types/allLocales";
@@ -1 +0,0 @@
1
- import { GetLocaleLang, LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { LocalesValues, LocalizedUrl, ResolvedDefaultLocale } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { DeclaredLocales, LocalesValues, PathWithoutLocale } from "@intlayer/types/module_augmentation";
@@ -1,3 +0,0 @@
1
- import { DeclaredLocales, LocalesValues, ResolvedDefaultLocale, ResolvedRoutingMode } from "@intlayer/types/module_augmentation";
2
- import { Locale } from "@intlayer/types/allLocales";
3
- import { RoutingConfig } from "@intlayer/types/config";
@@ -1 +0,0 @@
1
- import { Locale } from "@intlayer/types/allLocales";
@@ -1,2 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
2
- import { Locale } from "@intlayer/types/allLocales";
@@ -1,2 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
2
- import { Locale } from "@intlayer/types/allLocales";
@@ -1,3 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
2
- import { Locale } from "@intlayer/types/allLocales";
3
- import { RewriteObject, RewriteRules, RoutingConfig } from "@intlayer/types/config";
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { CONDITION, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { ENUMERATION, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { FILE, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { GENDER, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { HTML, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { INSERTION, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { MARKDOWN, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1,2 +0,0 @@
1
- import { DictionaryKeys, DictionaryRegistryContent } from "@intlayer/types/module_augmentation";
2
- import { NESTED, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- import { PLURAL, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1,2 +0,0 @@
1
- import { StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
2
- import { TRANSLATION, TypedNodeModel } from "@intlayer/types/nodeType";
@@ -1 +0,0 @@
1
- export { };
@@ -1 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
@@ -1 +0,0 @@
1
- import { KeyPath } from "@intlayer/types/keyPath";
@@ -1,2 +0,0 @@
1
- import { LocalesValues } from "@intlayer/types/module_augmentation";
2
- import { Locale } from "@intlayer/types/allLocales";
@@ -1,19 +0,0 @@
1
- //#region src/interpreter/getCollection.d.ts
2
- /**
3
- * Picks a single item from a resolved collection array, or returns the full
4
- * array when no index is requested.
5
- *
6
- * @param items - The already-resolved collection items.
7
- * @param itemIndex - Optional 0-based index of the item to retrieve.
8
- * @returns The item at `itemIndex`, or the full array when no index is given.
9
- *
10
- * @example
11
- * ```ts
12
- * const all = getCollection(['a', 'b', 'c']); // ['a', 'b', 'c']
13
- * const one = getCollection(['a', 'b', 'c'], 1); // 'b'
14
- * ```
15
- */
16
- declare const getCollection: <T>(items: T[], itemIndex?: number) => T | T[];
17
- //#endregion
18
- export { getCollection };
19
- //# sourceMappingURL=getCollection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getCollection.d.ts","names":[],"sources":["../../../src/interpreter/getCollection.ts"],"mappings":";;AAcA;;;;;;;;;;;;;cAAa,aAAA,MAAoB,KAAA,EAAO,CAAA,IAAK,SAAA,cAAqB,CAAA,GAAI,CAAA"}
@@ -1,26 +0,0 @@
1
- import { VariantContentState } from "../transpiler/variant/variant.js";
2
-
3
- //#region src/interpreter/getVariant.d.ts
4
- /**
5
- * Resolves a variant node to its selected alternative.
6
- *
7
- * Falls back to `control` when the requested `variantKey` does not exist in
8
- * the node or when no key is specified.
9
- *
10
- * @param variantContent - The map of variant alternatives.
11
- * @param variantKey - Optional name of the alternative to select.
12
- * @returns The resolved content for the requested variant.
13
- *
14
- * @example
15
- * ```ts
16
- * const node = { control: 'Welcome', black_friday: 'Up to 50% off' };
17
- *
18
- * getVariant(node); // 'Welcome'
19
- * getVariant(node, 'black_friday'); // 'Up to 50% off'
20
- * getVariant(node, 'nonexistent'); // 'Welcome' (fallback to control)
21
- * ```
22
- */
23
- declare const getVariant: <T>(variantContent: VariantContentState<T>, variantKey?: string) => T;
24
- //#endregion
25
- export { getVariant };
26
- //# sourceMappingURL=getVariant.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getVariant.d.ts","names":[],"sources":["../../../src/interpreter/getVariant.ts"],"mappings":";;;;;AAqBA;;;;;;;;;;;;;;;;;cAAa,UAAA,MACX,cAAA,EAAgB,mBAAA,CAAoB,CAAA,GACpC,UAAA,cACC,CAAA"}
@@ -1,4 +0,0 @@
1
- import { Dictionary } from "@intlayer/types/dictionary";
2
- import { LocalesValues as LocalesValues$1 } from "@intlayer/types/module_augmentation";
3
- import { IntlayerConfig } from "@intlayer/types/config";
4
- export { type LocalesValues$1 as LocalesValues };
@@ -1,34 +0,0 @@
1
- import { COLLECTION } from "@intlayer/types/nodeType";
2
-
3
- //#region src/transpiler/collection/collection.d.ts
4
- /**
5
- * Shape of a collection node stored in the dictionary JSON.
6
- * Items may contain any other node type (translations, conditions, etc.).
7
- */
8
- type CollectionContent<T = unknown> = {
9
- nodeType: typeof COLLECTION;
10
- collection: T[];
11
- };
12
- /**
13
- * Declares an ordered list of content items inside a dictionary.
14
- *
15
- * At runtime, `useIntlayer('my-key')` returns all items as an array.
16
- * `useIntlayer('my-key', { item: 2 })` returns only the item at index 2.
17
- *
18
- * @example
19
- * ```ts
20
- * import { t, collection } from 'intlayer';
21
- *
22
- * export default {
23
- * key: 'faq',
24
- * content: collection([
25
- * { question: t({ en: 'What is Intlayer?' }), answer: t({ en: '...' }) },
26
- * { question: t({ en: 'Is it free?' }), answer: t({ en: '...' }) },
27
- * ]),
28
- * } satisfies Dictionary;
29
- * ```
30
- */
31
- declare const collection: <T>(items: T[]) => CollectionContent<T>;
32
- //#endregion
33
- export { CollectionContent, collection };
34
- //# sourceMappingURL=collection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"collection.d.ts","names":[],"sources":["../../../../src/transpiler/collection/collection.ts"],"mappings":";;;;;AAMA;;KAAY,iBAAA;EACV,QAAA,SAAiB,UAAA;EACjB,UAAA,EAAY,CAAA;AAAA;;;;;;AAsBd;;;;;;;;;;;;;;cAAa,UAAA,MAAiB,KAAA,EAAO,CAAA,OAAM,iBAAA,CAAkB,CAAA"}
@@ -1,2 +0,0 @@
1
- import { CollectionContent, collection } from "./collection.js";
2
- export { CollectionContent, collection };
@@ -1,2 +0,0 @@
1
- import { VariantContent, VariantContentState, variant } from "./variant.js";
2
- export { VariantContent, VariantContentState, variant };
@@ -1,43 +0,0 @@
1
- import { VARIANT } from "@intlayer/types/nodeType";
2
-
3
- //#region src/transpiler/variant/variant.d.ts
4
- /**
5
- * Shape of a variant node stored in the dictionary JSON.
6
- * `control` is the mandatory default/fallback key; all other keys are
7
- * optional named experiment branches.
8
- */
9
- type VariantContentState<T = unknown> = {
10
- control: T;
11
- } & Record<string, T>;
12
- type VariantContent<T = unknown> = {
13
- nodeType: typeof VARIANT;
14
- variant: VariantContentState<T>;
15
- };
16
- /**
17
- * Declares a set of named content alternatives for A/B testing or feature flags.
18
- *
19
- * The `control` key is mandatory and acts as the default when no variant is
20
- * selected. At runtime, `useIntlayer('my-key')` returns the `control` variant.
21
- * `useIntlayer('my-key', { variant: 'black_friday' })` returns that variant.
22
- *
23
- * @example
24
- * ```ts
25
- * import { t, variant } from 'intlayer';
26
- *
27
- * export default {
28
- * key: 'hero-banner',
29
- * content: {
30
- * headline: variant({
31
- * control: t({ en: 'Welcome', fr: 'Bienvenue' }),
32
- * black_friday: t({ en: 'Up to 50% off', fr: 'Jusqu\'à -50 %' }),
33
- * }),
34
- * },
35
- * } satisfies Dictionary;
36
- * ```
37
- */
38
- declare const variant: <T>(variants: {
39
- control: T;
40
- } & Partial<Record<string, T>>) => VariantContent<T>;
41
- //#endregion
42
- export { VariantContent, VariantContentState, variant };
43
- //# sourceMappingURL=variant.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"variant.d.ts","names":[],"sources":["../../../../src/transpiler/variant/variant.ts"],"mappings":";;;;;AAOA;;;KAAY,mBAAA;EAAqC,OAAA,EAAS,CAAA;AAAA,IAAM,MAAA,SAE9D,CAAA;AAAA,KAGU,cAAA;EACV,QAAA,SAAiB,OAAA;EACjB,OAAA,EAAS,mBAAA,CAAoB,CAAA;AAAA;;;;;;AAF/B;;;;;;;;;;;;;;;;AA2BA;cAAa,OAAA,MACX,QAAA;EAAY,OAAA,EAAS,CAAA;AAAA,IAAM,OAAA,CAAQ,MAAA,SAAe,CAAA,OACjD,cAAA,CAAe,CAAA"}