@expo/cli 56.1.5 → 56.1.7

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 (94) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/api/rest/client.js +27 -12
  3. package/build/src/api/rest/client.js.map +1 -1
  4. package/build/src/api/user/UserSettings.js +17 -4
  5. package/build/src/api/user/UserSettings.js.map +1 -1
  6. package/build/src/events/index.js +1 -1
  7. package/build/src/export/embed/exportEmbedAsync.js +3 -3
  8. package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
  9. package/build/src/export/embed/exportServer.js +1 -1
  10. package/build/src/export/embed/exportServer.js.map +1 -1
  11. package/build/src/export/exportApp.js +1 -1
  12. package/build/src/export/exportApp.js.map +1 -1
  13. package/build/src/export/publicFolder.js +19 -1
  14. package/build/src/export/publicFolder.js.map +1 -1
  15. package/build/src/install/utils/checkPackagesCompatibility.js +32 -16
  16. package/build/src/install/utils/checkPackagesCompatibility.js.map +1 -1
  17. package/build/src/login/index.js +25 -5
  18. package/build/src/login/index.js.map +1 -1
  19. package/build/src/prebuild/resolveTemplate.js +10 -5
  20. package/build/src/prebuild/resolveTemplate.js.map +1 -1
  21. package/build/src/run/android/resolveLaunchProps.js +4 -1
  22. package/build/src/run/android/resolveLaunchProps.js.map +1 -1
  23. package/build/src/start/doctor/dependencies/reactNativeTv.js +149 -0
  24. package/build/src/start/doctor/dependencies/reactNativeTv.js.map +1 -0
  25. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js +28 -3
  26. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js.map +1 -1
  27. package/build/src/start/platforms/AppIdResolver.js +4 -0
  28. package/build/src/start/platforms/AppIdResolver.js.map +1 -1
  29. package/build/src/start/platforms/android/adb.js +16 -15
  30. package/build/src/start/platforms/android/adb.js.map +1 -1
  31. package/build/src/start/server/DevToolsPlugin.js +26 -1
  32. package/build/src/start/server/DevToolsPlugin.js.map +1 -1
  33. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js +57 -22
  34. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js.map +1 -1
  35. package/build/src/start/server/DevToolsPluginCliExtensionResults.js +29 -0
  36. package/build/src/start/server/DevToolsPluginCliExtensionResults.js.map +1 -1
  37. package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js +15 -5
  38. package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js.map +1 -1
  39. package/build/src/start/server/UrlCreator.js +14 -1
  40. package/build/src/start/server/UrlCreator.js.map +1 -1
  41. package/build/src/start/server/createMCPDevToolsExtensionSchema.js +13 -1
  42. package/build/src/start/server/createMCPDevToolsExtensionSchema.js.map +1 -1
  43. package/build/src/start/server/getStaticRenderFunctions.js +2 -1
  44. package/build/src/start/server/getStaticRenderFunctions.js.map +1 -1
  45. package/build/src/start/server/metro/MetroBundlerDevServer.js +44 -0
  46. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  47. package/build/src/start/server/metro/createServerComponentsMiddleware.js +13 -13
  48. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  49. package/build/src/start/server/metro/debugging/createDebugMiddleware.js +5 -4
  50. package/build/src/start/server/metro/debugging/createDebugMiddleware.js.map +1 -1
  51. package/build/src/start/server/metro/debugging/messageHandlers/NetworkResponse.js +17 -1
  52. package/build/src/start/server/metro/debugging/messageHandlers/NetworkResponse.js.map +1 -1
  53. package/build/src/start/server/metro/dev-server/createMessageSocket.js +13 -2
  54. package/build/src/start/server/metro/dev-server/createMessageSocket.js.map +1 -1
  55. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +9 -2
  56. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
  57. package/build/src/start/server/metro/instantiateMetro.js +8 -5
  58. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  59. package/build/src/start/server/metro/metroErrorInterface.js +5 -2
  60. package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
  61. package/build/src/start/server/metro/router.js +10 -1
  62. package/build/src/start/server/metro/router.js.map +1 -1
  63. package/build/src/start/server/metro/withMetroMultiPlatform.js +8 -0
  64. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  65. package/build/src/start/server/middleware/InterstitialPageMiddleware.js +7 -4
  66. package/build/src/start/server/middleware/InterstitialPageMiddleware.js.map +1 -1
  67. package/build/src/start/server/middleware/OpenMiddleware.js +150 -0
  68. package/build/src/start/server/middleware/OpenMiddleware.js.map +1 -0
  69. package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js +13 -4
  70. package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js.map +1 -1
  71. package/build/src/start/server/middleware/ServeStaticMiddleware.js +2 -9
  72. package/build/src/start/server/middleware/ServeStaticMiddleware.js.map +1 -1
  73. package/build/src/start/server/middleware/inspector/createJsInspectorMiddleware.js +14 -24
  74. package/build/src/start/server/middleware/inspector/createJsInspectorMiddleware.js.map +1 -1
  75. package/build/src/start/server/middleware/openHandlers.js +157 -0
  76. package/build/src/start/server/middleware/openHandlers.js.map +1 -0
  77. package/build/src/start/server/webTemplate.js +3 -5
  78. package/build/src/start/server/webTemplate.js.map +1 -1
  79. package/build/src/utils/codesigning.js +6 -0
  80. package/build/src/utils/codesigning.js.map +1 -1
  81. package/build/src/utils/env.js +29 -6
  82. package/build/src/utils/env.js.map +1 -1
  83. package/build/src/utils/net.js +20 -1
  84. package/build/src/utils/net.js.map +1 -1
  85. package/build/src/utils/open.js +2 -5
  86. package/build/src/utils/open.js.map +1 -1
  87. package/build/src/utils/tar.js +2 -2
  88. package/build/src/utils/tar.js.map +1 -1
  89. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  90. package/build/src/utils/telemetry/utils/context.js +1 -1
  91. package/build/src/utils/url.js +0 -12
  92. package/build/src/utils/url.js.map +1 -1
  93. package/package.json +22 -22
  94. package/static/loading-page/index.html +10 -2
@@ -23,6 +23,7 @@ function _path() {
23
23
  return data;
24
24
  }
25
25
  const _DevToolsPluginCliExtensionResults = require("./DevToolsPluginCliExtensionResults");
26
+ const _dir = require("../../utils/dir");
26
27
  function _interop_require_default(obj) {
27
28
  return obj && obj.__esModule ? obj : {
28
29
  default: obj
@@ -45,27 +46,50 @@ class DevToolsPluginCliExtensionExecutor {
45
46
  command,
46
47
  args
47
48
  });
48
- return new Promise(async (resolve)=>{
49
- // Set up the command and its arguments
50
- const tool = _path().default.join(this.plugin.packageRoot, this.plugin.cliExtensions.entryPoint);
51
- const child = this.spawnFunc('node', [
52
- tool,
53
- command,
54
- `${JSON.stringify(args)}`,
55
- `${metroServerOrigin}`
56
- ], {
57
- cwd: this.projectRoot,
58
- env: {
59
- ...process.env
60
- }
61
- });
49
+ return new Promise((resolve)=>{
62
50
  let finished = false;
51
+ let timeout;
63
52
  const pluginResults = new _DevToolsPluginCliExtensionResults.DevToolsPluginCliExtensionResults(onOutput);
53
+ // process.execPath instead of 'node' so the child can't be redirected by a PATH shim.
54
+ let child;
55
+ try {
56
+ child = this.spawnFunc(process.execPath, [
57
+ this.resolvedEntryPoint,
58
+ command,
59
+ `${JSON.stringify(args)}`,
60
+ `${metroServerOrigin}`
61
+ ], {
62
+ cwd: this.projectRoot,
63
+ env: {
64
+ ...process.env
65
+ }
66
+ });
67
+ } catch (err) {
68
+ var _err_toString;
69
+ // spawn can throw synchronously; resolve with an error result instead of hanging.
70
+ pluginResults.append((err == null ? void 0 : (_err_toString = err.toString) == null ? void 0 : _err_toString.call(err)) ?? String(err), 'error');
71
+ resolve(pluginResults.getOutput());
72
+ return;
73
+ }
74
+ const finishOnTruncation = ()=>{
75
+ if (pluginResults.isTruncated() && !finished) {
76
+ finished = true;
77
+ if (timeout) clearTimeout(timeout);
78
+ child.kill('SIGKILL');
79
+ resolve(pluginResults.getOutput());
80
+ }
81
+ };
64
82
  // Collect output/error data
65
- child.stdout.on('data', (data)=>pluginResults.append(data.toString()));
66
- child.stderr.on('data', (data)=>pluginResults.append(data.toString(), 'error'));
83
+ child.stdout.on('data', (data)=>{
84
+ pluginResults.append(data.toString());
85
+ finishOnTruncation();
86
+ });
87
+ child.stderr.on('data', (data)=>{
88
+ pluginResults.append(data.toString(), 'error');
89
+ finishOnTruncation();
90
+ });
67
91
  // Setup timeout
68
- const timeout = setTimeout(()=>{
92
+ timeout = setTimeout(()=>{
69
93
  if (!finished) {
70
94
  finished = true;
71
95
  child.kill('SIGKILL');
@@ -75,14 +99,14 @@ class DevToolsPluginCliExtensionExecutor {
75
99
  }, this.timeoutMs);
76
100
  child.on('close', (code)=>{
77
101
  if (finished) return;
78
- clearTimeout(timeout);
102
+ if (timeout) clearTimeout(timeout);
79
103
  finished = true;
80
104
  pluginResults.exit(code);
81
105
  resolve(pluginResults.getOutput());
82
106
  });
83
107
  child.on('error', (err)=>{
84
108
  if (finished) return;
85
- clearTimeout(timeout);
109
+ if (timeout) clearTimeout(timeout);
86
110
  finished = true;
87
111
  pluginResults.append(err.toString(), 'error');
88
112
  resolve(pluginResults.getOutput());
@@ -93,6 +117,12 @@ class DevToolsPluginCliExtensionExecutor {
93
117
  if (!((_this_plugin_cliExtensions = this.plugin.cliExtensions) == null ? void 0 : _this_plugin_cliExtensions.entryPoint)) {
94
118
  throw new Error(`Plugin ${this.plugin.packageName} has no CLI extensions`);
95
119
  }
120
+ // Reject entryPoints that escape packageRoot (e.g. "../../other-pkg/dist/cli.js").
121
+ const resolved = _path().default.resolve(this.plugin.packageRoot, this.plugin.cliExtensions.entryPoint);
122
+ if (!(0, _dir.isPathInside)(resolved, this.plugin.packageRoot)) {
123
+ throw new Error(`Plugin ${this.plugin.packageName} entryPoint "${this.plugin.cliExtensions.entryPoint}" ` + `escapes packageRoot (${this.plugin.packageRoot}); must be a relative path inside the package.`);
124
+ }
125
+ this.resolvedEntryPoint = resolved;
96
126
  }
97
127
  validate({ command, args }) {
98
128
  var _this_plugin_cliExtensions, _commandElement_parameters;
@@ -106,12 +136,17 @@ class DevToolsPluginCliExtensionExecutor {
106
136
  // Quick check to see if the lengths match
107
137
  throw new Error(`Expected ${paramLength} parameter(s), but got ${argsLength} argument(s) for the command "${command}".`);
108
138
  }
109
- const argsKeys = Object.keys(args ?? {});
139
+ const argsObj = args ?? {};
110
140
  for (const param of commandElement.parameters ?? []){
111
- const found = argsKeys.find((key)=>key === param.name);
112
- if (!found) {
141
+ if (!Object.prototype.hasOwnProperty.call(argsObj, param.name)) {
113
142
  throw new Error(`Parameter "${param.name}" not found in command "${command}" of plugin ${this.plugin.packageName}`);
114
143
  }
144
+ // Enforce declared parameter type; don't rely on upstream Zod validation alone.
145
+ const expected = param.type === 'confirm' ? 'boolean' : param.type === 'number' ? 'number' : 'string';
146
+ const actual = typeof argsObj[param.name];
147
+ if (actual !== expected) {
148
+ throw new Error(`Parameter "${param.name}" of "${command}" expected ${expected} (declared "${param.type}"), got ${actual}.`);
149
+ }
115
150
  }
116
151
  }
117
152
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/DevToolsPluginCliExtensionExecutor.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport path from 'path';\n\nimport type {\n DevToolsPluginExecutorArguments,\n DevToolsPluginInfo,\n DevToolsPluginOutput,\n} from './DevToolsPlugin.schema';\nimport { DevToolsPluginCliExtensionResults } from './DevToolsPluginCliExtensionResults';\n\nconst DEFAULT_TIMEOUT_MS = 10_000; // 10 seconds\n\n/**\n * Class that executes CLI Extension commands for a given plugin\n *\n * ## Responsibilities:\n * - Verifies that requested commands exist and have correct parameters\n * - Validates that provided arguments match expected parameter schema\n * - Spawns and manages child processes for command execution\n * - Captures and streams stdout/stderr data from executed commands\n * - Manages process errors, timeouts, and unexpected failures\n * - Enforces execution time limits to prevent hanging processes\n * - Configures proper execution environment with color support\n * - Ensures proper cleanup of processes and timeouts\n * - Provides structured output with exit codes and error states\n */\nexport class DevToolsPluginCliExtensionExecutor {\n constructor(\n private plugin: DevToolsPluginInfo,\n private projectRoot: string,\n private spawnFunc: typeof spawn = spawn, // Used for injection when testing,\n private timeoutMs = DEFAULT_TIMEOUT_MS // Timeout for command execution\n ) {\n // Validate that this is a plugin with cli extensions\n if (!this.plugin.cliExtensions?.entryPoint) {\n throw new Error(`Plugin ${this.plugin.packageName} has no CLI extensions`);\n }\n }\n\n public validate({ command, args }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) {\n const commandElement = this.plugin.cliExtensions?.commands.find((c) => c.name === command);\n if (!commandElement) {\n throw new Error(`Command \"${command}\" not found in plugin ${this.plugin.packageName}`);\n }\n\n const paramLength = commandElement.parameters?.length ?? 0;\n const argsLength = Object.keys(args ?? {}).length;\n if (paramLength !== argsLength) {\n // Quick check to see if the lengths match\n throw new Error(\n `Expected ${paramLength} parameter(s), but got ${argsLength} argument(s) for the command \"${command}\".`\n );\n }\n\n const argsKeys = Object.keys(args ?? {});\n for (const param of commandElement.parameters ?? []) {\n const found = argsKeys.find((key) => key === param.name);\n if (!found) {\n throw new Error(\n `Parameter \"${param.name}\" not found in command \"${command}\" of plugin ${this.plugin.packageName}`\n );\n }\n }\n }\n\n /** this function is used for testing and showing the command in UI */\n public getCommandString = ({\n command,\n args,\n }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) => {\n return `node ${this.plugin.cliExtensions!.entryPoint} ${command}${Object.keys(args ?? {}).length > 0 ? ' ' + JSON.stringify(args) : ''}`;\n };\n\n public execute = async ({\n command,\n args,\n metroServerOrigin,\n onOutput,\n }: DevToolsPluginExecutorArguments): Promise<DevToolsPluginOutput> => {\n this.validate({ command, args });\n return new Promise<DevToolsPluginOutput>(async (resolve) => {\n // Set up the command and its arguments\n const tool = path.join(this.plugin.packageRoot, this.plugin.cliExtensions!.entryPoint);\n const child = this.spawnFunc(\n 'node',\n [tool, command, `${JSON.stringify(args)}`, `${metroServerOrigin}`],\n {\n cwd: this.projectRoot,\n env: { ...process.env },\n }\n );\n\n let finished = false;\n const pluginResults = new DevToolsPluginCliExtensionResults(onOutput);\n\n // Collect output/error data\n child.stdout.on('data', (data) => pluginResults.append(data.toString()));\n child.stderr.on('data', (data) => pluginResults.append(data.toString(), 'error'));\n\n // Setup timeout\n const timeout = setTimeout(() => {\n if (!finished) {\n finished = true;\n child.kill('SIGKILL');\n pluginResults.append('Command timed out', 'error');\n resolve(pluginResults.getOutput());\n }\n }, this.timeoutMs);\n\n child.on('close', (code: number) => {\n if (finished) return;\n clearTimeout(timeout);\n finished = true;\n pluginResults.exit(code);\n resolve(pluginResults.getOutput());\n });\n\n child.on('error', (err: Error) => {\n if (finished) return;\n clearTimeout(timeout);\n finished = true;\n pluginResults.append(err.toString(), 'error');\n resolve(pluginResults.getOutput());\n });\n });\n };\n}\n"],"names":["DevToolsPluginCliExtensionExecutor","DEFAULT_TIMEOUT_MS","plugin","projectRoot","spawnFunc","spawn","timeoutMs","getCommandString","command","args","cliExtensions","entryPoint","Object","keys","length","JSON","stringify","execute","metroServerOrigin","onOutput","validate","Promise","resolve","tool","path","join","packageRoot","child","cwd","env","process","finished","pluginResults","DevToolsPluginCliExtensionResults","stdout","on","data","append","toString","stderr","timeout","setTimeout","kill","getOutput","code","clearTimeout","exit","err","Error","packageName","commandElement","commands","find","c","name","paramLength","parameters","argsLength","argsKeys","param","found","key"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/server/DevToolsPluginCliExtensionExecutor.ts"],"sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from 'child_process';\nimport path from 'path';\n\nimport type {\n DevToolsPluginExecutorArguments,\n DevToolsPluginInfo,\n DevToolsPluginOutput,\n} from './DevToolsPlugin.schema';\nimport { DevToolsPluginCliExtensionResults } from './DevToolsPluginCliExtensionResults';\nimport { isPathInside } from '../../utils/dir';\n\nconst DEFAULT_TIMEOUT_MS = 10_000; // 10 seconds\n\n/**\n * Class that executes CLI Extension commands for a given plugin\n *\n * ## Responsibilities:\n * - Verifies that requested commands exist and have correct parameters\n * - Validates that provided arguments match expected parameter schema\n * - Spawns and manages child processes for command execution\n * - Captures and streams stdout/stderr data from executed commands\n * - Manages process errors, timeouts, and unexpected failures\n * - Enforces execution time limits to prevent hanging processes\n * - Configures proper execution environment with color support\n * - Ensures proper cleanup of processes and timeouts\n * - Provides structured output with exit codes and error states\n */\nexport class DevToolsPluginCliExtensionExecutor {\n private readonly resolvedEntryPoint: string;\n\n constructor(\n private plugin: DevToolsPluginInfo,\n private projectRoot: string,\n private spawnFunc: typeof spawn = spawn, // Used for injection when testing,\n private timeoutMs = DEFAULT_TIMEOUT_MS // Timeout for command execution\n ) {\n // Validate that this is a plugin with cli extensions\n if (!this.plugin.cliExtensions?.entryPoint) {\n throw new Error(`Plugin ${this.plugin.packageName} has no CLI extensions`);\n }\n // Reject entryPoints that escape packageRoot (e.g. \"../../other-pkg/dist/cli.js\").\n const resolved = path.resolve(this.plugin.packageRoot, this.plugin.cliExtensions.entryPoint);\n if (!isPathInside(resolved, this.plugin.packageRoot)) {\n throw new Error(\n `Plugin ${this.plugin.packageName} entryPoint \"${this.plugin.cliExtensions.entryPoint}\" ` +\n `escapes packageRoot (${this.plugin.packageRoot}); must be a relative path inside the package.`\n );\n }\n this.resolvedEntryPoint = resolved;\n }\n\n public validate({ command, args }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) {\n const commandElement = this.plugin.cliExtensions?.commands.find((c) => c.name === command);\n if (!commandElement) {\n throw new Error(`Command \"${command}\" not found in plugin ${this.plugin.packageName}`);\n }\n\n const paramLength = commandElement.parameters?.length ?? 0;\n const argsLength = Object.keys(args ?? {}).length;\n if (paramLength !== argsLength) {\n // Quick check to see if the lengths match\n throw new Error(\n `Expected ${paramLength} parameter(s), but got ${argsLength} argument(s) for the command \"${command}\".`\n );\n }\n\n const argsObj = (args ?? {}) as Record<string, unknown>;\n for (const param of commandElement.parameters ?? []) {\n if (!Object.prototype.hasOwnProperty.call(argsObj, param.name)) {\n throw new Error(\n `Parameter \"${param.name}\" not found in command \"${command}\" of plugin ${this.plugin.packageName}`\n );\n }\n // Enforce declared parameter type; don't rely on upstream Zod validation alone.\n const expected =\n param.type === 'confirm' ? 'boolean' : param.type === 'number' ? 'number' : 'string';\n const actual = typeof argsObj[param.name];\n if (actual !== expected) {\n throw new Error(\n `Parameter \"${param.name}\" of \"${command}\" expected ${expected} (declared \"${param.type}\"), got ${actual}.`\n );\n }\n }\n }\n\n /** this function is used for testing and showing the command in UI */\n public getCommandString = ({\n command,\n args,\n }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) => {\n return `node ${this.plugin.cliExtensions!.entryPoint} ${command}${Object.keys(args ?? {}).length > 0 ? ' ' + JSON.stringify(args) : ''}`;\n };\n\n public execute = async ({\n command,\n args,\n metroServerOrigin,\n onOutput,\n }: DevToolsPluginExecutorArguments): Promise<DevToolsPluginOutput> => {\n this.validate({ command, args });\n return new Promise<DevToolsPluginOutput>((resolve) => {\n let finished = false;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const pluginResults = new DevToolsPluginCliExtensionResults(onOutput);\n\n // process.execPath instead of 'node' so the child can't be redirected by a PATH shim.\n let child: ChildProcessWithoutNullStreams;\n try {\n child = this.spawnFunc(\n process.execPath,\n [this.resolvedEntryPoint, command, `${JSON.stringify(args)}`, `${metroServerOrigin}`],\n {\n cwd: this.projectRoot,\n env: { ...process.env },\n }\n );\n } catch (err: any) {\n // spawn can throw synchronously; resolve with an error result instead of hanging.\n pluginResults.append(err?.toString?.() ?? String(err), 'error');\n resolve(pluginResults.getOutput());\n return;\n }\n\n const finishOnTruncation = () => {\n if (pluginResults.isTruncated() && !finished) {\n finished = true;\n if (timeout) clearTimeout(timeout);\n child.kill('SIGKILL');\n resolve(pluginResults.getOutput());\n }\n };\n\n // Collect output/error data\n child.stdout.on('data', (data) => {\n pluginResults.append(data.toString());\n finishOnTruncation();\n });\n child.stderr.on('data', (data) => {\n pluginResults.append(data.toString(), 'error');\n finishOnTruncation();\n });\n\n // Setup timeout\n timeout = setTimeout(() => {\n if (!finished) {\n finished = true;\n child.kill('SIGKILL');\n pluginResults.append('Command timed out', 'error');\n resolve(pluginResults.getOutput());\n }\n }, this.timeoutMs);\n\n child.on('close', (code: number) => {\n if (finished) return;\n if (timeout) clearTimeout(timeout);\n finished = true;\n pluginResults.exit(code);\n resolve(pluginResults.getOutput());\n });\n\n child.on('error', (err: Error) => {\n if (finished) return;\n if (timeout) clearTimeout(timeout);\n finished = true;\n pluginResults.append(err.toString(), 'error');\n resolve(pluginResults.getOutput());\n });\n });\n };\n}\n"],"names":["DevToolsPluginCliExtensionExecutor","DEFAULT_TIMEOUT_MS","plugin","projectRoot","spawnFunc","spawn","timeoutMs","getCommandString","command","args","cliExtensions","entryPoint","Object","keys","length","JSON","stringify","execute","metroServerOrigin","onOutput","validate","Promise","resolve","finished","timeout","pluginResults","DevToolsPluginCliExtensionResults","child","process","execPath","resolvedEntryPoint","cwd","env","err","append","toString","String","getOutput","finishOnTruncation","isTruncated","clearTimeout","kill","stdout","on","data","stderr","setTimeout","code","exit","Error","packageName","resolved","path","packageRoot","isPathInside","commandElement","commands","find","c","name","paramLength","parameters","argsLength","argsObj","param","prototype","hasOwnProperty","call","expected","type","actual"],"mappings":"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"}
@@ -8,17 +8,46 @@ Object.defineProperty(exports, "DevToolsPluginCliExtensionResults", {
8
8
  return DevToolsPluginCliExtensionResults;
9
9
  }
10
10
  });
11
+ function _nodebuffer() {
12
+ const data = require("node:buffer");
13
+ _nodebuffer = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
11
18
  const _DevToolsPluginschema = require("./DevToolsPlugin.schema");
19
+ // Cap accumulated output at V8's max single-string length to bound heap growth.
20
+ const MAX_OUTPUT_LENGTH = _nodebuffer().constants.MAX_STRING_LENGTH;
12
21
  class DevToolsPluginCliExtensionResults {
13
22
  constructor(onOutput){
14
23
  this.onOutput = onOutput;
15
24
  this._output = [];
25
+ this._totalLength = 0;
26
+ this._truncated = false;
16
27
  }
17
28
  append(output, level = 'info') {
29
+ if (this._truncated) return;
30
+ if (this._totalLength + output.length > MAX_OUTPUT_LENGTH) {
31
+ this._truncated = true;
32
+ const message = {
33
+ type: 'text',
34
+ text: `Output truncated: plugin exceeded V8's max string length (${MAX_OUTPUT_LENGTH} chars). Reduce output, paginate, or write to a file.`,
35
+ level: 'error'
36
+ };
37
+ this._output.push(message);
38
+ this.onOutput == null ? void 0 : this.onOutput.call(this, [
39
+ message
40
+ ]);
41
+ return;
42
+ }
43
+ this._totalLength += output.length;
18
44
  const results = this.parseOutputText(output, level);
19
45
  this._output.push(...results);
20
46
  this.onOutput == null ? void 0 : this.onOutput.call(this, results);
21
47
  }
48
+ isTruncated() {
49
+ return this._truncated;
50
+ }
22
51
  exit(code) {
23
52
  if (code === 0) return;
24
53
  this.append(`Process exited with code ${code}`, 'error');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/DevToolsPluginCliExtensionResults.ts"],"sourcesContent":["import type { DevToolsPluginOutput } from './DevToolsPlugin.schema';\nimport { DevToolsPluginOutputSchema } from './DevToolsPlugin.schema';\n\n/**\n * Class that collects and manages output from executed plugin commands\n *\n * Responsibilities:\n * - Collects output data from executed commands\n * - Parses and validates output data against expected schema\n * - Provides methods to append new output entries\n * - Handles exit codes and appends relevant messages\n * - Handles streaming of output via optional callback\n */\nexport class DevToolsPluginCliExtensionResults {\n constructor(private onOutput?: (output: DevToolsPluginOutput) => void) {}\n\n private _output: DevToolsPluginOutput = [];\n\n public append(output: string, level: 'info' | 'warning' | 'error' = 'info') {\n const results = this.parseOutputText(output, level);\n this._output.push(...results);\n this.onOutput?.(results);\n }\n\n public exit(code: number) {\n if (code === 0) return;\n this.append(`Process exited with code ${code}`, 'error');\n }\n\n public getOutput(): DevToolsPluginOutput {\n return this._output;\n }\n\n private parseOutputText(\n txt: string,\n level: 'info' | 'warning' | 'error' = 'info'\n ): DevToolsPluginOutput {\n // Validate against schema\n try {\n const result = DevToolsPluginOutputSchema.safeParse(JSON.parse(txt));\n if (!result.success) {\n return [\n {\n type: 'text',\n text: `Invalid JSON: ${result.error.issues.map((issue) => issue.message).join(', ')}`,\n level: 'error',\n },\n ];\n }\n return result.data;\n } catch {\n // Not JSON, treat as plain text\n const lines = txt.split('\\n');\n const results: DevToolsPluginOutput = [];\n for (const line of lines) {\n if (line) {\n results.push({ type: 'text', text: line, level });\n }\n }\n return results;\n }\n }\n}\n"],"names":["DevToolsPluginCliExtensionResults","onOutput","_output","append","output","level","results","parseOutputText","push","exit","code","getOutput","txt","result","DevToolsPluginOutputSchema","safeParse","JSON","parse","success","type","text","error","issues","map","issue","message","join","data","lines","split","line"],"mappings":";;;;+BAaaA;;;eAAAA;;;sCAZ8B;AAYpC,MAAMA;IACX,YAAY,AAAQC,QAAiD,CAAE;aAAnDA,WAAAA;aAEZC,UAAgC,EAAE;IAF8B;IAIjEC,OAAOC,MAAc,EAAEC,QAAsC,MAAM,EAAE;QAC1E,MAAMC,UAAU,IAAI,CAACC,eAAe,CAACH,QAAQC;QAC7C,IAAI,CAACH,OAAO,CAACM,IAAI,IAAIF;QACrB,IAAI,CAACL,QAAQ,oBAAb,IAAI,CAACA,QAAQ,MAAb,IAAI,EAAYK;IAClB;IAEOG,KAAKC,IAAY,EAAE;QACxB,IAAIA,SAAS,GAAG;QAChB,IAAI,CAACP,MAAM,CAAC,CAAC,yBAAyB,EAAEO,MAAM,EAAE;IAClD;IAEOC,YAAkC;QACvC,OAAO,IAAI,CAACT,OAAO;IACrB;IAEQK,gBACNK,GAAW,EACXP,QAAsC,MAAM,EACtB;QACtB,0BAA0B;QAC1B,IAAI;YACF,MAAMQ,SAASC,gDAA0B,CAACC,SAAS,CAACC,KAAKC,KAAK,CAACL;YAC/D,IAAI,CAACC,OAAOK,OAAO,EAAE;gBACnB,OAAO;oBACL;wBACEC,MAAM;wBACNC,MAAM,CAAC,cAAc,EAAEP,OAAOQ,KAAK,CAACC,MAAM,CAACC,GAAG,CAAC,CAACC,QAAUA,MAAMC,OAAO,EAAEC,IAAI,CAAC,OAAO;wBACrFrB,OAAO;oBACT;iBACD;YACH;YACA,OAAOQ,OAAOc,IAAI;QACpB,EAAE,OAAM;YACN,gCAAgC;YAChC,MAAMC,QAAQhB,IAAIiB,KAAK,CAAC;YACxB,MAAMvB,UAAgC,EAAE;YACxC,KAAK,MAAMwB,QAAQF,MAAO;gBACxB,IAAIE,MAAM;oBACRxB,QAAQE,IAAI,CAAC;wBAAEW,MAAM;wBAAQC,MAAMU;wBAAMzB;oBAAM;gBACjD;YACF;YACA,OAAOC;QACT;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/start/server/DevToolsPluginCliExtensionResults.ts"],"sourcesContent":["import { constants as bufferConstants } from 'node:buffer';\n\nimport type { DevToolsPluginOutput } from './DevToolsPlugin.schema';\nimport { DevToolsPluginOutputSchema } from './DevToolsPlugin.schema';\n\n// Cap accumulated output at V8's max single-string length to bound heap growth.\nconst MAX_OUTPUT_LENGTH = bufferConstants.MAX_STRING_LENGTH;\n\n/**\n * Class that collects and manages output from executed plugin commands\n *\n * Responsibilities:\n * - Collects output data from executed commands\n * - Parses and validates output data against expected schema\n * - Provides methods to append new output entries\n * - Handles exit codes and appends relevant messages\n * - Handles streaming of output via optional callback\n */\nexport class DevToolsPluginCliExtensionResults {\n constructor(private onOutput?: (output: DevToolsPluginOutput) => void) {}\n\n private _output: DevToolsPluginOutput = [];\n private _totalLength = 0;\n private _truncated = false;\n\n public append(output: string, level: 'info' | 'warning' | 'error' = 'info') {\n if (this._truncated) return;\n if (this._totalLength + output.length > MAX_OUTPUT_LENGTH) {\n this._truncated = true;\n const message = {\n type: 'text' as const,\n text: `Output truncated: plugin exceeded V8's max string length (${MAX_OUTPUT_LENGTH} chars). Reduce output, paginate, or write to a file.`,\n level: 'error' as const,\n };\n this._output.push(message);\n this.onOutput?.([message]);\n return;\n }\n this._totalLength += output.length;\n const results = this.parseOutputText(output, level);\n this._output.push(...results);\n this.onOutput?.(results);\n }\n\n public isTruncated(): boolean {\n return this._truncated;\n }\n\n public exit(code: number) {\n if (code === 0) return;\n this.append(`Process exited with code ${code}`, 'error');\n }\n\n public getOutput(): DevToolsPluginOutput {\n return this._output;\n }\n\n private parseOutputText(\n txt: string,\n level: 'info' | 'warning' | 'error' = 'info'\n ): DevToolsPluginOutput {\n // Validate against schema\n try {\n const result = DevToolsPluginOutputSchema.safeParse(JSON.parse(txt));\n if (!result.success) {\n return [\n {\n type: 'text',\n text: `Invalid JSON: ${result.error.issues.map((issue) => issue.message).join(', ')}`,\n level: 'error',\n },\n ];\n }\n return result.data;\n } catch {\n // Not JSON, treat as plain text\n const lines = txt.split('\\n');\n const results: DevToolsPluginOutput = [];\n for (const line of lines) {\n if (line) {\n results.push({ type: 'text', text: line, level });\n }\n }\n return results;\n }\n }\n}\n"],"names":["DevToolsPluginCliExtensionResults","MAX_OUTPUT_LENGTH","bufferConstants","MAX_STRING_LENGTH","onOutput","_output","_totalLength","_truncated","append","output","level","length","message","type","text","push","results","parseOutputText","isTruncated","exit","code","getOutput","txt","result","DevToolsPluginOutputSchema","safeParse","JSON","parse","success","error","issues","map","issue","join","data","lines","split","line"],"mappings":";;;;+BAkBaA;;;eAAAA;;;;yBAlBgC;;;;;;sCAGF;AAE3C,gFAAgF;AAChF,MAAMC,oBAAoBC,uBAAe,CAACC,iBAAiB;AAYpD,MAAMH;IACX,YAAY,AAAQI,QAAiD,CAAE;aAAnDA,WAAAA;aAEZC,UAAgC,EAAE;aAClCC,eAAe;aACfC,aAAa;IAJmD;IAMjEC,OAAOC,MAAc,EAAEC,QAAsC,MAAM,EAAE;QAC1E,IAAI,IAAI,CAACH,UAAU,EAAE;QACrB,IAAI,IAAI,CAACD,YAAY,GAAGG,OAAOE,MAAM,GAAGV,mBAAmB;YACzD,IAAI,CAACM,UAAU,GAAG;YAClB,MAAMK,UAAU;gBACdC,MAAM;gBACNC,MAAM,CAAC,0DAA0D,EAAEb,kBAAkB,qDAAqD,CAAC;gBAC3IS,OAAO;YACT;YACA,IAAI,CAACL,OAAO,CAACU,IAAI,CAACH;YAClB,IAAI,CAACR,QAAQ,oBAAb,IAAI,CAACA,QAAQ,MAAb,IAAI,EAAY;gBAACQ;aAAQ;YACzB;QACF;QACA,IAAI,CAACN,YAAY,IAAIG,OAAOE,MAAM;QAClC,MAAMK,UAAU,IAAI,CAACC,eAAe,CAACR,QAAQC;QAC7C,IAAI,CAACL,OAAO,CAACU,IAAI,IAAIC;QACrB,IAAI,CAACZ,QAAQ,oBAAb,IAAI,CAACA,QAAQ,MAAb,IAAI,EAAYY;IAClB;IAEOE,cAAuB;QAC5B,OAAO,IAAI,CAACX,UAAU;IACxB;IAEOY,KAAKC,IAAY,EAAE;QACxB,IAAIA,SAAS,GAAG;QAChB,IAAI,CAACZ,MAAM,CAAC,CAAC,yBAAyB,EAAEY,MAAM,EAAE;IAClD;IAEOC,YAAkC;QACvC,OAAO,IAAI,CAAChB,OAAO;IACrB;IAEQY,gBACNK,GAAW,EACXZ,QAAsC,MAAM,EACtB;QACtB,0BAA0B;QAC1B,IAAI;YACF,MAAMa,SAASC,gDAA0B,CAACC,SAAS,CAACC,KAAKC,KAAK,CAACL;YAC/D,IAAI,CAACC,OAAOK,OAAO,EAAE;gBACnB,OAAO;oBACL;wBACEf,MAAM;wBACNC,MAAM,CAAC,cAAc,EAAES,OAAOM,KAAK,CAACC,MAAM,CAACC,GAAG,CAAC,CAACC,QAAUA,MAAMpB,OAAO,EAAEqB,IAAI,CAAC,OAAO;wBACrFvB,OAAO;oBACT;iBACD;YACH;YACA,OAAOa,OAAOW,IAAI;QACpB,EAAE,OAAM;YACN,gCAAgC;YAChC,MAAMC,QAAQb,IAAIc,KAAK,CAAC;YACxB,MAAMpB,UAAgC,EAAE;YACxC,KAAK,MAAMqB,QAAQF,MAAO;gBACxB,IAAIE,MAAM;oBACRrB,QAAQD,IAAI,CAAC;wBAAEF,MAAM;wBAAQC,MAAMuB;wBAAM3B;oBAAM;gBACjD;YACF;YACA,OAAOM;QACT;IACF;AACF"}
@@ -17,15 +17,25 @@ async function addMcpCapabilities(mcpServer, devServerManager) {
17
17
  const plugins = await devServerManager.devtoolsPluginManager.queryPluginsAsync();
18
18
  for (const plugin of plugins){
19
19
  if (plugin.cliExtensions) {
20
- const commands = (plugin.cliExtensions.commands ?? []).filter((p)=>{
20
+ const mcpCommands = (plugin.cliExtensions.commands ?? []).filter((p)=>{
21
21
  var _p_environments;
22
22
  return (_p_environments = p.environments) == null ? void 0 : _p_environments.includes('mcp');
23
23
  });
24
- if (commands.length === 0) {
24
+ if (mcpCommands.length === 0) {
25
25
  continue;
26
26
  }
27
- const schema = (0, _createMCPDevToolsExtensionSchema.createMCPDevToolsExtensionSchema)(plugin);
28
- debug(`Installing MCP CLI extension for plugin: ${plugin.packageName} - found ${commands.length} commands`);
27
+ // Build an MCP-scoped descriptor so the schema enum and the executor's
28
+ // existence check both reject commands that were not declared MCP-enabled.
29
+ const mcpPlugin = {
30
+ packageName: plugin.packageName,
31
+ packageRoot: plugin.packageRoot,
32
+ cliExtensions: {
33
+ ...plugin.cliExtensions,
34
+ commands: mcpCommands
35
+ }
36
+ };
37
+ const schema = (0, _createMCPDevToolsExtensionSchema.createMCPDevToolsExtensionSchema)(mcpPlugin);
38
+ debug(`Installing MCP CLI extension for plugin: ${plugin.packageName} - found ${mcpCommands.length} commands`);
29
39
  mcpServer.registerTool(plugin.packageName, {
30
40
  title: plugin.packageName,
31
41
  description: plugin.description,
@@ -36,7 +46,7 @@ async function addMcpCapabilities(mcpServer, devServerManager) {
36
46
  try {
37
47
  const { command, ...args } = parameters;
38
48
  const metroServerOrigin = devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();
39
- const results = await new _DevToolsPluginCliExtensionExecutor.DevToolsPluginCliExtensionExecutor(plugin, devServerManager.projectRoot).execute({
49
+ const results = await new _DevToolsPluginCliExtensionExecutor.DevToolsPluginCliExtensionExecutor(mcpPlugin, devServerManager.projectRoot).execute({
40
50
  command,
41
51
  args,
42
52
  metroServerOrigin
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/MCPDevToolsPluginCLIExtensions.ts"],"sourcesContent":["import type { DevServerManager } from './DevServerManager';\nimport { DevToolsPluginOutputSchema } from './DevToolsPlugin.schema';\nimport { DevToolsPluginCliExtensionExecutor } from './DevToolsPluginCliExtensionExecutor';\nimport type { McpServer } from './MCP';\nimport { createMCPDevToolsExtensionSchema } from './createMCPDevToolsExtensionSchema';\nimport { Log } from '../../log';\n\nconst debug = require('debug')('expo:start:server:devtools:mcp');\n\nexport async function addMcpCapabilities(mcpServer: McpServer, devServerManager: DevServerManager) {\n const plugins = await devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n for (const plugin of plugins) {\n if (plugin.cliExtensions) {\n const commands = (plugin.cliExtensions.commands ?? []).filter((p) =>\n p.environments?.includes('mcp')\n );\n if (commands.length === 0) {\n continue;\n }\n\n const schema = createMCPDevToolsExtensionSchema(plugin);\n\n debug(\n `Installing MCP CLI extension for plugin: ${plugin.packageName} - found ${commands.length} commands`\n );\n\n mcpServer.registerTool(\n plugin.packageName,\n {\n title: plugin.packageName,\n description: plugin.description,\n inputSchema: { parameters: schema },\n },\n async ({ parameters }) => {\n try {\n const { command, ...args } = parameters;\n\n const metroServerOrigin = devServerManager\n .getDefaultDevServer()\n .getJsInspectorBaseUrl();\n\n const results = await new DevToolsPluginCliExtensionExecutor(\n plugin,\n devServerManager.projectRoot\n ).execute({ command, args, metroServerOrigin });\n\n const parsedResults = DevToolsPluginOutputSchema.safeParse(results);\n if (parsedResults.success === false) {\n throw new Error(\n `Invalid output from CLI command: ${parsedResults.error.issues\n .map((issue) => issue.message)\n .join(', ')}`\n );\n }\n return {\n content: parsedResults.data\n .map((line) => {\n const { type } = line;\n if (type === 'text') {\n return { type, text: line.text, level: line.level, url: line.url };\n } else if (line.type === 'image' || line.type === 'audio') {\n // We could present this as a resource_link, but it seems not to be well supported in MCP clients,\n // so we'll return a text with the link instead.\n return {\n type: 'text',\n text: `${type} resource: ${line.url}${line.text ? ' (' + line.text + ')' : ''}`,\n } as const;\n }\n return null;\n })\n .filter((line): line is Exclude<typeof line, null> => line !== null),\n };\n } catch (e: any) {\n Log.error('Error executing MCP CLI command:', e);\n return {\n content: [{ type: 'text', text: `Error executing command: ${e.toString()}` }],\n isError: true,\n };\n }\n }\n );\n }\n }\n}\n"],"names":["addMcpCapabilities","debug","require","mcpServer","devServerManager","plugins","devtoolsPluginManager","queryPluginsAsync","plugin","cliExtensions","commands","filter","p","environments","includes","length","schema","createMCPDevToolsExtensionSchema","packageName","registerTool","title","description","inputSchema","parameters","command","args","metroServerOrigin","getDefaultDevServer","getJsInspectorBaseUrl","results","DevToolsPluginCliExtensionExecutor","projectRoot","execute","parsedResults","DevToolsPluginOutputSchema","safeParse","success","Error","error","issues","map","issue","message","join","content","data","line","type","text","level","url","e","Log","toString","isError"],"mappings":";;;;+BASsBA;;;eAAAA;;;sCARqB;oDACQ;kDAEF;qBAC7B;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,eAAeF,mBAAmBG,SAAoB,EAAEC,gBAAkC;IAC/F,MAAMC,UAAU,MAAMD,iBAAiBE,qBAAqB,CAACC,iBAAiB;IAE9E,KAAK,MAAMC,UAAUH,QAAS;QAC5B,IAAIG,OAAOC,aAAa,EAAE;YACxB,MAAMC,WAAW,AAACF,CAAAA,OAAOC,aAAa,CAACC,QAAQ,IAAI,EAAE,AAAD,EAAGC,MAAM,CAAC,CAACC;oBAC7DA;wBAAAA,kBAAAA,EAAEC,YAAY,qBAAdD,gBAAgBE,QAAQ,CAAC;;YAE3B,IAAIJ,SAASK,MAAM,KAAK,GAAG;gBACzB;YACF;YAEA,MAAMC,SAASC,IAAAA,kEAAgC,EAACT;YAEhDP,MACE,CAAC,yCAAyC,EAAEO,OAAOU,WAAW,CAAC,SAAS,EAAER,SAASK,MAAM,CAAC,SAAS,CAAC;YAGtGZ,UAAUgB,YAAY,CACpBX,OAAOU,WAAW,EAClB;gBACEE,OAAOZ,OAAOU,WAAW;gBACzBG,aAAab,OAAOa,WAAW;gBAC/BC,aAAa;oBAAEC,YAAYP;gBAAO;YACpC,GACA,OAAO,EAAEO,UAAU,EAAE;gBACnB,IAAI;oBACF,MAAM,EAAEC,OAAO,EAAE,GAAGC,MAAM,GAAGF;oBAE7B,MAAMG,oBAAoBtB,iBACvBuB,mBAAmB,GACnBC,qBAAqB;oBAExB,MAAMC,UAAU,MAAM,IAAIC,sEAAkC,CAC1DtB,QACAJ,iBAAiB2B,WAAW,EAC5BC,OAAO,CAAC;wBAAER;wBAASC;wBAAMC;oBAAkB;oBAE7C,MAAMO,gBAAgBC,gDAA0B,CAACC,SAAS,CAACN;oBAC3D,IAAII,cAAcG,OAAO,KAAK,OAAO;wBACnC,MAAM,IAAIC,MACR,CAAC,iCAAiC,EAAEJ,cAAcK,KAAK,CAACC,MAAM,CAC3DC,GAAG,CAAC,CAACC,QAAUA,MAAMC,OAAO,EAC5BC,IAAI,CAAC,OAAO;oBAEnB;oBACA,OAAO;wBACLC,SAASX,cAAcY,IAAI,CACxBL,GAAG,CAAC,CAACM;4BACJ,MAAM,EAAEC,IAAI,EAAE,GAAGD;4BACjB,IAAIC,SAAS,QAAQ;gCACnB,OAAO;oCAAEA;oCAAMC,MAAMF,KAAKE,IAAI;oCAAEC,OAAOH,KAAKG,KAAK;oCAAEC,KAAKJ,KAAKI,GAAG;gCAAC;4BACnE,OAAO,IAAIJ,KAAKC,IAAI,KAAK,WAAWD,KAAKC,IAAI,KAAK,SAAS;gCACzD,kGAAkG;gCAClG,gDAAgD;gCAChD,OAAO;oCACLA,MAAM;oCACNC,MAAM,GAAGD,KAAK,WAAW,EAAED,KAAKI,GAAG,GAAGJ,KAAKE,IAAI,GAAG,OAAOF,KAAKE,IAAI,GAAG,MAAM,IAAI;gCACjF;4BACF;4BACA,OAAO;wBACT,GACCrC,MAAM,CAAC,CAACmC,OAA6CA,SAAS;oBACnE;gBACF,EAAE,OAAOK,GAAQ;oBACfC,QAAG,CAACd,KAAK,CAAC,oCAAoCa;oBAC9C,OAAO;wBACLP,SAAS;4BAAC;gCAAEG,MAAM;gCAAQC,MAAM,CAAC,yBAAyB,EAAEG,EAAEE,QAAQ,IAAI;4BAAC;yBAAE;wBAC7EC,SAAS;oBACX;gBACF;YACF;QAEJ;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/start/server/MCPDevToolsPluginCLIExtensions.ts"],"sourcesContent":["import type { DevServerManager } from './DevServerManager';\nimport type { DevToolsPluginInfo } from './DevToolsPlugin.schema';\nimport { DevToolsPluginOutputSchema } from './DevToolsPlugin.schema';\nimport { DevToolsPluginCliExtensionExecutor } from './DevToolsPluginCliExtensionExecutor';\nimport type { McpServer } from './MCP';\nimport { createMCPDevToolsExtensionSchema } from './createMCPDevToolsExtensionSchema';\nimport { Log } from '../../log';\n\nconst debug = require('debug')('expo:start:server:devtools:mcp');\n\nexport async function addMcpCapabilities(mcpServer: McpServer, devServerManager: DevServerManager) {\n const plugins = await devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n for (const plugin of plugins) {\n if (plugin.cliExtensions) {\n const mcpCommands = (plugin.cliExtensions.commands ?? []).filter((p) =>\n p.environments?.includes('mcp')\n );\n if (mcpCommands.length === 0) {\n continue;\n }\n\n // Build an MCP-scoped descriptor so the schema enum and the executor's\n // existence check both reject commands that were not declared MCP-enabled.\n const mcpPlugin: DevToolsPluginInfo = {\n packageName: plugin.packageName,\n packageRoot: plugin.packageRoot,\n cliExtensions: {\n ...plugin.cliExtensions,\n commands: mcpCommands,\n },\n };\n\n const schema = createMCPDevToolsExtensionSchema(mcpPlugin);\n\n debug(\n `Installing MCP CLI extension for plugin: ${plugin.packageName} - found ${mcpCommands.length} commands`\n );\n\n mcpServer.registerTool(\n plugin.packageName,\n {\n title: plugin.packageName,\n description: plugin.description,\n inputSchema: { parameters: schema },\n },\n async ({ parameters }) => {\n try {\n const { command, ...args } = parameters;\n\n const metroServerOrigin = devServerManager\n .getDefaultDevServer()\n .getJsInspectorBaseUrl();\n\n const results = await new DevToolsPluginCliExtensionExecutor(\n mcpPlugin,\n devServerManager.projectRoot\n ).execute({ command, args, metroServerOrigin });\n\n const parsedResults = DevToolsPluginOutputSchema.safeParse(results);\n if (parsedResults.success === false) {\n throw new Error(\n `Invalid output from CLI command: ${parsedResults.error.issues\n .map((issue) => issue.message)\n .join(', ')}`\n );\n }\n return {\n content: parsedResults.data\n .map((line) => {\n const { type } = line;\n if (type === 'text') {\n return { type, text: line.text, level: line.level, url: line.url };\n } else if (line.type === 'image' || line.type === 'audio') {\n // We could present this as a resource_link, but it seems not to be well supported in MCP clients,\n // so we'll return a text with the link instead.\n return {\n type: 'text',\n text: `${type} resource: ${line.url}${line.text ? ' (' + line.text + ')' : ''}`,\n } as const;\n }\n return null;\n })\n .filter((line): line is Exclude<typeof line, null> => line !== null),\n };\n } catch (e: any) {\n Log.error('Error executing MCP CLI command:', e);\n return {\n content: [{ type: 'text', text: `Error executing command: ${e.toString()}` }],\n isError: true,\n };\n }\n }\n );\n }\n }\n}\n"],"names":["addMcpCapabilities","debug","require","mcpServer","devServerManager","plugins","devtoolsPluginManager","queryPluginsAsync","plugin","cliExtensions","mcpCommands","commands","filter","p","environments","includes","length","mcpPlugin","packageName","packageRoot","schema","createMCPDevToolsExtensionSchema","registerTool","title","description","inputSchema","parameters","command","args","metroServerOrigin","getDefaultDevServer","getJsInspectorBaseUrl","results","DevToolsPluginCliExtensionExecutor","projectRoot","execute","parsedResults","DevToolsPluginOutputSchema","safeParse","success","Error","error","issues","map","issue","message","join","content","data","line","type","text","level","url","e","Log","toString","isError"],"mappings":";;;;+BAUsBA;;;eAAAA;;;sCARqB;oDACQ;kDAEF;qBAC7B;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,eAAeF,mBAAmBG,SAAoB,EAAEC,gBAAkC;IAC/F,MAAMC,UAAU,MAAMD,iBAAiBE,qBAAqB,CAACC,iBAAiB;IAE9E,KAAK,MAAMC,UAAUH,QAAS;QAC5B,IAAIG,OAAOC,aAAa,EAAE;YACxB,MAAMC,cAAc,AAACF,CAAAA,OAAOC,aAAa,CAACE,QAAQ,IAAI,EAAE,AAAD,EAAGC,MAAM,CAAC,CAACC;oBAChEA;wBAAAA,kBAAAA,EAAEC,YAAY,qBAAdD,gBAAgBE,QAAQ,CAAC;;YAE3B,IAAIL,YAAYM,MAAM,KAAK,GAAG;gBAC5B;YACF;YAEA,uEAAuE;YACvE,2EAA2E;YAC3E,MAAMC,YAAgC;gBACpCC,aAAaV,OAAOU,WAAW;gBAC/BC,aAAaX,OAAOW,WAAW;gBAC/BV,eAAe;oBACb,GAAGD,OAAOC,aAAa;oBACvBE,UAAUD;gBACZ;YACF;YAEA,MAAMU,SAASC,IAAAA,kEAAgC,EAACJ;YAEhDhB,MACE,CAAC,yCAAyC,EAAEO,OAAOU,WAAW,CAAC,SAAS,EAAER,YAAYM,MAAM,CAAC,SAAS,CAAC;YAGzGb,UAAUmB,YAAY,CACpBd,OAAOU,WAAW,EAClB;gBACEK,OAAOf,OAAOU,WAAW;gBACzBM,aAAahB,OAAOgB,WAAW;gBAC/BC,aAAa;oBAAEC,YAAYN;gBAAO;YACpC,GACA,OAAO,EAAEM,UAAU,EAAE;gBACnB,IAAI;oBACF,MAAM,EAAEC,OAAO,EAAE,GAAGC,MAAM,GAAGF;oBAE7B,MAAMG,oBAAoBzB,iBACvB0B,mBAAmB,GACnBC,qBAAqB;oBAExB,MAAMC,UAAU,MAAM,IAAIC,sEAAkC,CAC1DhB,WACAb,iBAAiB8B,WAAW,EAC5BC,OAAO,CAAC;wBAAER;wBAASC;wBAAMC;oBAAkB;oBAE7C,MAAMO,gBAAgBC,gDAA0B,CAACC,SAAS,CAACN;oBAC3D,IAAII,cAAcG,OAAO,KAAK,OAAO;wBACnC,MAAM,IAAIC,MACR,CAAC,iCAAiC,EAAEJ,cAAcK,KAAK,CAACC,MAAM,CAC3DC,GAAG,CAAC,CAACC,QAAUA,MAAMC,OAAO,EAC5BC,IAAI,CAAC,OAAO;oBAEnB;oBACA,OAAO;wBACLC,SAASX,cAAcY,IAAI,CACxBL,GAAG,CAAC,CAACM;4BACJ,MAAM,EAAEC,IAAI,EAAE,GAAGD;4BACjB,IAAIC,SAAS,QAAQ;gCACnB,OAAO;oCAAEA;oCAAMC,MAAMF,KAAKE,IAAI;oCAAEC,OAAOH,KAAKG,KAAK;oCAAEC,KAAKJ,KAAKI,GAAG;gCAAC;4BACnE,OAAO,IAAIJ,KAAKC,IAAI,KAAK,WAAWD,KAAKC,IAAI,KAAK,SAAS;gCACzD,kGAAkG;gCAClG,gDAAgD;gCAChD,OAAO;oCACLA,MAAM;oCACNC,MAAM,GAAGD,KAAK,WAAW,EAAED,KAAKI,GAAG,GAAGJ,KAAKE,IAAI,GAAG,OAAOF,KAAKE,IAAI,GAAG,MAAM,IAAI;gCACjF;4BACF;4BACA,OAAO;wBACT,GACCvC,MAAM,CAAC,CAACqC,OAA6CA,SAAS;oBACnE;gBACF,EAAE,OAAOK,GAAQ;oBACfC,QAAG,CAACd,KAAK,CAAC,oCAAoCa;oBAC9C,OAAO;wBACLP,SAAS;4BAAC;gCAAEG,MAAM;gCAAQC,MAAM,CAAC,yBAAyB,EAAEG,EAAEE,QAAQ,IAAI;4BAAC;yBAAE;wBAC7EC,SAAS;oBACX;gBACF;YACF;QAEJ;IACF;AACF"}
@@ -8,6 +8,13 @@ Object.defineProperty(exports, "UrlCreator", {
8
8
  return UrlCreator;
9
9
  }
10
10
  });
11
+ function _env() {
12
+ const data = require("@expo/env");
13
+ _env = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
11
18
  function _assert() {
12
19
  const data = /*#__PURE__*/ _interop_require_default(require("assert"));
13
20
  _assert = function() {
@@ -136,6 +143,10 @@ class UrlCreator {
136
143
  getDefaultRouteAddress() {
137
144
  return this.gatewayInfo.address;
138
145
  }
146
+ /** URL scheme configured for development-build deep links (e.g. `myapp`). `null` when unset. */ getScheme() {
147
+ var _this_defaults;
148
+ return ((_this_defaults = this.defaults) == null ? void 0 : _this_defaults.scheme) ?? null;
149
+ }
139
150
  /** Get the URL components from the Ngrok server URL. */ getTunnelUrlComponents(options) {
140
151
  const tunnelUrl = this.bundlerInfo.getTunnelUrl == null ? void 0 : this.bundlerInfo.getTunnelUrl.call(this.bundlerInfo);
141
152
  if (!tunnelUrl) {
@@ -211,7 +222,9 @@ function joinUrlComponents({ protocol, hostname, port }) {
211
222
  return url;
212
223
  }
213
224
  /** @deprecated */ function getProxyUrl() {
214
- return process.env.EXPO_PACKAGER_PROXY_URL;
225
+ // Read from the pre-dotenv env — overriding this would redirect connected dev
226
+ // clients through an attacker-controlled URL.
227
+ return (0, _env().getOriginalEnvValue)('EXPO_PACKAGER_PROXY_URL');
215
228
  } // TODO: Drop the undocumented env variables:
216
229
  // REACT_NATIVE_PACKAGER_HOSTNAME
217
230
  // EXPO_PACKAGER_PROXY_URL
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/UrlCreator.ts"],"sourcesContent":["import assert from 'assert';\nimport { URL } from 'url';\n\nimport * as Log from '../../log';\nimport type { GatewayInfo } from '../../utils/ip';\nimport { getGateway, getGatewayAsync } from '../../utils/ip';\n\nconst debug = require('debug')('expo:start:server:urlCreator') as typeof console.log;\n\nexport interface CreateURLOptions {\n /** URL scheme to use when opening apps in custom runtimes. */\n scheme?: string | null;\n /** Type of dev server host to use. */\n hostType?: 'localhost' | 'lan' | 'tunnel';\n /** Requested hostname. */\n hostname?: string | null;\n}\n\ninterface UrlComponents {\n port: string;\n hostname: string;\n protocol: string;\n}\n\ninterface BundlerInfo {\n port: number;\n getTunnelUrl?(): string | null;\n}\n\nexport class UrlCreator {\n constructor(\n public defaults: CreateURLOptions,\n private bundlerInfo: BundlerInfo,\n private gatewayInfo: GatewayInfo = getGateway()\n ) {}\n\n static async init(defaults: CreateURLOptions | undefined | null, bundlerInfo: BundlerInfo) {\n const gatewayInfo = await getGatewayAsync();\n return new UrlCreator(defaults || {}, bundlerInfo, gatewayInfo);\n }\n\n /**\n * Return a URL for the \"loading\" interstitial page that is used to disambiguate which\n * native runtime to open the dev server with.\n *\n * @param options options for creating the URL\n * @param platform when opening the URL from the CLI to a connected device we can specify the platform as a query parameter, otherwise it will be inferred from the unsafe user agent sniffing.\n *\n * @returns URL like `http://localhost:8081/_expo/loading?platform=ios`\n * @returns URL like `http://localhost:8081/_expo/loading` when no platform is provided.\n */\n public constructLoadingUrl(options: CreateURLOptions, platform: string | null): string {\n const url = new URL('_expo/loading', this.constructUrl({ scheme: 'http', ...options }));\n if (platform) {\n url.search = new URLSearchParams({ platform }).toString();\n }\n const loadingUrl = url.toString();\n debug(`Loading URL: ${loadingUrl}`);\n return loadingUrl;\n }\n\n /** Create a URI for launching in a native dev client. Returns `null` when no `scheme` can be resolved. */\n public constructDevClientUrl(options?: CreateURLOptions): null | string {\n const protocol = options?.scheme || this.defaults?.scheme;\n\n if (\n !protocol ||\n // Prohibit the use of http(s) in dev client URIs since they'll never be valid.\n ['http', 'https'].includes(protocol.toLowerCase()) ||\n // Prohibit the use of `_` characters in the protocol, Node will throw an error when parsing these URLs\n protocol.includes('_')\n ) {\n debug(`Invalid protocol for dev client URL: ${protocol}`);\n return null;\n }\n\n const manifestUrl = this.constructUrl({\n ...options,\n scheme: this.defaults?.hostType === 'tunnel' ? 'https' : 'http',\n });\n const devClientUrl = `${protocol}://expo-development-client/?url=${encodeURIComponent(\n manifestUrl\n )}`;\n debug(`Dev client URL: ${devClientUrl} -- manifestUrl: ${manifestUrl} -- %O`, options);\n return devClientUrl;\n }\n\n /** Create a generic URL. */\n public constructUrl(options?: Partial<CreateURLOptions> | null): string {\n const urlComponents = this.getUrlComponents({\n ...this.defaults,\n ...options,\n });\n const url = joinUrlComponents(urlComponents);\n debug(`URL: ${url}`);\n return url;\n }\n\n public getDefaultRouteAddress(): string {\n return this.gatewayInfo.address;\n }\n\n /** Get the URL components from the Ngrok server URL. */\n private getTunnelUrlComponents(options: Pick<CreateURLOptions, 'scheme'>): UrlComponents | null {\n const tunnelUrl = this.bundlerInfo.getTunnelUrl?.();\n if (!tunnelUrl) {\n return null;\n }\n const parsed = new URL(tunnelUrl);\n return {\n port: parsed.port,\n hostname: parsed.hostname,\n protocol: options.scheme ?? 'http',\n };\n }\n\n private getUrlComponents(options: CreateURLOptions): UrlComponents {\n // Proxy comes first.\n const proxyURL = getProxyUrl();\n if (proxyURL) {\n return getUrlComponentsFromProxyUrl(options, proxyURL);\n }\n\n // Ngrok.\n if (options.hostType === 'tunnel') {\n const components = this.getTunnelUrlComponents(options);\n if (components) {\n return components;\n }\n Log.warn('Tunnel URL not found (it might not be ready yet), falling back to LAN URL.');\n } else if (options.hostType === 'localhost' && !options.hostname) {\n options.hostname = 'localhost';\n }\n\n return {\n hostname: getDefaultHostname(options, this.gatewayInfo),\n port: this.bundlerInfo.port.toString(),\n protocol: options.scheme ?? 'http',\n };\n }\n}\n\nfunction getUrlComponentsFromProxyUrl(\n options: Pick<CreateURLOptions, 'scheme'>,\n url: string\n): UrlComponents {\n const parsedProxyUrl = new URL(url);\n let protocol = options.scheme ?? 'http';\n if (parsedProxyUrl.protocol === 'https:') {\n if (protocol === 'http') {\n protocol = 'https';\n }\n if (!parsedProxyUrl.port) {\n parsedProxyUrl.port = '443';\n }\n }\n return {\n port: parsedProxyUrl.port,\n hostname: parsedProxyUrl.hostname,\n protocol,\n };\n}\n\nconst getDefaultHostname = (options: CreateURLOptions, gateway: GatewayInfo) => {\n // TODO: Drop REACT_NATIVE_PACKAGER_HOSTNAME\n if (process.env.REACT_NATIVE_PACKAGER_HOSTNAME) {\n return process.env.REACT_NATIVE_PACKAGER_HOSTNAME.trim();\n } else if (options.hostname === 'localhost') {\n // NOTE: We always convert \"localhost\" as a request to 127.0.0.1,\n // to normalize to an address that's consistent\n return '127.0.0.1';\n } else {\n // Fall back to local address\n return options.hostname || gateway.address;\n }\n};\n\nfunction joinUrlComponents({ protocol, hostname, port }: Partial<UrlComponents>): string {\n assert(hostname, 'hostname cannot be inferred.');\n const validProtocol = protocol ? `${protocol}://` : '';\n\n const url = `${validProtocol}${hostname}`;\n\n if (port) {\n return url + `:${port}`;\n }\n\n return url;\n}\n\n/** @deprecated */\nfunction getProxyUrl(): string | undefined {\n return process.env.EXPO_PACKAGER_PROXY_URL;\n}\n\n// TODO: Drop the undocumented env variables:\n// REACT_NATIVE_PACKAGER_HOSTNAME\n// EXPO_PACKAGER_PROXY_URL\n"],"names":["UrlCreator","debug","require","defaults","bundlerInfo","gatewayInfo","getGateway","init","getGatewayAsync","constructLoadingUrl","options","platform","url","URL","constructUrl","scheme","search","URLSearchParams","toString","loadingUrl","constructDevClientUrl","protocol","includes","toLowerCase","manifestUrl","hostType","devClientUrl","encodeURIComponent","urlComponents","getUrlComponents","joinUrlComponents","getDefaultRouteAddress","address","getTunnelUrlComponents","tunnelUrl","getTunnelUrl","parsed","port","hostname","proxyURL","getProxyUrl","getUrlComponentsFromProxyUrl","components","Log","warn","getDefaultHostname","parsedProxyUrl","gateway","process","env","REACT_NATIVE_PACKAGER_HOSTNAME","trim","assert","validProtocol","EXPO_PACKAGER_PROXY_URL"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/server/UrlCreator.ts"],"sourcesContent":["import { getOriginalEnvValue } from '@expo/env';\nimport assert from 'assert';\nimport { URL } from 'url';\n\nimport * as Log from '../../log';\nimport type { GatewayInfo } from '../../utils/ip';\nimport { getGateway, getGatewayAsync } from '../../utils/ip';\n\nconst debug = require('debug')('expo:start:server:urlCreator') as typeof console.log;\n\nexport interface CreateURLOptions {\n /** URL scheme to use when opening apps in custom runtimes. */\n scheme?: string | null;\n /** Type of dev server host to use. */\n hostType?: 'localhost' | 'lan' | 'tunnel';\n /** Requested hostname. */\n hostname?: string | null;\n}\n\ninterface UrlComponents {\n port: string;\n hostname: string;\n protocol: string;\n}\n\ninterface BundlerInfo {\n port: number;\n getTunnelUrl?(): string | null;\n}\n\nexport class UrlCreator {\n constructor(\n public defaults: CreateURLOptions,\n private bundlerInfo: BundlerInfo,\n private gatewayInfo: GatewayInfo = getGateway()\n ) {}\n\n static async init(defaults: CreateURLOptions | undefined | null, bundlerInfo: BundlerInfo) {\n const gatewayInfo = await getGatewayAsync();\n return new UrlCreator(defaults || {}, bundlerInfo, gatewayInfo);\n }\n\n /**\n * Return a URL for the \"loading\" interstitial page that is used to disambiguate which\n * native runtime to open the dev server with.\n *\n * @param options options for creating the URL\n * @param platform when opening the URL from the CLI to a connected device we can specify the platform as a query parameter, otherwise it will be inferred from the unsafe user agent sniffing.\n *\n * @returns URL like `http://localhost:8081/_expo/loading?platform=ios`\n * @returns URL like `http://localhost:8081/_expo/loading` when no platform is provided.\n */\n public constructLoadingUrl(options: CreateURLOptions, platform: string | null): string {\n const url = new URL('_expo/loading', this.constructUrl({ scheme: 'http', ...options }));\n if (platform) {\n url.search = new URLSearchParams({ platform }).toString();\n }\n const loadingUrl = url.toString();\n debug(`Loading URL: ${loadingUrl}`);\n return loadingUrl;\n }\n\n /** Create a URI for launching in a native dev client. Returns `null` when no `scheme` can be resolved. */\n public constructDevClientUrl(options?: CreateURLOptions): null | string {\n const protocol = options?.scheme || this.defaults?.scheme;\n\n if (\n !protocol ||\n // Prohibit the use of http(s) in dev client URIs since they'll never be valid.\n ['http', 'https'].includes(protocol.toLowerCase()) ||\n // Prohibit the use of `_` characters in the protocol, Node will throw an error when parsing these URLs\n protocol.includes('_')\n ) {\n debug(`Invalid protocol for dev client URL: ${protocol}`);\n return null;\n }\n\n const manifestUrl = this.constructUrl({\n ...options,\n scheme: this.defaults?.hostType === 'tunnel' ? 'https' : 'http',\n });\n const devClientUrl = `${protocol}://expo-development-client/?url=${encodeURIComponent(\n manifestUrl\n )}`;\n debug(`Dev client URL: ${devClientUrl} -- manifestUrl: ${manifestUrl} -- %O`, options);\n return devClientUrl;\n }\n\n /** Create a generic URL. */\n public constructUrl(options?: Partial<CreateURLOptions> | null): string {\n const urlComponents = this.getUrlComponents({\n ...this.defaults,\n ...options,\n });\n const url = joinUrlComponents(urlComponents);\n debug(`URL: ${url}`);\n return url;\n }\n\n public getDefaultRouteAddress(): string {\n return this.gatewayInfo.address;\n }\n\n /** URL scheme configured for development-build deep links (e.g. `myapp`). `null` when unset. */\n public getScheme(): string | null {\n return this.defaults?.scheme ?? null;\n }\n\n /** Get the URL components from the Ngrok server URL. */\n private getTunnelUrlComponents(options: Pick<CreateURLOptions, 'scheme'>): UrlComponents | null {\n const tunnelUrl = this.bundlerInfo.getTunnelUrl?.();\n if (!tunnelUrl) {\n return null;\n }\n const parsed = new URL(tunnelUrl);\n return {\n port: parsed.port,\n hostname: parsed.hostname,\n protocol: options.scheme ?? 'http',\n };\n }\n\n private getUrlComponents(options: CreateURLOptions): UrlComponents {\n // Proxy comes first.\n const proxyURL = getProxyUrl();\n if (proxyURL) {\n return getUrlComponentsFromProxyUrl(options, proxyURL);\n }\n\n // Ngrok.\n if (options.hostType === 'tunnel') {\n const components = this.getTunnelUrlComponents(options);\n if (components) {\n return components;\n }\n Log.warn('Tunnel URL not found (it might not be ready yet), falling back to LAN URL.');\n } else if (options.hostType === 'localhost' && !options.hostname) {\n options.hostname = 'localhost';\n }\n\n return {\n hostname: getDefaultHostname(options, this.gatewayInfo),\n port: this.bundlerInfo.port.toString(),\n protocol: options.scheme ?? 'http',\n };\n }\n}\n\nfunction getUrlComponentsFromProxyUrl(\n options: Pick<CreateURLOptions, 'scheme'>,\n url: string\n): UrlComponents {\n const parsedProxyUrl = new URL(url);\n let protocol = options.scheme ?? 'http';\n if (parsedProxyUrl.protocol === 'https:') {\n if (protocol === 'http') {\n protocol = 'https';\n }\n if (!parsedProxyUrl.port) {\n parsedProxyUrl.port = '443';\n }\n }\n return {\n port: parsedProxyUrl.port,\n hostname: parsedProxyUrl.hostname,\n protocol,\n };\n}\n\nconst getDefaultHostname = (options: CreateURLOptions, gateway: GatewayInfo) => {\n // TODO: Drop REACT_NATIVE_PACKAGER_HOSTNAME\n if (process.env.REACT_NATIVE_PACKAGER_HOSTNAME) {\n return process.env.REACT_NATIVE_PACKAGER_HOSTNAME.trim();\n } else if (options.hostname === 'localhost') {\n // NOTE: We always convert \"localhost\" as a request to 127.0.0.1,\n // to normalize to an address that's consistent\n return '127.0.0.1';\n } else {\n // Fall back to local address\n return options.hostname || gateway.address;\n }\n};\n\nfunction joinUrlComponents({ protocol, hostname, port }: Partial<UrlComponents>): string {\n assert(hostname, 'hostname cannot be inferred.');\n const validProtocol = protocol ? `${protocol}://` : '';\n\n const url = `${validProtocol}${hostname}`;\n\n if (port) {\n return url + `:${port}`;\n }\n\n return url;\n}\n\n/** @deprecated */\nfunction getProxyUrl(): string | undefined {\n // Read from the pre-dotenv env — overriding this would redirect connected dev\n // clients through an attacker-controlled URL.\n return getOriginalEnvValue('EXPO_PACKAGER_PROXY_URL');\n}\n\n// TODO: Drop the undocumented env variables:\n// REACT_NATIVE_PACKAGER_HOSTNAME\n// EXPO_PACKAGER_PROXY_URL\n"],"names":["UrlCreator","debug","require","defaults","bundlerInfo","gatewayInfo","getGateway","init","getGatewayAsync","constructLoadingUrl","options","platform","url","URL","constructUrl","scheme","search","URLSearchParams","toString","loadingUrl","constructDevClientUrl","protocol","includes","toLowerCase","manifestUrl","hostType","devClientUrl","encodeURIComponent","urlComponents","getUrlComponents","joinUrlComponents","getDefaultRouteAddress","address","getScheme","getTunnelUrlComponents","tunnelUrl","getTunnelUrl","parsed","port","hostname","proxyURL","getProxyUrl","getUrlComponentsFromProxyUrl","components","Log","warn","getDefaultHostname","parsedProxyUrl","gateway","process","env","REACT_NATIVE_PACKAGER_HOSTNAME","trim","assert","validProtocol","getOriginalEnvValue"],"mappings":"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"}
@@ -33,6 +33,7 @@ function createMCPDevToolsExtensionSchema(plugin) {
33
33
  // Track which commands use each parameter for documentation
34
34
  const parameterCommandMap = {};
35
35
  const parameterDescriptions = {};
36
+ const parameterTypes = {};
36
37
  for (const command of commands){
37
38
  if (command.parameters && command.parameters.length > 0) {
38
39
  for (const param of command.parameters){
@@ -41,6 +42,7 @@ function createMCPDevToolsExtensionSchema(plugin) {
41
42
  commands = [];
42
43
  parameterCommandMap[param.name] = commands;
43
44
  parameterDescriptions[param.name] = param.description || '';
45
+ parameterTypes[param.name] = param.type;
44
46
  }
45
47
  commands.push(command.name);
46
48
  }
@@ -53,7 +55,7 @@ function createMCPDevToolsExtensionSchema(plugin) {
53
55
  const commandsUsingParam = commandList.length === commands.length ? 'all commands' : commandList.map((c)=>`"${c}"`).join(', ');
54
56
  // Include command context in the description so LLMs know when to use each parameter
55
57
  const fullDescription = baseDescription ? `${baseDescription} (Used by: ${commandsUsingParam})` : `Parameter for: ${commandsUsingParam}`;
56
- allParameters[paramName] = _zod().z.string().optional().describe(fullDescription);
58
+ allParameters[paramName] = paramTypeToZod(parameterTypes[paramName]).optional().describe(fullDescription);
57
59
  }
58
60
  // Build the command description with clear instructions for the LLM
59
61
  const hasParameters = Object.keys(allParameters).length > 0;
@@ -65,5 +67,15 @@ function createMCPDevToolsExtensionSchema(plugin) {
65
67
  }).strict(); // .strict() adds additionalProperties: false
66
68
  return schema;
67
69
  }
70
+ function paramTypeToZod(type) {
71
+ switch(type){
72
+ case 'number':
73
+ return _zod().z.number();
74
+ case 'confirm':
75
+ return _zod().z.boolean();
76
+ case 'text':
77
+ return _zod().z.string();
78
+ }
79
+ }
68
80
 
69
81
  //# sourceMappingURL=createMCPDevToolsExtensionSchema.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/createMCPDevToolsExtensionSchema.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport type { DevToolsPlugin } from './DevToolsPlugin';\n\n/**\n * Creates an MCP-compatible JSON schema for a DevTools plugin's CLI extensions.\n *\n * LLM agents have varying support for complex JSON schema features like `anyOf`/`oneOf`\n * discriminated unions. This implementation uses a flat schema with an enum for the\n * command name, which provides the best compatibility across different LLM providers:\n *\n * - OpenAI: Supports `anyOf` but requires `additionalProperties: false` and all fields `required`\n * - Claude/Anthropic: Works best with simple flat schemas with enums\n * - Other providers: Generally have limited or inconsistent support for discriminated unions\n *\n * To compensate for the lack of discriminated unions, parameter descriptions include\n * which command(s) they belong to, and command descriptions include their parameters.\n *\n * The resulting schema structure is:\n * ```json\n * {\n * \"type\": \"object\",\n * \"properties\": {\n * \"command\": {\n * \"type\": \"string\",\n * \"enum\": [\"cmd1\", \"cmd2\", ...],\n * \"description\": \"The command to execute. Available commands: \\\"cmd1\\\" - Title 1 (params: foo); ...\"\n * },\n * \"foo\": { \"type\": \"string\", \"description\": \"Foo description (Used by: \\\"cmd1\\\")\" },\n * ...\n * },\n * \"required\": [\"command\"],\n * \"additionalProperties\": false\n * }\n * ```\n */\nexport function createMCPDevToolsExtensionSchema(plugin: DevToolsPlugin) {\n if (plugin.cliExtensions == null || plugin.cliExtensions?.commands.length === 0) {\n throw new Error(\n `Plugin ${plugin.packageName} has no commands defined. Please define at least one command.`\n );\n }\n\n const commands = plugin.cliExtensions.commands;\n\n // Build a rich description that explains each command and its parameters\n const commandDescriptions = commands\n .map((c) => {\n const params = c.parameters?.map((p) => p.name).join(', ');\n return params ? `\"${c.name}\": ${c.title} (params: ${params})` : `\"${c.name}\": ${c.title}`;\n })\n .join('. ');\n\n // Create enum of command names for clear LLM selection\n const commandNames = commands.map((c) => c.name) as [string, ...string[]];\n\n // Collect all unique parameters across all commands\n // Track which commands use each parameter for documentation\n const parameterCommandMap: Record<string, string[]> = {};\n const parameterDescriptions: Record<string, string> = {};\n\n for (const command of commands) {\n if (command.parameters && command.parameters.length > 0) {\n for (const param of command.parameters) {\n let commands = parameterCommandMap[param.name];\n if (!commands) {\n commands = [];\n parameterCommandMap[param.name] = commands;\n parameterDescriptions[param.name] = param.description || '';\n }\n commands.push(command.name);\n }\n }\n }\n\n // Build parameters with descriptions that indicate which command(s) they belong to\n const allParameters: Record<string, z.ZodTypeAny> = {};\n for (const [paramName, commandList] of Object.entries(parameterCommandMap)) {\n const baseDescription = parameterDescriptions[paramName];\n const commandsUsingParam =\n commandList.length === commands.length\n ? 'all commands'\n : commandList.map((c) => `\"${c}\"`).join(', ');\n\n // Include command context in the description so LLMs know when to use each parameter\n const fullDescription = baseDescription\n ? `${baseDescription} (Used by: ${commandsUsingParam})`\n : `Parameter for: ${commandsUsingParam}`;\n\n allParameters[paramName] = z.string().optional().describe(fullDescription);\n }\n\n // Build the command description with clear instructions for the LLM\n const hasParameters = Object.keys(allParameters).length > 0;\n const commandDescription = hasParameters\n ? `Required. The command to execute. You must select exactly one command from the enum values. ` +\n `Each command may require specific parameters - only include parameters that belong to the selected command. ` +\n `Commands: ${commandDescriptions}.`\n : `Required. The command to execute. Select exactly one from the available options. ` +\n `Commands: ${commandDescriptions}.`;\n\n // Build the flat schema with additionalProperties: false for LLM compatibility\n const schema = z\n .object({\n command: z.enum(commandNames).describe(commandDescription),\n ...allParameters,\n })\n .strict(); // .strict() adds additionalProperties: false\n\n return schema;\n}\n"],"names":["createMCPDevToolsExtensionSchema","plugin","cliExtensions","commands","length","Error","packageName","commandDescriptions","map","c","params","parameters","p","name","join","title","commandNames","parameterCommandMap","parameterDescriptions","command","param","description","push","allParameters","paramName","commandList","Object","entries","baseDescription","commandsUsingParam","fullDescription","z","string","optional","describe","hasParameters","keys","commandDescription","schema","object","enum","strict"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/server/createMCPDevToolsExtensionSchema.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport type { DevToolsPluginCommandParameter, DevToolsPluginInfo } from './DevToolsPlugin.schema';\n\n/**\n * Creates an MCP-compatible JSON schema for a DevTools plugin's CLI extensions.\n *\n * LLM agents have varying support for complex JSON schema features like `anyOf`/`oneOf`\n * discriminated unions. This implementation uses a flat schema with an enum for the\n * command name, which provides the best compatibility across different LLM providers:\n *\n * - OpenAI: Supports `anyOf` but requires `additionalProperties: false` and all fields `required`\n * - Claude/Anthropic: Works best with simple flat schemas with enums\n * - Other providers: Generally have limited or inconsistent support for discriminated unions\n *\n * To compensate for the lack of discriminated unions, parameter descriptions include\n * which command(s) they belong to, and command descriptions include their parameters.\n *\n * The resulting schema structure is:\n * ```json\n * {\n * \"type\": \"object\",\n * \"properties\": {\n * \"command\": {\n * \"type\": \"string\",\n * \"enum\": [\"cmd1\", \"cmd2\", ...],\n * \"description\": \"The command to execute. Available commands: \\\"cmd1\\\" - Title 1 (params: foo); ...\"\n * },\n * \"foo\": { \"type\": \"string\", \"description\": \"Foo description (Used by: \\\"cmd1\\\")\" },\n * ...\n * },\n * \"required\": [\"command\"],\n * \"additionalProperties\": false\n * }\n * ```\n */\nexport function createMCPDevToolsExtensionSchema(plugin: DevToolsPluginInfo) {\n if (plugin.cliExtensions == null || plugin.cliExtensions?.commands.length === 0) {\n throw new Error(\n `Plugin ${plugin.packageName} has no commands defined. Please define at least one command.`\n );\n }\n\n const commands = plugin.cliExtensions.commands;\n\n // Build a rich description that explains each command and its parameters\n const commandDescriptions = commands\n .map((c) => {\n const params = c.parameters?.map((p) => p.name).join(', ');\n return params ? `\"${c.name}\": ${c.title} (params: ${params})` : `\"${c.name}\": ${c.title}`;\n })\n .join('. ');\n\n // Create enum of command names for clear LLM selection\n const commandNames = commands.map((c) => c.name) as [string, ...string[]];\n\n // Collect all unique parameters across all commands\n // Track which commands use each parameter for documentation\n const parameterCommandMap: Record<string, string[]> = {};\n const parameterDescriptions: Record<string, string> = {};\n const parameterTypes: Record<string, DevToolsPluginCommandParameter['type']> = {};\n\n for (const command of commands) {\n if (command.parameters && command.parameters.length > 0) {\n for (const param of command.parameters) {\n let commands = parameterCommandMap[param.name];\n if (!commands) {\n commands = [];\n parameterCommandMap[param.name] = commands;\n parameterDescriptions[param.name] = param.description || '';\n parameterTypes[param.name] = param.type;\n }\n commands.push(command.name);\n }\n }\n }\n\n // Build parameters with descriptions that indicate which command(s) they belong to\n const allParameters: Record<string, z.ZodTypeAny> = {};\n for (const [paramName, commandList] of Object.entries(parameterCommandMap)) {\n const baseDescription = parameterDescriptions[paramName];\n const commandsUsingParam =\n commandList.length === commands.length\n ? 'all commands'\n : commandList.map((c) => `\"${c}\"`).join(', ');\n\n // Include command context in the description so LLMs know when to use each parameter\n const fullDescription = baseDescription\n ? `${baseDescription} (Used by: ${commandsUsingParam})`\n : `Parameter for: ${commandsUsingParam}`;\n\n allParameters[paramName] = paramTypeToZod(parameterTypes[paramName]!)\n .optional()\n .describe(fullDescription);\n }\n\n // Build the command description with clear instructions for the LLM\n const hasParameters = Object.keys(allParameters).length > 0;\n const commandDescription = hasParameters\n ? `Required. The command to execute. You must select exactly one command from the enum values. ` +\n `Each command may require specific parameters - only include parameters that belong to the selected command. ` +\n `Commands: ${commandDescriptions}.`\n : `Required. The command to execute. Select exactly one from the available options. ` +\n `Commands: ${commandDescriptions}.`;\n\n // Build the flat schema with additionalProperties: false for LLM compatibility\n const schema = z\n .object({\n command: z.enum(commandNames).describe(commandDescription),\n ...allParameters,\n })\n .strict(); // .strict() adds additionalProperties: false\n\n return schema;\n}\n\nfunction paramTypeToZod(type: DevToolsPluginCommandParameter['type']) {\n switch (type) {\n case 'number':\n return z.number();\n case 'confirm':\n return z.boolean();\n case 'text':\n return z.string();\n }\n}\n"],"names":["createMCPDevToolsExtensionSchema","plugin","cliExtensions","commands","length","Error","packageName","commandDescriptions","map","c","params","parameters","p","name","join","title","commandNames","parameterCommandMap","parameterDescriptions","parameterTypes","command","param","description","type","push","allParameters","paramName","commandList","Object","entries","baseDescription","commandsUsingParam","fullDescription","paramTypeToZod","optional","describe","hasParameters","keys","commandDescription","schema","z","object","enum","strict","number","boolean","string"],"mappings":"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"}
@@ -56,6 +56,7 @@ const _metroErrorInterface = require("./metro/metroErrorInterface");
56
56
  const _metroOptions = require("./middleware/metroOptions");
57
57
  const _serverLogLikeMetro = require("./serverLogLikeMetro");
58
58
  const _delay = require("../../utils/delay");
59
+ const _dir = require("../../utils/dir");
59
60
  const _errors = require("../../utils/errors");
60
61
  const _filePath = require("../../utils/filePath");
61
62
  const _profile = require("../../utils/profile");
@@ -68,7 +69,7 @@ const debug = require('debug')('expo:start:server:getStaticRenderFunctions');
68
69
  async function ensureFileInRootDirectory(projectRoot, otherFile) {
69
70
  // Cannot be accessed using Metro's server API, we need to move the file
70
71
  // into the project root and try again.
71
- if (!_path().default.relative(projectRoot, otherFile).startsWith('..' + _path().default.sep)) {
72
+ if (!(0, _dir.isPathInside)(otherFile, projectRoot)) {
72
73
  return otherFile;
73
74
  }
74
75
  // Copy the file into the project to ensure it works in monorepos.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/start/server/getStaticRenderFunctions.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 */\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport { evalModule } from '@expo/require-utils';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { IS_METRO_BUNDLE_ERROR_SYMBOL, logMetroError } from './metro/metroErrorInterface';\nimport type { ExpoMetroOptions } from './middleware/metroOptions';\nimport { createBundleUrlPath } from './middleware/metroOptions';\nimport { augmentLogs } from './serverLogLikeMetro';\nimport { delayAsync } from '../../utils/delay';\nimport { SilentError } from '../../utils/errors';\nimport { toPosixPath } from '../../utils/filePath';\nimport { profile } from '../../utils/profile';\n\nconst debug = require('debug')('expo:start:server:getStaticRenderFunctions') as typeof console.log;\n\n/** The list of input keys will become optional, everything else will remain the same. */\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nasync function ensureFileInRootDirectory(projectRoot: string, otherFile: string) {\n // Cannot be accessed using Metro's server API, we need to move the file\n // into the project root and try again.\n if (!path.relative(projectRoot, otherFile).startsWith('..' + path.sep)) {\n return otherFile;\n }\n\n // Copy the file into the project to ensure it works in monorepos.\n // This means the file cannot have any relative imports.\n const tempDir = path.join(projectRoot, '.expo/static-tmp');\n await fs.promises.mkdir(tempDir, { recursive: true });\n const moduleId = path.join(tempDir, path.basename(otherFile));\n await fs.promises.writeFile(moduleId, await fs.promises.readFile(otherFile, 'utf8'));\n // Sleep to give watchman time to register the file.\n await delayAsync(50);\n return moduleId;\n}\n\nexport async function createMetroEndpointAsync(\n projectRoot: string,\n devServerUrl: string,\n absoluteFilePath: string,\n props: PickPartial<ExpoMetroOptions, 'mainModuleName' | 'bytecode'>\n): Promise<string> {\n const root = getMetroServerRoot(projectRoot);\n const safeOtherFile = await ensureFileInRootDirectory(projectRoot, absoluteFilePath);\n const serverPath = path.relative(root, safeOtherFile).replace(/\\.[jt]sx?$/, '');\n\n const urlFragment = createBundleUrlPath({\n mainModuleName: serverPath,\n lazy: false,\n asyncRoutes: false,\n inlineSourceMap: false,\n engine: 'hermes',\n minify: false,\n bytecode: false,\n ...props,\n });\n\n let url: string;\n if (devServerUrl) {\n url = new URL(urlFragment.replace(/^\\//, ''), devServerUrl).toString();\n } else {\n url = '/' + urlFragment.replace(/^\\/+/, '');\n }\n return url;\n}\n\nexport function evalMetroAndWrapFunctions<T = Record<string, any>>(\n projectRoot: string,\n script: string,\n filename: string,\n sourceMap: string | undefined,\n isExporting: boolean\n): T {\n // TODO: Add back stack trace logic that hides traces from metro-runtime and other internal modules.\n const contents = evalMetroNoHandling(projectRoot, script, filename, sourceMap);\n\n if (!contents) {\n // This can happen if ErrorUtils isn't working correctly on web and failing to throw an error when a module throws.\n // This is unexpected behavior and should not be pretty formatted, therefore we're avoiding CommandError.\n throw new Error(\n '[Expo SSR] Module returned undefined, this could be due to a misconfiguration in Metro error handling'\n );\n }\n // wrap each function with a try/catch that uses Metro's error formatter\n return Object.keys(contents).reduce((acc, key) => {\n const fn = contents[key];\n if (typeof fn !== 'function') {\n return { ...acc, [key]: fn };\n }\n\n acc[key] = async function (...props: any[]) {\n try {\n return await fn.apply(this, props);\n } catch (error: any) {\n await logMetroError(projectRoot, { error });\n\n if (isExporting || error[IS_METRO_BUNDLE_ERROR_SYMBOL]) {\n throw error;\n } else {\n // TODO: When does this happen?\n throw new SilentError(error);\n }\n }\n };\n return acc;\n }, {} as any);\n}\n\nexport function evalMetroNoHandling(\n projectRoot: string,\n src: string,\n filename: string,\n sourceMap?: string\n) {\n augmentLogs(projectRoot);\n\n // NOTE(@kitten): `require-from-string` derives a base path from the filename we pass it,\n // but doesn't validate that the filename exists. These debug messages should help identify\n // these problems, if they occur in user projects without reproductions\n if (!fs.existsSync(path.dirname(filename))) {\n debug(`evalMetroNoHandling received filename in a directory that does not exist: ${filename}`);\n } else if (!toPosixPath(path.dirname(filename)).startsWith(toPosixPath(projectRoot))) {\n debug(`evalMetroNoHandling received filename outside of the project root: ${filename}`);\n }\n\n return profile(evalModule, 'eval-metro-bundle')(src, filename, {\n cache: false,\n sourceMap,\n });\n}\n"],"names":["createMetroEndpointAsync","evalMetroAndWrapFunctions","evalMetroNoHandling","debug","require","ensureFileInRootDirectory","projectRoot","otherFile","path","relative","startsWith","sep","tempDir","join","fs","promises","mkdir","recursive","moduleId","basename","writeFile","readFile","delayAsync","devServerUrl","absoluteFilePath","props","root","getMetroServerRoot","safeOtherFile","serverPath","replace","urlFragment","createBundleUrlPath","mainModuleName","lazy","asyncRoutes","inlineSourceMap","engine","minify","bytecode","url","URL","toString","script","filename","sourceMap","isExporting","contents","Error","Object","keys","reduce","acc","key","fn","apply","error","logMetroError","IS_METRO_BUNDLE_ERROR_SYMBOL","SilentError","src","augmentLogs","existsSync","dirname","toPosixPath","profile","evalModule","cache"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/start/server/getStaticRenderFunctions.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 */\nimport { getMetroServerRoot } from '@expo/config/paths';\nimport { evalModule } from '@expo/require-utils';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { IS_METRO_BUNDLE_ERROR_SYMBOL, logMetroError } from './metro/metroErrorInterface';\nimport type { ExpoMetroOptions } from './middleware/metroOptions';\nimport { createBundleUrlPath } from './middleware/metroOptions';\nimport { augmentLogs } from './serverLogLikeMetro';\nimport { delayAsync } from '../../utils/delay';\nimport { isPathInside } from '../../utils/dir';\nimport { SilentError } from '../../utils/errors';\nimport { toPosixPath } from '../../utils/filePath';\nimport { profile } from '../../utils/profile';\n\nconst debug = require('debug')('expo:start:server:getStaticRenderFunctions') as typeof console.log;\n\n/** The list of input keys will become optional, everything else will remain the same. */\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nasync function ensureFileInRootDirectory(projectRoot: string, otherFile: string) {\n // Cannot be accessed using Metro's server API, we need to move the file\n // into the project root and try again.\n if (!isPathInside(otherFile, projectRoot)) {\n return otherFile;\n }\n\n // Copy the file into the project to ensure it works in monorepos.\n // This means the file cannot have any relative imports.\n const tempDir = path.join(projectRoot, '.expo/static-tmp');\n await fs.promises.mkdir(tempDir, { recursive: true });\n const moduleId = path.join(tempDir, path.basename(otherFile));\n await fs.promises.writeFile(moduleId, await fs.promises.readFile(otherFile, 'utf8'));\n // Sleep to give watchman time to register the file.\n await delayAsync(50);\n return moduleId;\n}\n\nexport async function createMetroEndpointAsync(\n projectRoot: string,\n devServerUrl: string,\n absoluteFilePath: string,\n props: PickPartial<ExpoMetroOptions, 'mainModuleName' | 'bytecode'>\n): Promise<string> {\n const root = getMetroServerRoot(projectRoot);\n const safeOtherFile = await ensureFileInRootDirectory(projectRoot, absoluteFilePath);\n const serverPath = path.relative(root, safeOtherFile).replace(/\\.[jt]sx?$/, '');\n\n const urlFragment = createBundleUrlPath({\n mainModuleName: serverPath,\n lazy: false,\n asyncRoutes: false,\n inlineSourceMap: false,\n engine: 'hermes',\n minify: false,\n bytecode: false,\n ...props,\n });\n\n let url: string;\n if (devServerUrl) {\n url = new URL(urlFragment.replace(/^\\//, ''), devServerUrl).toString();\n } else {\n url = '/' + urlFragment.replace(/^\\/+/, '');\n }\n return url;\n}\n\nexport function evalMetroAndWrapFunctions<T = Record<string, any>>(\n projectRoot: string,\n script: string,\n filename: string,\n sourceMap: string | undefined,\n isExporting: boolean\n): T {\n // TODO: Add back stack trace logic that hides traces from metro-runtime and other internal modules.\n const contents = evalMetroNoHandling(projectRoot, script, filename, sourceMap);\n\n if (!contents) {\n // This can happen if ErrorUtils isn't working correctly on web and failing to throw an error when a module throws.\n // This is unexpected behavior and should not be pretty formatted, therefore we're avoiding CommandError.\n throw new Error(\n '[Expo SSR] Module returned undefined, this could be due to a misconfiguration in Metro error handling'\n );\n }\n // wrap each function with a try/catch that uses Metro's error formatter\n return Object.keys(contents).reduce((acc, key) => {\n const fn = contents[key];\n if (typeof fn !== 'function') {\n return { ...acc, [key]: fn };\n }\n\n acc[key] = async function (...props: any[]) {\n try {\n return await fn.apply(this, props);\n } catch (error: any) {\n await logMetroError(projectRoot, { error });\n\n if (isExporting || error[IS_METRO_BUNDLE_ERROR_SYMBOL]) {\n throw error;\n } else {\n // TODO: When does this happen?\n throw new SilentError(error);\n }\n }\n };\n return acc;\n }, {} as any);\n}\n\nexport function evalMetroNoHandling(\n projectRoot: string,\n src: string,\n filename: string,\n sourceMap?: string\n) {\n augmentLogs(projectRoot);\n\n // NOTE(@kitten): `require-from-string` derives a base path from the filename we pass it,\n // but doesn't validate that the filename exists. These debug messages should help identify\n // these problems, if they occur in user projects without reproductions\n if (!fs.existsSync(path.dirname(filename))) {\n debug(`evalMetroNoHandling received filename in a directory that does not exist: ${filename}`);\n } else if (!toPosixPath(path.dirname(filename)).startsWith(toPosixPath(projectRoot))) {\n debug(`evalMetroNoHandling received filename outside of the project root: ${filename}`);\n }\n\n return profile(evalModule, 'eval-metro-bundle')(src, filename, {\n cache: false,\n sourceMap,\n });\n}\n"],"names":["createMetroEndpointAsync","evalMetroAndWrapFunctions","evalMetroNoHandling","debug","require","ensureFileInRootDirectory","projectRoot","otherFile","isPathInside","tempDir","path","join","fs","promises","mkdir","recursive","moduleId","basename","writeFile","readFile","delayAsync","devServerUrl","absoluteFilePath","props","root","getMetroServerRoot","safeOtherFile","serverPath","relative","replace","urlFragment","createBundleUrlPath","mainModuleName","lazy","asyncRoutes","inlineSourceMap","engine","minify","bytecode","url","URL","toString","script","filename","sourceMap","isExporting","contents","Error","Object","keys","reduce","acc","key","fn","apply","error","logMetroError","IS_METRO_BUNDLE_ERROR_SYMBOL","SilentError","src","augmentLogs","existsSync","dirname","toPosixPath","startsWith","profile","evalModule","cache"],"mappings":"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"}