react-native-intlayer 8.12.2 → 8.12.4-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/configMetroIntlayer.cjs +35 -2
- 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 +35 -2
- 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 +2 -1
- package/dist/types/intlayerProvider.d.ts.map +1 -1
- package/package.json +9 -10
|
@@ -4,9 +4,16 @@ let node_path = require("node:path");
|
|
|
4
4
|
let _intlayer_chokidar_build = require("@intlayer/chokidar/build");
|
|
5
5
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
6
6
|
let _intlayer_config_utils = require("@intlayer/config/utils");
|
|
7
|
-
let metro_resolver = require("metro-resolver");
|
|
8
7
|
|
|
9
8
|
//#region src/configMetroIntlayer.ts
|
|
9
|
+
const getMetroResolve = () => {
|
|
10
|
+
try {
|
|
11
|
+
const metroPackageDir = (0, node_path.resolve)(require.resolve("metro/package.json"), "..");
|
|
12
|
+
return require((0, node_path.resolve)(metroPackageDir, "node_modules", "metro-resolver")).resolve;
|
|
13
|
+
} catch {
|
|
14
|
+
return require("metro-resolver").resolve;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
10
17
|
/**
|
|
11
18
|
* // metro.config.js
|
|
12
19
|
* const { getDefaultConfig } = require("expo/metro-config");
|
|
@@ -28,6 +35,23 @@ const configMetroIntlayerSync = (baseConfig) => {
|
|
|
28
35
|
const existingBlockList = baseConfig?.resolver?.blockList;
|
|
29
36
|
const existingPatterns = existingBlockList instanceof RegExp ? [existingBlockList] : existingBlockList ?? [];
|
|
30
37
|
const existingResolveRequest = baseConfig?.resolver?.resolveRequest;
|
|
38
|
+
/**
|
|
39
|
+
* Tracks resolution contexts that are currently executing inside the
|
|
40
|
+
* metro-resolver fallback call. When metro-resolver cannot find a module it
|
|
41
|
+
* may call back through `context.resolveRequest` (the outermost resolver in
|
|
42
|
+
* the chain, e.g. Sentry → NativeWind → ours). That callback eventually
|
|
43
|
+
* reaches our resolver again. Without a guard we would recurse indefinitely
|
|
44
|
+
* (see issue #457).
|
|
45
|
+
*
|
|
46
|
+
* On the second entry we break the cycle by stripping `resolveRequest` from
|
|
47
|
+
* the context so metro-resolver finishes with its built-in logic only
|
|
48
|
+
* (alias, extraNodeModules, …) rather than calling back a third time.
|
|
49
|
+
*
|
|
50
|
+
* Metro creates a fresh context object per module resolution, so using a
|
|
51
|
+
* WeakSet keyed on context is safe and causes no cross-resolution
|
|
52
|
+
* interference.
|
|
53
|
+
*/
|
|
54
|
+
const inflightFallbackContexts = /* @__PURE__ */ new WeakSet();
|
|
31
55
|
return {
|
|
32
56
|
...baseConfig,
|
|
33
57
|
resolver: {
|
|
@@ -46,7 +70,16 @@ const configMetroIntlayerSync = (baseConfig) => {
|
|
|
46
70
|
type: "sourceFile"
|
|
47
71
|
};
|
|
48
72
|
if (existingResolveRequest) return existingResolveRequest(context, moduleName, ...args);
|
|
49
|
-
|
|
73
|
+
if (inflightFallbackContexts.has(context)) {
|
|
74
|
+
const { resolveRequest: _r, ...pureContext } = context;
|
|
75
|
+
return getMetroResolve()(pureContext, moduleName, ...args);
|
|
76
|
+
}
|
|
77
|
+
inflightFallbackContexts.add(context);
|
|
78
|
+
try {
|
|
79
|
+
return getMetroResolve()(context, moduleName, ...args);
|
|
80
|
+
} finally {
|
|
81
|
+
inflightFallbackContexts.delete(context);
|
|
82
|
+
}
|
|
50
83
|
},
|
|
51
84
|
blockList: require_exclusionList.exclusionList([...existingPatterns, /.*\.content\.(?:ts|tsx|js|jsx|cjs|cjx|mjs|mjx|json)$/])
|
|
52
85
|
}
|
|
@@ -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 {
|
|
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 { exclusionList } from './exclusionList';\n\n/**\n * Returns the `resolve` function from metro-resolver, preferring the copy\n * bundled inside Metro itself. Loading from Metro's own package directory\n * ensures we use the same resolver instance that Metro uses internally,\n * which prevents the cross-version recursion described in\n * https://github.com/aymericzip/intlayer/issues/457.\n */\ntype AnyResolver = (context: any, moduleName: string, ...args: any[]) => any;\n\nconst getMetroResolve = (): AnyResolver => {\n try {\n const metroPackageDir = pathResolve(\n require.resolve('metro/package.json'),\n '..'\n );\n return (\n require(\n pathResolve(metroPackageDir, 'node_modules', 'metro-resolver')\n ) as typeof import('metro-resolver')\n ).resolve as AnyResolver;\n } catch {\n return (require('metro-resolver') as typeof import('metro-resolver'))\n .resolve as AnyResolver;\n }\n};\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 /**\n * Tracks resolution contexts that are currently executing inside the\n * metro-resolver fallback call. When metro-resolver cannot find a module it\n * may call back through `context.resolveRequest` (the outermost resolver in\n * the chain, e.g. Sentry → NativeWind → ours). That callback eventually\n * reaches our resolver again. Without a guard we would recurse indefinitely\n * (see issue #457).\n *\n * On the second entry we break the cycle by stripping `resolveRequest` from\n * the context so metro-resolver finishes with its built-in logic only\n * (alias, extraNodeModules, …) rather than calling back a third time.\n *\n * Metro creates a fresh context object per module resolution, so using a\n * WeakSet keyed on context is safe and causes no cross-resolution\n * interference.\n */\n const inflightFallbackContexts = new WeakSet<object>();\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 // Re-entry guard: metro-resolver has already been invoked for this\n // context and is now calling back through context.resolveRequest (the\n // outer chain) which has bubbled back to us. Strip resolveRequest so\n // metro-resolver resolves the module with only its built-in rules\n // (alias, extraNodeModules, etc.) and does not recurse again.\n if (inflightFallbackContexts.has(context)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { resolveRequest: _r, ...pureContext } = context as any;\n return getMetroResolve()(pureContext, moduleName, ...args);\n }\n\n // First pass: call metro-resolver while preserving context.resolveRequest\n // so outer wrappers (NativeWind, Sentry, …) still get a chance to\n // handle modules that metro-resolver cannot locate on its own (e.g. @/\n // tsconfig path aliases that a wrapper resolves via its own logic).\n inflightFallbackContexts.add(context);\n try {\n return getMetroResolve()(context, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\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":";;;;;;;;AAgBA,MAAM,wBAAqC;AACzC,KAAI;EACF,MAAM,yCACJ,QAAQ,QAAQ,qBAAqB,EACrC,KACD;AACD,SACE,+BACc,iBAAiB,gBAAgB,iBAAiB,CAC/D,CACD;SACI;AACN,SAAQ,QAAQ,iBAAiB,CAC9B;;;;;;;;;;;;;;;;AAmBP,MAAa,2BACX,eACgB;CAGhB,MAAM,6CAAiB;EACrB,4DAAa;EACb,WAAWA;EACZ,CAAC;CAEF,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,kBAAkB,GAClB,qBAAqB,EAAE;CAE9B,MAAM,yBAAyB,YAAY,UAAU;;;;;;;;;;;;;;;;;CAkBrD,MAAM,2CAA2B,IAAI,SAAiB;AAoEtD,QAAO;EAjEL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;AAChD,QAAI,OAAO,KAAK,MAAM,CAAC,SAAS,WAAW,CACzC,QAAO;KACL,UAAU,MAAM;KAChB,MAAM;KACP;AAIH,QAAI,eAAe,0BACjB,QAAO;KACL,UAAU,QAAQ,QAAQ,0BAA0B;KACpD,MAAM;KACP;AAIH,QAAI,eAAe,sBAEjB,QAAO;KACL,UAAU,QAAQ,QAAQ,8BAA8B;KACxD,MAAM;KACP;AAIH,QAAI,uBACF,QAAO,uBAAuB,SAAS,YAAY,GAAG,KAAK;AAQ7D,QAAI,yBAAyB,IAAI,QAAQ,EAAE;KAEzC,MAAM,EAAE,gBAAgB,IAAI,GAAG,gBAAgB;AAC/C,YAAO,iBAAiB,CAAC,aAAa,YAAY,GAAG,KAAK;;AAO5D,6BAAyB,IAAI,QAAQ;AACrC,QAAI;AACF,YAAO,iBAAiB,CAAC,SAAS,YAAY,GAAG,KAAK;cAC9C;AACR,8BAAyB,OAAO,QAAQ;;;GAG5C,WAAWC,oCAAc,CACvB,GAAG,kBAGH,uDACD,CAAC;GACH;EAGU;;;;;;;;;;;;;;;;AAiBf,MAAa,sBAAsB,OACjC,eACyB;AAGzB,kGAAmC,CAAC;AAEpC,QAAO,wBAAwB,WAAW"}
|
|
@@ -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;
|
|
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;AAE3C,KAAI,mBAAmB,OACrB,QAAO,QAAQ,OAAO,QAAQ,OAAO,WAAW;AAGlD,KAAI,OAAO,YAAY,SAErB,QADgB,QAAQ,QAAQ,uBAAuB,OACzC,CAAC,QAAQ,OAAO,WAAW;AAG3C,OAAM,IAAI,MAAM,iCAAiC,UAAU;;AAG7D,MAAa,iBACX,yBACa,CACb,IAAI,OAAO,IAAI,qBAAqB,IAAI,iBAAiB,CAAC,KAAK,IAAI,CAAC,IAAI,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;
|
|
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;AACpC,KAAI,OAAO,OAAO,oBAAoB,WACpC,QAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAGnE,KAAI,OAAO,WAAW,aAAa;AACjC,MAAI,OAAO,OAAO,qBAAqB,WACrC,QAAO,yBAAyB;AAElC,MAAI,OAAO,OAAO,wBAAwB,WACxC,QAAO,4BAA4B;AAErC,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAO,oBAAoB"}
|
|
@@ -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,2CAAkB;;;;;;;;;;;;;;;;;;;;AA0BlB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,2CAACC,wCAAD;CAAyB,GAAI;CAAQ;CAAmC"}
|
|
@@ -4,9 +4,16 @@ import { resolve } from "node:path";
|
|
|
4
4
|
import { prepareIntlayer } from "@intlayer/chokidar/build";
|
|
5
5
|
import { getConfiguration } from "@intlayer/config/node";
|
|
6
6
|
import { getAlias } from "@intlayer/config/utils";
|
|
7
|
-
import { resolve as resolve$1 } from "metro-resolver";
|
|
8
7
|
|
|
9
8
|
//#region src/configMetroIntlayer.ts
|
|
9
|
+
const getMetroResolve = () => {
|
|
10
|
+
try {
|
|
11
|
+
const metroPackageDir = resolve(__require.resolve("metro/package.json"), "..");
|
|
12
|
+
return __require(resolve(metroPackageDir, "node_modules", "metro-resolver")).resolve;
|
|
13
|
+
} catch {
|
|
14
|
+
return __require("metro-resolver").resolve;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
10
17
|
/**
|
|
11
18
|
* // metro.config.js
|
|
12
19
|
* const { getDefaultConfig } = require("expo/metro-config");
|
|
@@ -28,6 +35,23 @@ const configMetroIntlayerSync = (baseConfig) => {
|
|
|
28
35
|
const existingBlockList = baseConfig?.resolver?.blockList;
|
|
29
36
|
const existingPatterns = existingBlockList instanceof RegExp ? [existingBlockList] : existingBlockList ?? [];
|
|
30
37
|
const existingResolveRequest = baseConfig?.resolver?.resolveRequest;
|
|
38
|
+
/**
|
|
39
|
+
* Tracks resolution contexts that are currently executing inside the
|
|
40
|
+
* metro-resolver fallback call. When metro-resolver cannot find a module it
|
|
41
|
+
* may call back through `context.resolveRequest` (the outermost resolver in
|
|
42
|
+
* the chain, e.g. Sentry → NativeWind → ours). That callback eventually
|
|
43
|
+
* reaches our resolver again. Without a guard we would recurse indefinitely
|
|
44
|
+
* (see issue #457).
|
|
45
|
+
*
|
|
46
|
+
* On the second entry we break the cycle by stripping `resolveRequest` from
|
|
47
|
+
* the context so metro-resolver finishes with its built-in logic only
|
|
48
|
+
* (alias, extraNodeModules, …) rather than calling back a third time.
|
|
49
|
+
*
|
|
50
|
+
* Metro creates a fresh context object per module resolution, so using a
|
|
51
|
+
* WeakSet keyed on context is safe and causes no cross-resolution
|
|
52
|
+
* interference.
|
|
53
|
+
*/
|
|
54
|
+
const inflightFallbackContexts = /* @__PURE__ */ new WeakSet();
|
|
31
55
|
return {
|
|
32
56
|
...baseConfig,
|
|
33
57
|
resolver: {
|
|
@@ -46,7 +70,16 @@ const configMetroIntlayerSync = (baseConfig) => {
|
|
|
46
70
|
type: "sourceFile"
|
|
47
71
|
};
|
|
48
72
|
if (existingResolveRequest) return existingResolveRequest(context, moduleName, ...args);
|
|
49
|
-
|
|
73
|
+
if (inflightFallbackContexts.has(context)) {
|
|
74
|
+
const { resolveRequest: _r, ...pureContext } = context;
|
|
75
|
+
return getMetroResolve()(pureContext, moduleName, ...args);
|
|
76
|
+
}
|
|
77
|
+
inflightFallbackContexts.add(context);
|
|
78
|
+
try {
|
|
79
|
+
return getMetroResolve()(context, moduleName, ...args);
|
|
80
|
+
} finally {
|
|
81
|
+
inflightFallbackContexts.delete(context);
|
|
82
|
+
}
|
|
50
83
|
},
|
|
51
84
|
blockList: exclusionList([...existingPatterns, /.*\.content\.(?:ts|tsx|js|jsx|cjs|cjx|mjs|mjx|json)$/])
|
|
52
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configMetroIntlayer.mjs","names":["pathResolve"
|
|
1
|
+
{"version":3,"file":"configMetroIntlayer.mjs","names":["pathResolve"],"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 { exclusionList } from './exclusionList';\n\n/**\n * Returns the `resolve` function from metro-resolver, preferring the copy\n * bundled inside Metro itself. Loading from Metro's own package directory\n * ensures we use the same resolver instance that Metro uses internally,\n * which prevents the cross-version recursion described in\n * https://github.com/aymericzip/intlayer/issues/457.\n */\ntype AnyResolver = (context: any, moduleName: string, ...args: any[]) => any;\n\nconst getMetroResolve = (): AnyResolver => {\n try {\n const metroPackageDir = pathResolve(\n require.resolve('metro/package.json'),\n '..'\n );\n return (\n require(\n pathResolve(metroPackageDir, 'node_modules', 'metro-resolver')\n ) as typeof import('metro-resolver')\n ).resolve as AnyResolver;\n } catch {\n return (require('metro-resolver') as typeof import('metro-resolver'))\n .resolve as AnyResolver;\n }\n};\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 /**\n * Tracks resolution contexts that are currently executing inside the\n * metro-resolver fallback call. When metro-resolver cannot find a module it\n * may call back through `context.resolveRequest` (the outermost resolver in\n * the chain, e.g. Sentry → NativeWind → ours). That callback eventually\n * reaches our resolver again. Without a guard we would recurse indefinitely\n * (see issue #457).\n *\n * On the second entry we break the cycle by stripping `resolveRequest` from\n * the context so metro-resolver finishes with its built-in logic only\n * (alias, extraNodeModules, …) rather than calling back a third time.\n *\n * Metro creates a fresh context object per module resolution, so using a\n * WeakSet keyed on context is safe and causes no cross-resolution\n * interference.\n */\n const inflightFallbackContexts = new WeakSet<object>();\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 // Re-entry guard: metro-resolver has already been invoked for this\n // context and is now calling back through context.resolveRequest (the\n // outer chain) which has bubbled back to us. Strip resolveRequest so\n // metro-resolver resolves the module with only its built-in rules\n // (alias, extraNodeModules, etc.) and does not recurse again.\n if (inflightFallbackContexts.has(context)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const { resolveRequest: _r, ...pureContext } = context as any;\n return getMetroResolve()(pureContext, moduleName, ...args);\n }\n\n // First pass: call metro-resolver while preserving context.resolveRequest\n // so outer wrappers (NativeWind, Sentry, …) still get a chance to\n // handle modules that metro-resolver cannot locate on its own (e.g. @/\n // tsconfig path aliases that a wrapper resolves via its own logic).\n inflightFallbackContexts.add(context);\n try {\n return getMetroResolve()(context, moduleName, ...args);\n } finally {\n inflightFallbackContexts.delete(context);\n }\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":";;;;;;;;AAgBA,MAAM,wBAAqC;AACzC,KAAI;EACF,MAAM,kBAAkBA,kBACd,QAAQ,qBAAqB,EACrC,KACD;AACD,mBAEIA,QAAY,iBAAiB,gBAAgB,iBAAiB,CAC/D,CACD;SACI;AACN,mBAAgB,iBAAiB,CAC9B;;;;;;;;;;;;;;;;AAmBP,MAAa,2BACX,eACgB;CAGhB,MAAM,QAAQ,SAAS;EACrB,eAHoB,kBAGP;EACb,WAAWA;EACZ,CAAC;CAEF,MAAM,oBAAoB,YAAY,UAAU;CAChD,MAAM,mBACJ,6BAA6B,SACzB,CAAC,kBAAkB,GAClB,qBAAqB,EAAE;CAE9B,MAAM,yBAAyB,YAAY,UAAU;;;;;;;;;;;;;;;;;CAkBrD,MAAM,2CAA2B,IAAI,SAAiB;AAoEtD,QAAO;EAjEL,GAAG;EAEH,UAAU;GACR,GAAG,YAAY;GACf,iBAAiB,SAAS,YAAY,GAAG,SAAS;AAChD,QAAI,OAAO,KAAK,MAAM,CAAC,SAAS,WAAW,CACzC,QAAO;KACL,UAAU,MAAM;KAChB,MAAM;KACP;AAIH,QAAI,eAAe,0BACjB,QAAO;KACL,oBAAkB,QAAQ,0BAA0B;KACpD,MAAM;KACP;AAIH,QAAI,eAAe,sBAEjB,QAAO;KACL,oBAAkB,QAAQ,8BAA8B;KACxD,MAAM;KACP;AAIH,QAAI,uBACF,QAAO,uBAAuB,SAAS,YAAY,GAAG,KAAK;AAQ7D,QAAI,yBAAyB,IAAI,QAAQ,EAAE;KAEzC,MAAM,EAAE,gBAAgB,IAAI,GAAG,gBAAgB;AAC/C,YAAO,iBAAiB,CAAC,aAAa,YAAY,GAAG,KAAK;;AAO5D,6BAAyB,IAAI,QAAQ;AACrC,QAAI;AACF,YAAO,iBAAiB,CAAC,SAAS,YAAY,GAAG,KAAK;cAC9C;AACR,8BAAyB,OAAO,QAAQ;;;GAG5C,WAAW,cAAc,CACvB,GAAG,kBAGH,uDACD,CAAC;GACH;EAGU;;;;;;;;;;;;;;;;AAiBf,MAAa,sBAAsB,OACjC,eACyB;AAGzB,OAAM,gBAFgB,kBAEa,CAAC;AAEpC,QAAO,wBAAwB,WAAW"}
|
|
@@ -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;
|
|
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;AAE3C,KAAI,mBAAmB,OACrB,QAAO,QAAQ,OAAO,QAAQ,OAAO,WAAW;AAGlD,KAAI,OAAO,YAAY,SAErB,QADgB,QAAQ,QAAQ,uBAAuB,OACzC,CAAC,QAAQ,OAAO,WAAW;AAG3C,OAAM,IAAI,MAAM,iCAAiC,UAAU;;AAG7D,MAAa,iBACX,yBACa,CACb,IAAI,OAAO,IAAI,qBAAqB,IAAI,iBAAiB,CAAC,KAAK,IAAI,CAAC,IAAI,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;
|
|
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;AACpC,KAAI,OAAO,OAAO,oBAAoB,WACpC,QAAO,mBAAmB,QAAQ,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAGnE,KAAI,OAAO,WAAW,aAAa;AACjC,MAAI,OAAO,OAAO,qBAAqB,WACrC,QAAO,yBAAyB;AAElC,MAAI,OAAO,OAAO,wBAAwB,WACxC,QAAO,4BAA4B;AAErC,MAAI,OAAO,OAAO,gBAAgB,WAChC,QAAO,oBAAoB"}
|
|
@@ -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,kBAAkB;;;;;;;;;;;;;;;;;;;;AA0BlB,MAAa,oBAAoB,EAC/B,UACA,GAAG,YAEH,oBAAC,yBAAD;CAAyB,GAAI;CAAQ;CAAmC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configMetroIntlayer.d.ts","names":[],"sources":["../../src/configMetroIntlayer.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"configMetroIntlayer.d.ts","names":[],"sources":["../../src/configMetroIntlayer.ts"],"mappings":";;;KAiCK,WAAA,GAAc,UAAA,QAAkB,gBAAA;;AA7BqB;;;;;AA4C1D;;;;;;;cAAa,uBAAA,GACX,UAAA,GAAa,WAAA,KACZ,WAAA;;AAqHH;;;;;;;;;;;;;cAAa,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,MAAA"}
|
|
@@ -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;;;;;;;cAAa,gBAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as _$react from "react";
|
|
1
2
|
import { IntlayerProviderProps } from "react-intlayer";
|
|
2
3
|
|
|
3
4
|
//#region src/intlayerProvider.d.ts
|
|
@@ -24,7 +25,7 @@ type IntlayerProviderProps$1 = Omit<IntlayerProviderProps, 'disableEditor' | 'is
|
|
|
24
25
|
declare const IntlayerProvider: ({
|
|
25
26
|
children,
|
|
26
27
|
...props
|
|
27
|
-
}: IntlayerProviderProps$1) =>
|
|
28
|
+
}: IntlayerProviderProps$1) => _$react.JSX.Element;
|
|
28
29
|
//#endregion
|
|
29
30
|
export { IntlayerProvider };
|
|
30
31
|
//# 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,IAAA,CAC3B,qBAAA;;;AANsB;;;;;AA6BxB;;;;;;;;;;;;cAAa,gBAAA;EAAoB,QAAA;EAAA,GAAA;AAAA,GAG9B,uBAAA,KAAqB,OAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-intlayer",
|
|
3
|
-
"version": "8.12.
|
|
3
|
+
"version": "8.12.4-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.12.
|
|
90
|
-
"@intlayer/config": "8.12.
|
|
91
|
-
"@intlayer/core": "8.12.
|
|
92
|
-
"@intlayer/types": "8.12.
|
|
93
|
-
"react-intlayer": "8.12.
|
|
89
|
+
"@intlayer/chokidar": "8.12.4-canary.0",
|
|
90
|
+
"@intlayer/config": "8.12.4-canary.0",
|
|
91
|
+
"@intlayer/core": "8.12.4-canary.0",
|
|
92
|
+
"@intlayer/types": "8.12.4-canary.0",
|
|
93
|
+
"react-intlayer": "8.12.4-canary.0"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
-
"@types/node": "25.9.
|
|
96
|
+
"@types/node": "25.9.2",
|
|
97
97
|
"@types/react": ">=18.0.0",
|
|
98
98
|
"@utils/ts-config": "1.0.4",
|
|
99
99
|
"@utils/ts-config-types": "1.0.4",
|
|
@@ -102,15 +102,14 @@
|
|
|
102
102
|
"metro-resolver": "0.84.4",
|
|
103
103
|
"react": ">=18.0.0",
|
|
104
104
|
"rimraf": "6.1.3",
|
|
105
|
-
"tsdown": "0.
|
|
105
|
+
"tsdown": "0.21.10",
|
|
106
106
|
"typescript": "6.0.3",
|
|
107
107
|
"vitest": "4.1.8"
|
|
108
108
|
},
|
|
109
109
|
"peerDependencies": {
|
|
110
110
|
"expo": ">=52",
|
|
111
|
-
"metro-resolver": ">=0.80",
|
|
112
111
|
"react": ">=18.0.0",
|
|
113
|
-
"react-intlayer": "8.12.
|
|
112
|
+
"react-intlayer": "8.12.4-canary.0"
|
|
114
113
|
},
|
|
115
114
|
"engines": {
|
|
116
115
|
"node": ">=14.18"
|