@intlayer/core 7.3.15 → 7.5.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +3 -1
- package/dist/cjs/localization/getLocalizedUrl.cjs +8 -2
- package/dist/cjs/localization/getLocalizedUrl.cjs.map +1 -1
- package/dist/cjs/localization/getMultilingualUrls.cjs +7 -1
- package/dist/cjs/localization/getMultilingualUrls.cjs.map +1 -1
- package/dist/cjs/localization/getPrefix.cjs +8 -2
- package/dist/cjs/localization/getPrefix.cjs.map +1 -1
- package/dist/cjs/localization/index.cjs +3 -1
- package/dist/cjs/localization/validatePrefix.cjs +54 -0
- package/dist/cjs/localization/validatePrefix.cjs.map +1 -0
- package/dist/cjs/messageFormat/ICU.cjs +309 -0
- package/dist/cjs/messageFormat/ICU.cjs.map +1 -0
- package/dist/cjs/messageFormat/i18next.cjs +320 -0
- package/dist/cjs/messageFormat/i18next.cjs.map +1 -0
- package/dist/cjs/messageFormat/index.cjs +10 -0
- package/dist/cjs/messageFormat/vue-i18n.cjs +166 -0
- package/dist/cjs/messageFormat/vue-i18n.cjs.map +1 -0
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/localization/getLocalizedUrl.mjs +8 -2
- package/dist/esm/localization/getLocalizedUrl.mjs.map +1 -1
- package/dist/esm/localization/getMultilingualUrls.mjs +7 -1
- package/dist/esm/localization/getMultilingualUrls.mjs.map +1 -1
- package/dist/esm/localization/getPrefix.mjs +8 -2
- package/dist/esm/localization/getPrefix.mjs.map +1 -1
- package/dist/esm/localization/index.mjs +2 -1
- package/dist/esm/localization/validatePrefix.mjs +52 -0
- package/dist/esm/localization/validatePrefix.mjs.map +1 -0
- package/dist/esm/messageFormat/ICU.mjs +307 -0
- package/dist/esm/messageFormat/ICU.mjs.map +1 -0
- package/dist/esm/messageFormat/i18next.mjs +318 -0
- package/dist/esm/messageFormat/i18next.mjs.map +1 -0
- package/dist/esm/messageFormat/index.mjs +5 -0
- package/dist/esm/messageFormat/vue-i18n.mjs +164 -0
- package/dist/esm/messageFormat/vue-i18n.mjs.map +1 -0
- package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +1 -0
- package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +8 -7
- package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts.map +1 -1
- package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +8 -7
- package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts.map +1 -1
- package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +2 -2
- package/dist/types/index.d.ts +2 -1
- package/dist/types/localization/getMultilingualUrls.d.ts.map +1 -1
- package/dist/types/localization/getPrefix.d.ts +2 -1
- package/dist/types/localization/getPrefix.d.ts.map +1 -1
- package/dist/types/localization/index.d.ts +2 -1
- package/dist/types/localization/validatePrefix.d.ts +38 -0
- package/dist/types/localization/validatePrefix.d.ts.map +1 -0
- package/dist/types/messageFormat/ICU.d.ts +11 -0
- package/dist/types/messageFormat/ICU.d.ts.map +1 -0
- package/dist/types/messageFormat/i18next.d.ts +9 -0
- package/dist/types/messageFormat/i18next.d.ts.map +1 -0
- package/dist/types/messageFormat/index.d.ts +4 -0
- package/dist/types/messageFormat/vue-i18n.d.ts +9 -0
- package/dist/types/messageFormat/vue-i18n.d.ts.map +1 -0
- package/dist/types/transpiler/enumeration/enumeration.d.ts.map +1 -1
- package/package.json +11 -6
package/dist/cjs/index.cjs
CHANGED
|
@@ -66,6 +66,7 @@ const require_localization_getPrefix = require('./localization/getPrefix.cjs');
|
|
|
66
66
|
const require_localization_getLocalizedUrl = require('./localization/getLocalizedUrl.cjs');
|
|
67
67
|
const require_localization_getMultilingualUrls = require('./localization/getMultilingualUrls.cjs');
|
|
68
68
|
const require_localization_localeMapper = require('./localization/localeMapper.cjs');
|
|
69
|
+
const require_localization_validatePrefix = require('./localization/validatePrefix.cjs');
|
|
69
70
|
const require_utils_isSameKeyPath = require('./utils/isSameKeyPath.cjs');
|
|
70
71
|
|
|
71
72
|
exports.CachedIntl = require_utils_intl.CachedIntl;
|
|
@@ -161,4 +162,5 @@ exports.setLocaleInStorage = require_utils_localeStorage.setLocaleInStorage;
|
|
|
161
162
|
exports.t = require_transpiler_translation_translation.t;
|
|
162
163
|
exports.translationPlugin = require_interpreter_getContent_plugins.translationPlugin;
|
|
163
164
|
exports.units = require_formatters_units.units;
|
|
164
|
-
exports.updateNodeChildren = require_dictionaryManipulator_updateNodeChildren.updateNodeChildren;
|
|
165
|
+
exports.updateNodeChildren = require_dictionaryManipulator_updateNodeChildren.updateNodeChildren;
|
|
166
|
+
exports.validatePrefix = require_localization_validatePrefix.validatePrefix;
|
|
@@ -44,7 +44,12 @@ __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_bui
|
|
|
44
44
|
* @returns The localized URL for the current locale.
|
|
45
45
|
*/
|
|
46
46
|
const getLocalizedUrl = (url, currentLocale, options = {}) => {
|
|
47
|
-
const {
|
|
47
|
+
const { defaultLocale, mode, locales } = {
|
|
48
|
+
defaultLocale: __intlayer_config_built.default?.internationalization?.defaultLocale ?? __intlayer_config_client.DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
49
|
+
mode: __intlayer_config_built.default?.routing?.mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE,
|
|
50
|
+
locales: __intlayer_config_built.default?.internationalization?.locales ?? __intlayer_config_client.DefaultValues.Internationalization.LOCALES,
|
|
51
|
+
...options
|
|
52
|
+
};
|
|
48
53
|
const urlWithoutLocale = require_localization_getPathWithoutLocale.getPathWithoutLocale(url, locales);
|
|
49
54
|
if (mode === "no-prefix") return urlWithoutLocale;
|
|
50
55
|
const isAbsoluteUrl = require_utils_checkIsURLAbsolute.checkIsURLAbsolute(urlWithoutLocale);
|
|
@@ -60,7 +65,8 @@ const getLocalizedUrl = (url, currentLocale, options = {}) => {
|
|
|
60
65
|
}
|
|
61
66
|
const { prefix } = require_localization_getPrefix.getPrefix(currentLocale, {
|
|
62
67
|
defaultLocale,
|
|
63
|
-
mode
|
|
68
|
+
mode,
|
|
69
|
+
locales
|
|
64
70
|
});
|
|
65
71
|
let localizedPath = `/${prefix}${parsedUrl.pathname}`;
|
|
66
72
|
localizedPath = localizedPath.replaceAll(/\/+/g, "/");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLocalizedUrl.cjs","names":["configuration","DefaultValues","getPathWithoutLocale","checkIsURLAbsolute","getPrefix"],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport { getPrefix } from './getPrefix';\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): string => {\n const {
|
|
1
|
+
{"version":3,"file":"getLocalizedUrl.cjs","names":["configuration","DefaultValues","getPathWithoutLocale","checkIsURLAbsolute","getPrefix"],"sources":["../../../src/localization/getLocalizedUrl.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { checkIsURLAbsolute } from '../utils/checkIsURLAbsolute';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport { getPrefix } from './getPrefix';\n\n/**\n * Generate URL by prefixing the given URL with the referenced locale or adding search parameters\n * based on the routing mode. Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' });\n * // Returns '/fr/about' for the French locale\n * // Returns '/about' for the English locale (default)\n *\n * // prefix-all mode\n * getLocalizedUrl('/about', 'en', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' });\n * // Returns '/en/about' for the English locale\n * // Returns '/fr/about' for the French locale\n *\n * // search-params mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' });\n * // Returns '/about?locale=fr' for the French locale\n *\n * // no-prefix mode\n * getLocalizedUrl('/about', 'fr', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' });\n * // Returns '/about' for any locale\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param currentLocale - The current locale.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns The localized URL for the current locale.\n */\nexport const getLocalizedUrl = (\n url: string,\n currentLocale: LocalesValues,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): string => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // Remove any existing locale segment from the URL\n const urlWithoutLocale = getPathWithoutLocale(url, locales);\n\n if (mode === 'no-prefix') {\n // No locale prefixing\n return urlWithoutLocale;\n }\n\n // Determine if the original URL is absolute (includes protocol)\n const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);\n\n // Initialize a URL object if the URL is absolute\n // For relative URLs, use a dummy base to leverage the URL API\n const parsedUrl = isAbsoluteUrl\n ? new URL(urlWithoutLocale)\n : new URL(urlWithoutLocale, 'http://example.com');\n\n // Prepare the base URL (protocol + host) if it's absolute\n const baseUrl = isAbsoluteUrl\n ? `${parsedUrl.protocol}//${parsedUrl.host}`\n : '';\n\n if (mode === 'search-params') {\n // Use search parameters for locale handling\n const searchParams = new URLSearchParams(parsedUrl.search);\n searchParams.set('locale', currentLocale.toString());\n\n const queryString = searchParams.toString();\n const pathWithQuery = queryString\n ? `${parsedUrl.pathname}?${queryString}`\n : parsedUrl.pathname;\n\n if (isAbsoluteUrl) {\n return `${baseUrl}${pathWithQuery}${parsedUrl.hash}`;\n }\n\n return `${pathWithQuery}${parsedUrl.hash}`;\n }\n\n const { prefix } = getPrefix(currentLocale, {\n defaultLocale,\n mode,\n locales,\n });\n\n // Construct the new pathname with or without the locale prefix\n let localizedPath = `/${prefix}${parsedUrl.pathname}`;\n\n // Remove double slashes\n localizedPath = localizedPath.replaceAll(/\\/+/g, '/');\n\n // Remove trailing slash for non-root paths\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n // Combine with the base URL if the original URL was absolute\n if (isAbsoluteUrl) {\n return `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n }\n\n return `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,mBACX,KACA,eACA,UAII,EAAE,KACK;CACX,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACEA,iCAAe,sBAAsB,iBACrCC,uCAAc,qBAAqB;EACrC,MAAMD,iCAAe,SAAS,QAAQC,uCAAc,QAAQ;EAC5D,SACED,iCAAe,sBAAsB,WACrCC,uCAAc,qBAAqB;EACrC,GAAG;EACJ;CAGD,MAAM,mBAAmBC,+DAAqB,KAAK,QAAQ;AAE3D,KAAI,SAAS,YAEX,QAAO;CAIT,MAAM,gBAAgBC,oDAAmB,iBAAiB;CAI1D,MAAM,YAAY,gBACd,IAAI,IAAI,iBAAiB,GACzB,IAAI,IAAI,kBAAkB,qBAAqB;CAGnD,MAAM,UAAU,gBACZ,GAAG,UAAU,SAAS,IAAI,UAAU,SACpC;AAEJ,KAAI,SAAS,iBAAiB;EAE5B,MAAM,eAAe,IAAI,gBAAgB,UAAU,OAAO;AAC1D,eAAa,IAAI,UAAU,cAAc,UAAU,CAAC;EAEpD,MAAM,cAAc,aAAa,UAAU;EAC3C,MAAM,gBAAgB,cAClB,GAAG,UAAU,SAAS,GAAG,gBACzB,UAAU;AAEd,MAAI,cACF,QAAO,GAAG,UAAU,gBAAgB,UAAU;AAGhD,SAAO,GAAG,gBAAgB,UAAU;;CAGtC,MAAM,EAAE,WAAWC,yCAAU,eAAe;EAC1C;EACA;EACA;EACD,CAAC;CAGF,IAAI,gBAAgB,IAAI,SAAS,UAAU;AAG3C,iBAAgB,cAAc,WAAW,QAAQ,IAAI;AAGrD,KAAI,cAAc,SAAS,KAAK,cAAc,SAAS,IAAI,CACzD,iBAAgB,cAAc,MAAM,GAAG,GAAG;AAI5C,KAAI,cACF,QAAO,GAAG,UAAU,gBAAgB,UAAU,SAAS,UAAU;AAGnE,QAAO,GAAG,gBAAgB,UAAU,SAAS,UAAU"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
2
|
const require_localization_getLocalizedUrl = require('./getLocalizedUrl.cjs');
|
|
3
|
+
let __intlayer_config_client = require("@intlayer/config/client");
|
|
3
4
|
let __intlayer_config_built = require("@intlayer/config/built");
|
|
4
5
|
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
|
|
5
6
|
|
|
@@ -39,7 +40,12 @@ __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_bui
|
|
|
39
40
|
* @returns An object mapping each locale to its corresponding multilingual URL.
|
|
40
41
|
*/
|
|
41
42
|
const getMultilingualUrls = (url, options = {}) => {
|
|
42
|
-
const {
|
|
43
|
+
const { defaultLocale, mode, locales } = {
|
|
44
|
+
defaultLocale: __intlayer_config_built.default?.internationalization?.defaultLocale ?? __intlayer_config_client.DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
45
|
+
mode: __intlayer_config_built.default?.routing?.mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE,
|
|
46
|
+
locales: __intlayer_config_built.default?.internationalization?.locales ?? __intlayer_config_client.DefaultValues.Internationalization.LOCALES,
|
|
47
|
+
...options
|
|
48
|
+
};
|
|
43
49
|
return (locales ?? []).reduce((acc, locale) => {
|
|
44
50
|
acc[locale] = require_localization_getLocalizedUrl.getLocalizedUrl(url, locale, {
|
|
45
51
|
locales,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getMultilingualUrls.cjs","names":["configuration","getLocalizedUrl"],"sources":["../../../src/localization/getMultilingualUrls.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport { getLocalizedUrl } from './getLocalizedUrl';\n\n/**\n * Generates multilingual URLs by prefixing the given URL with each supported locale\n * or adding search parameters based on the routing mode.\n * Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { en: '/dashboard', fr: '/fr/dashboard' }\n *\n * // prefix-all mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }\n *\n * // search-params mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' })\n * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }\n *\n * // no-prefix mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { en: '/dashboard', fr: '/dashboard' }\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object mapping each locale to its corresponding multilingual URL.\n */\nexport const getMultilingualUrls = (\n url: string,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): StrictModeLocaleMap<string> => {\n const {
|
|
1
|
+
{"version":3,"file":"getMultilingualUrls.cjs","names":["configuration","DefaultValues","getLocalizedUrl"],"sources":["../../../src/localization/getMultilingualUrls.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues, StrictModeLocaleMap } from '@intlayer/types';\nimport { getLocalizedUrl } from './getLocalizedUrl';\n\n/**\n * Generates multilingual URLs by prefixing the given URL with each supported locale\n * or adding search parameters based on the routing mode.\n * Handles both absolute and relative URLs appropriately.\n *\n * This function gets the locales, default locale, and routing mode from the configuration if not provided.\n *\n * Example:\n *\n * ```ts\n * // prefix-no-default mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-no-default' })\n * // Returns { en: '/dashboard', fr: '/fr/dashboard' }\n *\n * // prefix-all mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'prefix-all' })\n * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }\n *\n * // search-params mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'search-params' })\n * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }\n *\n * // no-prefix mode\n * getMultilingualUrls('/dashboard', { locales: ['en', 'fr'], defaultLocale: 'en', mode: 'no-prefix' })\n * // Returns { en: '/dashboard', fr: '/dashboard' }\n * ```\n *\n * @param url - The original URL string to be processed.\n * @param options - Configuration options\n * @param options.locales - Optional array of supported locales. Defaults to configured locales.\n * @param options.defaultLocale - The default locale. Defaults to configured default locale.\n * @param options.mode - URL routing mode for locale handling. Defaults to configured mode.\n * @returns An object mapping each locale to its corresponding multilingual URL.\n */\nexport const getMultilingualUrls = (\n url: string,\n options: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): StrictModeLocaleMap<string> => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // Generate multilingual URLs by iterating over each locale and calling getLocalizedUrl\n const multilingualUrls = (locales ?? []).reduce<StrictModeLocaleMap<string>>(\n (acc, locale) => {\n // Get the localized URL for this locale\n const localizedUrl = getLocalizedUrl(url, locale, {\n locales,\n defaultLocale,\n mode,\n });\n\n // Assign the constructed URL to the corresponding locale key\n acc[locale as unknown as keyof typeof acc] = localizedUrl;\n\n return acc;\n },\n {} as StrictModeLocaleMap<string>\n );\n\n return multilingualUrls;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,MAAa,uBACX,KACA,UAII,EAAE,KAC0B;CAChC,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACEA,iCAAe,sBAAsB,iBACrCC,uCAAc,qBAAqB;EACrC,MAAMD,iCAAe,SAAS,QAAQC,uCAAc,QAAQ;EAC5D,SACED,iCAAe,sBAAsB,WACrCC,uCAAc,qBAAqB;EACrC,GAAG;EACJ;AAoBD,SAjB0B,WAAW,EAAE,EAAE,QACtC,KAAK,WAAW;AASf,MAAI,UAPiBC,qDAAgB,KAAK,QAAQ;GAChD;GACA;GACA;GACD,CAAC;AAKF,SAAO;IAET,EAAE,CACH"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let __intlayer_config_client = require("@intlayer/config/client");
|
|
2
3
|
let __intlayer_config_built = require("@intlayer/config/built");
|
|
3
4
|
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
|
|
4
5
|
|
|
@@ -37,8 +38,13 @@ __intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_bui
|
|
|
37
38
|
* @returns An object containing pathPrefix, prefix, and localePrefix for the given locale.
|
|
38
39
|
*/
|
|
39
40
|
const getPrefix = (locale, options = {}) => {
|
|
40
|
-
const { defaultLocale
|
|
41
|
-
|
|
41
|
+
const { defaultLocale, mode, locales } = {
|
|
42
|
+
defaultLocale: __intlayer_config_built.default?.internationalization?.defaultLocale ?? __intlayer_config_client.DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
43
|
+
mode: __intlayer_config_built.default?.routing?.mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE,
|
|
44
|
+
locales: __intlayer_config_built.default?.internationalization?.locales ?? __intlayer_config_client.DefaultValues.Internationalization.LOCALES,
|
|
45
|
+
...options
|
|
46
|
+
};
|
|
47
|
+
if (!locale || !locales.includes(locale)) return {
|
|
42
48
|
prefix: "",
|
|
43
49
|
localePrefix: void 0
|
|
44
50
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPrefix.cjs","names":["configuration"],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport type { Locale, LocalesValues } from '@intlayer/types';\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n};\n\nexport type GetPrefixResult = {\n /**\n * The complete base URL path with leading and trailing slashes.\n *\n * @example\n * // https://example.com/fr/about -> '/fr'\n * // https://example.com/about -> ''\n */\n prefix: string;\n /**\n * The locale identifier without slashes.\n *\n * @example\n * // https://example.com/fr/about -> 'fr'\n * // https://example.com/about -> undefined\n */\n localePrefix: Locale | undefined;\n};\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 = (\n locale: LocalesValues,\n options: {\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): GetPrefixResult => {\n const {\n defaultLocale
|
|
1
|
+
{"version":3,"file":"getPrefix.cjs","names":["configuration","DefaultValues"],"sources":["../../../src/localization/getPrefix.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { Locale, LocalesValues } from '@intlayer/types';\n\nexport type GetPrefixOptions = {\n defaultLocale?: LocalesValues;\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n};\n\nexport type GetPrefixResult = {\n /**\n * The complete base URL path with leading and trailing slashes.\n *\n * @example\n * // https://example.com/fr/about -> '/fr'\n * // https://example.com/about -> ''\n */\n prefix: string;\n /**\n * The locale identifier without slashes.\n *\n * @example\n * // https://example.com/fr/about -> 'fr'\n * // https://example.com/about -> undefined\n */\n localePrefix: Locale | undefined;\n};\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 = (\n locale: LocalesValues | undefined,\n options: {\n defaultLocale?: LocalesValues;\n locales?: LocalesValues[];\n mode?: 'prefix-no-default' | 'prefix-all' | 'no-prefix' | 'search-params';\n } = {}\n): GetPrefixResult => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n if (!locale || !locales.includes(locale)) {\n return {\n prefix: '',\n localePrefix: undefined,\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 };\n }\n\n return {\n prefix: '',\n localePrefix: undefined,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DA,MAAa,aACX,QACA,UAII,EAAE,KACc;CACpB,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACEA,iCAAe,sBAAsB,iBACrCC,uCAAc,qBAAqB;EACrC,MAAMD,iCAAe,SAAS,QAAQC,uCAAc,QAAQ;EAC5D,SACED,iCAAe,sBAAsB,WACrCC,uCAAc,qBAAqB;EACrC,GAAG;EACJ;AAED,KAAI,CAAC,UAAU,CAAC,QAAQ,SAAS,OAAO,CACtC,QAAO;EACL,QAAQ;EACR,cAAc;EACf;AAQH,KAHE,SAAS,gBACR,SAAS,uBAAuB,kBAAkB,OAGnD,QAAO;EACL,QAAQ,GAAG,OAAO;EAClB,cAAc;EACf;AAGH,QAAO;EACL,QAAQ;EACR,cAAc;EACf"}
|
|
@@ -10,6 +10,7 @@ const require_localization_getPrefix = require('./getPrefix.cjs');
|
|
|
10
10
|
const require_localization_getLocalizedUrl = require('./getLocalizedUrl.cjs');
|
|
11
11
|
const require_localization_getMultilingualUrls = require('./getMultilingualUrls.cjs');
|
|
12
12
|
const require_localization_localeMapper = require('./localeMapper.cjs');
|
|
13
|
+
const require_localization_validatePrefix = require('./validatePrefix.cjs');
|
|
13
14
|
|
|
14
15
|
exports.getBrowserLocale = require_localization_getBrowserLocale.getBrowserLocale;
|
|
15
16
|
exports.getHTMLTextDir = require_localization_getHTMLTextDir.getHTMLTextDir;
|
|
@@ -25,4 +26,5 @@ exports.localeFlatMap = require_localization_localeMapper.localeFlatMap;
|
|
|
25
26
|
exports.localeMap = require_localization_localeMapper.localeMap;
|
|
26
27
|
exports.localeRecord = require_localization_localeMapper.localeRecord;
|
|
27
28
|
exports.localeResolver = require_localization_localeResolver.localeResolver;
|
|
28
|
-
exports.localeStorageOptions = require_localization_getBrowserLocale.localeStorageOptions;
|
|
29
|
+
exports.localeStorageOptions = require_localization_getBrowserLocale.localeStorageOptions;
|
|
30
|
+
exports.validatePrefix = require_localization_validatePrefix.validatePrefix;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_localization_getPrefix = require('./getPrefix.cjs');
|
|
3
|
+
let __intlayer_config_client = require("@intlayer/config/client");
|
|
4
|
+
let __intlayer_config_built = require("@intlayer/config/built");
|
|
5
|
+
__intlayer_config_built = require_rolldown_runtime.__toESM(__intlayer_config_built);
|
|
6
|
+
|
|
7
|
+
//#region src/localization/validatePrefix.ts
|
|
8
|
+
/**
|
|
9
|
+
* Checks whether a given locale is valid based on the configured locales.
|
|
10
|
+
*
|
|
11
|
+
* @param locale - The locale value to validate. Can be `undefined` or `null`.
|
|
12
|
+
* @param options - Optional configuration to override default settings.
|
|
13
|
+
* @param options.locales - Array of valid locales. Defaults to the configured internationalization locales.
|
|
14
|
+
* @param options.defaultLocale - The default locale to use as fallback. Defaults to the configured default locale.
|
|
15
|
+
* @param options.mode - The routing mode (`'prefix'`, `'prefix-all'`, or `'no-prefix'`). Defaults to the configured routing mode.
|
|
16
|
+
* @returns An object containing the validation result and the locale prefix.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Check if 'en' is a valid locale
|
|
20
|
+
* const { isValid, localePrefix } = validatePrefix('en');
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Check with custom options
|
|
24
|
+
* const { isValid, localePrefix } = validatePrefix('fr', {
|
|
25
|
+
* locales: ['en', 'fr', 'es'],
|
|
26
|
+
* defaultLocale: 'en',
|
|
27
|
+
* mode: 'prefix-all',
|
|
28
|
+
* });
|
|
29
|
+
*/
|
|
30
|
+
const validatePrefix = (locale, options) => {
|
|
31
|
+
const { defaultLocale, mode, locales } = {
|
|
32
|
+
defaultLocale: __intlayer_config_built.default?.internationalization?.defaultLocale ?? __intlayer_config_client.DefaultValues.Internationalization.DEFAULT_LOCALE,
|
|
33
|
+
mode: __intlayer_config_built.default?.routing?.mode ?? __intlayer_config_client.DefaultValues.Routing.ROUTING_MODE,
|
|
34
|
+
locales: __intlayer_config_built.default?.internationalization?.locales ?? __intlayer_config_client.DefaultValues.Internationalization.LOCALES,
|
|
35
|
+
...options
|
|
36
|
+
};
|
|
37
|
+
const { localePrefix } = require_localization_getPrefix.getPrefix(locale || defaultLocale, {
|
|
38
|
+
mode,
|
|
39
|
+
locales,
|
|
40
|
+
defaultLocale
|
|
41
|
+
});
|
|
42
|
+
if (localePrefix === locale && locale === void 0) return {
|
|
43
|
+
isValid: true,
|
|
44
|
+
localePrefix: void 0
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
isValid: locales.some((localeEl) => localeEl === locale),
|
|
48
|
+
localePrefix
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//#endregion
|
|
53
|
+
exports.validatePrefix = validatePrefix;
|
|
54
|
+
//# sourceMappingURL=validatePrefix.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatePrefix.cjs","names":["configuration","DefaultValues","getPrefix"],"sources":["../../../src/localization/validatePrefix.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\nimport { DefaultValues } from '@intlayer/config/client';\nimport type { LocalesValues } from '@intlayer/types';\nimport { getPrefix } from './getPrefix';\n\nexport type ValidatePrefixResult = {\n isValid: boolean;\n localePrefix: string | undefined;\n};\n\n/**\n * Checks whether a given locale is valid based on the configured locales.\n *\n * @param locale - The locale value to validate. Can be `undefined` or `null`.\n * @param options - Optional configuration to override default settings.\n * @param options.locales - Array of valid locales. Defaults to the configured internationalization locales.\n * @param options.defaultLocale - The default locale to use as fallback. Defaults to the configured default locale.\n * @param options.mode - The routing mode (`'prefix'`, `'prefix-all'`, or `'no-prefix'`). Defaults to the configured routing mode.\n * @returns An object containing the validation result and the locale prefix.\n *\n * @example\n * // Check if 'en' is a valid locale\n * const { isValid, localePrefix } = validatePrefix('en');\n *\n * @example\n * // Check with custom options\n * const { isValid, localePrefix } = validatePrefix('fr', {\n * locales: ['en', 'fr', 'es'],\n * defaultLocale: 'en',\n * mode: 'prefix-all',\n * });\n */\nexport const validatePrefix = (\n locale: LocalesValues | undefined | null,\n options?: {\n locales?: LocalesValues[];\n defaultLocale?: LocalesValues;\n mode?: typeof configuration.routing.mode;\n }\n): ValidatePrefixResult => {\n const { defaultLocale, mode, locales } = {\n defaultLocale:\n configuration?.internationalization?.defaultLocale ??\n DefaultValues.Internationalization.DEFAULT_LOCALE,\n mode: configuration?.routing?.mode ?? DefaultValues.Routing.ROUTING_MODE,\n locales:\n configuration?.internationalization?.locales ??\n DefaultValues.Internationalization.LOCALES,\n ...options,\n };\n\n // If no locale provided (optional param), will use default\n // In `routing.mode = 'prefix-all'`, the locale is required to be a valid locale\n const { localePrefix } = getPrefix(locale || defaultLocale, {\n mode,\n locales,\n defaultLocale,\n });\n\n if (localePrefix === locale && locale === undefined) {\n return { isValid: true, localePrefix: undefined };\n }\n\n // Check if the provided locale is valid\n const isValid: boolean = locales.some((localeEl) => localeEl === locale);\n\n return { isValid: isValid, localePrefix };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,kBACX,QACA,YAKyB;CACzB,MAAM,EAAE,eAAe,MAAM,YAAY;EACvC,eACEA,iCAAe,sBAAsB,iBACrCC,uCAAc,qBAAqB;EACrC,MAAMD,iCAAe,SAAS,QAAQC,uCAAc,QAAQ;EAC5D,SACED,iCAAe,sBAAsB,WACrCC,uCAAc,qBAAqB;EACrC,GAAG;EACJ;CAID,MAAM,EAAE,iBAAiBC,yCAAU,UAAU,eAAe;EAC1D;EACA;EACA;EACD,CAAC;AAEF,KAAI,iBAAiB,UAAU,WAAW,OACxC,QAAO;EAAE,SAAS;EAAM,cAAc;EAAW;AAMnD,QAAO;EAAE,SAFgB,QAAQ,MAAM,aAAa,aAAa,OAAO;EAE7C;EAAc"}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_interpreter_getContent_deepTransform = require('../interpreter/getContent/deepTransform.cjs');
|
|
3
|
+
const require_transpiler_enumeration_enumeration = require('../transpiler/enumeration/enumeration.cjs');
|
|
4
|
+
const require_transpiler_gender_gender = require('../transpiler/gender/gender.cjs');
|
|
5
|
+
const require_transpiler_insertion_insertion = require('../transpiler/insertion/insertion.cjs');
|
|
6
|
+
let __intlayer_types = require("@intlayer/types");
|
|
7
|
+
|
|
8
|
+
//#region src/messageFormat/ICU.ts
|
|
9
|
+
const parseICU = (text) => {
|
|
10
|
+
let index = 0;
|
|
11
|
+
const parseNodes = () => {
|
|
12
|
+
const nodes = [];
|
|
13
|
+
let currentText = "";
|
|
14
|
+
while (index < text.length) {
|
|
15
|
+
const char = text[index];
|
|
16
|
+
if (char === "{") {
|
|
17
|
+
if (currentText) {
|
|
18
|
+
nodes.push(currentText);
|
|
19
|
+
currentText = "";
|
|
20
|
+
}
|
|
21
|
+
index++;
|
|
22
|
+
nodes.push(parseArgument());
|
|
23
|
+
} else if (char === "}") break;
|
|
24
|
+
else if (char === "'") if (index + 1 < text.length && text[index + 1] === "'") {
|
|
25
|
+
currentText += "'";
|
|
26
|
+
index += 2;
|
|
27
|
+
} else {
|
|
28
|
+
const nextQuote = text.indexOf("'", index + 1);
|
|
29
|
+
if (nextQuote !== -1) {
|
|
30
|
+
currentText += text.substring(index + 1, nextQuote);
|
|
31
|
+
index = nextQuote + 1;
|
|
32
|
+
} else {
|
|
33
|
+
currentText += "'";
|
|
34
|
+
index++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
currentText += char;
|
|
39
|
+
index++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (currentText) nodes.push(currentText);
|
|
43
|
+
return nodes;
|
|
44
|
+
};
|
|
45
|
+
const parseArgument = () => {
|
|
46
|
+
let name = "";
|
|
47
|
+
while (index < text.length && /[^,}]/.test(text[index])) {
|
|
48
|
+
name += text[index];
|
|
49
|
+
index++;
|
|
50
|
+
}
|
|
51
|
+
name = name.trim();
|
|
52
|
+
if (index >= text.length) throw new Error("Unclosed argument");
|
|
53
|
+
if (text[index] === "}") {
|
|
54
|
+
index++;
|
|
55
|
+
return {
|
|
56
|
+
type: "argument",
|
|
57
|
+
name
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (text[index] === ",") {
|
|
61
|
+
index++;
|
|
62
|
+
let type = "";
|
|
63
|
+
while (index < text.length && /[^,}]/.test(text[index])) {
|
|
64
|
+
type += text[index];
|
|
65
|
+
index++;
|
|
66
|
+
}
|
|
67
|
+
type = type.trim();
|
|
68
|
+
if (index >= text.length) throw new Error("Unclosed argument");
|
|
69
|
+
if (text[index] === "}") {
|
|
70
|
+
index++;
|
|
71
|
+
return {
|
|
72
|
+
type: "argument",
|
|
73
|
+
name,
|
|
74
|
+
format: { type }
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (text[index] === ",") {
|
|
78
|
+
index++;
|
|
79
|
+
if (type === "plural" || type === "select") {
|
|
80
|
+
const options = {};
|
|
81
|
+
while (index < text.length && text[index] !== "}") {
|
|
82
|
+
while (index < text.length && /\s/.test(text[index])) index++;
|
|
83
|
+
let key = "";
|
|
84
|
+
while (index < text.length && /[^{\s]/.test(text[index])) {
|
|
85
|
+
key += text[index];
|
|
86
|
+
index++;
|
|
87
|
+
}
|
|
88
|
+
while (index < text.length && /\s/.test(text[index])) index++;
|
|
89
|
+
if (text[index] !== "{") throw new Error("Expected { after option key");
|
|
90
|
+
index++;
|
|
91
|
+
const value = parseNodes();
|
|
92
|
+
if (text[index] !== "}") throw new Error("Expected } after option value");
|
|
93
|
+
index++;
|
|
94
|
+
options[key] = value;
|
|
95
|
+
while (index < text.length && /\s/.test(text[index])) index++;
|
|
96
|
+
}
|
|
97
|
+
index++;
|
|
98
|
+
if (type === "plural") return {
|
|
99
|
+
type: "plural",
|
|
100
|
+
name,
|
|
101
|
+
options
|
|
102
|
+
};
|
|
103
|
+
else if (type === "select") return {
|
|
104
|
+
type: "select",
|
|
105
|
+
name,
|
|
106
|
+
options
|
|
107
|
+
};
|
|
108
|
+
} else {
|
|
109
|
+
let style = "";
|
|
110
|
+
while (index < text.length && text[index] !== "}") {
|
|
111
|
+
style += text[index];
|
|
112
|
+
index++;
|
|
113
|
+
}
|
|
114
|
+
if (index >= text.length) throw new Error("Unclosed argument");
|
|
115
|
+
style = style.trim();
|
|
116
|
+
index++;
|
|
117
|
+
return {
|
|
118
|
+
type: "argument",
|
|
119
|
+
name,
|
|
120
|
+
format: {
|
|
121
|
+
type,
|
|
122
|
+
style
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
throw new Error("Malformed argument");
|
|
129
|
+
};
|
|
130
|
+
return parseNodes();
|
|
131
|
+
};
|
|
132
|
+
const icuNodesToIntlayer = (nodes) => {
|
|
133
|
+
if (nodes.length === 0) return "";
|
|
134
|
+
if (nodes.length === 1 && typeof nodes[0] === "string") return nodes[0];
|
|
135
|
+
if (nodes.every((node) => typeof node === "string" || node.type === "argument")) {
|
|
136
|
+
let str = "";
|
|
137
|
+
for (const node of nodes) if (typeof node === "string") str += node;
|
|
138
|
+
else if (typeof node !== "string" && node.type === "argument") if (node.format) str += `{${node.name}, ${node.format.type}${node.format.style ? `, ${node.format.style}` : ""}}`;
|
|
139
|
+
else str += `{{${node.name}}}`;
|
|
140
|
+
return require_transpiler_insertion_insertion.insert(str);
|
|
141
|
+
}
|
|
142
|
+
if (nodes.length === 1) {
|
|
143
|
+
const node = nodes[0];
|
|
144
|
+
if (typeof node === "string") return node;
|
|
145
|
+
if (node.type === "argument") {
|
|
146
|
+
if (node.format) return require_transpiler_insertion_insertion.insert(`{${node.name}, ${node.format.type}${node.format.style ? `, ${node.format.style}` : ""}}`);
|
|
147
|
+
return require_transpiler_insertion_insertion.insert(`{{${node.name}}}`);
|
|
148
|
+
}
|
|
149
|
+
if (node.type === "plural") {
|
|
150
|
+
const options = {};
|
|
151
|
+
for (const [key, val] of Object.entries(node.options)) {
|
|
152
|
+
let newKey = key;
|
|
153
|
+
if (key.startsWith("=")) newKey = key.substring(1);
|
|
154
|
+
else if (key === "one") newKey = "1";
|
|
155
|
+
else if (key === "two") newKey = "2";
|
|
156
|
+
else if (key === "few") newKey = "<=3";
|
|
157
|
+
else if (key === "many") newKey = ">=4";
|
|
158
|
+
else if (key === "other") newKey = "fallback";
|
|
159
|
+
options[newKey] = icuNodesToIntlayer(val.map((v) => {
|
|
160
|
+
if (typeof v === "string") return v.replace(/#/g, `{{${node.name}}}`);
|
|
161
|
+
return v;
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
options.__intlayer_icu_var = node.name;
|
|
165
|
+
return require_transpiler_enumeration_enumeration.enu(options);
|
|
166
|
+
}
|
|
167
|
+
if (node.type === "select") {
|
|
168
|
+
const options = {};
|
|
169
|
+
for (const [key, val] of Object.entries(node.options)) options[key] = icuNodesToIntlayer(val);
|
|
170
|
+
const optionKeys = Object.keys(options);
|
|
171
|
+
if ((options.male || options.female) && optionKeys.every((k) => [
|
|
172
|
+
"male",
|
|
173
|
+
"female",
|
|
174
|
+
"other",
|
|
175
|
+
"fallback"
|
|
176
|
+
].includes(k))) return require_transpiler_gender_gender.gender({
|
|
177
|
+
fallback: options.other,
|
|
178
|
+
male: options.male,
|
|
179
|
+
female: options.female
|
|
180
|
+
});
|
|
181
|
+
options.__intlayer_icu_var = node.name;
|
|
182
|
+
return require_transpiler_enumeration_enumeration.enu(options);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return nodes.map((node) => icuNodesToIntlayer([node]));
|
|
186
|
+
};
|
|
187
|
+
const icuToIntlayerPlugin = {
|
|
188
|
+
canHandle: (node) => typeof node === "string" && (node.includes("{") || node.includes("}")),
|
|
189
|
+
transform: (node) => {
|
|
190
|
+
try {
|
|
191
|
+
return icuNodesToIntlayer(parseICU(node));
|
|
192
|
+
} catch {
|
|
193
|
+
return node;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const intlayerToIcuPlugin = {
|
|
198
|
+
canHandle: (node) => typeof node === "string" && (node.includes("{") || node.includes("}")) || node && typeof node === "object" && (node.nodeType === __intlayer_types.NodeType.Insertion || node.nodeType === __intlayer_types.NodeType.Enumeration || node.nodeType === __intlayer_types.NodeType.Gender || node.nodeType === "composite") || Array.isArray(node),
|
|
199
|
+
transform: (node, props, next) => {
|
|
200
|
+
if (typeof node === "string") return node.replace(/\{\{([^}]+)\}\}/g, "{$1}");
|
|
201
|
+
if (node.nodeType === __intlayer_types.NodeType.Insertion) return node.insertion.replace(/\{\{([^}]+)\}\}/g, "{$1}");
|
|
202
|
+
if (node.nodeType === __intlayer_types.NodeType.Enumeration) {
|
|
203
|
+
const options = node.enumeration;
|
|
204
|
+
const transformedOptions = {};
|
|
205
|
+
for (const [key, val] of Object.entries(options)) {
|
|
206
|
+
if (key === "__intlayer_icu_var") continue;
|
|
207
|
+
const childVal = next(val, props);
|
|
208
|
+
transformedOptions[key] = typeof childVal === "string" ? childVal : JSON.stringify(childVal);
|
|
209
|
+
}
|
|
210
|
+
let varName = options.__intlayer_icu_var || "n";
|
|
211
|
+
if (!options.__intlayer_icu_var) {
|
|
212
|
+
const match = (transformedOptions.fallback || transformedOptions.other || Object.values(transformedOptions)[0]).match(/\{([a-zA-Z0-9_]+)\}(?!,)/);
|
|
213
|
+
if (match) varName = match[1];
|
|
214
|
+
}
|
|
215
|
+
const keys = Object.keys(transformedOptions);
|
|
216
|
+
const pluralKeys = [
|
|
217
|
+
"1",
|
|
218
|
+
"2",
|
|
219
|
+
"<=3",
|
|
220
|
+
">=4",
|
|
221
|
+
"fallback",
|
|
222
|
+
"other",
|
|
223
|
+
"zero",
|
|
224
|
+
"one",
|
|
225
|
+
"two",
|
|
226
|
+
"few",
|
|
227
|
+
"many"
|
|
228
|
+
];
|
|
229
|
+
const isPlural = keys.every((k) => pluralKeys.includes(k) || /^[<>=]?\d+(\.\d+)?$/.test(k));
|
|
230
|
+
const parts = [];
|
|
231
|
+
if (isPlural) {
|
|
232
|
+
for (const [key, val] of Object.entries(transformedOptions)) {
|
|
233
|
+
let icuKey = key;
|
|
234
|
+
if (key === "fallback") icuKey = "other";
|
|
235
|
+
else if (key === "<=3") icuKey = "few";
|
|
236
|
+
else if (key === ">=4") icuKey = "many";
|
|
237
|
+
else if (/^\d+$/.test(key)) icuKey = `=${key}`;
|
|
238
|
+
else if ([
|
|
239
|
+
"zero",
|
|
240
|
+
"few",
|
|
241
|
+
"many"
|
|
242
|
+
].includes(key)) icuKey = key;
|
|
243
|
+
else icuKey = "other";
|
|
244
|
+
let strVal = val;
|
|
245
|
+
strVal = strVal.replace(new RegExp(`\\{${varName}\\}`, "g"), "#");
|
|
246
|
+
parts.push(`${icuKey} {${strVal}}`);
|
|
247
|
+
}
|
|
248
|
+
return `{${varName}, plural, ${parts.join(" ")}}`;
|
|
249
|
+
} else {
|
|
250
|
+
const entries = Object.entries(transformedOptions).sort(([keyA], [keyB]) => {
|
|
251
|
+
if (keyA === "fallback" || keyA === "other") return 1;
|
|
252
|
+
if (keyB === "fallback" || keyB === "other") return -1;
|
|
253
|
+
return 0;
|
|
254
|
+
});
|
|
255
|
+
for (const [key, val] of entries) {
|
|
256
|
+
let icuKey = key;
|
|
257
|
+
if (key === "fallback") icuKey = "other";
|
|
258
|
+
parts.push(`${icuKey} {${val}}`);
|
|
259
|
+
}
|
|
260
|
+
return `{${varName}, select, ${parts.join(" ")}}`;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (node.nodeType === __intlayer_types.NodeType.Gender) {
|
|
264
|
+
const options = node.gender;
|
|
265
|
+
const varName = "gender";
|
|
266
|
+
const parts = [];
|
|
267
|
+
const entries = Object.entries(options).sort(([keyA], [keyB]) => {
|
|
268
|
+
if (keyA === "fallback") return 1;
|
|
269
|
+
if (keyB === "fallback") return -1;
|
|
270
|
+
return 0;
|
|
271
|
+
});
|
|
272
|
+
for (const [key, val] of entries) {
|
|
273
|
+
let icuKey = key;
|
|
274
|
+
if (key === "fallback") icuKey = "other";
|
|
275
|
+
const childVal = next(val, props);
|
|
276
|
+
const strVal = typeof childVal === "string" ? childVal : JSON.stringify(childVal);
|
|
277
|
+
parts.push(`${icuKey} {${strVal}}`);
|
|
278
|
+
}
|
|
279
|
+
return `{${varName}, select, ${parts.join(" ")}}`;
|
|
280
|
+
}
|
|
281
|
+
if (Array.isArray(node) || node.nodeType === "composite" && Array.isArray(node.composite)) return (Array.isArray(node) ? node : node.composite).map((item) => next(item, props)).join("");
|
|
282
|
+
return next(node, props);
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const intlayerToICUFormatter = (message) => {
|
|
286
|
+
return require_interpreter_getContent_deepTransform.deepTransformNode(message, {
|
|
287
|
+
dictionaryKey: "icu",
|
|
288
|
+
keyPath: [],
|
|
289
|
+
plugins: [{
|
|
290
|
+
id: "icu",
|
|
291
|
+
...intlayerToIcuPlugin
|
|
292
|
+
}]
|
|
293
|
+
});
|
|
294
|
+
};
|
|
295
|
+
const icuToIntlayerFormatter = (message) => {
|
|
296
|
+
return require_interpreter_getContent_deepTransform.deepTransformNode(message, {
|
|
297
|
+
dictionaryKey: "icu",
|
|
298
|
+
keyPath: [],
|
|
299
|
+
plugins: [{
|
|
300
|
+
id: "icu",
|
|
301
|
+
...icuToIntlayerPlugin
|
|
302
|
+
}]
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
//#endregion
|
|
307
|
+
exports.icuToIntlayerFormatter = icuToIntlayerFormatter;
|
|
308
|
+
exports.intlayerToICUFormatter = intlayerToICUFormatter;
|
|
309
|
+
//# sourceMappingURL=ICU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ICU.cjs","names":["nodes: ICUNode[]","options: Record<string, ICUNode[]>","insert","options: Record<string, any>","enu","gender","NodeType","transformedOptions: Record<string, string>","deepTransformNode"],"sources":["../../../src/messageFormat/ICU.ts"],"sourcesContent":["import { type Dictionary, NodeType } from '@intlayer/types';\nimport { deepTransformNode } from '../interpreter';\nimport { enu, gender, insert } from '../transpiler';\n\n// Types for our AST\ntype ICUNode =\n | string\n | {\n type: 'argument';\n name: string;\n format?: { type: string; style?: string };\n }\n | { type: 'plural'; name: string; options: Record<string, ICUNode[]> }\n | { type: 'select'; name: string; options: Record<string, ICUNode[]> };\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\nconst parseICU = (text: string): ICUNode[] => {\n let index = 0;\n\n const parseNodes = (): ICUNode[] => {\n const nodes: ICUNode[] = [];\n let currentText = '';\n\n while (index < text.length) {\n const char = text[index];\n\n if (char === '{') {\n if (currentText) {\n nodes.push(currentText);\n currentText = '';\n }\n index++; // skip {\n nodes.push(parseArgument());\n } else if (char === '}') {\n // End of current block\n break;\n } else if (char === \"'\") {\n // Escaping\n if (index + 1 < text.length && text[index + 1] === \"'\") {\n currentText += \"'\";\n index += 2;\n } else {\n // Find next quote\n const nextQuote = text.indexOf(\"'\", index + 1);\n if (nextQuote !== -1) {\n // Determine if this is escaping syntax characters\n // For simplicity, we'll treat content between single quotes as literal\n // provided it contains syntax chars.\n // Standard ICU: ' quoted string '\n // If it is just an apostrophe, it should be doubled.\n // But simplified: take content between quotes literally.\n currentText += text.substring(index + 1, nextQuote);\n index = nextQuote + 1;\n } else {\n currentText += \"'\";\n index++;\n }\n }\n } else {\n currentText += char;\n index++;\n }\n }\n\n if (currentText) {\n nodes.push(currentText);\n }\n return nodes;\n };\n\n const parseArgument = (): ICUNode => {\n // We are past '{'\n // Parse name\n let name = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n name += text[index];\n index++;\n }\n name = name.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name };\n }\n\n // Must be comma\n if (text[index] === ',') {\n index++;\n // Parse type\n let type = '';\n while (index < text.length && /[^,}]/.test(text[index])) {\n type += text[index];\n index++;\n }\n type = type.trim();\n\n if (index >= text.length) throw new Error('Unclosed argument');\n\n if (text[index] === '}') {\n index++;\n return { type: 'argument', name, format: { type } };\n }\n\n if (text[index] === ',') {\n index++;\n\n // If plural or select, parse options\n if (type === 'plural' || type === 'select') {\n // Parse options\n const options: Record<string, ICUNode[]> = {};\n\n while (index < text.length && text[index] !== '}') {\n // skip whitespace\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n // parse key\n let key = '';\n while (index < text.length && /[^{\\s]/.test(text[index])) {\n key += text[index];\n index++;\n }\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n\n if (text[index] !== '{')\n throw new Error('Expected { after option key');\n index++; // skip {\n\n const value = parseNodes();\n\n if (text[index] !== '}')\n throw new Error('Expected } after option value');\n index++; // skip }\n\n options[key] = value;\n\n while (index < text.length && /\\s/.test(text[index])) index++;\n }\n\n index++; // skip closing argument }\n\n if (type === 'plural') {\n return { type: 'plural', name, options };\n } else if (type === 'select') {\n return { type: 'select', name, options };\n }\n } else {\n // Parse style for number/date/time\n let style = '';\n while (index < text.length && text[index] !== '}') {\n style += text[index];\n index++;\n }\n if (index >= text.length) throw new Error('Unclosed argument');\n\n style = style.trim();\n index++; // skip }\n\n return { type: 'argument', name, format: { type, style } };\n }\n }\n }\n\n throw new Error('Malformed argument');\n };\n\n return parseNodes();\n};\n\nconst icuNodesToIntlayer = (nodes: ICUNode[]): any => {\n if (nodes.length === 0) return '';\n if (nodes.length === 1 && typeof nodes[0] === 'string') return nodes[0];\n\n // Check if we can flatten to a single string (insert)\n const canFlatten = nodes.every(\n (node) => typeof node === 'string' || node.type === 'argument'\n );\n if (canFlatten) {\n let str = '';\n for (const node of nodes) {\n if (typeof node === 'string') {\n str += node;\n } else if (typeof node !== 'string' && node.type === 'argument') {\n if (node.format) {\n str += `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`;\n } else {\n str += `{{${node.name}}}`;\n }\n }\n }\n return insert(str);\n }\n\n // Mix of string and complex types.\n // If we have just one complex type and it covers everything?\n if (nodes.length === 1) {\n const node = nodes[0];\n\n if (typeof node === 'string') return node; // already handled\n if (node.type === 'argument') {\n if (node.format) {\n return insert(\n `{${node.name}, ${node.format.type}${\n node.format.style ? `, ${node.format.style}` : ''\n }}`\n );\n }\n return insert(`{{${node.name}}}`);\n }\n if (node.type === 'plural') {\n const options: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(node.options)) {\n // Map ICU keys to Intlayer keys\n let newKey = key;\n if (key.startsWith('=')) {\n newKey = key.substring(1); // =0 -> 0\n } else if (key === 'one') {\n newKey = '1';\n } else if (key === 'two') {\n newKey = '2';\n } else if (key === 'few') {\n newKey = '<=3';\n } else if (key === 'many') {\n newKey = '>=4';\n } else if (key === 'other') {\n newKey = 'fallback';\n }\n // Handle # in plural value\n // For plural, we need to pass the variable name down or replace #\n // Intlayer uses {{n}} (or whatever var name)\n // We should replace # with {{n}} in the string parts of val\n const replacedVal = val.map((v) => {\n if (typeof v === 'string') {\n return v.replace(/#/g, `{{${node.name}}}`);\n }\n return v;\n });\n\n options[newKey] = icuNodesToIntlayer(replacedVal);\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n if (node.type === 'select') {\n const options: Record<string, any> = {};\n\n for (const [key, val] of Object.entries(node.options)) {\n options[key] = icuNodesToIntlayer(val);\n }\n\n // Check if it looks like gender\n const optionKeys = Object.keys(options);\n // It is gender if it has 'male' OR 'female' AND only contains gender keys (male, female, other)\n const isGender =\n (options.male || options.female) &&\n optionKeys.every((k) =>\n ['male', 'female', 'other', 'fallback'].includes(k)\n );\n\n if (isGender) {\n return gender({\n fallback: options.other,\n male: options.male,\n female: options.female,\n });\n }\n\n // Preserve variable name\n options.__intlayer_icu_var = node.name;\n\n return enu(options);\n }\n }\n\n // If multiple nodes, return array\n return nodes.map((node) => icuNodesToIntlayer([node]));\n};\n\nconst icuToIntlayerPlugin = {\n canHandle: (node: any) =>\n typeof node === 'string' && (node.includes('{') || node.includes('}')),\n transform: (node: any) => {\n try {\n const ast = parseICU(node);\n return icuNodesToIntlayer(ast);\n } catch {\n // If parsing fails, return original string\n return node;\n }\n },\n};\n\nconst intlayerToIcuPlugin = {\n canHandle: (node: any) =>\n (typeof node === 'string' && (node.includes('{') || node.includes('}'))) ||\n (node &&\n typeof node === 'object' &&\n (node.nodeType === NodeType.Insertion ||\n node.nodeType === NodeType.Enumeration ||\n node.nodeType === NodeType.Gender ||\n node.nodeType === 'composite')) ||\n Array.isArray(node),\n transform: (node: any, props: any, next: any) => {\n if (typeof node === 'string') {\n return node.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeType.Insertion) {\n // insert(\"Hello {{name}}\") -> \"Hello {name}\"\n return node.insertion.replace(/\\{\\{([^}]+)\\}\\}/g, '{$1}');\n }\n\n if (node.nodeType === NodeType.Enumeration) {\n const options = node.enumeration;\n\n // Transform all values first\n const transformedOptions: Record<string, string> = {};\n for (const [key, val] of Object.entries(options)) {\n if (key === '__intlayer_icu_var') continue;\n const childVal = next(val, props);\n transformedOptions[key] =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n }\n\n // Infer variable name\n let varName = options.__intlayer_icu_var || 'n';\n\n if (!options.__intlayer_icu_var) {\n const fallbackVal =\n transformedOptions.fallback ||\n transformedOptions.other ||\n Object.values(transformedOptions)[0];\n // Match {variable} but avoid {variable, ...} (which are nested ICUs)\n // Actually nested ICU starts with {var, ...\n // Simple variable is {var}\n // We look for {var} that is NOT followed by ,\n const match = fallbackVal.match(/\\{([a-zA-Z0-9_]+)\\}(?!,)/);\n if (match) {\n varName = match[1];\n }\n }\n\n const keys = Object.keys(transformedOptions);\n const pluralKeys = [\n '1',\n '2',\n '<=3',\n '>=4',\n 'fallback',\n 'other',\n 'zero',\n 'one',\n 'two',\n 'few',\n 'many',\n ];\n // Also check for numbers\n const isPlural = keys.every(\n (k) => pluralKeys.includes(k) || /^[<>=]?\\d+(\\.\\d+)?$/.test(k)\n );\n\n const parts = [];\n\n if (isPlural) {\n for (const [key, val] of Object.entries(transformedOptions)) {\n let icuKey = key;\n\n if (key === 'fallback') icuKey = 'other';\n else if (key === '<=3') icuKey = 'few';\n else if (key === '>=4') icuKey = 'many';\n else if (/^\\d+$/.test(key)) icuKey = `=${key}`;\n else if (['zero', 'few', 'many'].includes(key)) icuKey = key;\n else icuKey = 'other';\n\n let strVal = val;\n\n // Replace {varName} with #\n // Note: next() has already converted {{var}} -> {var}\n strVal = strVal.replace(new RegExp(`\\\\{${varName}\\\\}`, 'g'), '#');\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n\n return `{${varName}, plural, ${parts.join(' ')}}`;\n } else {\n // Select\n const entries = Object.entries(transformedOptions).sort(\n ([keyA], [keyB]) => {\n if (keyA === 'fallback' || keyA === 'other') return 1;\n if (keyB === 'fallback' || keyB === 'other') return -1;\n return 0;\n }\n );\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n // Do NOT map other keys to 'other'. Keep 'active', 'inactive', etc.\n\n parts.push(`${icuKey} {${val}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n }\n\n if (node.nodeType === NodeType.Gender) {\n const options = node.gender;\n const varName = 'gender';\n const parts = [];\n\n const entries = Object.entries(options).sort(([keyA], [keyB]) => {\n if (keyA === 'fallback') return 1;\n if (keyB === 'fallback') return -1;\n return 0;\n });\n\n for (const [key, val] of entries) {\n let icuKey = key;\n if (key === 'fallback') icuKey = 'other';\n\n const childVal = next(val, props);\n const strVal =\n typeof childVal === 'string' ? childVal : JSON.stringify(childVal);\n\n parts.push(`${icuKey} {${strVal}}`);\n }\n return `{${varName}, select, ${parts.join(' ')}}`;\n }\n\n if (\n Array.isArray(node) ||\n (node.nodeType === 'composite' && Array.isArray(node.composite))\n ) {\n // handle array/composite\n const arr = Array.isArray(node) ? node : node.composite;\n const items = arr.map((item: any) => next(item, props));\n return items.join('');\n }\n\n return next(node, props);\n },\n};\n\nexport const intlayerToICUFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'icu',\n keyPath: [],\n plugins: [{ id: 'icu', ...intlayerToIcuPlugin }],\n });\n};\n\nexport const icuToIntlayerFormatter = (\n message: Dictionary['content']\n): JsonValue => {\n return deepTransformNode(message, {\n dictionaryKey: 'icu',\n keyPath: [],\n plugins: [{ id: 'icu', ...icuToIntlayerPlugin }],\n });\n};\n"],"mappings":"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"}
|