@teardown/metro-config 2.0.85 → 2.0.87
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/bun.d.ts.map +1 -1
- package/dist/dev-client.d.ts +60 -0
- package/dist/dev-client.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/tsconfig-paths.d.ts.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -4
- package/dist/bun.js +0 -107
- package/dist/index.js +0 -160
- package/dist/tsconfig-paths.js +0 -239
- package/dist/types.js +0 -5
- package/dist/workspace.js +0 -231
package/dist/bun.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../src/bun.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGhD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../src/bun.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGhD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAwB,CAAC;AAwCvD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,CAsBjH;AAmCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAQ5E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dev Client Metro Configuration
|
|
3
|
+
*
|
|
4
|
+
* Provides Metro configuration for injecting the dev client launcher
|
|
5
|
+
* before the main application entry point. This enables expo-dev-client-like
|
|
6
|
+
* behavior for bare React Native apps.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
import type { MetroConfig } from "./types";
|
|
11
|
+
/**
|
|
12
|
+
* Dev client configuration options
|
|
13
|
+
*/
|
|
14
|
+
export interface DevClientOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Whether to enable the dev client launcher.
|
|
17
|
+
* Only applies in development mode (__DEV__).
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Custom bootstrap module path (advanced usage).
|
|
23
|
+
* Defaults to @teardown/dev-client/bootstrap
|
|
24
|
+
*/
|
|
25
|
+
bootstrapModule?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Enable verbose logging
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
verbose?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Wrap Metro config with dev client launcher support.
|
|
34
|
+
*
|
|
35
|
+
* This injects a bootstrap module that runs before the main entry point,
|
|
36
|
+
* allowing the dev client launcher to show before the app loads.
|
|
37
|
+
* The bootstrap module:
|
|
38
|
+
* - Patches AppRegistry.registerComponent to capture app registrations
|
|
39
|
+
* - Shows a launcher UI before the main app
|
|
40
|
+
* - Automatically wraps the app with DevClientProvider when launched
|
|
41
|
+
*
|
|
42
|
+
* @param config - Metro configuration
|
|
43
|
+
* @param options - Dev client options
|
|
44
|
+
* @returns Enhanced Metro configuration
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```js
|
|
48
|
+
* // metro.config.js
|
|
49
|
+
* const { withTeardown, withTeardownDevClient } = require('@teardown/metro-config');
|
|
50
|
+
* const { getDefaultConfig } = require('@react-native/metro-config');
|
|
51
|
+
*
|
|
52
|
+
* let config = getDefaultConfig(__dirname);
|
|
53
|
+
* config = withTeardown(config);
|
|
54
|
+
* config = withTeardownDevClient(config);
|
|
55
|
+
*
|
|
56
|
+
* module.exports = config;
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function withTeardownDevClient(config: MetroConfig, options?: DevClientOptions): MetroConfig;
|
|
60
|
+
//# sourceMappingURL=dev-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-client.d.ts","sourceRoot":"","sources":["../src/dev-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,gBAAqB,GAAG,WAAW,CAyCtG"}
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,7 @@ import type { MetroConfig, TeardownMetroOptions } from "./types";
|
|
|
56
56
|
export declare function withTeardown(config: MetroConfig, options?: TeardownMetroOptions): MetroConfig;
|
|
57
57
|
export { getStoredOptions };
|
|
58
58
|
export { BUN_BLOCK_PATTERN, getBlockList } from "./bun";
|
|
59
|
+
export { type DevClientOptions, withTeardownDevClient } from "./dev-client";
|
|
59
60
|
export { createTsConfigPathsResolver, parseTsConfigPaths } from "./tsconfig-paths";
|
|
60
61
|
export { getMetroServerRoot, getModulesPaths, getRelativeProjectRoot, getWatchFolders, getWorkspaceRoot, isInMonorepo, } from "./workspace";
|
|
61
62
|
export type { TeardownMetroOptions, MetroConfig };
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,gBAAgB,EAAiB,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAE,WAAW,EAAoB,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAUnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,oBAAyB,GAAG,WAAW,CAmGjG;AAGD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAExD,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACZ,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,gBAAgB,EAAiB,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAE,WAAW,EAAoB,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAUnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,oBAAyB,GAAG,WAAW,CAmGjG;AAGD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAExD,OAAO,EAAE,KAAK,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,YAAY,GACZ,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tsconfig-paths.d.ts","sourceRoot":"","sources":["../src/tsconfig-paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,UAAU,aAAa;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACjC;AAED,UAAU,WAAW;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACvB;AAoGD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAqB5E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,WAAW,EAAE,CAsB3F;
|
|
1
|
+
{"version":3,"file":"tsconfig-paths.d.ts","sourceRoot":"","sources":["../src/tsconfig-paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,UAAU,aAAa;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACjC;AAED,UAAU,WAAW;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACvB;AAoGD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAqB5E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,WAAW,EAAE,CAsB3F;AAmGD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,GAAG,IAAI,CAQnG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAC1C,WAAW,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,gBAAgB,EAC/B,OAAO,UAAQ,GACb,gBAAgB,CAyClB"}
|
package/dist/types.d.ts
CHANGED
|
@@ -18,6 +18,14 @@ export interface MetroConfig extends FacetpackMetroConfig {
|
|
|
18
18
|
customTransformOptions?: Record<string, unknown>;
|
|
19
19
|
[key: string]: unknown;
|
|
20
20
|
};
|
|
21
|
+
serializer?: {
|
|
22
|
+
/**
|
|
23
|
+
* Function that returns modules to run before the main entry point.
|
|
24
|
+
* Used by dev-client to inject bootstrap code.
|
|
25
|
+
*/
|
|
26
|
+
getModulesRunBeforeMainModule?: (entryFilePath: string) => string[];
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
};
|
|
21
29
|
[key: string]: unknown;
|
|
22
30
|
}
|
|
23
31
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,oBAAoB;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC9B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC5B,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,WAAW,CAAC,EAAE;QACb,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC9B,OAAO,EAAE;IAAE,cAAc,EAAE,gBAAgB,CAAA;CAAE,EAC7C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,KACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,oBAAoB;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC9B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC5B,cAAc,CAAC,EAAE,gBAAgB,CAAC;QAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,WAAW,CAAC,EAAE;QACb,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,UAAU,CAAC,EAAE;QACZ;;;WAGG;QACH,6BAA6B,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;QACpE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC9B,OAAO,EAAE;IAAE,cAAc,EAAE,gBAAgB,CAAA;CAAE,EAC7C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,KACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teardown/metro-config",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.87",
|
|
4
4
|
"description": "Metro configuration for Teardown - Rust-powered transforms via Facetpack",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
"require": "./dist/index.js",
|
|
15
15
|
"default": "./dist/index.js"
|
|
16
16
|
},
|
|
17
|
+
"./dev-client": {
|
|
18
|
+
"types": "./dist/dev-client.d.ts",
|
|
19
|
+
"require": "./dist/dev-client.js",
|
|
20
|
+
"default": "./dist/dev-client.js"
|
|
21
|
+
},
|
|
17
22
|
"./package.json": "./package.json"
|
|
18
23
|
},
|
|
19
24
|
"files": [
|
|
@@ -22,7 +27,7 @@
|
|
|
22
27
|
"scripts": {
|
|
23
28
|
"build": "tsc",
|
|
24
29
|
"prepublishOnly": "bun run build",
|
|
25
|
-
"typecheck": "
|
|
30
|
+
"typecheck": "bunx tsgo --noEmit",
|
|
26
31
|
"lint": "bun x biome lint --write ./src",
|
|
27
32
|
"fmt": "bun x biome format --write ./src",
|
|
28
33
|
"check": "bun x biome check ./src"
|
|
@@ -45,8 +50,11 @@
|
|
|
45
50
|
"resolve-workspace-root": "^2.0.0"
|
|
46
51
|
},
|
|
47
52
|
"devDependencies": {
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
53
|
+
"@typescript/native-preview": "^7.0.0-dev.20260203.1",
|
|
54
|
+
"@ecrindigital/facetpack": "^0.2.0",
|
|
55
|
+
"@teardown/tsconfig": "2.0.87",
|
|
56
|
+
"@types/bun": "1.3.8",
|
|
57
|
+
"@types/node": "24.10.1",
|
|
50
58
|
"typescript": "5.9.3"
|
|
51
59
|
},
|
|
52
60
|
"keywords": [
|
package/dist/bun.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Bun-specific Metro configuration utilities.
|
|
4
|
-
*
|
|
5
|
-
* Handles blocking of .bun directories which can cause Metro resolution issues.
|
|
6
|
-
*/
|
|
7
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.BUN_BLOCK_PATTERN = void 0;
|
|
12
|
-
exports.createBunAwareResolver = createBunAwareResolver;
|
|
13
|
-
exports.getBlockList = getBlockList;
|
|
14
|
-
const node_fs_1 = require("node:fs");
|
|
15
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
-
const workspace_1 = require("./workspace");
|
|
17
|
-
/**
|
|
18
|
-
* Block pattern for .bun directories.
|
|
19
|
-
* Metro's blockList prevents processing of matched paths.
|
|
20
|
-
*/
|
|
21
|
-
exports.BUN_BLOCK_PATTERN = /.*[/\\]\.bun[/\\].*/;
|
|
22
|
-
/**
|
|
23
|
-
* Create a custom resolver that filters out .bun paths during module resolution.
|
|
24
|
-
*
|
|
25
|
-
* Note: The primary mechanism for blocking .bun directories is the blockList pattern.
|
|
26
|
-
* This resolver provides an additional layer of protection by finding alternative
|
|
27
|
-
* paths when a resolution from an existing custom resolver points to .bun.
|
|
28
|
-
*
|
|
29
|
-
* IMPORTANT: This resolver returns null when it doesn't handle resolution, signaling
|
|
30
|
-
* Metro to use its default resolution. Do NOT call context.resolveRequest as that
|
|
31
|
-
* points to the outermost resolver (e.g., Uniwind) and creates infinite loops.
|
|
32
|
-
*
|
|
33
|
-
* @param projectRoot - The project root directory
|
|
34
|
-
* @param existingResolver - Optional existing resolver from the config that should be preserved.
|
|
35
|
-
*/
|
|
36
|
-
function createBunAwareResolver(projectRoot, existingResolver) {
|
|
37
|
-
const modulesPaths = (0, workspace_1.getModulesPaths)(projectRoot);
|
|
38
|
-
return (context, moduleName, platform) => {
|
|
39
|
-
// If there's an existing resolver, try it first
|
|
40
|
-
let result = null;
|
|
41
|
-
if (existingResolver) {
|
|
42
|
-
result = existingResolver(context, moduleName, platform);
|
|
43
|
-
}
|
|
44
|
-
// If no result from existing resolver, return null to let Metro use its default
|
|
45
|
-
// Do NOT call context.resolveRequest - it points to the outermost resolver
|
|
46
|
-
if (!result) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
// If resolved path contains .bun, try to find alternative
|
|
50
|
-
if (result.filePath?.includes("/.bun/")) {
|
|
51
|
-
for (const modulesPath of modulesPaths) {
|
|
52
|
-
if (modulesPath.includes("/.bun/"))
|
|
53
|
-
continue;
|
|
54
|
-
const packagePath = node_path_1.default.join(modulesPath, moduleName);
|
|
55
|
-
if ((0, node_fs_1.existsSync)(packagePath)) {
|
|
56
|
-
const mainFile = resolvePackageMain(packagePath);
|
|
57
|
-
if (mainFile) {
|
|
58
|
-
return { type: "sourceFile", filePath: mainFile };
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return result;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Resolve the main entry point of a package.
|
|
68
|
-
*/
|
|
69
|
-
function resolvePackageMain(packagePath) {
|
|
70
|
-
const packageJsonPath = node_path_1.default.join(packagePath, "package.json");
|
|
71
|
-
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
72
|
-
try {
|
|
73
|
-
const pkg = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, "utf8"));
|
|
74
|
-
const main = pkg.main || pkg.module || "index.js";
|
|
75
|
-
const mainPath = node_path_1.default.join(packagePath, main);
|
|
76
|
-
if ((0, node_fs_1.existsSync)(mainPath)) {
|
|
77
|
-
return mainPath;
|
|
78
|
-
}
|
|
79
|
-
// Try with .js extension
|
|
80
|
-
const mainPathJs = mainPath + ".js";
|
|
81
|
-
if ((0, node_fs_1.existsSync)(mainPathJs)) {
|
|
82
|
-
return mainPathJs;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
// Ignore parse errors
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// Fallback to index.js
|
|
90
|
-
const indexPath = node_path_1.default.join(packagePath, "index.js");
|
|
91
|
-
if ((0, node_fs_1.existsSync)(indexPath)) {
|
|
92
|
-
return indexPath;
|
|
93
|
-
}
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Get blockList patterns for Metro config.
|
|
98
|
-
* Includes .bun directory blocking.
|
|
99
|
-
*/
|
|
100
|
-
function getBlockList(existingBlockList) {
|
|
101
|
-
const blockListArray = Array.isArray(existingBlockList)
|
|
102
|
-
? existingBlockList
|
|
103
|
-
: existingBlockList
|
|
104
|
-
? [existingBlockList]
|
|
105
|
-
: [];
|
|
106
|
-
return [...blockListArray, exports.BUN_BLOCK_PATTERN];
|
|
107
|
-
}
|
package/dist/index.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @teardown/metro-config
|
|
4
|
-
*
|
|
5
|
-
* Metro configuration wrapper that provides:
|
|
6
|
-
* - Rust-powered transforms via Facetpack (36x faster than Babel)
|
|
7
|
-
* - Automatic monorepo/workspace detection and configuration
|
|
8
|
-
* - Bun-specific handling (blocks .bun directories)
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```js
|
|
12
|
-
* // metro.config.js
|
|
13
|
-
* const { withTeardown } = require('@teardown/metro-config')
|
|
14
|
-
* const { getDefaultConfig } = require('@react-native/metro-config')
|
|
15
|
-
*
|
|
16
|
-
* module.exports = withTeardown(getDefaultConfig(__dirname))
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* @packageDocumentation
|
|
20
|
-
*/
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.isInMonorepo = exports.getWorkspaceRoot = exports.getWatchFolders = exports.getRelativeProjectRoot = exports.getModulesPaths = exports.getMetroServerRoot = exports.parseTsConfigPaths = exports.createTsConfigPathsResolver = exports.getBlockList = exports.BUN_BLOCK_PATTERN = exports.getStoredOptions = void 0;
|
|
23
|
-
exports.withTeardown = withTeardown;
|
|
24
|
-
const facetpack_1 = require("@ecrindigital/facetpack");
|
|
25
|
-
Object.defineProperty(exports, "getStoredOptions", { enumerable: true, get: function () { return facetpack_1.getStoredOptions; } });
|
|
26
|
-
const bun_1 = require("./bun");
|
|
27
|
-
const tsconfig_paths_1 = require("./tsconfig-paths");
|
|
28
|
-
const workspace_1 = require("./workspace");
|
|
29
|
-
/**
|
|
30
|
-
* Wraps a Metro configuration with Teardown's enhancements.
|
|
31
|
-
*
|
|
32
|
-
* This function applies:
|
|
33
|
-
* - Facetpack for Rust-powered transforms (36x faster)
|
|
34
|
-
* - Automatic monorepo detection and watch folder configuration
|
|
35
|
-
* - Bun-specific handling (.bun directory blocking)
|
|
36
|
-
* - Proper nodeModulesPaths for monorepo resolution
|
|
37
|
-
*
|
|
38
|
-
* @param config - Base Metro configuration
|
|
39
|
-
* @param options - Optional configuration options
|
|
40
|
-
* @returns Enhanced Metro configuration
|
|
41
|
-
*
|
|
42
|
-
* @example
|
|
43
|
-
* ```js
|
|
44
|
-
* // Basic usage - all monorepo handling is automatic
|
|
45
|
-
* const { withTeardown } = require('@teardown/metro-config')
|
|
46
|
-
* const { getDefaultConfig } = require('@react-native/metro-config')
|
|
47
|
-
*
|
|
48
|
-
* module.exports = withTeardown(getDefaultConfig(__dirname))
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```js
|
|
53
|
-
* // With options
|
|
54
|
-
* const { withTeardown } = require('@teardown/metro-config')
|
|
55
|
-
* const { getDefaultConfig } = require('@react-native/metro-config')
|
|
56
|
-
*
|
|
57
|
-
* module.exports = withTeardown(getDefaultConfig(__dirname), {
|
|
58
|
-
* verbose: true,
|
|
59
|
-
* projectRoot: __dirname, // explicitly set project root
|
|
60
|
-
* })
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
function withTeardown(config, options = {}) {
|
|
64
|
-
const { verbose, projectRoot: explicitProjectRoot, tsconfigPaths = true, ...facetpackOptions } = options;
|
|
65
|
-
// Determine project root
|
|
66
|
-
const projectRoot = explicitProjectRoot || config.projectRoot || process.cwd();
|
|
67
|
-
if (verbose) {
|
|
68
|
-
console.log("[teardown/metro-config] Applying Teardown configuration...");
|
|
69
|
-
console.log(`[teardown/metro-config] Project root: ${projectRoot}`);
|
|
70
|
-
}
|
|
71
|
-
// Check if in monorepo
|
|
72
|
-
const inMonorepo = (0, workspace_1.isInMonorepo)(projectRoot);
|
|
73
|
-
if (verbose && inMonorepo) {
|
|
74
|
-
const workspaceRoot = (0, workspace_1.getWorkspaceRoot)(projectRoot);
|
|
75
|
-
console.log(`[teardown/metro-config] Monorepo detected: ${workspaceRoot}`);
|
|
76
|
-
}
|
|
77
|
-
// Get monorepo-aware watch folders
|
|
78
|
-
const additionalWatchFolders = (0, workspace_1.getWatchFolders)(projectRoot);
|
|
79
|
-
const existingWatchFolders = config.watchFolders || [];
|
|
80
|
-
// Get monorepo-aware node modules paths
|
|
81
|
-
const modulesPaths = (0, workspace_1.getModulesPaths)(projectRoot);
|
|
82
|
-
const existingNodeModulesPaths = config.resolver?.nodeModulesPaths || [];
|
|
83
|
-
// Get block list with .bun blocking
|
|
84
|
-
const blockList = (0, bun_1.getBlockList)(config.resolver?.blockList);
|
|
85
|
-
// Get any existing custom resolver from the config
|
|
86
|
-
const existingResolver = config.resolver?.resolveRequest;
|
|
87
|
-
// Create resolver chain: tsconfig paths -> bun-aware -> existing/default
|
|
88
|
-
// The bun-aware resolver handles .bun path filtering
|
|
89
|
-
const bunAwareResolver = (0, bun_1.createBunAwareResolver)(projectRoot, existingResolver);
|
|
90
|
-
// Apply tsconfig paths resolver on top (so it runs first)
|
|
91
|
-
const chainedResolver = tsconfigPaths
|
|
92
|
-
? (0, tsconfig_paths_1.createTsConfigPathsResolver)(projectRoot, bunAwareResolver, verbose)
|
|
93
|
-
: bunAwareResolver;
|
|
94
|
-
// Wrap with null-safe handling so external plugins (like Uniwind) don't receive null
|
|
95
|
-
// When our resolver chain returns null, use Metro's internal resolver as fallback
|
|
96
|
-
const nullSafeResolver = (context, moduleName, platform) => {
|
|
97
|
-
const result = chainedResolver(context, moduleName, platform);
|
|
98
|
-
if (result === null) {
|
|
99
|
-
return context.resolveRequest(context, moduleName, platform);
|
|
100
|
-
}
|
|
101
|
-
return result;
|
|
102
|
-
};
|
|
103
|
-
// Build enhanced config
|
|
104
|
-
const enhancedConfig = {
|
|
105
|
-
...config,
|
|
106
|
-
projectRoot,
|
|
107
|
-
watchFolders: [...new Set([...existingWatchFolders, ...additionalWatchFolders])],
|
|
108
|
-
resolver: {
|
|
109
|
-
...config.resolver,
|
|
110
|
-
blockList,
|
|
111
|
-
nodeModulesPaths: [...new Set([...modulesPaths, ...existingNodeModulesPaths])],
|
|
112
|
-
resolveRequest: nullSafeResolver,
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
// Set unstable_serverRoot for monorepo web support
|
|
116
|
-
if (inMonorepo) {
|
|
117
|
-
const serverRoot = (0, workspace_1.getMetroServerRoot)(projectRoot);
|
|
118
|
-
enhancedConfig.unstable_serverRoot = serverRoot;
|
|
119
|
-
// Add relative project root to transformer cache key for cache collision prevention
|
|
120
|
-
const relativeRoot = (0, workspace_1.getRelativeProjectRoot)(projectRoot);
|
|
121
|
-
if (relativeRoot) {
|
|
122
|
-
const existingCacheKey = config.transformer?.customTransformOptions || {};
|
|
123
|
-
enhancedConfig.transformer = {
|
|
124
|
-
...config.transformer,
|
|
125
|
-
customTransformOptions: {
|
|
126
|
-
...existingCacheKey,
|
|
127
|
-
_teardownRelativeProjectRoot: relativeRoot,
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (verbose) {
|
|
133
|
-
const watchFoldersCount = enhancedConfig.watchFolders?.length || 0;
|
|
134
|
-
const nodeModulesPathsCount = enhancedConfig.resolver?.nodeModulesPaths?.length || 0;
|
|
135
|
-
console.log(`[teardown/metro-config] Watch folders: ${watchFoldersCount}`);
|
|
136
|
-
console.log(`[teardown/metro-config] Node modules paths: ${nodeModulesPathsCount}`);
|
|
137
|
-
}
|
|
138
|
-
// Apply Facetpack for Rust-powered transforms
|
|
139
|
-
const finalConfig = (0, facetpack_1.withFacetpack)(enhancedConfig, facetpackOptions);
|
|
140
|
-
if (verbose) {
|
|
141
|
-
console.log("[teardown/metro-config] Metro config enhanced successfully");
|
|
142
|
-
}
|
|
143
|
-
return finalConfig;
|
|
144
|
-
}
|
|
145
|
-
// Re-export Bun utilities
|
|
146
|
-
var bun_2 = require("./bun");
|
|
147
|
-
Object.defineProperty(exports, "BUN_BLOCK_PATTERN", { enumerable: true, get: function () { return bun_2.BUN_BLOCK_PATTERN; } });
|
|
148
|
-
Object.defineProperty(exports, "getBlockList", { enumerable: true, get: function () { return bun_2.getBlockList; } });
|
|
149
|
-
// Re-export tsconfig paths utilities
|
|
150
|
-
var tsconfig_paths_2 = require("./tsconfig-paths");
|
|
151
|
-
Object.defineProperty(exports, "createTsConfigPathsResolver", { enumerable: true, get: function () { return tsconfig_paths_2.createTsConfigPathsResolver; } });
|
|
152
|
-
Object.defineProperty(exports, "parseTsConfigPaths", { enumerable: true, get: function () { return tsconfig_paths_2.parseTsConfigPaths; } });
|
|
153
|
-
// Re-export workspace utilities for advanced use cases
|
|
154
|
-
var workspace_2 = require("./workspace");
|
|
155
|
-
Object.defineProperty(exports, "getMetroServerRoot", { enumerable: true, get: function () { return workspace_2.getMetroServerRoot; } });
|
|
156
|
-
Object.defineProperty(exports, "getModulesPaths", { enumerable: true, get: function () { return workspace_2.getModulesPaths; } });
|
|
157
|
-
Object.defineProperty(exports, "getRelativeProjectRoot", { enumerable: true, get: function () { return workspace_2.getRelativeProjectRoot; } });
|
|
158
|
-
Object.defineProperty(exports, "getWatchFolders", { enumerable: true, get: function () { return workspace_2.getWatchFolders; } });
|
|
159
|
-
Object.defineProperty(exports, "getWorkspaceRoot", { enumerable: true, get: function () { return workspace_2.getWorkspaceRoot; } });
|
|
160
|
-
Object.defineProperty(exports, "isInMonorepo", { enumerable: true, get: function () { return workspace_2.isInMonorepo; } });
|
package/dist/tsconfig-paths.js
DELETED
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* TSConfig paths resolution for Metro.
|
|
4
|
-
*
|
|
5
|
-
* Enables `compilerOptions.paths` and `compilerOptions.baseUrl` support for import aliases.
|
|
6
|
-
*/
|
|
7
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
-
};
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.parseTsConfigPaths = parseTsConfigPaths;
|
|
12
|
-
exports.buildPathMappings = buildPathMappings;
|
|
13
|
-
exports.resolveWithTsConfigPaths = resolveWithTsConfigPaths;
|
|
14
|
-
exports.createTsConfigPathsResolver = createTsConfigPathsResolver;
|
|
15
|
-
const node_fs_1 = require("node:fs");
|
|
16
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
-
/**
|
|
18
|
-
* Try to import TypeScript from the project.
|
|
19
|
-
*/
|
|
20
|
-
function importTypeScriptFromProjectOptionally(projectRoot) {
|
|
21
|
-
try {
|
|
22
|
-
const tsPath = require.resolve("typescript", { paths: [projectRoot] });
|
|
23
|
-
return require(tsPath);
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Evaluate tsconfig.json using TypeScript's parseJsonConfigFileContent.
|
|
31
|
-
* This properly handles `extends` and all inheritance.
|
|
32
|
-
*/
|
|
33
|
-
function evaluateTsConfig(ts, configPath) {
|
|
34
|
-
const configDir = node_path_1.default.dirname(configPath);
|
|
35
|
-
const configFileText = ts.sys.readFile(configPath);
|
|
36
|
-
if (!configFileText) {
|
|
37
|
-
return {};
|
|
38
|
-
}
|
|
39
|
-
const result = ts.parseConfigFileTextToJson(configPath, configFileText);
|
|
40
|
-
if (result.error) {
|
|
41
|
-
return {};
|
|
42
|
-
}
|
|
43
|
-
const parsedConfig = ts.parseJsonConfigFileContent(result.config, ts.sys, configDir, undefined, configPath);
|
|
44
|
-
return {
|
|
45
|
-
compilerOptions: {
|
|
46
|
-
baseUrl: parsedConfig.options.baseUrl,
|
|
47
|
-
paths: parsedConfig.options.paths,
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Clean JSON5 content (remove comments and trailing commas) for JSON.parse.
|
|
53
|
-
*/
|
|
54
|
-
function cleanJsonContent(content) {
|
|
55
|
-
return content
|
|
56
|
-
.replace(/\/\*[\s\S]*?\*\//g, "") // Remove /* */ comments
|
|
57
|
-
.replace(/\/\/.*/g, "") // Remove // comments
|
|
58
|
-
.replace(/,(\s*[}\]])/g, "$1"); // Remove trailing commas
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Parse a config file manually (fallback when TypeScript isn't available).
|
|
62
|
-
*/
|
|
63
|
-
function parseConfigFileManually(configPath) {
|
|
64
|
-
try {
|
|
65
|
-
const content = (0, node_fs_1.readFileSync)(configPath, "utf8");
|
|
66
|
-
const config = JSON.parse(cleanJsonContent(content));
|
|
67
|
-
const compilerOptions = config.compilerOptions || {};
|
|
68
|
-
return {
|
|
69
|
-
baseUrl: compilerOptions.baseUrl,
|
|
70
|
-
paths: compilerOptions.paths,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
console.warn(`[teardown/metro-config] Failed to parse ${node_path_1.default.basename(configPath)}: ${error}`);
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Normalize baseUrl from TypeScript's absolute path to relative.
|
|
80
|
-
*/
|
|
81
|
-
function normalizeBaseUrl(baseUrl, projectRoot) {
|
|
82
|
-
if (!baseUrl)
|
|
83
|
-
return undefined;
|
|
84
|
-
return node_path_1.default.isAbsolute(baseUrl) ? node_path_1.default.relative(projectRoot, baseUrl) : baseUrl;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Try to parse tsconfig using TypeScript for full extends support.
|
|
88
|
-
*/
|
|
89
|
-
function parseTsConfigWithTypeScript(projectRoot, configPath) {
|
|
90
|
-
const ts = importTypeScriptFromProjectOptionally(projectRoot);
|
|
91
|
-
if (!ts)
|
|
92
|
-
return null;
|
|
93
|
-
try {
|
|
94
|
-
const config = evaluateTsConfig(ts, configPath);
|
|
95
|
-
return {
|
|
96
|
-
baseUrl: normalizeBaseUrl(config.compilerOptions?.baseUrl, projectRoot),
|
|
97
|
-
paths: config.compilerOptions?.paths,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
console.warn(`[teardown/metro-config] Failed to evaluate tsconfig with TypeScript: ${error}`);
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Parse tsconfig.json and extract paths configuration.
|
|
107
|
-
* Properly evaluates the full config including `extends` inheritance.
|
|
108
|
-
*/
|
|
109
|
-
function parseTsConfigPaths(projectRoot) {
|
|
110
|
-
const tsconfigPath = node_path_1.default.join(projectRoot, "tsconfig.json");
|
|
111
|
-
const jsconfigPath = node_path_1.default.join(projectRoot, "jsconfig.json");
|
|
112
|
-
// Try tsconfig.json first
|
|
113
|
-
if ((0, node_fs_1.existsSync)(tsconfigPath)) {
|
|
114
|
-
// Try TypeScript evaluation first (handles extends)
|
|
115
|
-
const tsResult = parseTsConfigWithTypeScript(projectRoot, tsconfigPath);
|
|
116
|
-
if (tsResult)
|
|
117
|
-
return tsResult;
|
|
118
|
-
// Fallback to manual parsing
|
|
119
|
-
const manualResult = parseConfigFileManually(tsconfigPath);
|
|
120
|
-
if (manualResult)
|
|
121
|
-
return manualResult;
|
|
122
|
-
}
|
|
123
|
-
// Try jsconfig.json as fallback
|
|
124
|
-
if ((0, node_fs_1.existsSync)(jsconfigPath)) {
|
|
125
|
-
return parseConfigFileManually(jsconfigPath);
|
|
126
|
-
}
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Convert tsconfig paths to regex patterns for efficient matching.
|
|
131
|
-
*/
|
|
132
|
-
function buildPathMappings(projectRoot, config) {
|
|
133
|
-
if (!config.paths) {
|
|
134
|
-
return [];
|
|
135
|
-
}
|
|
136
|
-
const baseUrl = config.baseUrl ? node_path_1.default.resolve(projectRoot, config.baseUrl) : projectRoot;
|
|
137
|
-
const mappings = [];
|
|
138
|
-
for (const [alias, targets] of Object.entries(config.paths)) {
|
|
139
|
-
// Convert path pattern to regex
|
|
140
|
-
// @/* -> @/(.*) -> matches @/anything
|
|
141
|
-
const regexPattern = alias
|
|
142
|
-
.replace(/[.+?^${}()|[\]\\]/g, "\\$&") // Escape special regex chars except *
|
|
143
|
-
.replace(/\*/g, "(.*)"); // Convert * to capture group
|
|
144
|
-
mappings.push({
|
|
145
|
-
pattern: new RegExp(`^${regexPattern}$`),
|
|
146
|
-
replacements: targets.map((target) => node_path_1.default.join(baseUrl, target)),
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
return mappings;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Resolve a module using tsconfig paths.
|
|
153
|
-
* Returns the resolved file path or null if not matched.
|
|
154
|
-
*/
|
|
155
|
-
function resolveWithTsConfigPaths(moduleName, mappings) {
|
|
156
|
-
for (const { pattern, replacements } of mappings) {
|
|
157
|
-
const match = moduleName.match(pattern);
|
|
158
|
-
if (match) {
|
|
159
|
-
// match[1] contains the captured part (the * replacement)
|
|
160
|
-
const captured = match[1] || "";
|
|
161
|
-
for (const replacement of replacements) {
|
|
162
|
-
// Replace * in the replacement path with the captured part
|
|
163
|
-
const resolvedPath = replacement.replace("*", captured);
|
|
164
|
-
// Try various extensions (file must exist and be a file, not directory)
|
|
165
|
-
const extensions = [".ts", ".tsx", ".js", ".jsx", ".json"];
|
|
166
|
-
for (const ext of extensions) {
|
|
167
|
-
const fullPath = resolvedPath + ext;
|
|
168
|
-
if ((0, node_fs_1.existsSync)(fullPath) && (0, node_fs_1.statSync)(fullPath).isFile()) {
|
|
169
|
-
return fullPath;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
// Check if path exists without extension (could be exact file or directory)
|
|
173
|
-
if ((0, node_fs_1.existsSync)(resolvedPath)) {
|
|
174
|
-
const stat = (0, node_fs_1.statSync)(resolvedPath);
|
|
175
|
-
if (stat.isFile()) {
|
|
176
|
-
return resolvedPath;
|
|
177
|
-
}
|
|
178
|
-
// If it's a directory, try index files
|
|
179
|
-
if (stat.isDirectory()) {
|
|
180
|
-
const indexExtensions = [".ts", ".tsx", ".js", ".jsx"];
|
|
181
|
-
for (const ext of indexExtensions) {
|
|
182
|
-
const indexPath = node_path_1.default.join(resolvedPath, `index${ext}`);
|
|
183
|
-
if ((0, node_fs_1.existsSync)(indexPath) && (0, node_fs_1.statSync)(indexPath).isFile()) {
|
|
184
|
-
return indexPath;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Create a resolver that handles tsconfig paths.
|
|
196
|
-
*
|
|
197
|
-
* IMPORTANT: This resolver returns null when it doesn't handle resolution, signaling
|
|
198
|
-
* Metro to use its default resolution. Do NOT call context.resolveRequest as that
|
|
199
|
-
* points to the outermost resolver (e.g., Uniwind) and creates infinite loops.
|
|
200
|
-
*
|
|
201
|
-
* @param projectRoot - The project root directory
|
|
202
|
-
* @param nextResolver - Optional next resolver in the chain.
|
|
203
|
-
* @param verbose - Whether to log debug information
|
|
204
|
-
*/
|
|
205
|
-
function createTsConfigPathsResolver(projectRoot, nextResolver, verbose = false) {
|
|
206
|
-
const config = parseTsConfigPaths(projectRoot);
|
|
207
|
-
if (!config?.paths) {
|
|
208
|
-
if (verbose) {
|
|
209
|
-
console.log("[teardown/metro-config] No tsconfig paths found, skipping path resolution");
|
|
210
|
-
}
|
|
211
|
-
// Pass through to next resolver or return null for Metro's default
|
|
212
|
-
// Do NOT call context.resolveRequest - it points to the outermost resolver
|
|
213
|
-
return nextResolver ?? ((_context, _moduleName, _platform) => null);
|
|
214
|
-
}
|
|
215
|
-
const mappings = buildPathMappings(projectRoot, config);
|
|
216
|
-
if (verbose) {
|
|
217
|
-
console.log(`[teardown/metro-config] Loaded ${mappings.length} path mappings from tsconfig.json`);
|
|
218
|
-
for (const { pattern, replacements } of mappings) {
|
|
219
|
-
console.log(` ${pattern.source} -> ${replacements.join(", ")}`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return (context, moduleName, platform) => {
|
|
223
|
-
// Try tsconfig paths first for alias patterns (typically start with @ or other configured prefixes)
|
|
224
|
-
const resolvedPath = resolveWithTsConfigPaths(moduleName, mappings);
|
|
225
|
-
if (resolvedPath) {
|
|
226
|
-
if (verbose) {
|
|
227
|
-
console.log(`[teardown/metro-config] Resolved ${moduleName} -> ${resolvedPath}`);
|
|
228
|
-
}
|
|
229
|
-
return { type: "sourceFile", filePath: resolvedPath };
|
|
230
|
-
}
|
|
231
|
-
// Fall back to next resolver in chain
|
|
232
|
-
if (nextResolver) {
|
|
233
|
-
return nextResolver(context, moduleName, platform);
|
|
234
|
-
}
|
|
235
|
-
// Return null to let Metro use its default resolution
|
|
236
|
-
// Do NOT call context.resolveRequest - it points to the outermost resolver
|
|
237
|
-
return null;
|
|
238
|
-
};
|
|
239
|
-
}
|
package/dist/types.js
DELETED
package/dist/workspace.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Workspace and monorepo detection utilities for Metro configuration.
|
|
4
|
-
*
|
|
5
|
-
* Uses `resolve-workspace-root` to detect workspace roots across:
|
|
6
|
-
* - Yarn workspaces
|
|
7
|
-
* - npm workspaces
|
|
8
|
-
* - pnpm workspaces
|
|
9
|
-
* - Bun workspaces
|
|
10
|
-
*/
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.globAllPackageJsonPaths = globAllPackageJsonPaths;
|
|
16
|
-
exports.resolveAllWorkspacePackageJsonPaths = resolveAllWorkspacePackageJsonPaths;
|
|
17
|
-
exports.getWorkspaceRoot = getWorkspaceRoot;
|
|
18
|
-
exports.getWorkspaceGlobs = getWorkspaceGlobs;
|
|
19
|
-
exports.isInMonorepo = isInMonorepo;
|
|
20
|
-
exports.getMetroServerRoot = getMetroServerRoot;
|
|
21
|
-
exports.getWatchFolders = getWatchFolders;
|
|
22
|
-
exports.getModulesPaths = getModulesPaths;
|
|
23
|
-
exports.getRelativeProjectRoot = getRelativeProjectRoot;
|
|
24
|
-
const node_fs_1 = require("node:fs");
|
|
25
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
26
|
-
const glob_1 = require("glob");
|
|
27
|
-
/**
|
|
28
|
-
* Read and parse a JSON file, returning null if invalid.
|
|
29
|
-
*/
|
|
30
|
-
function readJsonFile(filePath) {
|
|
31
|
-
const file = (0, node_fs_1.readFileSync)(filePath, "utf8");
|
|
32
|
-
return JSON.parse(file);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Check if a file is a valid JSON file.
|
|
36
|
-
*/
|
|
37
|
-
function isValidJsonFile(filePath) {
|
|
38
|
-
try {
|
|
39
|
-
readJsonFile(filePath);
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Glob all package.json paths in a workspace.
|
|
48
|
-
* Matches Expo's implementation pattern.
|
|
49
|
-
*
|
|
50
|
-
* @param workspaceRoot Root file path for the workspace
|
|
51
|
-
* @param linkedPackages List of folders that contain linked node modules, ex: `['packages/*', 'apps/*']`
|
|
52
|
-
* @returns List of valid package.json file paths
|
|
53
|
-
*/
|
|
54
|
-
function globAllPackageJsonPaths(workspaceRoot, linkedPackages) {
|
|
55
|
-
return linkedPackages
|
|
56
|
-
.flatMap((pattern) => {
|
|
57
|
-
// Globs should only contain `/` as separator, even on Windows.
|
|
58
|
-
return (0, glob_1.globSync)(node_path_1.default.posix.join(pattern, "package.json").replace(/\\/g, "/"), {
|
|
59
|
-
cwd: workspaceRoot,
|
|
60
|
-
absolute: true,
|
|
61
|
-
ignore: ["**/@(Carthage|Pods|node_modules)/**"],
|
|
62
|
-
}).filter((pkgPath) => isValidJsonFile(pkgPath));
|
|
63
|
-
})
|
|
64
|
-
.map((p) => node_path_1.default.join(p));
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Resolve all workspace package.json paths.
|
|
68
|
-
*
|
|
69
|
-
* @param workspaceRoot root file path for a workspace.
|
|
70
|
-
* @returns list of package.json file paths that are linked to the workspace.
|
|
71
|
-
*/
|
|
72
|
-
function resolveAllWorkspacePackageJsonPaths(workspaceRoot) {
|
|
73
|
-
try {
|
|
74
|
-
const workspaceGlobs = getWorkspaceGlobs(workspaceRoot);
|
|
75
|
-
if (!workspaceGlobs?.length)
|
|
76
|
-
return [];
|
|
77
|
-
return globAllPackageJsonPaths(workspaceRoot, workspaceGlobs);
|
|
78
|
-
}
|
|
79
|
-
catch {
|
|
80
|
-
return [];
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Resolve the workspace root directory.
|
|
85
|
-
* Returns the project root if not in a workspace.
|
|
86
|
-
*/
|
|
87
|
-
function getWorkspaceRoot(projectRoot) {
|
|
88
|
-
try {
|
|
89
|
-
// Dynamic import to handle the package
|
|
90
|
-
const { resolveWorkspaceRoot } = require("resolve-workspace-root");
|
|
91
|
-
const workspaceRoot = resolveWorkspaceRoot(projectRoot);
|
|
92
|
-
return workspaceRoot || projectRoot;
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
// Fallback: check for turbo.jsonc or package.json with workspaces
|
|
96
|
-
return findMonorepoRootFallback(projectRoot);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Fallback monorepo root detection for when resolve-workspace-root fails.
|
|
101
|
-
* Checks for turbo.jsonc or package.json with workspaces field.
|
|
102
|
-
*/
|
|
103
|
-
function findMonorepoRootFallback(startDir) {
|
|
104
|
-
let current = startDir;
|
|
105
|
-
while (current !== node_path_1.default.dirname(current)) {
|
|
106
|
-
const turboConfig = node_path_1.default.join(current, "turbo.jsonc");
|
|
107
|
-
const turboJson = node_path_1.default.join(current, "turbo.json");
|
|
108
|
-
const packageJson = node_path_1.default.join(current, "package.json");
|
|
109
|
-
if ((0, node_fs_1.existsSync)(turboConfig) || (0, node_fs_1.existsSync)(turboJson)) {
|
|
110
|
-
return current;
|
|
111
|
-
}
|
|
112
|
-
if ((0, node_fs_1.existsSync)(packageJson)) {
|
|
113
|
-
try {
|
|
114
|
-
const pkg = JSON.parse((0, node_fs_1.readFileSync)(packageJson, "utf8"));
|
|
115
|
-
if (pkg.workspaces) {
|
|
116
|
-
return current;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
// Ignore parse errors
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
current = node_path_1.default.dirname(current);
|
|
124
|
-
}
|
|
125
|
-
return startDir;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Get workspace glob patterns from the workspace root.
|
|
129
|
-
*/
|
|
130
|
-
function getWorkspaceGlobs(workspaceRoot) {
|
|
131
|
-
try {
|
|
132
|
-
const { getWorkspaceGlobs: getGlobs } = require("resolve-workspace-root");
|
|
133
|
-
return getGlobs(workspaceRoot) ?? [];
|
|
134
|
-
}
|
|
135
|
-
catch {
|
|
136
|
-
// Fallback: try to read from package.json
|
|
137
|
-
const packageJsonPath = node_path_1.default.join(workspaceRoot, "package.json");
|
|
138
|
-
if ((0, node_fs_1.existsSync)(packageJsonPath)) {
|
|
139
|
-
try {
|
|
140
|
-
const pkg = JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, "utf8"));
|
|
141
|
-
if (Array.isArray(pkg.workspaces)) {
|
|
142
|
-
return pkg.workspaces;
|
|
143
|
-
}
|
|
144
|
-
if (pkg.workspaces?.packages) {
|
|
145
|
-
return pkg.workspaces.packages;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
catch {
|
|
149
|
-
// Ignore parse errors
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return [];
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Check if the project is in a monorepo (workspace root differs from project root).
|
|
157
|
-
*/
|
|
158
|
-
function isInMonorepo(projectRoot) {
|
|
159
|
-
const workspaceRoot = getWorkspaceRoot(projectRoot);
|
|
160
|
-
return workspaceRoot !== projectRoot;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Get the Metro server root for monorepo support.
|
|
164
|
-
* This should be set as `unstable_serverRoot` in Metro config.
|
|
165
|
-
*/
|
|
166
|
-
function getMetroServerRoot(projectRoot) {
|
|
167
|
-
// Can be disabled with environment variable
|
|
168
|
-
if (process.env.TEARDOWN_NO_METRO_WORKSPACE_ROOT) {
|
|
169
|
-
return projectRoot;
|
|
170
|
-
}
|
|
171
|
-
return getWorkspaceRoot(projectRoot);
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Helper to get unique items from an array.
|
|
175
|
-
*/
|
|
176
|
-
function uniqueItems(items) {
|
|
177
|
-
return [...new Set(items)];
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Get watch folders for Metro in a monorepo setup.
|
|
181
|
-
*
|
|
182
|
-
* Returns:
|
|
183
|
-
* - Empty array if not in a monorepo
|
|
184
|
-
* - Workspace root node_modules + all workspace package directories if in monorepo
|
|
185
|
-
*/
|
|
186
|
-
function getWatchFolders(projectRoot) {
|
|
187
|
-
const resolvedProjectRoot = node_path_1.default.resolve(projectRoot);
|
|
188
|
-
const workspaceRoot = getMetroServerRoot(resolvedProjectRoot);
|
|
189
|
-
// Rely on default behavior in standard projects.
|
|
190
|
-
if (workspaceRoot === resolvedProjectRoot) {
|
|
191
|
-
return [];
|
|
192
|
-
}
|
|
193
|
-
const packages = resolveAllWorkspacePackageJsonPaths(workspaceRoot);
|
|
194
|
-
if (!packages?.length) {
|
|
195
|
-
return [];
|
|
196
|
-
}
|
|
197
|
-
return uniqueItems([node_path_1.default.join(workspaceRoot, "node_modules"), ...packages.map((pkg) => node_path_1.default.dirname(pkg))]);
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Get node module paths for Metro resolver.
|
|
201
|
-
*
|
|
202
|
-
* Returns paths in priority order:
|
|
203
|
-
* 1. Project's local node_modules (always included)
|
|
204
|
-
* 2. Workspace root node_modules (if in monorepo)
|
|
205
|
-
*
|
|
206
|
-
* The project's node_modules must always be included to support packages
|
|
207
|
-
* that publish TypeScript source and need to resolve peer dependencies
|
|
208
|
-
* (e.g., react-native) from deeply nested paths.
|
|
209
|
-
*/
|
|
210
|
-
function getModulesPaths(projectRoot) {
|
|
211
|
-
const resolvedProjectRoot = node_path_1.default.resolve(projectRoot);
|
|
212
|
-
const workspaceRoot = getMetroServerRoot(resolvedProjectRoot);
|
|
213
|
-
// Always include project's node_modules for proper peer dependency resolution
|
|
214
|
-
const paths = [node_path_1.default.resolve(projectRoot, "node_modules")];
|
|
215
|
-
// Add workspace root node_modules if in a monorepo
|
|
216
|
-
if (workspaceRoot !== resolvedProjectRoot) {
|
|
217
|
-
paths.push(node_path_1.default.resolve(workspaceRoot, "node_modules"));
|
|
218
|
-
}
|
|
219
|
-
return paths;
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Get the relative project root from workspace root.
|
|
223
|
-
* Used for cache key generation to prevent collisions in monorepos.
|
|
224
|
-
*/
|
|
225
|
-
function getRelativeProjectRoot(projectRoot) {
|
|
226
|
-
const workspaceRoot = getWorkspaceRoot(projectRoot);
|
|
227
|
-
if (workspaceRoot === projectRoot) {
|
|
228
|
-
return "";
|
|
229
|
-
}
|
|
230
|
-
return node_path_1.default.relative(workspaceRoot, projectRoot);
|
|
231
|
-
}
|