miaoda-expo-devkit 0.1.1-beta.39 → 0.1.1-beta.40

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/metro.d.mts CHANGED
@@ -119,6 +119,7 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
119
119
  * withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
120
120
  * withExpoMediaLibraryStub — Web / Expo Go:expo-media-library → stub(弹 Alert 提示,Dev Build 透传)
121
121
  * withExpoCalendarStub — Web / Expo Go:expo-calendar → stub(弹 Alert 提示,Dev Build 透传)
122
+ * withExpoFileSystemStub — Web:expo-file-system/legacy → stub(弹 Dialog 提示,原生透传)
122
123
  * withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
123
124
  * withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
124
125
  * withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
@@ -295,6 +296,23 @@ declare function withExpoMediaLibraryStub(config: MetroConfig): MetroConfig;
295
296
  */
296
297
  declare function withExpoCalendarStub(config: MetroConfig): MetroConfig;
297
298
 
299
+ /**
300
+ * withExpoFileSystemStub — Web 端将 expo-file-system/legacy 替换为 stub
301
+ *
302
+ * expo-file-system 的文件 API 在 Web 端不可用(底层 shim 方法均缺失)。
303
+ * stub 在运行时通过 Platform.OS 判断:
304
+ * - Web:no-op(核心 API 弹 Dialog 提示,不崩溃)
305
+ * - Expo Go / Development Build(原生):透传真实 expo-file-system/legacy,功能完全正常
306
+ *
307
+ * 注意:此 wrapper 拦截 expo-file-system/legacy 子路径,不拦截新版 expo-file-system(File API)。
308
+ */
309
+
310
+ /**
311
+ * @param config Metro config 对象
312
+ * @returns 注入 resolveRequest 后的新 Metro config
313
+ */
314
+ declare function withExpoFileSystemStub(config: MetroConfig): MetroConfig;
315
+
298
316
  /**
299
317
  * 将 Metro transformer 的 minifier 切换为 esbuild。
300
318
  *
@@ -320,4 +338,4 @@ declare function withEsbuildMinify(config: MetroConfig): MetroConfig;
320
338
 
321
339
  declare function withWasmSupport(config: MetroConfig): MetroConfig;
322
340
 
323
- export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
341
+ export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoFileSystemStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
package/dist/metro.d.ts CHANGED
@@ -119,6 +119,7 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
119
119
  * withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
120
120
  * withExpoMediaLibraryStub — Web / Expo Go:expo-media-library → stub(弹 Alert 提示,Dev Build 透传)
121
121
  * withExpoCalendarStub — Web / Expo Go:expo-calendar → stub(弹 Alert 提示,Dev Build 透传)
122
+ * withExpoFileSystemStub — Web:expo-file-system/legacy → stub(弹 Dialog 提示,原生透传)
122
123
  * withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
123
124
  * withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
124
125
  * withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
@@ -295,6 +296,23 @@ declare function withExpoMediaLibraryStub(config: MetroConfig): MetroConfig;
295
296
  */
296
297
  declare function withExpoCalendarStub(config: MetroConfig): MetroConfig;
297
298
 
299
+ /**
300
+ * withExpoFileSystemStub — Web 端将 expo-file-system/legacy 替换为 stub
301
+ *
302
+ * expo-file-system 的文件 API 在 Web 端不可用(底层 shim 方法均缺失)。
303
+ * stub 在运行时通过 Platform.OS 判断:
304
+ * - Web:no-op(核心 API 弹 Dialog 提示,不崩溃)
305
+ * - Expo Go / Development Build(原生):透传真实 expo-file-system/legacy,功能完全正常
306
+ *
307
+ * 注意:此 wrapper 拦截 expo-file-system/legacy 子路径,不拦截新版 expo-file-system(File API)。
308
+ */
309
+
310
+ /**
311
+ * @param config Metro config 对象
312
+ * @returns 注入 resolveRequest 后的新 Metro config
313
+ */
314
+ declare function withExpoFileSystemStub(config: MetroConfig): MetroConfig;
315
+
298
316
  /**
299
317
  * 将 Metro transformer 的 minifier 切换为 esbuild。
300
318
  *
@@ -320,4 +338,4 @@ declare function withEsbuildMinify(config: MetroConfig): MetroConfig;
320
338
 
321
339
  declare function withWasmSupport(config: MetroConfig): MetroConfig;
322
340
 
323
- export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
341
+ export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoFileSystemStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
package/dist/metro.js CHANGED
@@ -37,6 +37,7 @@ __export(metro_exports, {
37
37
  withEntryInjection: () => withEntryInjection,
38
38
  withEsbuildMinify: () => withEsbuildMinify,
39
39
  withExpoCalendarStub: () => withExpoCalendarStub,
40
+ withExpoFileSystemStub: () => withExpoFileSystemStub,
40
41
  withExpoMediaLibraryStub: () => withExpoMediaLibraryStub,
41
42
  withExpoNotificationsStub: () => withExpoNotificationsStub,
42
43
  withLucideResolver: () => withLucideResolver,
@@ -286,7 +287,7 @@ function withCssInterop(config) {
286
287
  }
287
288
 
288
289
  // src/metro/withDevkit.ts
289
- var import_path11 = __toESM(require("path"));
290
+ var import_path12 = __toESM(require("path"));
290
291
 
291
292
  // src/metro/withEsbuildMinify.ts
292
293
  function withEsbuildMinify(config) {
@@ -405,6 +406,26 @@ function withExpoCalendarStub(config) {
405
406
  return { ...config, resolver: { ...config.resolver, resolveRequest } };
406
407
  }
407
408
 
409
+ // src/metro/withExpoFileSystemStub.ts
410
+ var import_path11 = __toESM(require("path"));
411
+ var EXPO_FILE_SYSTEM_STUB_FILENAME = "expo-file-system-stub.js";
412
+ var EXPO_FILE_SYSTEM_STUB_PATH = import_path11.default.resolve(
413
+ __dirname,
414
+ "stubs",
415
+ EXPO_FILE_SYSTEM_STUB_FILENAME
416
+ );
417
+ function withExpoFileSystemStub(config) {
418
+ const upstream = config.resolver?.resolveRequest ?? null;
419
+ const resolveRequest = (context, moduleName, platform) => {
420
+ if (moduleName === "expo-file-system/legacy" && !context.originModulePath.includes(EXPO_FILE_SYSTEM_STUB_FILENAME)) {
421
+ return { filePath: EXPO_FILE_SYSTEM_STUB_PATH, type: "sourceFile" };
422
+ }
423
+ if (upstream) return upstream(context, moduleName, platform);
424
+ return context.resolveRequest(context, moduleName, platform);
425
+ };
426
+ return { ...config, resolver: { ...config.resolver, resolveRequest } };
427
+ }
428
+
408
429
  // src/metro/withWasmSupport.ts
409
430
  function withWasmSupport(config) {
410
431
  const existing = config.resolver?.assetExts ?? [];
@@ -430,10 +451,11 @@ function withDevkit(config, options = {}) {
430
451
  config = withExpoNotificationsStub(config);
431
452
  config = withExpoMediaLibraryStub(config);
432
453
  config = withExpoCalendarStub(config);
454
+ config = withExpoFileSystemStub(config);
433
455
  if (typeof __DEV__ !== "undefined" && __DEV__) {
434
456
  config = withEntryInjection(config);
435
457
  config = withDevStubs(config);
436
- config = withRouteEndpoint(config, { appDir: import_path11.default.join(projectRoot, "src", "app") });
458
+ config = withRouteEndpoint(config, { appDir: import_path12.default.join(projectRoot, "src", "app") });
437
459
  }
438
460
  return withNativeWind(config, { input, inlineRem: 16 });
439
461
  }
@@ -454,6 +476,7 @@ try {
454
476
  withEntryInjection,
455
477
  withEsbuildMinify,
456
478
  withExpoCalendarStub,
479
+ withExpoFileSystemStub,
457
480
  withExpoMediaLibraryStub,
458
481
  withExpoNotificationsStub,
459
482
  withLucideResolver,
package/dist/metro.mjs CHANGED
@@ -244,7 +244,7 @@ function withCssInterop(config) {
244
244
  }
245
245
 
246
246
  // src/metro/withDevkit.ts
247
- import path11 from "path";
247
+ import path12 from "path";
248
248
 
249
249
  // src/metro/withEsbuildMinify.ts
250
250
  function withEsbuildMinify(config) {
@@ -363,6 +363,26 @@ function withExpoCalendarStub(config) {
363
363
  return { ...config, resolver: { ...config.resolver, resolveRequest } };
364
364
  }
365
365
 
366
+ // src/metro/withExpoFileSystemStub.ts
367
+ import path11 from "path";
368
+ var EXPO_FILE_SYSTEM_STUB_FILENAME = "expo-file-system-stub.js";
369
+ var EXPO_FILE_SYSTEM_STUB_PATH = path11.resolve(
370
+ __dirname,
371
+ "stubs",
372
+ EXPO_FILE_SYSTEM_STUB_FILENAME
373
+ );
374
+ function withExpoFileSystemStub(config) {
375
+ const upstream = config.resolver?.resolveRequest ?? null;
376
+ const resolveRequest = (context, moduleName, platform) => {
377
+ if (moduleName === "expo-file-system/legacy" && !context.originModulePath.includes(EXPO_FILE_SYSTEM_STUB_FILENAME)) {
378
+ return { filePath: EXPO_FILE_SYSTEM_STUB_PATH, type: "sourceFile" };
379
+ }
380
+ if (upstream) return upstream(context, moduleName, platform);
381
+ return context.resolveRequest(context, moduleName, platform);
382
+ };
383
+ return { ...config, resolver: { ...config.resolver, resolveRequest } };
384
+ }
385
+
366
386
  // src/metro/withWasmSupport.ts
367
387
  function withWasmSupport(config) {
368
388
  const existing = config.resolver?.assetExts ?? [];
@@ -388,10 +408,11 @@ function withDevkit(config, options = {}) {
388
408
  config = withExpoNotificationsStub(config);
389
409
  config = withExpoMediaLibraryStub(config);
390
410
  config = withExpoCalendarStub(config);
411
+ config = withExpoFileSystemStub(config);
391
412
  if (typeof __DEV__ !== "undefined" && __DEV__) {
392
413
  config = withEntryInjection(config);
393
414
  config = withDevStubs(config);
394
- config = withRouteEndpoint(config, { appDir: path11.join(projectRoot, "src", "app") });
415
+ config = withRouteEndpoint(config, { appDir: path12.join(projectRoot, "src", "app") });
395
416
  }
396
417
  return withNativeWind(config, { input, inlineRem: 16 });
397
418
  }
@@ -411,6 +432,7 @@ export {
411
432
  withEntryInjection,
412
433
  withEsbuildMinify,
413
434
  withExpoCalendarStub,
435
+ withExpoFileSystemStub,
414
436
  withExpoMediaLibraryStub,
415
437
  withExpoNotificationsStub,
416
438
  withLucideResolver,
@@ -34,10 +34,20 @@ __export(no_duplicate_expo_router_url_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(no_duplicate_expo_router_url_exports);
36
36
  var import_node_fs = __toESM(require("fs"));
37
+ var import_node_path2 = __toESM(require("path"));
38
+
39
+ // src/rules/utils.ts
37
40
  var import_node_path = __toESM(require("path"));
41
+ var import_package_up = require("package-up");
42
+ function findProjectRoot(startPath) {
43
+ const pkgPath = (0, import_package_up.packageUpSync)({ cwd: import_node_path.default.dirname(startPath) });
44
+ return pkgPath ? import_node_path.default.dirname(pkgPath) : null;
45
+ }
46
+
47
+ // src/rules/no-duplicate-expo-router-url.ts
38
48
  var ROUTE_EXTENSIONS = /* @__PURE__ */ new Set([".tsx", ".ts", ".jsx", ".js"]);
39
49
  function fileToUrl(relPath) {
40
- const ext = import_node_path.default.extname(relPath);
50
+ const ext = import_node_path2.default.extname(relPath);
41
51
  if (!ROUTE_EXTENSIONS.has(ext)) return null;
42
52
  const normalized = relPath.replace(/\\/g, "/");
43
53
  let p = normalized.slice(0, -ext.length);
@@ -50,17 +60,9 @@ function fileToUrl(relPath) {
50
60
  if (p.endsWith("/index")) return "/" + p.slice(0, -6);
51
61
  return "/" + p;
52
62
  }
53
- function findProjectRoot(startPath) {
54
- let dir = import_node_path.default.dirname(startPath);
55
- while (dir !== import_node_path.default.dirname(dir)) {
56
- if (import_node_fs.default.existsSync(import_node_path.default.join(dir, "package.json"))) return dir;
57
- dir = import_node_path.default.dirname(dir);
58
- }
59
- return null;
60
- }
61
63
  function getRouterRoot(projectRoot) {
62
64
  try {
63
- const raw = JSON.parse(import_node_fs.default.readFileSync(import_node_path.default.join(projectRoot, "app.json"), "utf-8"));
65
+ const raw = JSON.parse(import_node_fs.default.readFileSync(import_node_path2.default.join(projectRoot, "app.json"), "utf-8"));
64
66
  return raw?.expo?.router?.root ?? ".";
65
67
  } catch {
66
68
  return ".";
@@ -72,11 +74,11 @@ function buildUrlMap(appDir) {
72
74
  const urlMap = /* @__PURE__ */ new Map();
73
75
  function scanDir(dir) {
74
76
  for (const entry of import_node_fs.default.readdirSync(dir, { withFileTypes: true })) {
75
- const fullPath = import_node_path.default.join(dir, entry.name);
77
+ const fullPath = import_node_path2.default.join(dir, entry.name);
76
78
  if (entry.isDirectory()) {
77
79
  scanDir(fullPath);
78
80
  } else if (entry.isFile()) {
79
- const rel = import_node_path.default.relative(appDir, fullPath);
81
+ const rel = import_node_path2.default.relative(appDir, fullPath);
80
82
  const url = fileToUrl(rel);
81
83
  if (url !== null) {
82
84
  const existing = urlMap.get(url) ?? [];
@@ -107,8 +109,8 @@ var noDuplicateExpoRouterUrlRule = {
107
109
  const projectRoot = findProjectRoot(context.filename);
108
110
  if (!projectRoot) return;
109
111
  const routerRoot = getRouterRoot(projectRoot);
110
- const appDir = import_node_path.default.join(projectRoot, routerRoot, "app");
111
- const rel = import_node_path.default.relative(appDir, context.filename).replace(/\\/g, "/");
112
+ const appDir = import_node_path2.default.join(projectRoot, routerRoot, "app");
113
+ const rel = import_node_path2.default.relative(appDir, context.filename).replace(/\\/g, "/");
112
114
  if (rel.startsWith("..")) return;
113
115
  const url = fileToUrl(rel);
114
116
  if (url === null) return;