@expo/cli 54.0.10 → 54.1.0-canary-20251003-7b9d7ff

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.
Files changed (30) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/run/ios/runIosAsync.js +0 -8
  3. package/build/src/run/ios/runIosAsync.js.map +1 -1
  4. package/build/src/start/interface/cliExtensionMenuItemHandler.js +173 -0
  5. package/build/src/start/interface/cliExtensionMenuItemHandler.js.map +1 -0
  6. package/build/src/start/interface/createDevToolsMenuItems.js +159 -0
  7. package/build/src/start/interface/createDevToolsMenuItems.js.map +1 -0
  8. package/build/src/start/interface/interactiveActions.js +8 -12
  9. package/build/src/start/interface/interactiveActions.js.map +1 -1
  10. package/build/src/start/platforms/android/adb.js +1 -1
  11. package/build/src/start/platforms/android/adb.js.map +1 -1
  12. package/build/src/start/server/DevToolsPlugin.js +60 -0
  13. package/build/src/start/server/DevToolsPlugin.js.map +1 -0
  14. package/build/src/start/server/DevToolsPlugin.schema.js +79 -0
  15. package/build/src/start/server/DevToolsPlugin.schema.js.map +1 -0
  16. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js +119 -0
  17. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js.map +1 -0
  18. package/build/src/start/server/DevToolsPluginCliExtensionResults.js +61 -0
  19. package/build/src/start/server/DevToolsPluginCliExtensionResults.js.map +1 -0
  20. package/build/src/start/server/DevToolsPluginManager.js +4 -8
  21. package/build/src/start/server/DevToolsPluginManager.js.map +1 -1
  22. package/build/src/start/server/metro/MetroBundlerDevServer.js +125 -9
  23. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  24. package/build/src/start/server/metro/createServerRouteMiddleware.js +2 -2
  25. package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
  26. package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js +75 -0
  27. package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js.map +1 -0
  28. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  29. package/build/src/utils/telemetry/utils/context.js +1 -1
  30. package/package.json +20 -20
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/metro/createServerRouteMiddleware.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ProjectConfig } from '@expo/config';\nimport type { MiddlewareSettings } from 'expo-server';\nimport { createRequestHandler } from 'expo-server/adapter/http';\nimport resolve from 'resolve';\nimport resolveFrom from 'resolve-from';\nimport { promisify } from 'util';\n\nimport { fetchManifest } from './fetchRouterManifest';\nimport { getErrorOverlayHtmlAsync } from './metroErrorInterface';\nimport {\n warnInvalidWebOutput,\n warnInvalidMiddlewareOutput,\n warnInvalidMiddlewareMatcherSettings,\n} from './router';\nimport { CommandError } from '../../../utils/errors';\n\nconst debug = require('debug')('expo:start:server:metro') as typeof console.log;\n\nconst resolveAsync = promisify(resolve) as any as (\n id: string,\n opts: resolve.AsyncOpts\n) => Promise<string | null>;\n\nexport function createRouteHandlerMiddleware(\n projectRoot: string,\n options: {\n appDir: string;\n routerRoot: string;\n getStaticPageAsync: (pathname: string) => Promise<{ content: string }>;\n bundleApiRoute: (\n functionFilePath: string\n ) => Promise<null | Record<string, Function> | Response>;\n config: ProjectConfig;\n } & import('expo-router/build/routes-manifest').Options\n) {\n if (!resolveFrom.silent(projectRoot, 'expo-router')) {\n throw new CommandError(\n `static and server rendering requires the expo-router package to be installed in your project. Either install the expo-router package or change 'web.output' to 'single' in your app.json.`\n );\n }\n\n return createRequestHandler(\n { build: '' },\n {\n async getRoutesManifest() {\n const manifest = await fetchManifest<RegExp>(projectRoot, options);\n debug('manifest', manifest);\n // NOTE: no app dir if null\n // TODO: Redirect to 404 page\n return (\n manifest ?? {\n // Support the onboarding screen if there's no manifest\n htmlRoutes: [\n {\n file: 'index.js',\n page: '/index',\n routeKeys: {},\n namedRegex: /^\\/(?:index)?\\/?$/i,\n },\n ],\n apiRoutes: [],\n notFoundRoutes: [],\n redirects: [],\n rewrites: [],\n }\n );\n },\n async getHtml(request) {\n try {\n const { content } = await options.getStaticPageAsync(request.url);\n return content;\n } catch (error: any) {\n // Forward the Metro server response as-is. It won't be pretty, but at least it will be accurate.\n\n try {\n return new Response(\n await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot,\n }),\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n } catch (staticError: any) {\n debug('Failed to render static error overlay:', staticError);\n // Fallback error for when Expo Router is misconfigured in the project.\n return new Response(\n '<span><h3>Internal Error:</h3><b>Project is not setup correctly for static rendering (check terminal for more info):</b><br/>' +\n error.message +\n '<br/><br/>' +\n staticError.message +\n '</span>',\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n }\n },\n async handleRouteError(error) {\n // NOTE(@kitten): ExpoError is currently not exposed by expo-server just yet\n if (error && typeof error === 'object' && error.name === 'ExpoError') {\n // TODO(@krystofwoldrich): Can we show code snippet of the handler?\n // NOTE(@krystofwoldrich): Removing stack since to avoid confusion. The error is not in the server code.\n delete error.stack;\n }\n\n const htmlServerError = await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot!,\n });\n\n return new Response(htmlServerError, {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n });\n },\n async getApiRoute(route) {\n const { exp } = options.config;\n if (exp.web?.output !== 'server') {\n warnInvalidWebOutput();\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling API route at: ${resolvedFunctionPath}`);\n return await options.bundleApiRoute(resolvedFunctionPath!);\n } catch (error: any) {\n return new Response(\n 'Failed to load API Route: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n async getMiddleware(route) {\n const { exp } = options.config;\n\n if (!options.unstable_useServerMiddleware) {\n return {\n default: () => {\n throw new CommandError(\n 'Server middleware is not enabled. Add unstable_useServerMiddleware: true to your `expo-router` plugin config.'\n );\n },\n };\n }\n\n if (exp.web?.output !== 'server') {\n warnInvalidMiddlewareOutput();\n return {\n default: () => {\n console.warn(\n 'Server middleware is only supported when web.output is set to \"server\" in your app config'\n );\n },\n };\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling middleware at: ${resolvedFunctionPath}`);\n const middlewareModule = (await options.bundleApiRoute(resolvedFunctionPath!)) as any;\n\n if ((middlewareModule.unstable_settings as MiddlewareSettings)?.matcher) {\n warnInvalidMiddlewareMatcherSettings(middlewareModule.unstable_settings?.matcher);\n }\n\n return middlewareModule;\n } catch (error: any) {\n return new Response(\n 'Failed to load middleware: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n }\n );\n}\n"],"names":["createRouteHandlerMiddleware","debug","require","resolveAsync","promisify","resolve","projectRoot","options","resolveFrom","silent","CommandError","createRequestHandler","build","getRoutesManifest","manifest","fetchManifest","htmlRoutes","file","page","routeKeys","namedRegex","apiRoutes","notFoundRoutes","redirects","rewrites","getHtml","request","content","getStaticPageAsync","url","error","Response","getErrorOverlayHtmlAsync","routerRoot","status","headers","staticError","message","handleRouteError","name","stack","htmlServerError","getApiRoute","route","exp","config","web","output","warnInvalidWebOutput","resolvedFunctionPath","extensions","basedir","appDir","bundleApiRoute","getMiddleware","unstable_useServerMiddleware","default","warnInvalidMiddlewareOutput","console","warn","middlewareModule","unstable_settings","matcher","warnInvalidMiddlewareMatcherSettings"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/metro/createServerRouteMiddleware.ts"],"sourcesContent":["/**\n * Copyright © 2022 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { ProjectConfig } from '@expo/config';\nimport type { MiddlewareSettings } from 'expo-server';\nimport { createRequestHandler } from 'expo-server/adapter/http';\nimport resolve from 'resolve';\nimport resolveFrom from 'resolve-from';\nimport { promisify } from 'util';\n\nimport { fetchManifest, type ExpoRouterServerManifestV1Route } from './fetchRouterManifest';\nimport { getErrorOverlayHtmlAsync } from './metroErrorInterface';\nimport {\n warnInvalidWebOutput,\n warnInvalidMiddlewareOutput,\n warnInvalidMiddlewareMatcherSettings,\n} from './router';\nimport { CommandError } from '../../../utils/errors';\n\nconst debug = require('debug')('expo:start:server:metro') as typeof console.log;\n\nconst resolveAsync = promisify(resolve) as any as (\n id: string,\n opts: resolve.AsyncOpts\n) => Promise<string | null>;\n\nexport function createRouteHandlerMiddleware(\n projectRoot: string,\n options: {\n appDir: string;\n routerRoot: string;\n getStaticPageAsync: (\n pathname: string,\n route: ExpoRouterServerManifestV1Route<RegExp>\n ) => Promise<{ content: string }>;\n bundleApiRoute: (\n functionFilePath: string\n ) => Promise<null | Record<string, Function> | Response>;\n config: ProjectConfig;\n } & import('expo-router/build/routes-manifest').Options\n) {\n if (!resolveFrom.silent(projectRoot, 'expo-router')) {\n throw new CommandError(\n `static and server rendering requires the expo-router package to be installed in your project. Either install the expo-router package or change 'web.output' to 'single' in your app.json.`\n );\n }\n\n return createRequestHandler(\n { build: '' },\n {\n async getRoutesManifest() {\n const manifest = await fetchManifest<RegExp>(projectRoot, options);\n debug('manifest', manifest);\n // NOTE: no app dir if null\n // TODO: Redirect to 404 page\n return (\n manifest ?? {\n // Support the onboarding screen if there's no manifest\n htmlRoutes: [\n {\n file: 'index.js',\n page: '/index',\n routeKeys: {},\n namedRegex: /^\\/(?:index)?\\/?$/i,\n },\n ],\n apiRoutes: [],\n notFoundRoutes: [],\n redirects: [],\n rewrites: [],\n }\n );\n },\n async getHtml(request, route) {\n try {\n const { content } = await options.getStaticPageAsync(request.url, route);\n return content;\n } catch (error: any) {\n // Forward the Metro server response as-is. It won't be pretty, but at least it will be accurate.\n\n try {\n return new Response(\n await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot,\n }),\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n } catch (staticError: any) {\n debug('Failed to render static error overlay:', staticError);\n // Fallback error for when Expo Router is misconfigured in the project.\n return new Response(\n '<span><h3>Internal Error:</h3><b>Project is not setup correctly for static rendering (check terminal for more info):</b><br/>' +\n error.message +\n '<br/><br/>' +\n staticError.message +\n '</span>',\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n }\n },\n async handleRouteError(error) {\n // NOTE(@kitten): ExpoError is currently not exposed by expo-server just yet\n if (error && typeof error === 'object' && error.name === 'ExpoError') {\n // TODO(@krystofwoldrich): Can we show code snippet of the handler?\n // NOTE(@krystofwoldrich): Removing stack since to avoid confusion. The error is not in the server code.\n delete error.stack;\n }\n\n const htmlServerError = await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot!,\n });\n\n return new Response(htmlServerError, {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n });\n },\n async getApiRoute(route) {\n const { exp } = options.config;\n if (exp.web?.output !== 'server') {\n warnInvalidWebOutput();\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling API route at: ${resolvedFunctionPath}`);\n return await options.bundleApiRoute(resolvedFunctionPath!);\n } catch (error: any) {\n return new Response(\n 'Failed to load API Route: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n async getMiddleware(route) {\n const { exp } = options.config;\n\n if (!options.unstable_useServerMiddleware) {\n return {\n default: () => {\n throw new CommandError(\n 'Server middleware is not enabled. Add unstable_useServerMiddleware: true to your `expo-router` plugin config.'\n );\n },\n };\n }\n\n if (exp.web?.output !== 'server') {\n warnInvalidMiddlewareOutput();\n return {\n default: () => {\n console.warn(\n 'Server middleware is only supported when web.output is set to \"server\" in your app config'\n );\n },\n };\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling middleware at: ${resolvedFunctionPath}`);\n const middlewareModule = (await options.bundleApiRoute(resolvedFunctionPath!)) as any;\n\n if ((middlewareModule.unstable_settings as MiddlewareSettings)?.matcher) {\n warnInvalidMiddlewareMatcherSettings(middlewareModule.unstable_settings?.matcher);\n }\n\n return middlewareModule;\n } catch (error: any) {\n return new Response(\n 'Failed to load middleware: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n }\n );\n}\n"],"names":["createRouteHandlerMiddleware","debug","require","resolveAsync","promisify","resolve","projectRoot","options","resolveFrom","silent","CommandError","createRequestHandler","build","getRoutesManifest","manifest","fetchManifest","htmlRoutes","file","page","routeKeys","namedRegex","apiRoutes","notFoundRoutes","redirects","rewrites","getHtml","request","route","content","getStaticPageAsync","url","error","Response","getErrorOverlayHtmlAsync","routerRoot","status","headers","staticError","message","handleRouteError","name","stack","htmlServerError","getApiRoute","exp","config","web","output","warnInvalidWebOutput","resolvedFunctionPath","extensions","basedir","appDir","bundleApiRoute","getMiddleware","unstable_useServerMiddleware","default","warnInvalidMiddlewareOutput","console","warn","middlewareModule","unstable_settings","matcher","warnInvalidMiddlewareMatcherSettings"],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "DataLoaderModuleMiddleware", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return DataLoaderModuleMiddleware;
9
+ }
10
+ });
11
+ function _config() {
12
+ const data = require("@expo/config");
13
+ _config = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
18
+ const _ExpoMiddleware = require("./ExpoMiddleware");
19
+ const _fetchRouterManifest = require("../metro/fetchRouterManifest");
20
+ const LOADER_MODULE_ENDPOINT = '/_expo/loaders';
21
+ class DataLoaderModuleMiddleware extends _ExpoMiddleware.ExpoMiddleware {
22
+ constructor(projectRoot, appDir, executeServerDataLoaderAsync, getDevServerUrl){
23
+ super(projectRoot, [
24
+ LOADER_MODULE_ENDPOINT
25
+ ]), this.projectRoot = projectRoot, this.appDir = appDir, this.executeServerDataLoaderAsync = executeServerDataLoaderAsync, this.getDevServerUrl = getDevServerUrl;
26
+ }
27
+ /**
28
+ * Only handles a request if `req.pathname` begins with `/_expo/loaders/` and if the request
29
+ * headers include `Accept: application/json`.
30
+ */ shouldHandleRequest(req) {
31
+ var _exp_extra_router, _exp_extra;
32
+ if (!req.url) return false;
33
+ const { pathname } = new URL(req.url, 'http://localhost');
34
+ if (!pathname.startsWith(`${LOADER_MODULE_ENDPOINT}/`)) {
35
+ return false;
36
+ }
37
+ if (req.headers.accept !== 'application/json') {
38
+ return false;
39
+ }
40
+ const { exp } = (0, _config().getConfig)(this.projectRoot);
41
+ return !!((_exp_extra = exp.extra) == null ? void 0 : (_exp_extra_router = _exp_extra.router) == null ? void 0 : _exp_extra_router.unstable_useServerDataLoaders);
42
+ }
43
+ async handleRequestAsync(req, res, next) {
44
+ if (![
45
+ 'GET',
46
+ 'HEAD'
47
+ ].includes(req.method ?? '')) {
48
+ return next();
49
+ }
50
+ const manifest = await (0, _fetchRouterManifest.fetchManifest)(this.projectRoot, {
51
+ appDir: this.appDir
52
+ });
53
+ const { pathname } = new URL(req.url, 'http://localhost');
54
+ try {
55
+ const routePath = pathname.replace('/_expo/loaders', '').replace('/index', '/') || '/';
56
+ const matchingRoute = manifest == null ? void 0 : manifest.htmlRoutes.find((route)=>{
57
+ return route.namedRegex.test(routePath);
58
+ });
59
+ if (!matchingRoute) {
60
+ throw new Error(`No matching route for ${routePath}`);
61
+ }
62
+ const loaderData = await this.executeServerDataLoaderAsync(new URL(routePath, this.getDevServerUrl()), matchingRoute);
63
+ res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
64
+ res.setHeader('Cache-Control', 'no-cache');
65
+ res.statusCode = 200;
66
+ res.end(JSON.stringify(loaderData ?? {}));
67
+ } catch (error) {
68
+ console.error(`Failed to generate loader module for ${pathname}:`, error);
69
+ res.statusCode = 500;
70
+ res.end(`{}`);
71
+ }
72
+ }
73
+ }
74
+
75
+ //# sourceMappingURL=DataLoaderModuleMiddleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/start/server/middleware/DataLoaderModuleMiddleware.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\n\nimport { ExpoMiddleware } from './ExpoMiddleware';\nimport { ServerNext, ServerRequest, ServerResponse } from './server.types';\nimport { type ExpoRouterServerManifestV1Route, fetchManifest } from '../metro/fetchRouterManifest';\n\nconst LOADER_MODULE_ENDPOINT = '/_expo/loaders';\n\n/**\n * Middleware for serving loader data modules dynamically during development. This allows\n * client-side navigation to fetch loader data on-demand.\n *\n * In production, these modules are pre-generated as static files.\n */\nexport class DataLoaderModuleMiddleware extends ExpoMiddleware {\n constructor(\n protected projectRoot: string,\n protected appDir: string,\n private executeServerDataLoaderAsync: (\n url: URL,\n route: ExpoRouterServerManifestV1Route<RegExp>\n ) => Promise<any>,\n private getDevServerUrl: () => string\n ) {\n super(projectRoot, [LOADER_MODULE_ENDPOINT]);\n }\n\n /**\n * Only handles a request if `req.pathname` begins with `/_expo/loaders/` and if the request\n * headers include `Accept: application/json`.\n */\n override shouldHandleRequest(req: ServerRequest): boolean {\n if (!req.url) return false;\n const { pathname } = new URL(req.url, 'http://localhost');\n\n if (!pathname.startsWith(`${LOADER_MODULE_ENDPOINT}/`)) {\n return false;\n }\n\n if (req.headers.accept !== 'application/json') {\n return false;\n }\n\n const { exp } = getConfig(this.projectRoot);\n return !!exp.extra?.router?.unstable_useServerDataLoaders;\n }\n\n async handleRequestAsync(\n req: ServerRequest,\n res: ServerResponse,\n next: ServerNext\n ): Promise<void> {\n if (!['GET', 'HEAD'].includes(req.method ?? '')) {\n return next();\n }\n\n const manifest = await fetchManifest<RegExp>(this.projectRoot, {\n appDir: this.appDir,\n });\n\n const { pathname } = new URL(req.url!, 'http://localhost');\n\n try {\n const routePath = pathname.replace('/_expo/loaders', '').replace('/index', '/') || '/';\n\n const matchingRoute = manifest?.htmlRoutes.find((route) => {\n return route.namedRegex.test(routePath);\n });\n\n if (!matchingRoute) {\n throw new Error(`No matching route for ${routePath}`);\n }\n\n const loaderData = await this.executeServerDataLoaderAsync(\n new URL(routePath, this.getDevServerUrl()),\n matchingRoute\n );\n\n res.setHeader('Content-Type', 'application/javascript; charset=utf-8');\n res.setHeader('Cache-Control', 'no-cache');\n res.statusCode = 200;\n res.end(JSON.stringify(loaderData ?? {}));\n } catch (error) {\n console.error(`Failed to generate loader module for ${pathname}:`, error);\n res.statusCode = 500;\n res.end(`{}`);\n }\n }\n}\n"],"names":["DataLoaderModuleMiddleware","LOADER_MODULE_ENDPOINT","ExpoMiddleware","constructor","projectRoot","appDir","executeServerDataLoaderAsync","getDevServerUrl","shouldHandleRequest","req","exp","url","pathname","URL","startsWith","headers","accept","getConfig","extra","router","unstable_useServerDataLoaders","handleRequestAsync","res","next","includes","method","manifest","fetchManifest","routePath","replace","matchingRoute","htmlRoutes","find","route","namedRegex","test","Error","loaderData","setHeader","statusCode","end","JSON","stringify","error","console"],"mappings":";;;;+BAcaA;;;eAAAA;;;;yBAda;;;;;;gCAEK;qCAEqC;AAEpE,MAAMC,yBAAyB;AAQxB,MAAMD,mCAAmCE,8BAAc;IAC5DC,YACE,AAAUC,WAAmB,EAC7B,AAAUC,MAAc,EACxB,AAAQC,4BAGS,EACjB,AAAQC,eAA6B,CACrC;QACA,KAAK,CAACH,aAAa;YAACH;SAAuB,QARjCG,cAAAA,kBACAC,SAAAA,aACFC,+BAAAA,mCAIAC,kBAAAA;IAGV;IAEA;;;GAGC,GACD,AAASC,oBAAoBC,GAAkB,EAAW;YAa/CC,mBAAAA;QAZT,IAAI,CAACD,IAAIE,GAAG,EAAE,OAAO;QACrB,MAAM,EAAEC,QAAQ,EAAE,GAAG,IAAIC,IAAIJ,IAAIE,GAAG,EAAE;QAEtC,IAAI,CAACC,SAASE,UAAU,CAAC,GAAGb,uBAAuB,CAAC,CAAC,GAAG;YACtD,OAAO;QACT;QAEA,IAAIQ,IAAIM,OAAO,CAACC,MAAM,KAAK,oBAAoB;YAC7C,OAAO;QACT;QAEA,MAAM,EAAEN,GAAG,EAAE,GAAGO,IAAAA,mBAAS,EAAC,IAAI,CAACb,WAAW;QAC1C,OAAO,CAAC,GAACM,aAAAA,IAAIQ,KAAK,sBAATR,oBAAAA,WAAWS,MAAM,qBAAjBT,kBAAmBU,6BAA6B;IAC3D;IAEA,MAAMC,mBACJZ,GAAkB,EAClBa,GAAmB,EACnBC,IAAgB,EACD;QACf,IAAI,CAAC;YAAC;YAAO;SAAO,CAACC,QAAQ,CAACf,IAAIgB,MAAM,IAAI,KAAK;YAC/C,OAAOF;QACT;QAEA,MAAMG,WAAW,MAAMC,IAAAA,kCAAa,EAAS,IAAI,CAACvB,WAAW,EAAE;YAC7DC,QAAQ,IAAI,CAACA,MAAM;QACrB;QAEA,MAAM,EAAEO,QAAQ,EAAE,GAAG,IAAIC,IAAIJ,IAAIE,GAAG,EAAG;QAEvC,IAAI;YACF,MAAMiB,YAAYhB,SAASiB,OAAO,CAAC,kBAAkB,IAAIA,OAAO,CAAC,UAAU,QAAQ;YAEnF,MAAMC,gBAAgBJ,4BAAAA,SAAUK,UAAU,CAACC,IAAI,CAAC,CAACC;gBAC/C,OAAOA,MAAMC,UAAU,CAACC,IAAI,CAACP;YAC/B;YAEA,IAAI,CAACE,eAAe;gBAClB,MAAM,IAAIM,MAAM,CAAC,sBAAsB,EAAER,WAAW;YACtD;YAEA,MAAMS,aAAa,MAAM,IAAI,CAAC/B,4BAA4B,CACxD,IAAIO,IAAIe,WAAW,IAAI,CAACrB,eAAe,KACvCuB;YAGFR,IAAIgB,SAAS,CAAC,gBAAgB;YAC9BhB,IAAIgB,SAAS,CAAC,iBAAiB;YAC/BhB,IAAIiB,UAAU,GAAG;YACjBjB,IAAIkB,GAAG,CAACC,KAAKC,SAAS,CAACL,cAAc,CAAC;QACxC,EAAE,OAAOM,OAAO;YACdC,QAAQD,KAAK,CAAC,CAAC,qCAAqC,EAAE/B,SAAS,CAAC,CAAC,EAAE+B;YACnErB,IAAIiB,UAAU,GAAG;YACjBjB,IAAIkB,GAAG,CAAC,CAAC,EAAE,CAAC;QACd;IACF;AACF"}
@@ -33,7 +33,7 @@ class FetchClient {
33
33
  this.headers = {
34
34
  accept: 'application/json',
35
35
  'content-type': 'application/json',
36
- 'user-agent': `expo-cli/${"54.0.10"}`,
36
+ 'user-agent': `expo-cli/${"54.1.0-canary-20251003-7b9d7ff"}`,
37
37
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
38
38
  };
39
39
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "54.0.10"
86
+ version: "54.1.0-canary-20251003-7b9d7ff"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "54.0.10",
3
+ "version": "54.1.0-canary-20251003-7b9d7ff",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -43,24 +43,24 @@
43
43
  "dependencies": {
44
44
  "@0no-co/graphql.web": "^1.0.8",
45
45
  "@expo/code-signing-certificates": "^0.0.5",
46
- "@expo/config": "~12.0.10",
47
- "@expo/config-plugins": "~54.0.2",
46
+ "@expo/config": "12.0.11-canary-20251003-7b9d7ff",
47
+ "@expo/config-plugins": "54.0.3-canary-20251003-7b9d7ff",
48
48
  "@expo/devcert": "^1.1.2",
49
- "@expo/env": "~2.0.7",
50
- "@expo/image-utils": "^0.8.7",
51
- "@expo/json-file": "^10.0.7",
49
+ "@expo/env": "2.0.8-canary-20251003-7b9d7ff",
50
+ "@expo/image-utils": "0.8.8-canary-20251003-7b9d7ff",
51
+ "@expo/json-file": "10.0.8-canary-20251003-7b9d7ff",
52
52
  "@expo/mcp-tunnel": "~0.0.7",
53
53
  "@expo/metro": "~54.0.0",
54
- "@expo/metro-config": "~54.0.6",
55
- "@expo/osascript": "^2.3.7",
56
- "@expo/package-manager": "^1.9.8",
57
- "@expo/plist": "^0.4.7",
58
- "@expo/prebuild-config": "^54.0.4",
59
- "@expo/schema-utils": "^0.1.7",
54
+ "@expo/metro-config": "54.0.7-canary-20251003-7b9d7ff",
55
+ "@expo/osascript": "2.3.8-canary-20251003-7b9d7ff",
56
+ "@expo/package-manager": "1.9.9-canary-20251003-7b9d7ff",
57
+ "@expo/plist": "0.4.8-canary-20251003-7b9d7ff",
58
+ "@expo/prebuild-config": "54.0.5-canary-20251003-7b9d7ff",
59
+ "@expo/schema-utils": "0.1.8-canary-20251003-7b9d7ff",
60
60
  "@expo/spawn-async": "^1.7.2",
61
61
  "@expo/ws-tunnel": "^1.0.1",
62
62
  "@expo/xcpretty": "^4.3.0",
63
- "@react-native/dev-middleware": "0.81.4",
63
+ "@react-native/dev-middleware": "0.82.0-rc.5",
64
64
  "@urql/core": "^5.0.6",
65
65
  "@urql/exchange-retry": "^1.3.0",
66
66
  "accepts": "^1.3.8",
@@ -74,7 +74,7 @@
74
74
  "connect": "^3.7.0",
75
75
  "debug": "^4.3.4",
76
76
  "env-editor": "^0.4.1",
77
- "expo-server": "^1.0.0",
77
+ "expo-server": "1.0.1-canary-20251003-7b9d7ff",
78
78
  "freeport-async": "^2.0.0",
79
79
  "getenv": "^2.0.0",
80
80
  "glob": "^10.4.2",
@@ -104,7 +104,8 @@
104
104
  "terminal-link": "^2.1.1",
105
105
  "undici": "^6.18.2",
106
106
  "wrap-ansi": "^7.0.0",
107
- "ws": "^8.12.1"
107
+ "ws": "^8.12.1",
108
+ "zod": "^3.25.76"
108
109
  },
109
110
  "taskr": {
110
111
  "requires": [
@@ -112,8 +113,8 @@
112
113
  ]
113
114
  },
114
115
  "peerDependencies": {
115
- "expo": "*",
116
- "expo-router": "*",
116
+ "expo": "55.0.0-canary-20251003-7b9d7ff",
117
+ "expo-router": "6.1.0-canary-20251003-7b9d7ff",
117
118
  "react-native": "*"
118
119
  },
119
120
  "peerDependenciesMeta": {
@@ -156,7 +157,7 @@
156
157
  "@types/ws": "^8.5.4",
157
158
  "devtools-protocol": "^0.0.1113120",
158
159
  "expo-atlas": "^0.4.1",
159
- "expo-module-scripts": "^5.0.7",
160
+ "expo-module-scripts": "5.0.8-canary-20251003-7b9d7ff",
160
161
  "find-process": "^1.4.7",
161
162
  "jest-runner-tsd": "^6.0.0",
162
163
  "klaw-sync": "^6.0.0",
@@ -168,6 +169,5 @@
168
169
  "taskr": "^1.1.0",
169
170
  "tree-kill": "^1.2.2",
170
171
  "tsd": "^0.28.1"
171
- },
172
- "gitHead": "73d9bc0ee4f1e28cfda349dc36ee53d16fad0c5d"
172
+ }
173
173
  }