@expo/cli 57.0.4 → 57.0.6

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 (34) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/events/index.js +1 -1
  3. package/build/src/export/publicFolder.js +2 -8
  4. package/build/src/export/publicFolder.js.map +1 -1
  5. package/build/src/run/android/resolveInstallApkName.js +48 -1
  6. package/build/src/run/android/resolveInstallApkName.js.map +1 -1
  7. package/build/src/start/interface/interactiveActions.js +42 -5
  8. package/build/src/start/interface/interactiveActions.js.map +1 -1
  9. package/build/src/start/interface/startInterface.js +4 -4
  10. package/build/src/start/interface/startInterface.js.map +1 -1
  11. package/build/src/start/server/DevToolsPlugin.js +57 -22
  12. package/build/src/start/server/DevToolsPlugin.js.map +1 -1
  13. package/build/src/start/server/DevToolsPlugin.schema.js +5 -0
  14. package/build/src/start/server/DevToolsPlugin.schema.js.map +1 -1
  15. package/build/src/start/server/DevToolsPluginManager.js +17 -3
  16. package/build/src/start/server/DevToolsPluginManager.js.map +1 -1
  17. package/build/src/start/server/DevToolsPluginServerHelpers.js +83 -0
  18. package/build/src/start/server/DevToolsPluginServerHelpers.js.map +1 -0
  19. package/build/src/start/server/MCP.js +10 -3
  20. package/build/src/start/server/MCP.js.map +1 -1
  21. package/build/src/start/server/metro/MetroBundlerDevServer.js +2 -1
  22. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  23. package/build/src/start/server/metro/instantiateMetro.js +18 -1
  24. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  25. package/build/src/start/server/middleware/DevToolsPluginMiddleware.js +57 -6
  26. package/build/src/start/server/middleware/DevToolsPluginMiddleware.js.map +1 -1
  27. package/build/src/start/startAsync.js +3 -0
  28. package/build/src/start/startAsync.js.map +1 -1
  29. package/build/src/utils/dir.js +10 -0
  30. package/build/src/utils/dir.js.map +1 -1
  31. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  32. package/build/src/utils/telemetry/utils/context.js +1 -1
  33. package/package.json +11 -12
  34. package/add-module.js +0 -8
@@ -14,12 +14,19 @@ _export(exports, {
14
14
  },
15
15
  get default () {
16
16
  return DevToolsPluginManager;
17
+ },
18
+ get event () {
19
+ return event;
17
20
  }
18
21
  });
19
22
  const _DevToolsPlugin = require("./DevToolsPlugin");
23
+ const _events = require("../../events");
20
24
  const _log = require("../../log");
21
25
  const debug = require('debug')('expo:start:server:devtools');
22
26
  const DevToolsPluginEndpoint = '/_expo/plugins';
27
+ const event = (0, _events.events)('expo', (t)=>[
28
+ t.event()
29
+ ]);
23
30
  class DevToolsPluginManager {
24
31
  constructor(projectRoot){
25
32
  this.projectRoot = projectRoot;
@@ -28,13 +35,20 @@ class DevToolsPluginManager {
28
35
  async queryPluginsAsync() {
29
36
  if (!this.plugins) {
30
37
  this.plugins = await this.queryAutolinkedPluginsAsync(this.projectRoot);
38
+ event('dev-tools-plugin:load', {
39
+ plugins: this.plugins.map((plugin)=>({
40
+ packageName: plugin.packageName,
41
+ bannerTitle: plugin.bannerTitle,
42
+ cliBanner: plugin.cliBanner,
43
+ webpageEndpoint: plugin.webpageEndpoint
44
+ }))
45
+ });
31
46
  }
32
47
  return this.plugins;
33
48
  }
34
- async queryPluginWebpageRootAsync(pluginName) {
49
+ async queryPluginAsync(pluginName) {
35
50
  const plugins = await this.queryPluginsAsync();
36
- const plugin = plugins.find((p)=>p.packageName === pluginName);
37
- return (plugin == null ? void 0 : plugin.webpageRoot) ?? null;
51
+ return plugins.find((p)=>p.packageName === pluginName) ?? null;
38
52
  }
39
53
  async queryAutolinkedPluginsAsync(projectRoot) {
40
54
  const autolinking = require('expo/internal/unstable-autolinking-exports');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/DevToolsPluginManager.ts"],"sourcesContent":["import type { ModuleDescriptorDevTools } from 'expo-modules-autolinking/exports';\n\nimport { DevToolsPlugin } from './DevToolsPlugin';\nimport { Log } from '../../log';\n\nconst debug = require('debug')('expo:start:server:devtools');\n\nexport const DevToolsPluginEndpoint = '/_expo/plugins';\n\nexport default class DevToolsPluginManager {\n private plugins: DevToolsPlugin[] | null = null;\n\n constructor(private projectRoot: string) {}\n\n public async queryPluginsAsync(): Promise<DevToolsPlugin[]> {\n if (!this.plugins) {\n this.plugins = await this.queryAutolinkedPluginsAsync(this.projectRoot);\n }\n return this.plugins;\n }\n\n public async queryPluginWebpageRootAsync(pluginName: string): Promise<string | null> {\n const plugins = await this.queryPluginsAsync();\n const plugin = plugins.find((p) => p.packageName === pluginName);\n return plugin?.webpageRoot ?? null;\n }\n\n private async queryAutolinkedPluginsAsync(projectRoot: string): Promise<DevToolsPlugin[]> {\n const autolinking: typeof import('expo/internal/unstable-autolinking-exports') = require('expo/internal/unstable-autolinking-exports');\n const linker = autolinking.makeCachedDependenciesLinker({ projectRoot });\n const revisions = await autolinking.scanExpoModuleResolutionsForPlatform(linker, 'devtools');\n const { resolveModuleAsync } = autolinking.getLinkingImplementationForPlatform('devtools');\n const plugins: ModuleDescriptorDevTools[] = (\n await Promise.all(\n Object.values(revisions).map((revision) => resolveModuleAsync(revision.name, revision))\n )\n ).filter((maybePlugin) => maybePlugin != null);\n debug('Found autolinked plugins', plugins);\n return plugins\n .map((pluginInfo) => {\n try {\n return new DevToolsPlugin(pluginInfo, this.projectRoot);\n } catch (error: any) {\n Log.warn(\n `Skipping plugin \"${pluginInfo.packageName}\": ${error.message ?? 'invalid configuration'}`\n );\n debug('Plugin validation error for %s: %O', pluginInfo.packageName, error);\n return null;\n }\n })\n .filter((p) => p != null) as DevToolsPlugin[];\n }\n}\n"],"names":["DevToolsPluginEndpoint","DevToolsPluginManager","debug","require","projectRoot","plugins","queryPluginsAsync","queryAutolinkedPluginsAsync","queryPluginWebpageRootAsync","pluginName","plugin","find","p","packageName","webpageRoot","autolinking","linker","makeCachedDependenciesLinker","revisions","scanExpoModuleResolutionsForPlatform","resolveModuleAsync","getLinkingImplementationForPlatform","Promise","all","Object","values","map","revision","name","filter","maybePlugin","pluginInfo","DevToolsPlugin","error","Log","warn","message"],"mappings":";;;;;;;;;;;QAOaA;eAAAA;;QAEb;eAAqBC;;;gCAPU;qBACX;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,MAAMH,yBAAyB;AAEvB,MAAMC;IAGnB,YAAY,AAAQG,WAAmB,CAAE;aAArBA,cAAAA;aAFZC,UAAmC;IAED;IAE1C,MAAaC,oBAA+C;QAC1D,IAAI,CAAC,IAAI,CAACD,OAAO,EAAE;YACjB,IAAI,CAACA,OAAO,GAAG,MAAM,IAAI,CAACE,2BAA2B,CAAC,IAAI,CAACH,WAAW;QACxE;QACA,OAAO,IAAI,CAACC,OAAO;IACrB;IAEA,MAAaG,4BAA4BC,UAAkB,EAA0B;QACnF,MAAMJ,UAAU,MAAM,IAAI,CAACC,iBAAiB;QAC5C,MAAMI,SAASL,QAAQM,IAAI,CAAC,CAACC,IAAMA,EAAEC,WAAW,KAAKJ;QACrD,OAAOC,CAAAA,0BAAAA,OAAQI,WAAW,KAAI;IAChC;IAEA,MAAcP,4BAA4BH,WAAmB,EAA6B;QACxF,MAAMW,cAA2EZ,QAAQ;QACzF,MAAMa,SAASD,YAAYE,4BAA4B,CAAC;YAAEb;QAAY;QACtE,MAAMc,YAAY,MAAMH,YAAYI,oCAAoC,CAACH,QAAQ;QACjF,MAAM,EAAEI,kBAAkB,EAAE,GAAGL,YAAYM,mCAAmC,CAAC;QAC/E,MAAMhB,UAAsC,AAC1C,CAAA,MAAMiB,QAAQC,GAAG,CACfC,OAAOC,MAAM,CAACP,WAAWQ,GAAG,CAAC,CAACC,WAAaP,mBAAmBO,SAASC,IAAI,EAAED,WAC/E,EACAE,MAAM,CAAC,CAACC,cAAgBA,eAAe;QACzC5B,MAAM,4BAA4BG;QAClC,OAAOA,QACJqB,GAAG,CAAC,CAACK;YACJ,IAAI;gBACF,OAAO,IAAIC,8BAAc,CAACD,YAAY,IAAI,CAAC3B,WAAW;YACxD,EAAE,OAAO6B,OAAY;gBACnBC,QAAG,CAACC,IAAI,CACN,CAAC,iBAAiB,EAAEJ,WAAWlB,WAAW,CAAC,GAAG,EAAEoB,MAAMG,OAAO,IAAI,yBAAyB;gBAE5FlC,MAAM,sCAAsC6B,WAAWlB,WAAW,EAAEoB;gBACpE,OAAO;YACT;QACF,GACCJ,MAAM,CAAC,CAACjB,IAAMA,KAAK;IACxB;AACF"}
1
+ {"version":3,"sources":["../../../../src/start/server/DevToolsPluginManager.ts"],"sourcesContent":["import type { ModuleDescriptorDevTools } from 'expo-modules-autolinking/exports';\n\nimport { DevToolsPlugin } from './DevToolsPlugin';\nimport { events } from '../../events';\nimport { Log } from '../../log';\n\nconst debug = require('debug')('expo:start:server:devtools');\n\nexport const DevToolsPluginEndpoint = '/_expo/plugins';\n\nexport const event = events('expo', (t) => [\n t.event<\n 'dev-tools-plugin:load',\n {\n plugins: {\n packageName: string;\n bannerTitle: string;\n cliBanner: boolean;\n webpageEndpoint: string | undefined;\n }[];\n }\n >(),\n]);\n\nexport default class DevToolsPluginManager {\n private plugins: DevToolsPlugin[] | null = null;\n\n constructor(private projectRoot: string) {}\n\n public async queryPluginsAsync(): Promise<DevToolsPlugin[]> {\n if (!this.plugins) {\n this.plugins = await this.queryAutolinkedPluginsAsync(this.projectRoot);\n event('dev-tools-plugin:load', {\n plugins: this.plugins.map((plugin) => ({\n packageName: plugin.packageName,\n bannerTitle: plugin.bannerTitle,\n cliBanner: plugin.cliBanner,\n webpageEndpoint: plugin.webpageEndpoint,\n })),\n });\n }\n return this.plugins;\n }\n\n public async queryPluginAsync(pluginName: string): Promise<DevToolsPlugin | null> {\n const plugins = await this.queryPluginsAsync();\n return plugins.find((p) => p.packageName === pluginName) ?? null;\n }\n\n private async queryAutolinkedPluginsAsync(projectRoot: string): Promise<DevToolsPlugin[]> {\n const autolinking: typeof import('expo/internal/unstable-autolinking-exports') = require('expo/internal/unstable-autolinking-exports');\n const linker = autolinking.makeCachedDependenciesLinker({ projectRoot });\n const revisions = await autolinking.scanExpoModuleResolutionsForPlatform(linker, 'devtools');\n const { resolveModuleAsync } = autolinking.getLinkingImplementationForPlatform('devtools');\n const plugins: ModuleDescriptorDevTools[] = (\n await Promise.all(\n Object.values(revisions).map((revision) => resolveModuleAsync(revision.name, revision))\n )\n ).filter((maybePlugin) => maybePlugin != null);\n debug('Found autolinked plugins', plugins);\n return plugins\n .map((pluginInfo) => {\n try {\n return new DevToolsPlugin(pluginInfo, this.projectRoot);\n } catch (error: any) {\n Log.warn(\n `Skipping plugin \"${pluginInfo.packageName}\": ${error.message ?? 'invalid configuration'}`\n );\n debug('Plugin validation error for %s: %O', pluginInfo.packageName, error);\n return null;\n }\n })\n .filter((p) => p != null) as DevToolsPlugin[];\n }\n}\n"],"names":["DevToolsPluginEndpoint","DevToolsPluginManager","event","debug","require","events","t","projectRoot","plugins","queryPluginsAsync","queryAutolinkedPluginsAsync","map","plugin","packageName","bannerTitle","cliBanner","webpageEndpoint","queryPluginAsync","pluginName","find","p","autolinking","linker","makeCachedDependenciesLinker","revisions","scanExpoModuleResolutionsForPlatform","resolveModuleAsync","getLinkingImplementationForPlatform","Promise","all","Object","values","revision","name","filter","maybePlugin","pluginInfo","DevToolsPlugin","error","Log","warn","message"],"mappings":";;;;;;;;;;;QAQaA;eAAAA;;QAgBb;eAAqBC;;QAdRC;eAAAA;;;gCARkB;wBACR;qBACH;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,MAAMJ,yBAAyB;AAE/B,MAAME,QAAQG,IAAAA,cAAM,EAAC,QAAQ,CAACC,IAAM;QACzCA,EAAEJ,KAAK;KAWR;AAEc,MAAMD;IAGnB,YAAY,AAAQM,WAAmB,CAAE;aAArBA,cAAAA;aAFZC,UAAmC;IAED;IAE1C,MAAaC,oBAA+C;QAC1D,IAAI,CAAC,IAAI,CAACD,OAAO,EAAE;YACjB,IAAI,CAACA,OAAO,GAAG,MAAM,IAAI,CAACE,2BAA2B,CAAC,IAAI,CAACH,WAAW;YACtEL,MAAM,yBAAyB;gBAC7BM,SAAS,IAAI,CAACA,OAAO,CAACG,GAAG,CAAC,CAACC,SAAY,CAAA;wBACrCC,aAAaD,OAAOC,WAAW;wBAC/BC,aAAaF,OAAOE,WAAW;wBAC/BC,WAAWH,OAAOG,SAAS;wBAC3BC,iBAAiBJ,OAAOI,eAAe;oBACzC,CAAA;YACF;QACF;QACA,OAAO,IAAI,CAACR,OAAO;IACrB;IAEA,MAAaS,iBAAiBC,UAAkB,EAAkC;QAChF,MAAMV,UAAU,MAAM,IAAI,CAACC,iBAAiB;QAC5C,OAAOD,QAAQW,IAAI,CAAC,CAACC,IAAMA,EAAEP,WAAW,KAAKK,eAAe;IAC9D;IAEA,MAAcR,4BAA4BH,WAAmB,EAA6B;QACxF,MAAMc,cAA2EjB,QAAQ;QACzF,MAAMkB,SAASD,YAAYE,4BAA4B,CAAC;YAAEhB;QAAY;QACtE,MAAMiB,YAAY,MAAMH,YAAYI,oCAAoC,CAACH,QAAQ;QACjF,MAAM,EAAEI,kBAAkB,EAAE,GAAGL,YAAYM,mCAAmC,CAAC;QAC/E,MAAMnB,UAAsC,AAC1C,CAAA,MAAMoB,QAAQC,GAAG,CACfC,OAAOC,MAAM,CAACP,WAAWb,GAAG,CAAC,CAACqB,WAAaN,mBAAmBM,SAASC,IAAI,EAAED,WAC/E,EACAE,MAAM,CAAC,CAACC,cAAgBA,eAAe;QACzChC,MAAM,4BAA4BK;QAClC,OAAOA,QACJG,GAAG,CAAC,CAACyB;YACJ,IAAI;gBACF,OAAO,IAAIC,8BAAc,CAACD,YAAY,IAAI,CAAC7B,WAAW;YACxD,EAAE,OAAO+B,OAAY;gBACnBC,QAAG,CAACC,IAAI,CACN,CAAC,iBAAiB,EAAEJ,WAAWvB,WAAW,CAAC,GAAG,EAAEyB,MAAMG,OAAO,IAAI,yBAAyB;gBAE5FtC,MAAM,sCAAsCiC,WAAWvB,WAAW,EAAEyB;gBACpE,OAAO;YACT;QACF,GACCJ,MAAM,CAAC,CAACd,IAAMA,KAAK;IACxB;AACF"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get loadRequestHandlerAsync () {
13
+ return loadRequestHandlerAsync;
14
+ },
15
+ get loadWebSocketServerAsync () {
16
+ return loadWebSocketServerAsync;
17
+ }
18
+ });
19
+ function _requireutils() {
20
+ const data = require("@expo/require-utils");
21
+ _requireutils = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function _ws() {
27
+ const data = require("ws");
28
+ _ws = function() {
29
+ return data;
30
+ };
31
+ return data;
32
+ }
33
+ const debug = require('debug')('expo:start:server:devtools');
34
+ function convertUpgradeRequest(request, route) {
35
+ const proto = 'encrypted' in request.socket && !!request.socket.encrypted ? 'https' : 'http';
36
+ const origin = `${proto}://${request.headers.host}`;
37
+ const url = new URL(request.url ?? '/', origin);
38
+ url.pathname = route;
39
+ const headers = new Headers();
40
+ const { rawHeaders } = request;
41
+ for(let index = 0; index < rawHeaders.length; index += 2){
42
+ const name = rawHeaders[index];
43
+ const value = rawHeaders[index + 1];
44
+ if (name != null && value != null) {
45
+ headers.append(name, value);
46
+ }
47
+ }
48
+ return new Request(url.href, {
49
+ method: request.method,
50
+ headers
51
+ });
52
+ }
53
+ async function loadRequestHandlerAsync({ packageName, serverEntryPoint }) {
54
+ debug('Loading DevTools plugin server module: %s', serverEntryPoint);
55
+ const serverModule = await (0, _requireutils().loadModule)(serverEntryPoint);
56
+ const handler = typeof serverModule === 'function' ? serverModule : serverModule == null ? void 0 : serverModule.default;
57
+ if (typeof handler !== 'function') {
58
+ throw new Error(`The serverEntryPoint (${serverEntryPoint}) of plugin ${packageName} ` + `must default-export a handler function that takes a Request and returns a Response. ` + `Export it as \`export default function handler(request) {}\` ` + `or \`exports.default = function handler(request) {}\`.`);
59
+ }
60
+ return handler;
61
+ }
62
+ async function loadWebSocketServerAsync({ packageName, serverEntryPoint }) {
63
+ debug('Loading DevTools plugin WebSocket server module: %s', serverEntryPoint);
64
+ const serverModule = await (0, _requireutils().loadModule)(serverEntryPoint);
65
+ const handlers = (serverModule == null ? void 0 : serverModule.webSocketHandlers) ?? {};
66
+ return Object.fromEntries(Object.entries(handlers).map(([route, handler])=>{
67
+ if (typeof handler !== 'function') {
68
+ throw new Error(`The webSocketHandlers["${route}"] export of plugin ${packageName} ` + `must be a function (socket, request, server) => void.`);
69
+ }
70
+ // Routes are mounted relative to the plugin endpoint, so they must be absolute.
71
+ const normalizedRoute = route.startsWith('/') ? route : `/${route}`;
72
+ const server = new (_ws()).WebSocketServer({
73
+ noServer: true
74
+ });
75
+ server.on('connection', (socket, request)=>handler(socket, convertUpgradeRequest(request, normalizedRoute), server));
76
+ return [
77
+ normalizedRoute,
78
+ server
79
+ ];
80
+ }));
81
+ }
82
+
83
+ //# sourceMappingURL=DevToolsPluginServerHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/start/server/DevToolsPluginServerHelpers.ts"],"sourcesContent":["import { loadModule } from '@expo/require-utils';\nimport type { IncomingMessage } from 'node:http';\nimport { type WebSocket, WebSocketServer } from 'ws';\n\nconst debug = require('debug')('expo:start:server:devtools') as typeof console.log;\n\n/**\n * Handler default-exported by a plugin's `serverEntryPoint`. Receives a fetch API `Request`\n * with the plugin endpoint prefix stripped from the URL. Returning `null`/`undefined` falls\n * through to static `webpageRoot` serving.\n */\nexport type DevToolsPluginRequestHandler = (\n request: Request\n) => Response | null | undefined | Promise<Response | null | undefined>;\n\n/**\n * Per-connection WebSocket handler exported by a plugin's `serverEntryPoint`. Receives the\n * connected `ws` socket, the upgrade `request`, and the `WebSocketServer` the connection belongs\n * to (use `server.clients` to broadcast). Mirrors the `ws` `'connection'` event so plugin authors\n * use the familiar `socket.on('message', ...)` / `socket.send(...)` API.\n */\nexport type DevToolsPluginWebSocketHandler = (\n socket: WebSocket,\n request: Request,\n server: WebSocketServer\n) => void;\n\nfunction convertUpgradeRequest(request: IncomingMessage, route: string): Request {\n const proto = 'encrypted' in request.socket && !!request.socket.encrypted ? 'https' : 'http';\n const origin = `${proto}://${request.headers.host}`;\n const url = new URL(request.url ?? '/', origin);\n url.pathname = route;\n const headers = new Headers();\n const { rawHeaders } = request;\n for (let index = 0; index < rawHeaders.length; index += 2) {\n const name = rawHeaders[index];\n const value = rawHeaders[index + 1];\n if (name != null && value != null) {\n headers.append(name, value);\n }\n }\n return new Request(url.href, { method: request.method, headers });\n}\n\nexport async function loadRequestHandlerAsync({\n packageName,\n serverEntryPoint,\n}: {\n packageName: string;\n serverEntryPoint: string;\n}): Promise<DevToolsPluginRequestHandler> {\n debug('Loading DevTools plugin server module: %s', serverEntryPoint);\n const serverModule = (await loadModule(serverEntryPoint)) as\n | DevToolsPluginRequestHandler\n | { default?: DevToolsPluginRequestHandler };\n const handler = typeof serverModule === 'function' ? serverModule : serverModule?.default;\n if (typeof handler !== 'function') {\n throw new Error(\n `The serverEntryPoint (${serverEntryPoint}) of plugin ${packageName} ` +\n `must default-export a handler function that takes a Request and returns a Response. ` +\n `Export it as \\`export default function handler(request) {}\\` ` +\n `or \\`exports.default = function handler(request) {}\\`.`\n );\n }\n return handler;\n}\n\nexport async function loadWebSocketServerAsync({\n packageName,\n serverEntryPoint,\n}: {\n packageName: string;\n serverEntryPoint: string;\n}): Promise<Record<string, WebSocketServer>> {\n debug('Loading DevTools plugin WebSocket server module: %s', serverEntryPoint);\n const serverModule = (await loadModule(serverEntryPoint)) as {\n webSocketHandlers?: Record<string, DevToolsPluginWebSocketHandler>;\n };\n const handlers: Record<string, DevToolsPluginWebSocketHandler> =\n serverModule?.webSocketHandlers ?? {};\n\n return Object.fromEntries(\n Object.entries(handlers).map(([route, handler]) => {\n if (typeof handler !== 'function') {\n throw new Error(\n `The webSocketHandlers[\"${route}\"] export of plugin ${packageName} ` +\n `must be a function (socket, request, server) => void.`\n );\n }\n // Routes are mounted relative to the plugin endpoint, so they must be absolute.\n const normalizedRoute = route.startsWith('/') ? route : `/${route}`;\n const server = new WebSocketServer({ noServer: true });\n server.on('connection', (socket, request) =>\n handler(socket, convertUpgradeRequest(request, normalizedRoute), server)\n );\n return [normalizedRoute, server];\n })\n );\n}\n"],"names":["loadRequestHandlerAsync","loadWebSocketServerAsync","debug","require","convertUpgradeRequest","request","route","proto","socket","encrypted","origin","headers","host","url","URL","pathname","Headers","rawHeaders","index","length","name","value","append","Request","href","method","packageName","serverEntryPoint","serverModule","loadModule","handler","default","Error","handlers","webSocketHandlers","Object","fromEntries","entries","map","normalizedRoute","startsWith","server","WebSocketServer","noServer","on"],"mappings":";;;;;;;;;;;QA4CsBA;eAAAA;;QAuBAC;eAAAA;;;;yBAnEK;;;;;;;yBAEqB;;;;;;AAEhD,MAAMC,QAAQC,QAAQ,SAAS;AAuB/B,SAASC,sBAAsBC,OAAwB,EAAEC,KAAa;IACpE,MAAMC,QAAQ,eAAeF,QAAQG,MAAM,IAAI,CAAC,CAACH,QAAQG,MAAM,CAACC,SAAS,GAAG,UAAU;IACtF,MAAMC,SAAS,GAAGH,MAAM,GAAG,EAAEF,QAAQM,OAAO,CAACC,IAAI,EAAE;IACnD,MAAMC,MAAM,IAAIC,IAAIT,QAAQQ,GAAG,IAAI,KAAKH;IACxCG,IAAIE,QAAQ,GAAGT;IACf,MAAMK,UAAU,IAAIK;IACpB,MAAM,EAAEC,UAAU,EAAE,GAAGZ;IACvB,IAAK,IAAIa,QAAQ,GAAGA,QAAQD,WAAWE,MAAM,EAAED,SAAS,EAAG;QACzD,MAAME,OAAOH,UAAU,CAACC,MAAM;QAC9B,MAAMG,QAAQJ,UAAU,CAACC,QAAQ,EAAE;QACnC,IAAIE,QAAQ,QAAQC,SAAS,MAAM;YACjCV,QAAQW,MAAM,CAACF,MAAMC;QACvB;IACF;IACA,OAAO,IAAIE,QAAQV,IAAIW,IAAI,EAAE;QAAEC,QAAQpB,QAAQoB,MAAM;QAAEd;IAAQ;AACjE;AAEO,eAAeX,wBAAwB,EAC5C0B,WAAW,EACXC,gBAAgB,EAIjB;IACCzB,MAAM,6CAA6CyB;IACnD,MAAMC,eAAgB,MAAMC,IAAAA,0BAAU,EAACF;IAGvC,MAAMG,UAAU,OAAOF,iBAAiB,aAAaA,eAAeA,gCAAAA,aAAcG,OAAO;IACzF,IAAI,OAAOD,YAAY,YAAY;QACjC,MAAM,IAAIE,MACR,CAAC,sBAAsB,EAAEL,iBAAiB,YAAY,EAAED,YAAY,CAAC,CAAC,GACpE,CAAC,oFAAoF,CAAC,GACtF,CAAC,6DAA6D,CAAC,GAC/D,CAAC,sDAAsD,CAAC;IAE9D;IACA,OAAOI;AACT;AAEO,eAAe7B,yBAAyB,EAC7CyB,WAAW,EACXC,gBAAgB,EAIjB;IACCzB,MAAM,uDAAuDyB;IAC7D,MAAMC,eAAgB,MAAMC,IAAAA,0BAAU,EAACF;IAGvC,MAAMM,WACJL,CAAAA,gCAAAA,aAAcM,iBAAiB,KAAI,CAAC;IAEtC,OAAOC,OAAOC,WAAW,CACvBD,OAAOE,OAAO,CAACJ,UAAUK,GAAG,CAAC,CAAC,CAAChC,OAAOwB,QAAQ;QAC5C,IAAI,OAAOA,YAAY,YAAY;YACjC,MAAM,IAAIE,MACR,CAAC,uBAAuB,EAAE1B,MAAM,oBAAoB,EAAEoB,YAAY,CAAC,CAAC,GAClE,CAAC,qDAAqD,CAAC;QAE7D;QACA,gFAAgF;QAChF,MAAMa,kBAAkBjC,MAAMkC,UAAU,CAAC,OAAOlC,QAAQ,CAAC,CAAC,EAAEA,OAAO;QACnE,MAAMmC,SAAS,IAAIC,CAAAA,KAAc,iBAAC,CAAC;YAAEC,UAAU;QAAK;QACpDF,OAAOG,EAAE,CAAC,cAAc,CAACpC,QAAQH,UAC/ByB,QAAQtB,QAAQJ,sBAAsBC,SAASkC,kBAAkBE;QAEnE,OAAO;YAACF;YAAiBE;SAAO;IAClC;AAEJ"}
@@ -8,6 +8,13 @@ Object.defineProperty(exports, "maybeCreateMCPServerAsync", {
8
8
  return maybeCreateMCPServerAsync;
9
9
  }
10
10
  });
11
+ function _requireutils() {
12
+ const data = require("@expo/require-utils");
13
+ _requireutils = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
11
18
  function _nodepath() {
12
19
  const data = /*#__PURE__*/ _interop_require_default(require("node:path"));
13
20
  _nodepath = function() {
@@ -31,7 +38,6 @@ function _interop_require_default(obj) {
31
38
  default: obj
32
39
  };
33
40
  }
34
- const importESM = require('@expo/cli/add-module');
35
41
  const debug = require('debug')('expo:start:server:mcp');
36
42
  async function maybeCreateMCPServerAsync({ projectRoot, devServerUrl }) {
37
43
  const mcpServer = _env.env.EXPO_UNSTABLE_MCP_SERVER;
@@ -54,8 +60,9 @@ async function maybeCreateMCPServerAsync({ projectRoot, devServerUrl }) {
54
60
  const mcpServerUrl = `${scheme}//${mcpServerUrlObject.host}`;
55
61
  debug(`Creating MCP tunnel - server URL: ${mcpServerUrl}`);
56
62
  try {
57
- const { addMcpCapabilities } = await importESM(mcpPackagePath);
58
- const { TunnelMcpServerProxy } = await importESM(mcpTunnelPackagePath);
63
+ debug(`Loading MCP modules: expo-mcp=${mcpPackagePath}, mcp-tunnel=${mcpTunnelPackagePath}`);
64
+ const { addMcpCapabilities } = await (0, _requireutils().loadModule)(mcpPackagePath);
65
+ const { TunnelMcpServerProxy } = await (0, _requireutils().loadModule)(mcpTunnelPackagePath);
59
66
  const logger = {
60
67
  ..._log.Log,
61
68
  debug (...message) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/MCP.ts"],"sourcesContent":["import type {\n McpServerProxy,\n TunnelMcpServerProxy as TunnelMcpServerProxyType,\n} from '@expo/mcp-tunnel' with { 'resolution-mode': 'import' };\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\n\nimport { getAccessToken, getSession } from '../../api/user/UserSettings';\nimport { Log } from '../../log';\nimport { env } from '../../utils/env';\nimport { installExitHooks } from '../../utils/exit';\n\nconst importESM = require('@expo/cli/add-module') as <T>(moduleName: string) => Promise<T>;\n\nconst debug = require('debug')('expo:start:server:mcp') as typeof console.log;\n\n/**\n * The MCP server\n */\nexport type McpServer = Omit<McpServerProxy, 'close'> & {\n /**\n * Close the server\n */\n closeAsync: () => Promise<void>;\n};\n\n/**\n * Create the MCP server\n */\nexport async function maybeCreateMCPServerAsync({\n projectRoot,\n devServerUrl,\n}: {\n projectRoot: string;\n devServerUrl: string;\n}): Promise<McpServer | null> {\n const mcpServer = env.EXPO_UNSTABLE_MCP_SERVER;\n if (!mcpServer) {\n return null;\n }\n const mcpPackagePath = resolveFrom.silent(projectRoot, 'expo-mcp');\n if (!mcpPackagePath) {\n Log.error(\n 'Missing the `expo-mcp` package in the project. To enable the MCP integration, add the `expo-mcp` package to your project.'\n );\n return null;\n }\n const mcpTunnelPackagePath = resolveFrom.silent(path.dirname(mcpPackagePath), '@expo/mcp-tunnel');\n if (!mcpTunnelPackagePath) {\n Log.error('Unable to resolve the `@expo/mcp-tunnel` package');\n return null;\n }\n\n const normalizedServer = /^([a-zA-Z][a-zA-Z\\d+\\-.]*):\\/\\//.test(mcpServer)\n ? mcpServer\n : `wss://${mcpServer}`;\n const mcpServerUrlObject = new URL(normalizedServer);\n const scheme = mcpServerUrlObject.protocol ?? 'wss:';\n const mcpServerUrl = `${scheme}//${mcpServerUrlObject.host}`;\n debug(`Creating MCP tunnel - server URL: ${mcpServerUrl}`);\n\n try {\n const { addMcpCapabilities } = await importESM<{\n addMcpCapabilities: (server: McpServerProxy, projectRoot: string) => void;\n }>(mcpPackagePath);\n const { TunnelMcpServerProxy } = await importESM<{\n TunnelMcpServerProxy: typeof TunnelMcpServerProxyType;\n }>(mcpTunnelPackagePath);\n\n const logger = {\n ...Log,\n debug(...message: any[]): void {\n debug(...message);\n },\n info(...message: any[]): void {\n Log.log(...message);\n },\n };\n const serverProxy: McpServerProxy = new TunnelMcpServerProxy(mcpServerUrl, {\n logger,\n wsHeaders: createAuthHeaders(),\n projectRoot,\n devServerUrl,\n });\n addMcpCapabilities(serverProxy, projectRoot);\n\n const removeExitHook = installExitHooks(async () => {\n await serverProxy.close();\n });\n const server = serverProxy as unknown as McpServer;\n server.closeAsync = async () => {\n removeExitHook();\n await serverProxy.close();\n };\n\n return server;\n } catch (error: unknown) {\n debug(`Error creating MCP tunnel: ${error}`);\n }\n return null;\n}\n\nfunction createAuthHeaders(): Record<string, string> {\n const token = getAccessToken();\n if (token) {\n return {\n authorization: `Bearer ${token}`,\n };\n }\n const sessionSecret = getSession()?.sessionSecret;\n if (sessionSecret) {\n return {\n 'expo-session': sessionSecret,\n };\n }\n return {};\n}\n"],"names":["maybeCreateMCPServerAsync","importESM","require","debug","projectRoot","devServerUrl","mcpServer","env","EXPO_UNSTABLE_MCP_SERVER","mcpPackagePath","resolveFrom","silent","Log","error","mcpTunnelPackagePath","path","dirname","normalizedServer","test","mcpServerUrlObject","URL","scheme","protocol","mcpServerUrl","host","addMcpCapabilities","TunnelMcpServerProxy","logger","message","info","log","serverProxy","wsHeaders","createAuthHeaders","removeExitHook","installExitHooks","close","server","closeAsync","getSession","token","getAccessToken","authorization","sessionSecret"],"mappings":";;;;+BA6BsBA;;;eAAAA;;;;gEAzBL;;;;;;;gEACO;;;;;;8BAEmB;qBACvB;qBACA;sBACa;;;;;;AAEjC,MAAMC,YAAYC,QAAQ;AAE1B,MAAMC,QAAQD,QAAQ,SAAS;AAexB,eAAeF,0BAA0B,EAC9CI,WAAW,EACXC,YAAY,EAIb;IACC,MAAMC,YAAYC,QAAG,CAACC,wBAAwB;IAC9C,IAAI,CAACF,WAAW;QACd,OAAO;IACT;IACA,MAAMG,iBAAiBC,sBAAW,CAACC,MAAM,CAACP,aAAa;IACvD,IAAI,CAACK,gBAAgB;QACnBG,QAAG,CAACC,KAAK,CACP;QAEF,OAAO;IACT;IACA,MAAMC,uBAAuBJ,sBAAW,CAACC,MAAM,CAACI,mBAAI,CAACC,OAAO,CAACP,iBAAiB;IAC9E,IAAI,CAACK,sBAAsB;QACzBF,QAAG,CAACC,KAAK,CAAC;QACV,OAAO;IACT;IAEA,MAAMI,mBAAmB,kCAAkCC,IAAI,CAACZ,aAC5DA,YACA,CAAC,MAAM,EAAEA,WAAW;IACxB,MAAMa,qBAAqB,IAAIC,IAAIH;IACnC,MAAMI,SAASF,mBAAmBG,QAAQ,IAAI;IAC9C,MAAMC,eAAe,GAAGF,OAAO,EAAE,EAAEF,mBAAmBK,IAAI,EAAE;IAC5DrB,MAAM,CAAC,kCAAkC,EAAEoB,cAAc;IAEzD,IAAI;QACF,MAAM,EAAEE,kBAAkB,EAAE,GAAG,MAAMxB,UAElCQ;QACH,MAAM,EAAEiB,oBAAoB,EAAE,GAAG,MAAMzB,UAEpCa;QAEH,MAAMa,SAAS;YACb,GAAGf,QAAG;YACNT,OAAM,GAAGyB,OAAc;gBACrBzB,SAASyB;YACX;YACAC,MAAK,GAAGD,OAAc;gBACpBhB,QAAG,CAACkB,GAAG,IAAIF;YACb;QACF;QACA,MAAMG,cAA8B,IAAIL,qBAAqBH,cAAc;YACzEI;YACAK,WAAWC;YACX7B;YACAC;QACF;QACAoB,mBAAmBM,aAAa3B;QAEhC,MAAM8B,iBAAiBC,IAAAA,sBAAgB,EAAC;YACtC,MAAMJ,YAAYK,KAAK;QACzB;QACA,MAAMC,SAASN;QACfM,OAAOC,UAAU,GAAG;YAClBJ;YACA,MAAMH,YAAYK,KAAK;QACzB;QAEA,OAAOC;IACT,EAAE,OAAOxB,OAAgB;QACvBV,MAAM,CAAC,2BAA2B,EAAEU,OAAO;IAC7C;IACA,OAAO;AACT;AAEA,SAASoB;QAOeM;IANtB,MAAMC,QAAQC,IAAAA,4BAAc;IAC5B,IAAID,OAAO;QACT,OAAO;YACLE,eAAe,CAAC,OAAO,EAAEF,OAAO;QAClC;IACF;IACA,MAAMG,iBAAgBJ,cAAAA,IAAAA,wBAAU,wBAAVA,YAAcI,aAAa;IACjD,IAAIA,eAAe;QACjB,OAAO;YACL,gBAAgBA;QAClB;IACF;IACA,OAAO,CAAC;AACV"}
1
+ {"version":3,"sources":["../../../../src/start/server/MCP.ts"],"sourcesContent":["import type {\n McpServerProxy,\n TunnelMcpServerProxy as TunnelMcpServerProxyType,\n} from '@expo/mcp-tunnel' with { 'resolution-mode': 'import' };\nimport { loadModule } from '@expo/require-utils';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\n\nimport { getAccessToken, getSession } from '../../api/user/UserSettings';\nimport { Log } from '../../log';\nimport { env } from '../../utils/env';\nimport { installExitHooks } from '../../utils/exit';\n\nconst debug = require('debug')('expo:start:server:mcp') as typeof console.log;\n\n/**\n * The MCP server\n */\nexport type McpServer = Omit<McpServerProxy, 'close'> & {\n /**\n * Close the server\n */\n closeAsync: () => Promise<void>;\n};\n\n/**\n * Create the MCP server\n */\nexport async function maybeCreateMCPServerAsync({\n projectRoot,\n devServerUrl,\n}: {\n projectRoot: string;\n devServerUrl: string;\n}): Promise<McpServer | null> {\n const mcpServer = env.EXPO_UNSTABLE_MCP_SERVER;\n if (!mcpServer) {\n return null;\n }\n const mcpPackagePath = resolveFrom.silent(projectRoot, 'expo-mcp');\n if (!mcpPackagePath) {\n Log.error(\n 'Missing the `expo-mcp` package in the project. To enable the MCP integration, add the `expo-mcp` package to your project.'\n );\n return null;\n }\n const mcpTunnelPackagePath = resolveFrom.silent(path.dirname(mcpPackagePath), '@expo/mcp-tunnel');\n if (!mcpTunnelPackagePath) {\n Log.error('Unable to resolve the `@expo/mcp-tunnel` package');\n return null;\n }\n\n const normalizedServer = /^([a-zA-Z][a-zA-Z\\d+\\-.]*):\\/\\//.test(mcpServer)\n ? mcpServer\n : `wss://${mcpServer}`;\n const mcpServerUrlObject = new URL(normalizedServer);\n const scheme = mcpServerUrlObject.protocol ?? 'wss:';\n const mcpServerUrl = `${scheme}//${mcpServerUrlObject.host}`;\n debug(`Creating MCP tunnel - server URL: ${mcpServerUrl}`);\n\n try {\n debug(`Loading MCP modules: expo-mcp=${mcpPackagePath}, mcp-tunnel=${mcpTunnelPackagePath}`);\n const { addMcpCapabilities } = (await loadModule(mcpPackagePath)) as {\n addMcpCapabilities: (server: McpServerProxy, projectRoot: string) => void;\n };\n const { TunnelMcpServerProxy } = (await loadModule(mcpTunnelPackagePath)) as {\n TunnelMcpServerProxy: typeof TunnelMcpServerProxyType;\n };\n\n const logger = {\n ...Log,\n debug(...message: any[]): void {\n debug(...message);\n },\n info(...message: any[]): void {\n Log.log(...message);\n },\n };\n const serverProxy: McpServerProxy = new TunnelMcpServerProxy(mcpServerUrl, {\n logger,\n wsHeaders: createAuthHeaders(),\n projectRoot,\n devServerUrl,\n });\n addMcpCapabilities(serverProxy, projectRoot);\n\n const removeExitHook = installExitHooks(async () => {\n await serverProxy.close();\n });\n const server = serverProxy as unknown as McpServer;\n server.closeAsync = async () => {\n removeExitHook();\n await serverProxy.close();\n };\n\n return server;\n } catch (error: unknown) {\n debug(`Error creating MCP tunnel: ${error}`);\n }\n return null;\n}\n\nfunction createAuthHeaders(): Record<string, string> {\n const token = getAccessToken();\n if (token) {\n return {\n authorization: `Bearer ${token}`,\n };\n }\n const sessionSecret = getSession()?.sessionSecret;\n if (sessionSecret) {\n return {\n 'expo-session': sessionSecret,\n };\n }\n return {};\n}\n"],"names":["maybeCreateMCPServerAsync","debug","require","projectRoot","devServerUrl","mcpServer","env","EXPO_UNSTABLE_MCP_SERVER","mcpPackagePath","resolveFrom","silent","Log","error","mcpTunnelPackagePath","path","dirname","normalizedServer","test","mcpServerUrlObject","URL","scheme","protocol","mcpServerUrl","host","addMcpCapabilities","loadModule","TunnelMcpServerProxy","logger","message","info","log","serverProxy","wsHeaders","createAuthHeaders","removeExitHook","installExitHooks","close","server","closeAsync","getSession","token","getAccessToken","authorization","sessionSecret"],"mappings":";;;;+BA4BsBA;;;eAAAA;;;;yBAxBK;;;;;;;gEACV;;;;;;;gEACO;;;;;;8BAEmB;qBACvB;qBACA;sBACa;;;;;;AAEjC,MAAMC,QAAQC,QAAQ,SAAS;AAexB,eAAeF,0BAA0B,EAC9CG,WAAW,EACXC,YAAY,EAIb;IACC,MAAMC,YAAYC,QAAG,CAACC,wBAAwB;IAC9C,IAAI,CAACF,WAAW;QACd,OAAO;IACT;IACA,MAAMG,iBAAiBC,sBAAW,CAACC,MAAM,CAACP,aAAa;IACvD,IAAI,CAACK,gBAAgB;QACnBG,QAAG,CAACC,KAAK,CACP;QAEF,OAAO;IACT;IACA,MAAMC,uBAAuBJ,sBAAW,CAACC,MAAM,CAACI,mBAAI,CAACC,OAAO,CAACP,iBAAiB;IAC9E,IAAI,CAACK,sBAAsB;QACzBF,QAAG,CAACC,KAAK,CAAC;QACV,OAAO;IACT;IAEA,MAAMI,mBAAmB,kCAAkCC,IAAI,CAACZ,aAC5DA,YACA,CAAC,MAAM,EAAEA,WAAW;IACxB,MAAMa,qBAAqB,IAAIC,IAAIH;IACnC,MAAMI,SAASF,mBAAmBG,QAAQ,IAAI;IAC9C,MAAMC,eAAe,GAAGF,OAAO,EAAE,EAAEF,mBAAmBK,IAAI,EAAE;IAC5DtB,MAAM,CAAC,kCAAkC,EAAEqB,cAAc;IAEzD,IAAI;QACFrB,MAAM,CAAC,8BAA8B,EAAEO,eAAe,aAAa,EAAEK,sBAAsB;QAC3F,MAAM,EAAEW,kBAAkB,EAAE,GAAI,MAAMC,IAAAA,0BAAU,EAACjB;QAGjD,MAAM,EAAEkB,oBAAoB,EAAE,GAAI,MAAMD,IAAAA,0BAAU,EAACZ;QAInD,MAAMc,SAAS;YACb,GAAGhB,QAAG;YACNV,OAAM,GAAG2B,OAAc;gBACrB3B,SAAS2B;YACX;YACAC,MAAK,GAAGD,OAAc;gBACpBjB,QAAG,CAACmB,GAAG,IAAIF;YACb;QACF;QACA,MAAMG,cAA8B,IAAIL,qBAAqBJ,cAAc;YACzEK;YACAK,WAAWC;YACX9B;YACAC;QACF;QACAoB,mBAAmBO,aAAa5B;QAEhC,MAAM+B,iBAAiBC,IAAAA,sBAAgB,EAAC;YACtC,MAAMJ,YAAYK,KAAK;QACzB;QACA,MAAMC,SAASN;QACfM,OAAOC,UAAU,GAAG;YAClBJ;YACA,MAAMH,YAAYK,KAAK;QACzB;QAEA,OAAOC;IACT,EAAE,OAAOzB,OAAgB;QACvBX,MAAM,CAAC,2BAA2B,EAAEW,OAAO;IAC7C;IACA,OAAO;AACT;AAEA,SAASqB;QAOeM;IANtB,MAAMC,QAAQC,IAAAA,4BAAc;IAC5B,IAAID,OAAO;QACT,OAAO;YACLE,eAAe,CAAC,OAAO,EAAEF,OAAO;QAClC;IACF;IACA,MAAMG,iBAAgBJ,cAAAA,IAAAA,wBAAU,wBAAVA,YAAcI,aAAa;IACjD,IAAIA,eAAe;QACjB,OAAO;YACL,gBAAgBA;QAClB;IACF;IACA,OAAO,CAAC;AACV"}
@@ -928,7 +928,8 @@ class MetroBundlerDevServer extends _BundlerDevServer.BundlerDevServer {
928
928
  });
929
929
  const { metro, hmrServer, address, server, middleware, messageSocket } = await (0, _instantiateMetro.instantiateMetroAsync)(this, parsedOptions, {
930
930
  isExporting: !!options.isExporting,
931
- exp
931
+ exp,
932
+ devToolsPluginManager: this.devToolsPluginManager
932
933
  });
933
934
  // Required for symbolication:
934
935
  const serverBaseUrl = `${(address == null ? void 0 : address.protocol) ?? 'http'}://localhost:${(address == null ? void 0 : address.port) ?? options.port}`;