react-native-intlayer 8.9.7 → 8.10.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/README.md +14 -0
- package/dist/cjs/configMetroIntlayer.cjs.map +1 -1
- package/dist/cjs/exclusionList.cjs.map +1 -1
- package/dist/cjs/intlayerPolyfill.cjs.map +1 -1
- package/dist/cjs/intlayerProvider.cjs.map +1 -1
- package/dist/esm/configMetroIntlayer.mjs.map +1 -1
- package/dist/esm/exclusionList.mjs.map +1 -1
- package/dist/esm/intlayerPolyfill.mjs.map +1 -1
- package/dist/esm/intlayerProvider.mjs.map +1 -1
- package/dist/types/configMetroIntlayer.d.ts.map +1 -1
- package/dist/types/exclusionList.d.ts.map +1 -1
- package/dist/types/intlayerPolyfill.d.ts.map +1 -1
- package/dist/types/intlayerProvider.d.ts +1 -2
- package/dist/types/intlayerProvider.d.ts.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -67,6 +67,7 @@ With **per-locale content files**, **TypeScript autocompletion**, **tree-shakabl
|
|
|
67
67
|
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/mcp.png?raw=true" alt="Feature" width="700"> | **MCP Server Integration**<br><br>Provides an MCP (Model Context Protocol) server for IDE automation, enabling seamless content management and i18n workflows directly within your development environment. <br><br> - [MCP Server](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md) |
|
|
68
68
|
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/vscode_extension.png?raw=true" alt="Feature" width="700"> | **VSCode Extension**<br><br>Intlayer provides a VSCode extension to help you manage your content and translations, building your dictionaries, translating your content, and more. <br><br> - [VSCode Extension](https://intlayer.org/doc/vs-code-extension) |
|
|
69
69
|
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/interoperability.png?raw=true" alt="Feature" width="700"> | **Interoperability**<br><br>Allow interoperability with react-i18next, next-i18next, next-intl, react-intl, vue-i18n. <br><br> - [Intlayer and react-intl](https://intlayer.org/blog/intlayer-with-react-intl) <br> - [Intlayer and next-intl](https://intlayer.org/blog/intlayer-with-next-intl) <br> - [Intlayer and next-i18next](https://intlayer.org/blog/intlayer-with-next-i18next) <br> - [Intlayer and vue-i18n](https://intlayer.org/blog/intlayer-with-vue-i18n) |
|
|
70
|
+
| <img src="https://github.com/aymericzip/intlayer/blob/main/docs/assets/benchmark.png?raw=true" alt="Feature" width="700"> | **Performances & Benchmark**<br><br>Uses advanced tree-shaking and dynamic loading to boost performances and keep the solution as light as possible. <br><br> - [Performances & Benchmark](https://intlayer.org/doc/benchmark) |
|
|
70
71
|
|
|
71
72
|
---
|
|
72
73
|
|
|
@@ -249,6 +250,19 @@ Explore our comprehensive documentation to get started with Intlayer and learn h
|
|
|
249
250
|
</ul>
|
|
250
251
|
</details>
|
|
251
252
|
|
|
253
|
+
## Multilingual content management system
|
|
254
|
+
|
|
255
|
+
More than an i18n library, Intlayer is a complete **multilingual content management system**. A full CMS is available for free at [app.intlayer.org](https://app.intlayer.org).
|
|
256
|
+
|
|
257
|
+
Intlayer connects **developers**, **copywriters**, and **AI agents** in one workflow for creating and maintaining multilingual websites effortlessly.Intlayer replaces the following stack in a single solution:
|
|
258
|
+
|
|
259
|
+
- i18n solutions (e.g. `i18next`, `next-intl`, `vue-i18n`)
|
|
260
|
+
- TMSs (Translation Management Systems) (e.g. Crowdin, Phrase, Lokalise)
|
|
261
|
+
- Feature flags
|
|
262
|
+
- Headless CMSs (e.g. Contentful, Strapi, Sanity)
|
|
263
|
+
|
|
264
|
+

|
|
265
|
+
|
|
252
266
|
## 🌐 Readme in other languages
|
|
253
267
|
|
|
254
268
|
<p align="center">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configMetroIntlayer.cjs","names":["pathResolve","exclusionList"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\nimport { resolve } from 'metro-resolver';\nimport { exclusionList } from './exclusionList';\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Fallback to metro-resolver\n return resolve(context as any, moduleName, ...args);\n },\n blockList: exclusionList([\n ...existingPatterns,\n // the following instruction should be replaced by a pattern derived from configuration.content.fileExtensions\n // but generating the pattern from fileExtensions does not exclude the files properly for now\n /.*\\.content\\.(?:ts|tsx|js|jsx|cjs|cjx|mjs|mjx|json)$/,\n ]),\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,2BACX,eACgB;CAGhB,MAAM,6CAAiB;EACrB,
|
|
1
|
+
{"version":3,"file":"configMetroIntlayer.cjs","names":["pathResolve","exclusionList"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\nimport { resolve } from 'metro-resolver';\nimport { exclusionList } from './exclusionList';\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Fallback to metro-resolver\n return resolve(context as any, moduleName, ...args);\n },\n blockList: exclusionList([\n ...existingPatterns,\n // the following instruction should be replaced by a pattern derived from configuration.content.fileExtensions\n // but generating the pattern from fileExtensions does not exclude the files properly for now\n /.*\\.content\\.(?:ts|tsx|js|jsx|cjs|cjx|mjs|mjx|json)$/,\n ]),\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,2BACX,eACgB;CAGhB,MAAM,6CAAiB;EACrB,2DAAY;EACZ,WAAWA;CACb,CAAC;CAED,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,iBAAiB,IACjB,qBAAqB,CAAC;CAE7B,MAAM,yBAAyB,YAAY,UAAU;CAiDrD,OAAO;EA9CL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;IAChD,IAAI,OAAO,KAAK,KAAK,EAAE,SAAS,UAAU,GACxC,OAAO;KACL,UAAU,MAAM;KAChB,MAAM;IACR;IAIF,IAAI,eAAe,2BACjB,OAAO;KACL,UAAU,QAAQ,QAAQ,yBAAyB;KACnD,MAAM;IACR;IAIF,IAAI,eAAe,uBAEjB,OAAO;KACL,UAAU,QAAQ,QAAQ,6BAA6B;KACvD,MAAM;IACR;IAIF,IAAI,wBACF,OAAO,uBAAuB,SAAS,YAAY,GAAG,IAAI;IAI5D,mCAAe,SAAgB,YAAY,GAAG,IAAI;GACpD;GACA,WAAWC,oCAAc,CACvB,GAAG,kBAGH,sDACF,CAAC;EACH;CAGU;AACd;;;;;;;;;;;;;;;AAgBA,MAAa,sBAAsB,OACjC,eACyB;CAGzB,gGAAkC,CAAC;CAEnC,OAAO,wBAAwB,UAAU;AAC3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exclusionList.cjs","names":["sep"],"sources":["../../src/exclusionList.ts"],"sourcesContent":["import { sep } from 'node:path';\n\nconst normalizePattern = (pattern: RegExp | string): string => {\n // On Windows, path separators are backslashes; double-escape for use inside a RegExp source string\n const separators = sep === '\\\\' ? '\\\\\\\\' : '/';\n\n if (pattern instanceof RegExp) {\n return pattern.source.replace(/\\//g, separators);\n }\n\n if (typeof pattern === 'string') {\n const escaped = pattern.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n return escaped.replace(/\\//g, separators);\n }\n\n throw new Error(`Unexpected exclusion pattern: ${pattern}`);\n};\n\nexport const exclusionList = (\n additionalExclusions: (RegExp | string)[]\n): RegExp[] => [\n new RegExp(`(${additionalExclusions.map(normalizePattern).join('|')})$`),\n];\n"],"mappings":";;;;AAEA,MAAM,oBAAoB,YAAqC;CAE7D,MAAM,aAAaA,kBAAQ,OAAO,SAAS;CAE3C,IAAI,mBAAmB,QACrB,OAAO,QAAQ,OAAO,QAAQ,OAAO,
|
|
1
|
+
{"version":3,"file":"exclusionList.cjs","names":["sep"],"sources":["../../src/exclusionList.ts"],"sourcesContent":["import { sep } from 'node:path';\n\nconst normalizePattern = (pattern: RegExp | string): string => {\n // On Windows, path separators are backslashes; double-escape for use inside a RegExp source string\n const separators = sep === '\\\\' ? '\\\\\\\\' : '/';\n\n if (pattern instanceof RegExp) {\n return pattern.source.replace(/\\//g, separators);\n }\n\n if (typeof pattern === 'string') {\n const escaped = pattern.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n return escaped.replace(/\\//g, separators);\n }\n\n throw new Error(`Unexpected exclusion pattern: ${pattern}`);\n};\n\nexport const exclusionList = (\n additionalExclusions: (RegExp | string)[]\n): RegExp[] => [\n new RegExp(`(${additionalExclusions.map(normalizePattern).join('|')})$`),\n];\n"],"mappings":";;;;AAEA,MAAM,oBAAoB,YAAqC;CAE7D,MAAM,aAAaA,kBAAQ,OAAO,SAAS;CAE3C,IAAI,mBAAmB,QACrB,OAAO,QAAQ,OAAO,QAAQ,OAAO,UAAU;CAGjD,IAAI,OAAO,YAAY,UAErB,OADgB,QAAQ,QAAQ,uBAAuB,MAC1C,EAAE,QAAQ,OAAO,UAAU;CAG1C,MAAM,IAAI,MAAM,iCAAiC,SAAS;AAC5D;AAEA,MAAa,iBACX,yBACa,CACb,IAAI,OAAO,IAAI,qBAAqB,IAAI,gBAAgB,EAAE,KAAK,GAAG,EAAE,GAAG,CACzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intlayerPolyfill.cjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes polyfilling `structuredClone` if it is missing,\n * and providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`)\n * to ensure compatibility with libraries that expect a browser-like environment.\n */\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = () => null;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = () => null;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = () => null;\n }\n }\n};\n"],"mappings":";;;;;;;;;;;AAQA,MAAa,yBAAyB;CACpC,IAAI,OAAO,OAAO,oBAAoB,YACpC,OAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"intlayerPolyfill.cjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes polyfilling `structuredClone` if it is missing,\n * and providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`)\n * to ensure compatibility with libraries that expect a browser-like environment.\n */\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = () => null;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = () => null;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = () => null;\n }\n }\n};\n"],"mappings":";;;;;;;;;;;AAQA,MAAa,yBAAyB;CACpC,IAAI,OAAO,OAAO,oBAAoB,YACpC,OAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;CAGlE,IAAI,OAAO,WAAW,aAAa;EACjC,IAAI,OAAO,OAAO,qBAAqB,YACrC,OAAO,yBAAyB;EAElC,IAAI,OAAO,OAAO,wBAAwB,YACxC,OAAO,4BAA4B;EAErC,IAAI,OAAO,OAAO,gBAAgB,YAChC,OAAO,oBAAoB;CAE/B;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intlayerProvider.cjs","names":["intlayerPolyfill","IntlayerProviderContent"],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\ntype IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;;AAMAA,
|
|
1
|
+
{"version":3,"file":"intlayerProvider.cjs","names":["intlayerPolyfill","IntlayerProviderContent"],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\ntype IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;;AAMAA,0CAAiB;;;;;;;;;;;;;;;;;;;;AA0BjB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,2CAACC,wCAAD;CAAyB,GAAI;CAAQ;AAAkC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configMetroIntlayer.mjs","names":["pathResolve","resolve"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\nimport { resolve } from 'metro-resolver';\nimport { exclusionList } from './exclusionList';\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Fallback to metro-resolver\n return resolve(context as any, moduleName, ...args);\n },\n blockList: exclusionList([\n ...existingPatterns,\n // the following instruction should be replaced by a pattern derived from configuration.content.fileExtensions\n // but generating the pattern from fileExtensions does not exclude the files properly for now\n /.*\\.content\\.(?:ts|tsx|js|jsx|cjs|cjx|mjs|mjx|json)$/,\n ]),\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,2BACX,eACgB;CAGhB,MAAM,QAAQ,SAAS;EACrB,eAHoB,
|
|
1
|
+
{"version":3,"file":"configMetroIntlayer.mjs","names":["pathResolve","resolve"],"sources":["../../src/configMetroIntlayer.ts"],"sourcesContent":["import { resolve as pathResolve } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { getConfiguration } from '@intlayer/config/node';\nimport { getAlias } from '@intlayer/config/utils';\nimport type { getDefaultConfig } from 'expo/metro-config';\nimport { resolve } from 'metro-resolver';\nimport { exclusionList } from './exclusionList';\n\ntype MetroConfig = ReturnType<typeof getDefaultConfig>;\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayerSync } = require(\"react-native-intlayer/metro\");\n *\n *\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return configMetroIntlayerSync(defaultConfig);\n * ```\n *\n * > Note: `configMetroIntlayerSync` does not build intlayer dictionaries on server start. Use `configMetroIntlayer` for that.\n */\nexport const configMetroIntlayerSync = (\n baseConfig?: MetroConfig\n): MetroConfig => {\n const configuration = getConfiguration();\n\n const alias = getAlias({\n configuration,\n formatter: pathResolve, // get absolute path\n });\n\n const existingBlockList = baseConfig?.resolver?.blockList;\n const existingPatterns: RegExp[] =\n existingBlockList instanceof RegExp\n ? [existingBlockList]\n : (existingBlockList ?? []);\n\n const existingResolveRequest = baseConfig?.resolver?.resolveRequest;\n\n const config = {\n ...baseConfig,\n\n resolver: {\n ...baseConfig?.resolver,\n resolveRequest: (context, moduleName, ...args) => {\n if (Object.keys(alias).includes(moduleName)) {\n return {\n filePath: alias[moduleName as keyof typeof alias],\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/config/client') {\n return {\n filePath: require.resolve('@intlayer/config/client'),\n type: 'sourceFile',\n };\n }\n\n // Because metro does not resolve submodules, we need to resolve the path manually\n if (moduleName === '@intlayer/core/file') {\n // Force React Native to use the correct transpiled version\n return {\n filePath: require.resolve('@intlayer/core/file/browser'),\n type: 'sourceFile',\n };\n }\n\n // Delegate to the user-provided resolver if present\n if (existingResolveRequest) {\n return existingResolveRequest(context, moduleName, ...args);\n }\n\n // Fallback to metro-resolver\n return resolve(context as any, moduleName, ...args);\n },\n blockList: exclusionList([\n ...existingPatterns,\n // the following instruction should be replaced by a pattern derived from configuration.content.fileExtensions\n // but generating the pattern from fileExtensions does not exclude the files properly for now\n /.*\\.content\\.(?:ts|tsx|js|jsx|cjs|cjx|mjs|mjx|json)$/,\n ]),\n },\n } as MetroConfig;\n\n return config;\n};\n\n/**\n * // metro.config.js\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { configMetroIntlayer } = require(\"react-native-intlayer/metro\");\n *\n * module.exports = (async () => {\n * const defaultConfig = getDefaultConfig(__dirname);\n *\n * return await configMetroIntlayer(defaultConfig);\n * })();\n * ```\n *\n * > Note: `configMetroIntlayer` builds intlayer dictionaries on server start. Use `configMetroIntlayerSync` instead if you want to skip that.\n */\nexport const configMetroIntlayer = async (\n baseConfig?: MetroConfig\n): Promise<MetroConfig> => {\n const configuration = getConfiguration();\n\n await prepareIntlayer(configuration);\n\n return configMetroIntlayerSync(baseConfig);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,2BACX,eACgB;CAGhB,MAAM,QAAQ,SAAS;EACrB,eAHoB,iBAGR;EACZ,WAAWA;CACb,CAAC;CAED,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,iBAAiB,IACjB,qBAAqB,CAAC;CAE7B,MAAM,yBAAyB,YAAY,UAAU;CAiDrD,OAAO;EA9CL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;IAChD,IAAI,OAAO,KAAK,KAAK,EAAE,SAAS,UAAU,GACxC,OAAO;KACL,UAAU,MAAM;KAChB,MAAM;IACR;IAIF,IAAI,eAAe,2BACjB,OAAO;KACL,oBAAkB,QAAQ,yBAAyB;KACnD,MAAM;IACR;IAIF,IAAI,eAAe,uBAEjB,OAAO;KACL,oBAAkB,QAAQ,6BAA6B;KACvD,MAAM;IACR;IAIF,IAAI,wBACF,OAAO,uBAAuB,SAAS,YAAY,GAAG,IAAI;IAI5D,OAAOC,UAAQ,SAAgB,YAAY,GAAG,IAAI;GACpD;GACA,WAAW,cAAc,CACvB,GAAG,kBAGH,sDACF,CAAC;EACH;CAGU;AACd;;;;;;;;;;;;;;;AAgBA,MAAa,sBAAsB,OACjC,eACyB;CAGzB,MAAM,gBAFgB,iBAEY,CAAC;CAEnC,OAAO,wBAAwB,UAAU;AAC3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exclusionList.mjs","names":[],"sources":["../../src/exclusionList.ts"],"sourcesContent":["import { sep } from 'node:path';\n\nconst normalizePattern = (pattern: RegExp | string): string => {\n // On Windows, path separators are backslashes; double-escape for use inside a RegExp source string\n const separators = sep === '\\\\' ? '\\\\\\\\' : '/';\n\n if (pattern instanceof RegExp) {\n return pattern.source.replace(/\\//g, separators);\n }\n\n if (typeof pattern === 'string') {\n const escaped = pattern.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n return escaped.replace(/\\//g, separators);\n }\n\n throw new Error(`Unexpected exclusion pattern: ${pattern}`);\n};\n\nexport const exclusionList = (\n additionalExclusions: (RegExp | string)[]\n): RegExp[] => [\n new RegExp(`(${additionalExclusions.map(normalizePattern).join('|')})$`),\n];\n"],"mappings":";;;AAEA,MAAM,oBAAoB,YAAqC;CAE7D,MAAM,aAAa,QAAQ,OAAO,SAAS;CAE3C,IAAI,mBAAmB,QACrB,OAAO,QAAQ,OAAO,QAAQ,OAAO,
|
|
1
|
+
{"version":3,"file":"exclusionList.mjs","names":[],"sources":["../../src/exclusionList.ts"],"sourcesContent":["import { sep } from 'node:path';\n\nconst normalizePattern = (pattern: RegExp | string): string => {\n // On Windows, path separators are backslashes; double-escape for use inside a RegExp source string\n const separators = sep === '\\\\' ? '\\\\\\\\' : '/';\n\n if (pattern instanceof RegExp) {\n return pattern.source.replace(/\\//g, separators);\n }\n\n if (typeof pattern === 'string') {\n const escaped = pattern.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n return escaped.replace(/\\//g, separators);\n }\n\n throw new Error(`Unexpected exclusion pattern: ${pattern}`);\n};\n\nexport const exclusionList = (\n additionalExclusions: (RegExp | string)[]\n): RegExp[] => [\n new RegExp(`(${additionalExclusions.map(normalizePattern).join('|')})$`),\n];\n"],"mappings":";;;AAEA,MAAM,oBAAoB,YAAqC;CAE7D,MAAM,aAAa,QAAQ,OAAO,SAAS;CAE3C,IAAI,mBAAmB,QACrB,OAAO,QAAQ,OAAO,QAAQ,OAAO,UAAU;CAGjD,IAAI,OAAO,YAAY,UAErB,OADgB,QAAQ,QAAQ,uBAAuB,MAC1C,EAAE,QAAQ,OAAO,UAAU;CAG1C,MAAM,IAAI,MAAM,iCAAiC,SAAS;AAC5D;AAEA,MAAa,iBACX,yBACa,CACb,IAAI,OAAO,IAAI,qBAAqB,IAAI,gBAAgB,EAAE,KAAK,GAAG,EAAE,GAAG,CACzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intlayerPolyfill.mjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes polyfilling `structuredClone` if it is missing,\n * and providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`)\n * to ensure compatibility with libraries that expect a browser-like environment.\n */\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = () => null;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = () => null;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = () => null;\n }\n }\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,yBAAyB;CACpC,IAAI,OAAO,OAAO,oBAAoB,YACpC,OAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"intlayerPolyfill.mjs","names":[],"sources":["../../src/intlayerPolyfill.ts"],"sourcesContent":["/**\n * Applies necessary polyfills for React Native to support Intlayer.\n *\n * This includes polyfilling `structuredClone` if it is missing,\n * and providing no-op implementations for standard DOM `window` methods\n * (`addEventListener`, `removeEventListener`, `postMessage`)\n * to ensure compatibility with libraries that expect a browser-like environment.\n */\nexport const intlayerPolyfill = () => {\n if (typeof global.structuredClone !== 'function') {\n global.structuredClone = (obj) => JSON.parse(JSON.stringify(obj));\n }\n\n if (typeof window !== 'undefined') {\n if (typeof window.addEventListener !== 'function') {\n window.addEventListener = () => null;\n }\n if (typeof window.removeEventListener !== 'function') {\n window.removeEventListener = () => null;\n }\n if (typeof window.postMessage !== 'function') {\n window.postMessage = () => null;\n }\n }\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,yBAAyB;CACpC,IAAI,OAAO,OAAO,oBAAoB,YACpC,OAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,GAAG,CAAC;CAGlE,IAAI,OAAO,WAAW,aAAa;EACjC,IAAI,OAAO,OAAO,qBAAqB,YACrC,OAAO,yBAAyB;EAElC,IAAI,OAAO,OAAO,wBAAwB,YACxC,OAAO,4BAA4B;EAErC,IAAI,OAAO,OAAO,gBAAgB,YAChC,OAAO,oBAAoB;CAE/B;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intlayerProvider.mjs","names":[],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\ntype IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;AAMA,
|
|
1
|
+
{"version":3,"file":"intlayerProvider.mjs","names":[],"sources":["../../src/intlayerProvider.tsx"],"sourcesContent":["import {\n IntlayerProviderContent,\n type IntlayerProviderProps as IntlayerProviderPropsBase,\n} from 'react-intlayer';\nimport { intlayerPolyfill } from './intlayerPolyfill';\n\nintlayerPolyfill();\n\ntype IntlayerProviderProps = Omit<\n IntlayerProviderPropsBase,\n 'disableEditor' | 'isCookieEnabled'\n>;\n\n/**\n * Provider component that wraps your application and provides the Intlayer context.\n *\n * This provider also automatically applies necessary polyfills for React Native.\n *\n * @param props - The provider props, excluding editor-specific and cookie-specific options which are not applicable in React Native.\n * @returns The provider component.\n *\n * @example\n * ```tsx\n * import { IntlayerProvider } from 'react-native-intlayer';\n *\n * const App = () => (\n * <IntlayerProvider>\n * <MyComponent />\n * </IntlayerProvider>\n * );\n * ```\n */\nexport const IntlayerProvider = ({\n children,\n ...props\n}: IntlayerProviderProps) => (\n <IntlayerProviderContent {...props}>{children}</IntlayerProviderContent>\n);\n"],"mappings":";;;;;AAMA,iBAAiB;;;;;;;;;;;;;;;;;;;;AA0BjB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,oBAAC,yBAAD;CAAyB,GAAI;CAAQ;AAAkC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configMetroIntlayer.d.ts","names":[],"sources":["../../src/configMetroIntlayer.ts"],"mappings":";;;KAQK,WAAA,GAAc,
|
|
1
|
+
{"version":3,"file":"configMetroIntlayer.d.ts","names":[],"sources":["../../src/configMetroIntlayer.ts"],"mappings":";;;KAQK,WAAA,GAAc,UAAU,QAAQ,gBAAA;;AAJqB;;;;AAIL;AAerD;;;;;;;cAAa,uBAAA,GACX,UAAA,GAAa,WAAA,KACZ,WAgEF;AAAA;AAgBD;;;;;;;;;;;;;AAhBC,cAgBY,mBAAA,GACX,UAAA,GAAa,WAAA,KACZ,OAAA,CAAQ,WAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exclusionList.d.ts","names":[],"sources":["../../src/exclusionList.ts"],"mappings":";cAkBa,aAAA,GACX,oBAAA,GAAuB,MAAA,iBACtB,
|
|
1
|
+
{"version":3,"file":"exclusionList.d.ts","names":[],"sources":["../../src/exclusionList.ts"],"mappings":";cAkBa,aAAA,GACX,oBAAA,GAAuB,MAAA,iBACtB,MAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intlayerPolyfill.d.ts","names":[],"sources":["../../src/intlayerPolyfill.ts"],"mappings":";;AAQA
|
|
1
|
+
{"version":3,"file":"intlayerPolyfill.d.ts","names":[],"sources":["../../src/intlayerPolyfill.ts"],"mappings":";;AAQA;;;;AAgBC;;;cAhBY,gBAAA"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
1
|
import { IntlayerProviderProps } from "react-intlayer";
|
|
3
2
|
|
|
4
3
|
//#region src/intlayerProvider.d.ts
|
|
@@ -25,7 +24,7 @@ type IntlayerProviderProps$1 = Omit<IntlayerProviderProps, 'disableEditor' | 'is
|
|
|
25
24
|
declare const IntlayerProvider: ({
|
|
26
25
|
children,
|
|
27
26
|
...props
|
|
28
|
-
}: IntlayerProviderProps$1) =>
|
|
27
|
+
}: IntlayerProviderProps$1) => import("react/jsx-runtime").JSX.Element;
|
|
29
28
|
//#endregion
|
|
30
29
|
export { IntlayerProvider };
|
|
31
30
|
//# sourceMappingURL=intlayerProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intlayerProvider.d.ts","names":[],"sources":["../../src/intlayerProvider.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"intlayerProvider.d.ts","names":[],"sources":["../../src/intlayerProvider.tsx"],"mappings":";;;KAQK,uBAAA,GAAwB,IAAI,CAC/B,qBAAA;;AANsB;;;;AAMG;AAuB3B;;;;;;;;;;;AAKC;;cALY,gBAAA;EAAoB,QAAA;EAAA,GAAA;AAAA,GAG9B,uBAAqB,iCAAA,GAAA,CAAA,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-intlayer",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.10.0-canary.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A React Native plugin for seamless internationalization (i18n), providing locale detection, redirection, and environment-based configuration",
|
|
6
6
|
"keywords": [
|
|
@@ -86,14 +86,14 @@
|
|
|
86
86
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@intlayer/chokidar": "8.
|
|
90
|
-
"@intlayer/config": "8.
|
|
91
|
-
"@intlayer/core": "8.
|
|
92
|
-
"@intlayer/types": "8.
|
|
93
|
-
"react-intlayer": "8.
|
|
89
|
+
"@intlayer/chokidar": "8.10.0-canary.0",
|
|
90
|
+
"@intlayer/config": "8.10.0-canary.0",
|
|
91
|
+
"@intlayer/core": "8.10.0-canary.0",
|
|
92
|
+
"@intlayer/types": "8.10.0-canary.0",
|
|
93
|
+
"react-intlayer": "8.10.0-canary.0"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
-
"@types/node": "25.
|
|
96
|
+
"@types/node": "25.9.0",
|
|
97
97
|
"@types/react": ">=18.0.0",
|
|
98
98
|
"@utils/ts-config": "1.0.4",
|
|
99
99
|
"@utils/ts-config-types": "1.0.4",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"expo": ">=52",
|
|
111
111
|
"metro-resolver": ">=0.80",
|
|
112
112
|
"react": ">=18.0.0",
|
|
113
|
-
"react-intlayer": "8.
|
|
113
|
+
"react-intlayer": "8.10.0-canary.0"
|
|
114
114
|
},
|
|
115
115
|
"engines": {
|
|
116
116
|
"node": ">=14.18"
|