@expo/cli 55.0.2 → 55.0.4

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 (32) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/export/exportApp.js +3 -2
  3. package/build/src/export/exportApp.js.map +1 -1
  4. package/build/src/export/index.js +33 -10
  5. package/build/src/export/index.js.map +1 -1
  6. package/build/src/export/resolveOptions.js +6 -1
  7. package/build/src/export/resolveOptions.js.map +1 -1
  8. package/build/src/export/saveAssets.js +28 -9
  9. package/build/src/export/saveAssets.js.map +1 -1
  10. package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js +1 -1
  11. package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js.map +1 -1
  12. package/build/src/start/server/metro/MetroBundlerDevServer.js +4 -4
  13. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  14. package/build/src/start/server/metro/createServerComponentsMiddleware.js +2 -2
  15. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  16. package/build/src/start/server/metro/fetchRouterManifest.js +1 -13
  17. package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
  18. package/build/src/start/server/type-generation/routes.js +6 -9
  19. package/build/src/start/server/type-generation/routes.js.map +1 -1
  20. package/build/src/utils/array.js +6 -0
  21. package/build/src/utils/array.js.map +1 -1
  22. package/build/src/utils/build-cache-providers/index.js +1 -1
  23. package/build/src/utils/build-cache-providers/index.js.map +1 -1
  24. package/build/src/utils/freeport.js +70 -0
  25. package/build/src/utils/freeport.js.map +1 -0
  26. package/build/src/utils/port.js +13 -25
  27. package/build/src/utils/port.js.map +1 -1
  28. package/build/src/utils/resolveArgs.js +86 -19
  29. package/build/src/utils/resolveArgs.js.map +1 -1
  30. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  31. package/build/src/utils/telemetry/utils/context.js +1 -1
  32. package/package.json +16 -18
@@ -0,0 +1,70 @@
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: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ freePortAsync: function() {
13
+ return freePortAsync;
14
+ },
15
+ testPortAsync: function() {
16
+ return testPortAsync;
17
+ }
18
+ });
19
+ function _nodenet() {
20
+ const data = /*#__PURE__*/ _interop_require_default(require("node:net"));
21
+ _nodenet = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function _interop_require_default(obj) {
27
+ return obj && obj.__esModule ? obj : {
28
+ default: obj
29
+ };
30
+ }
31
+ async function testHostPortAsync(port, host) {
32
+ return new Promise((resolve)=>{
33
+ const server = _nodenet().default.createServer();
34
+ server.listen({
35
+ port,
36
+ host
37
+ }, ()=>{
38
+ server.once('close', ()=>{
39
+ setTimeout(()=>resolve(true), 0);
40
+ });
41
+ server.close();
42
+ });
43
+ server.once('error', (_error)=>{
44
+ setTimeout(()=>resolve(false), 0);
45
+ });
46
+ });
47
+ }
48
+ async function testPortAsync(port, hostnames) {
49
+ if (!(hostnames == null ? void 0 : hostnames.length)) {
50
+ hostnames = [
51
+ null
52
+ ];
53
+ }
54
+ for (const host of hostnames){
55
+ if (!await testHostPortAsync(port, host)) {
56
+ return false;
57
+ }
58
+ }
59
+ return true;
60
+ }
61
+ async function freePortAsync(portStart, hostnames) {
62
+ for(let port = portStart; port <= 65535; port++){
63
+ if (await testPortAsync(port, hostnames)) {
64
+ return port;
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+
70
+ //# sourceMappingURL=freeport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/freeport.ts"],"sourcesContent":["import net from 'node:net';\n\nasync function testHostPortAsync(port: number, host: string | null): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.listen({ port, host }, () => {\n server.once('close', () => {\n setTimeout(() => resolve(true), 0);\n });\n server.close();\n });\n server.once('error', (_error) => {\n setTimeout(() => resolve(false), 0);\n });\n });\n}\n\nexport async function testPortAsync(port: number, hostnames?: (string | null)[]): Promise<boolean> {\n if (!hostnames?.length) {\n hostnames = [null];\n }\n for (const host of hostnames) {\n if (!(await testHostPortAsync(port, host))) {\n return false;\n }\n }\n return true;\n}\n\nexport async function freePortAsync(\n portStart: number,\n hostnames?: (string | null)[]\n): Promise<number | null> {\n for (let port = portStart; port <= 65_535; port++) {\n if (await testPortAsync(port, hostnames)) {\n return port;\n }\n }\n return null;\n}\n"],"names":["freePortAsync","testPortAsync","testHostPortAsync","port","host","Promise","resolve","server","net","createServer","listen","once","setTimeout","close","_error","hostnames","length","portStart"],"mappings":";;;;;;;;;;;IA6BsBA,aAAa;eAAbA;;IAZAC,aAAa;eAAbA;;;;gEAjBN;;;;;;;;;;;AAEhB,eAAeC,kBAAkBC,IAAY,EAAEC,IAAmB;IAChE,OAAO,IAAIC,QAAQ,CAACC;QAClB,MAAMC,SAASC,kBAAG,CAACC,YAAY;QAC/BF,OAAOG,MAAM,CAAC;YAAEP;YAAMC;QAAK,GAAG;YAC5BG,OAAOI,IAAI,CAAC,SAAS;gBACnBC,WAAW,IAAMN,QAAQ,OAAO;YAClC;YACAC,OAAOM,KAAK;QACd;QACAN,OAAOI,IAAI,CAAC,SAAS,CAACG;YACpBF,WAAW,IAAMN,QAAQ,QAAQ;QACnC;IACF;AACF;AAEO,eAAeL,cAAcE,IAAY,EAAEY,SAA6B;IAC7E,IAAI,EAACA,6BAAAA,UAAWC,MAAM,GAAE;QACtBD,YAAY;YAAC;SAAK;IACpB;IACA,KAAK,MAAMX,QAAQW,UAAW;QAC5B,IAAI,CAAE,MAAMb,kBAAkBC,MAAMC,OAAQ;YAC1C,OAAO;QACT;IACF;IACA,OAAO;AACT;AAEO,eAAeJ,cACpBiB,SAAiB,EACjBF,SAA6B;IAE7B,IAAK,IAAIZ,OAAOc,WAAWd,QAAQ,OAAQA,OAAQ;QACjD,IAAI,MAAMF,cAAcE,MAAMY,YAAY;YACxC,OAAOZ;QACT;IACF;IACA,OAAO;AACT"}
@@ -29,15 +29,9 @@ function _chalk() {
29
29
  };
30
30
  return data;
31
31
  }
32
- function _freeportasync() {
33
- const data = /*#__PURE__*/ _interop_require_default(require("freeport-async"));
34
- _freeportasync = function() {
35
- return data;
36
- };
37
- return data;
38
- }
39
32
  const _env = require("./env");
40
33
  const _errors = require("./errors");
34
+ const _freeport = require("./freeport");
41
35
  const _log = /*#__PURE__*/ _interop_require_wildcard(require("../log"));
42
36
  function _interop_require_default(obj) {
43
37
  return obj && obj.__esModule ? obj : {
@@ -86,25 +80,21 @@ function _interop_require_wildcard(obj, nodeInterop) {
86
80
  return newObj;
87
81
  }
88
82
  async function getFreePortAsync(rangeStart) {
89
- const port = await (0, _freeportasync().default)(rangeStart, {
90
- hostnames: [
91
- null,
92
- 'localhost'
93
- ]
94
- });
83
+ const port = await (0, _freeport.freePortAsync)(rangeStart, [
84
+ null,
85
+ 'localhost'
86
+ ]);
95
87
  if (!port) {
96
88
  throw new _errors.CommandError('NO_PORT_FOUND', 'No available port found');
97
89
  }
98
90
  return port;
99
91
  }
100
92
  async function ensurePortAvailabilityAsync(projectRoot, { port }) {
101
- const freePort = await (0, _freeportasync().default)(port, {
102
- hostnames: [
103
- null
104
- ]
105
- });
93
+ const isFreePort = await (0, _freeport.testPortAsync)(port, [
94
+ null
95
+ ]);
106
96
  // Check if port has become busy during the build.
107
- if (freePort === port) {
97
+ if (isFreePort) {
108
98
  return true;
109
99
  }
110
100
  const isBusy = await isBusyPortRunningSameProcessAsync(projectRoot, {
@@ -138,15 +128,13 @@ async function isBusyPortRunningSameProcessAsync(projectRoot, { port }) {
138
128
  }
139
129
  async function choosePortAsync(projectRoot, { defaultPort, host, reuseExistingPort }) {
140
130
  try {
141
- const port = await (0, _freeportasync().default)(defaultPort, {
142
- hostnames: [
143
- host ?? null
144
- ]
145
- });
131
+ const port = await (0, _freeport.freePortAsync)(defaultPort, [
132
+ host ?? null
133
+ ]);
146
134
  if (port === defaultPort || defaultPort === 0) {
147
135
  return port;
148
136
  }
149
- const isRestricted = isRestrictedPort(port);
137
+ const isRestricted = port && isRestrictedPort(port);
150
138
  let message = isRestricted ? `Admin permissions are required to run a server on a port below 1024` : `Port ${_chalk().default.bold(defaultPort)} is`;
151
139
  const { getRunningProcess } = require('./getRunningProcess');
152
140
  const runningProcess = isRestricted ? null : getRunningProcess(defaultPort);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/port.ts"],"sourcesContent":["import chalk from 'chalk';\nimport freeportAsync from 'freeport-async';\n\nimport { env } from './env';\nimport { CommandError } from './errors';\nimport * as Log from '../log';\n\n/** Get a free port or assert a CLI command error. */\nexport async function getFreePortAsync(rangeStart: number): Promise<number> {\n const port = await freeportAsync(rangeStart, { hostnames: [null, 'localhost'] });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', 'No available port found');\n }\n\n return port;\n}\n\n/** @return `true` if the port can still be used to start the dev server, `false` if the dev server should be skipped, and asserts if the port is now taken. */\nexport async function ensurePortAvailabilityAsync(\n projectRoot: string,\n { port }: { port: number }\n): Promise<boolean> {\n const freePort = await freeportAsync(port, { hostnames: [null] });\n // Check if port has become busy during the build.\n if (freePort === port) {\n return true;\n }\n\n const isBusy = await isBusyPortRunningSameProcessAsync(projectRoot, { port });\n if (!isBusy) {\n throw new CommandError(\n `Port \"${port}\" became busy running another process while the app was compiling. Re-run command to use a new port.`\n );\n }\n\n // Log that the dev server will not be started and that the logs will appear in another window.\n Log.log(\n '› The dev server for this app is already running in another window. Logs will appear there.'\n );\n return false;\n}\n\nfunction isRestrictedPort(port: number) {\n if (process.platform !== 'win32' && port < 1024) {\n const isRoot = process.getuid && process.getuid() === 0;\n return !isRoot;\n }\n return false;\n}\n\nasync function isBusyPortRunningSameProcessAsync(projectRoot: string, { port }: { port: number }) {\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n\n const runningProcess = isRestrictedPort(port) ? null : getRunningProcess(port);\n if (runningProcess) {\n if (runningProcess.directory === projectRoot) {\n return true;\n } else {\n return false;\n }\n }\n\n return null;\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function choosePortAsync(\n projectRoot: string,\n {\n defaultPort,\n host,\n reuseExistingPort,\n }: {\n defaultPort: number;\n host?: string;\n reuseExistingPort?: boolean;\n }\n): Promise<number | null> {\n try {\n const port = await freeportAsync(defaultPort, { hostnames: [host ?? null] });\n if (port === defaultPort || defaultPort === 0) {\n return port;\n }\n\n const isRestricted = isRestrictedPort(port);\n\n let message = isRestricted\n ? `Admin permissions are required to run a server on a port below 1024`\n : `Port ${chalk.bold(defaultPort)} is`;\n\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n const runningProcess = isRestricted ? null : getRunningProcess(defaultPort);\n\n if (runningProcess) {\n const pidTag = chalk.gray(`(pid ${runningProcess.pid})`);\n if (runningProcess.directory === projectRoot) {\n message += ` running this app in another window`;\n if (reuseExistingPort) {\n return null;\n }\n } else {\n message += ` running ${chalk.cyan(runningProcess.command)} in another window`;\n }\n message += '\\n' + chalk.gray(` ${runningProcess.directory} ${pidTag}`);\n } else {\n message += ' being used by another process';\n }\n\n Log.log(`\\u203A ${message}`);\n const { confirmAsync } = require('./prompts') as typeof import('./prompts');\n const change = await confirmAsync({\n message: `Use port ${port} instead?`,\n initial: true,\n });\n return change ? port : null;\n } catch (error: any) {\n if (error.code === 'ABORTED') {\n throw error;\n } else if (error.code === 'NON_INTERACTIVE') {\n Log.warn(chalk.yellow(error.message));\n return null;\n }\n throw error;\n }\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function resolvePortAsync(\n projectRoot: string,\n {\n /** Should opt to reuse a port that is running the same project in another window. */\n reuseExistingPort,\n /** Preferred port. */\n defaultPort,\n /** Backup port for when the default isn't available. */\n fallbackPort,\n }: {\n reuseExistingPort?: boolean;\n defaultPort?: string | number;\n fallbackPort?: number;\n } = {}\n): Promise<number | null> {\n let port: number;\n if (typeof defaultPort === 'string') {\n port = parseInt(defaultPort, 10);\n } else if (typeof defaultPort === 'number') {\n port = defaultPort;\n } else {\n port = env.RCT_METRO_PORT || fallbackPort || 8081;\n }\n\n // Only check the port when the bundler is running.\n const resolvedPort = await choosePortAsync(projectRoot, {\n defaultPort: port,\n reuseExistingPort,\n });\n if (resolvedPort == null) {\n Log.log('\\u203A Skipping dev server');\n // Skip bundling if the port is null\n } else {\n // Use the new or resolved port\n process.env.RCT_METRO_PORT = String(resolvedPort);\n }\n\n return resolvedPort;\n}\n"],"names":["choosePortAsync","ensurePortAvailabilityAsync","getFreePortAsync","resolvePortAsync","rangeStart","port","freeportAsync","hostnames","CommandError","projectRoot","freePort","isBusy","isBusyPortRunningSameProcessAsync","Log","log","isRestrictedPort","process","platform","isRoot","getuid","getRunningProcess","require","runningProcess","directory","defaultPort","host","reuseExistingPort","isRestricted","message","chalk","bold","pidTag","gray","pid","cyan","command","confirmAsync","change","initial","error","code","warn","yellow","fallbackPort","parseInt","env","RCT_METRO_PORT","resolvedPort","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/port.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { env } from './env';\nimport { CommandError } from './errors';\nimport { testPortAsync, freePortAsync } from './freeport';\nimport * as Log from '../log';\n\n/** Get a free port or assert a CLI command error. */\nexport async function getFreePortAsync(rangeStart: number): Promise<number> {\n const port = await freePortAsync(rangeStart, [null, 'localhost']);\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', 'No available port found');\n }\n\n return port;\n}\n\n/** @return `true` if the port can still be used to start the dev server, `false` if the dev server should be skipped, and asserts if the port is now taken. */\nexport async function ensurePortAvailabilityAsync(\n projectRoot: string,\n { port }: { port: number }\n): Promise<boolean> {\n const isFreePort = await testPortAsync(port, [null]);\n // Check if port has become busy during the build.\n if (isFreePort) {\n return true;\n }\n\n const isBusy = await isBusyPortRunningSameProcessAsync(projectRoot, { port });\n if (!isBusy) {\n throw new CommandError(\n `Port \"${port}\" became busy running another process while the app was compiling. Re-run command to use a new port.`\n );\n }\n\n // Log that the dev server will not be started and that the logs will appear in another window.\n Log.log(\n '› The dev server for this app is already running in another window. Logs will appear there.'\n );\n return false;\n}\n\nfunction isRestrictedPort(port: number) {\n if (process.platform !== 'win32' && port < 1024) {\n const isRoot = process.getuid && process.getuid() === 0;\n return !isRoot;\n }\n return false;\n}\n\nasync function isBusyPortRunningSameProcessAsync(projectRoot: string, { port }: { port: number }) {\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n\n const runningProcess = isRestrictedPort(port) ? null : getRunningProcess(port);\n if (runningProcess) {\n if (runningProcess.directory === projectRoot) {\n return true;\n } else {\n return false;\n }\n }\n\n return null;\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function choosePortAsync(\n projectRoot: string,\n {\n defaultPort,\n host,\n reuseExistingPort,\n }: {\n defaultPort: number;\n host?: string;\n reuseExistingPort?: boolean;\n }\n): Promise<number | null> {\n try {\n const port = await freePortAsync(defaultPort, [host ?? null]);\n if (port === defaultPort || defaultPort === 0) {\n return port;\n }\n\n const isRestricted = port && isRestrictedPort(port);\n\n let message = isRestricted\n ? `Admin permissions are required to run a server on a port below 1024`\n : `Port ${chalk.bold(defaultPort)} is`;\n\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n const runningProcess = isRestricted ? null : getRunningProcess(defaultPort);\n\n if (runningProcess) {\n const pidTag = chalk.gray(`(pid ${runningProcess.pid})`);\n if (runningProcess.directory === projectRoot) {\n message += ` running this app in another window`;\n if (reuseExistingPort) {\n return null;\n }\n } else {\n message += ` running ${chalk.cyan(runningProcess.command)} in another window`;\n }\n message += '\\n' + chalk.gray(` ${runningProcess.directory} ${pidTag}`);\n } else {\n message += ' being used by another process';\n }\n\n Log.log(`\\u203A ${message}`);\n const { confirmAsync } = require('./prompts') as typeof import('./prompts');\n const change = await confirmAsync({\n message: `Use port ${port} instead?`,\n initial: true,\n });\n return change ? port : null;\n } catch (error: any) {\n if (error.code === 'ABORTED') {\n throw error;\n } else if (error.code === 'NON_INTERACTIVE') {\n Log.warn(chalk.yellow(error.message));\n return null;\n }\n throw error;\n }\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function resolvePortAsync(\n projectRoot: string,\n {\n /** Should opt to reuse a port that is running the same project in another window. */\n reuseExistingPort,\n /** Preferred port. */\n defaultPort,\n /** Backup port for when the default isn't available. */\n fallbackPort,\n }: {\n reuseExistingPort?: boolean;\n defaultPort?: string | number;\n fallbackPort?: number;\n } = {}\n): Promise<number | null> {\n let port: number;\n if (typeof defaultPort === 'string') {\n port = parseInt(defaultPort, 10);\n } else if (typeof defaultPort === 'number') {\n port = defaultPort;\n } else {\n port = env.RCT_METRO_PORT || fallbackPort || 8081;\n }\n\n // Only check the port when the bundler is running.\n const resolvedPort = await choosePortAsync(projectRoot, {\n defaultPort: port,\n reuseExistingPort,\n });\n if (resolvedPort == null) {\n Log.log('\\u203A Skipping dev server');\n // Skip bundling if the port is null\n } else {\n // Use the new or resolved port\n process.env.RCT_METRO_PORT = String(resolvedPort);\n }\n\n return resolvedPort;\n}\n"],"names":["choosePortAsync","ensurePortAvailabilityAsync","getFreePortAsync","resolvePortAsync","rangeStart","port","freePortAsync","CommandError","projectRoot","isFreePort","testPortAsync","isBusy","isBusyPortRunningSameProcessAsync","Log","log","isRestrictedPort","process","platform","isRoot","getuid","getRunningProcess","require","runningProcess","directory","defaultPort","host","reuseExistingPort","isRestricted","message","chalk","bold","pidTag","gray","pid","cyan","command","confirmAsync","change","initial","error","code","warn","yellow","fallbackPort","parseInt","env","RCT_METRO_PORT","resolvedPort","String"],"mappings":"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"}
@@ -33,6 +33,35 @@ _export(exports, {
33
33
  });
34
34
  const _array = require("./array");
35
35
  const _errors = require("./errors");
36
+ /** Convert ExtraArgsSpec to arg.Spec (for validation) and extract allowedValues */ function parseExtraArgMap(extraArgMap) {
37
+ const spec = {};
38
+ const allowedValues = {};
39
+ for (const [key, value] of Object.entries(extraArgMap)){
40
+ if (typeof value === 'string') {
41
+ // Alias (e.g. '-f': '--flag')
42
+ spec[key] = value;
43
+ } else if (Array.isArray(value)) {
44
+ // Tuple [Boolean, ...strings] - Boolean is enforced by the type, but check at runtime too
45
+ const [first, ...stringValues] = value;
46
+ if (first !== Boolean) {
47
+ throw new _errors.CommandError('BAD_ARGS', `Invalid extraArgMap spec for ${key}: first element must be Boolean`);
48
+ }
49
+ spec[key] = Boolean;
50
+ allowedValues[key] = [
51
+ 'true',
52
+ 'false',
53
+ ...stringValues
54
+ ];
55
+ } else {
56
+ // Boolean - any value allowed
57
+ spec[key] = Boolean;
58
+ }
59
+ }
60
+ return {
61
+ spec,
62
+ allowedValues
63
+ };
64
+ }
36
65
  /** Split up arguments that are formatted like `--foo=bar` or `-f="bar"` to `['--foo', 'bar']` */ function splitArgs(args) {
37
66
  const result = [];
38
67
  for (const arg of args){
@@ -48,27 +77,31 @@ const _errors = require("./errors");
48
77
  }
49
78
  return result;
50
79
  }
51
- async function resolveStringOrBooleanArgsAsync(args, rawMap, extraArgs) {
52
- args = splitArgs(args);
80
+ async function resolveStringOrBooleanArgsAsync(argv, rawArgMap, extraArgMap) {
81
+ let args = splitArgs(argv);
82
+ const { spec: extraArgSpec, allowedValues } = parseExtraArgMap(extraArgMap);
83
+ const combinedSpec = {
84
+ ...rawArgMap,
85
+ ...extraArgSpec
86
+ };
53
87
  // Assert any missing arguments
54
- assertUnknownArgs({
55
- ...rawMap,
56
- ...extraArgs
57
- }, args);
88
+ assertUnknownArgs(combinedSpec, args);
58
89
  // Collapse aliases into fully qualified arguments.
59
- args = collapseAliases(extraArgs, args);
90
+ args = collapseAliases(combinedSpec, args);
91
+ // Filter out array-type arguments so _resolveStringOrBooleanArgs can process the rest.
92
+ // This is necessary because _resolveStringOrBooleanArgs can't handle array-type args like --platform.
93
+ const filteredArgs = filterOutArrayArgs(args, combinedSpec);
60
94
  // Resolve all of the string or boolean arguments and the project root.
61
- return _resolveStringOrBooleanArgs({
62
- ...rawMap,
63
- ...extraArgs
64
- }, args);
95
+ return _resolveStringOrBooleanArgs(combinedSpec, filteredArgs, allowedValues);
65
96
  }
66
- async function resolveCustomBooleanArgsAsync(args, rawMap, extraArgs) {
67
- const results = await resolveStringOrBooleanArgsAsync(args, rawMap, extraArgs);
97
+ async function resolveCustomBooleanArgsAsync(argv, rawArgMap, extraArgMap) {
98
+ const results = await resolveStringOrBooleanArgsAsync(argv, rawArgMap, extraArgMap);
68
99
  return {
69
100
  ...results,
70
101
  args: Object.fromEntries(Object.entries(results.args).map(([key, value])=>{
71
- if (extraArgs[key]) {
102
+ // Skip aliases (e.g. '-f': '--flag') - only process actual flags
103
+ const extraArgValue = extraArgMap[key];
104
+ if (extraArgValue && typeof extraArgValue !== 'string') {
72
105
  if (typeof value === 'string') {
73
106
  if (![
74
107
  'true',
@@ -89,13 +122,20 @@ async function resolveCustomBooleanArgsAsync(args, rawMap, extraArgs) {
89
122
  }))
90
123
  };
91
124
  }
92
- function _resolveStringOrBooleanArgs(arg, args) {
125
+ function _resolveStringOrBooleanArgs(arg, args, allowedValues) {
93
126
  // Default project root, if a custom one is defined then it will overwrite this.
94
127
  let projectRoot = '.';
95
128
  // The resolved arguments.
96
129
  const settings = {};
97
130
  // Create a list of possible arguments, this will filter out aliases.
98
131
  const possibleArgs = Object.entries(arg).filter(([, value])=>typeof value !== 'string').map(([key])=>key);
132
+ // Check if a value is allowed for a given flag
133
+ const isAllowedValue = (flag, value)=>{
134
+ if (!allowedValues || !allowedValues[flag]) {
135
+ return true; // No restrictions, allow any value
136
+ }
137
+ return allowedValues[flag].includes(value);
138
+ };
99
139
  // Loop over arguments in reverse order so we can resolve if a value belongs to a flag.
100
140
  for(let i = args.length - 1; i > -1; i--){
101
141
  const value = args[i];
@@ -110,7 +150,7 @@ function _resolveStringOrBooleanArgs(arg, args) {
110
150
  } else {
111
151
  // Get the previous argument in the array.
112
152
  const nextValue = i > 0 ? args[i - 1] : null;
113
- if (nextValue && possibleArgs.includes(nextValue)) {
153
+ if (nextValue && possibleArgs.includes(nextValue) && isAllowedValue(nextValue, value)) {
114
154
  // We don't override arguments that are already set
115
155
  if (!(nextValue in settings)) {
116
156
  settings[nextValue] = value;
@@ -134,10 +174,11 @@ function _resolveStringOrBooleanArgs(arg, args) {
134
174
  function collapseAliases(arg, args) {
135
175
  const aliasMap = getAliasTuples(arg);
136
176
  for (const [arg, alias] of aliasMap){
137
- args = (0, _array.replaceValue)(args, arg, alias);
177
+ args = (0, _array.replaceAllValues)(args, arg, alias);
138
178
  }
139
179
  // Assert if there are duplicate flags after we collapse the aliases.
140
- assertDuplicateArgs(args, aliasMap);
180
+ // Skip array-type arguments (like --platform) which can have multiple values.
181
+ assertDuplicateArgs(args, aliasMap, arg);
141
182
  return args;
142
183
  }
143
184
  function assertUnknownArgs(arg, args) {
@@ -150,8 +191,34 @@ function assertUnknownArgs(arg, args) {
150
191
  function getAliasTuples(arg) {
151
192
  return Object.entries(arg).filter(([, value])=>typeof value === 'string');
152
193
  }
153
- function assertDuplicateArgs(args, argNameAliasTuple) {
194
+ /** Filter out array-type arguments from the spec (and their values).
195
+ * This is needed because _resolveStringOrBooleanArgs can't handle array args like --platform.
196
+ */ function filterOutArrayArgs(args, spec) {
197
+ // Get the set of flag names that are array types
198
+ const arrayFlags = new Set(Object.entries(spec).filter(([, value])=>Array.isArray(value)).map(([key])=>key));
199
+ if (arrayFlags.size === 0) {
200
+ return args;
201
+ }
202
+ const result = [];
203
+ for(let i = 0; i < args.length; i++){
204
+ const arg = args[i];
205
+ if (arrayFlags.has(arg)) {
206
+ // Skip this flag and its value if it has one
207
+ if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
208
+ i++;
209
+ }
210
+ } else {
211
+ result.push(arg);
212
+ }
213
+ }
214
+ return result;
215
+ }
216
+ function assertDuplicateArgs(args, argNameAliasTuple, spec) {
154
217
  for (const [argName, argNameAlias] of argNameAliasTuple){
218
+ // Skip array-type arguments (like --platform) which can have multiple values
219
+ if (spec && Array.isArray(spec[argNameAlias])) {
220
+ continue;
221
+ }
155
222
  if (args.filter((a)=>[
156
223
  argName,
157
224
  argNameAlias
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/resolveArgs.ts"],"sourcesContent":["import arg, { Spec } from 'arg';\n\nimport { replaceValue } from './array';\nimport { CommandError } from './errors';\n\n/** Split up arguments that are formatted like `--foo=bar` or `-f=\"bar\"` to `['--foo', 'bar']` */\nfunction splitArgs(args: string[]): string[] {\n const result: string[] = [];\n\n for (const arg of args) {\n if (arg.startsWith('-')) {\n const [key, ...props] = arg.split('=');\n result.push(key);\n if (props.length) {\n result.push(props.join('='));\n }\n } else {\n result.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * Enables the resolution of arguments that can either be a string or a boolean.\n *\n * @param args arguments that were passed to the command.\n * @param rawMap raw map of arguments that are passed to the command.\n * @param extraArgs extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveStringOrBooleanArgsAsync(\n args: string[],\n rawMap: arg.Spec,\n extraArgs: arg.Spec\n) {\n args = splitArgs(args);\n\n // Assert any missing arguments\n assertUnknownArgs(\n {\n ...rawMap,\n ...extraArgs,\n },\n args\n );\n\n // Collapse aliases into fully qualified arguments.\n args = collapseAliases(extraArgs, args);\n\n // Resolve all of the string or boolean arguments and the project root.\n return _resolveStringOrBooleanArgs({ ...rawMap, ...extraArgs }, args);\n}\n\n/**\n * Enables the resolution of boolean arguments that can be formatted like `--foo=true` or `--foo false`\n *\n * @param args arguments that were passed to the command.\n * @param rawMap raw map of arguments that are passed to the command.\n * @param extraArgs extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveCustomBooleanArgsAsync(\n args: string[],\n rawMap: arg.Spec,\n extraArgs: arg.Spec\n) {\n const results = await resolveStringOrBooleanArgsAsync(args, rawMap, extraArgs);\n\n return {\n ...results,\n args: Object.fromEntries(\n Object.entries(results.args).map(([key, value]) => {\n if (extraArgs[key]) {\n if (typeof value === 'string') {\n if (!['true', 'false'].includes(value)) {\n throw new CommandError(\n 'BAD_ARGS',\n `Invalid boolean argument: ${key}=${value}. Expected one of: true, false`\n );\n }\n return [key, value === 'true'];\n }\n }\n return [key, value];\n })\n ),\n };\n}\n\nexport function _resolveStringOrBooleanArgs(arg: Spec, args: string[]) {\n // Default project root, if a custom one is defined then it will overwrite this.\n let projectRoot: string = '.';\n // The resolved arguments.\n const settings: Record<string, string | boolean | undefined> = {};\n\n // Create a list of possible arguments, this will filter out aliases.\n const possibleArgs = Object.entries(arg)\n .filter(([, value]) => typeof value !== 'string')\n .map(([key]) => key);\n\n // Loop over arguments in reverse order so we can resolve if a value belongs to a flag.\n for (let i = args.length - 1; i > -1; i--) {\n const value = args[i];\n // At this point we should have converted all aliases to fully qualified arguments.\n if (value.startsWith('--')) {\n // If we ever find an argument then it must be a boolean because we are checking in reverse\n // and removing arguments from the array if we find a string.\n // We don't override arguments that are already set\n if (!(value in settings)) {\n settings[value] = true;\n }\n } else {\n // Get the previous argument in the array.\n const nextValue = i > 0 ? args[i - 1] : null;\n if (nextValue && possibleArgs.includes(nextValue)) {\n // We don't override arguments that are already set\n if (!(nextValue in settings)) {\n settings[nextValue] = value;\n }\n i--;\n } else if (\n // If the last value is not a flag and it doesn't have a recognized flag before it (instead having a string value or nothing)\n // then it must be the project root.\n i ===\n args.length - 1\n ) {\n projectRoot = value;\n } else {\n // This will asserts if two strings are passed in a row and not at the end of the line.\n throw new CommandError('BAD_ARGS', `Unknown argument: ${value}`);\n }\n }\n }\n\n return {\n args: settings,\n projectRoot,\n };\n}\n\n/** Convert all aliases to fully qualified flag names. */\nexport function collapseAliases(arg: Spec, args: string[]): string[] {\n const aliasMap = getAliasTuples(arg);\n\n for (const [arg, alias] of aliasMap) {\n args = replaceValue(args, arg, alias);\n }\n\n // Assert if there are duplicate flags after we collapse the aliases.\n assertDuplicateArgs(args, aliasMap);\n return args;\n}\n\n/** Assert that the spec has unknown arguments. */\nexport function assertUnknownArgs(arg: Spec, args: string[]) {\n const allowedArgs = Object.keys(arg);\n const unknownArgs = args.filter((arg) => !allowedArgs.includes(arg) && arg.startsWith('-'));\n if (unknownArgs.length > 0) {\n throw new CommandError(`Unknown arguments: ${unknownArgs.join(', ')}`);\n }\n}\n\nfunction getAliasTuples(arg: Spec): [string, string][] {\n return Object.entries(arg).filter(([, value]) => typeof value === 'string') as [string, string][];\n}\n\n/** Asserts that a duplicate flag has been used, this naively throws without knowing if an alias or flag were used as the duplicate. */\nexport function assertDuplicateArgs(args: string[], argNameAliasTuple: [string, string][]) {\n for (const [argName, argNameAlias] of argNameAliasTuple) {\n if (args.filter((a) => [argName, argNameAlias].includes(a)).length > 1) {\n throw new CommandError(\n 'BAD_ARGS',\n `Can only provide one instance of ${argName} or ${argNameAlias}`\n );\n }\n }\n}\n\nexport function assertNonBooleanArg(argName: string, arg: any): asserts arg is string | string[] {\n if (arg == null || typeof arg === 'boolean') {\n throw new CommandError('BAD_ARGS', `Expected input for arg ${argName}`);\n }\n}\n"],"names":["_resolveStringOrBooleanArgs","assertDuplicateArgs","assertNonBooleanArg","assertUnknownArgs","collapseAliases","resolveCustomBooleanArgsAsync","resolveStringOrBooleanArgsAsync","splitArgs","args","result","arg","startsWith","key","props","split","push","length","join","rawMap","extraArgs","results","Object","fromEntries","entries","map","value","includes","CommandError","projectRoot","settings","possibleArgs","filter","i","nextValue","aliasMap","getAliasTuples","alias","replaceValue","allowedArgs","keys","unknownArgs","argNameAliasTuple","argName","argNameAlias","a"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/resolveArgs.ts"],"sourcesContent":["import arg, { Spec } from 'arg';\n\nimport { replaceAllValues } from './array';\nimport { CommandError } from './errors';\n\n/**\n * Spec for extra arguments that can be string or boolean.\n * - `'--flag': Boolean` → accepts any value\n * - `'--flag': [Boolean, 'a', 'b']` → restricted to 'true', 'false', 'a', 'b'\n * - `'-f': '--flag'` → alias\n */\nexport type ExtraArgsSpec = Record<string, typeof Boolean | string | [typeof Boolean, ...string[]]>;\n\n/** Convert ExtraArgsSpec to arg.Spec (for validation) and extract allowedValues */\nfunction parseExtraArgMap(extraArgMap: ExtraArgsSpec): {\n spec: arg.Spec;\n allowedValues: Record<string, string[]>;\n} {\n const spec: arg.Spec = {};\n const allowedValues: Record<string, string[]> = {};\n\n for (const [key, value] of Object.entries(extraArgMap)) {\n if (typeof value === 'string') {\n // Alias (e.g. '-f': '--flag')\n spec[key] = value;\n } else if (Array.isArray(value)) {\n // Tuple [Boolean, ...strings] - Boolean is enforced by the type, but check at runtime too\n const [first, ...stringValues] = value;\n if (first !== Boolean) {\n throw new CommandError(\n 'BAD_ARGS',\n `Invalid extraArgMap spec for ${key}: first element must be Boolean`\n );\n }\n spec[key] = Boolean;\n allowedValues[key] = ['true', 'false', ...stringValues];\n } else {\n // Boolean - any value allowed\n spec[key] = Boolean;\n }\n }\n\n return { spec, allowedValues };\n}\n\n/** Split up arguments that are formatted like `--foo=bar` or `-f=\"bar\"` to `['--foo', 'bar']` */\nfunction splitArgs(args: string[]): string[] {\n const result: string[] = [];\n\n for (const arg of args) {\n if (arg.startsWith('-')) {\n const [key, ...props] = arg.split('=');\n result.push(key);\n if (props.length) {\n result.push(props.join('='));\n }\n } else {\n result.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * Enables the resolution of arguments that can either be a string or a boolean.\n *\n * @param argv arguments that were passed to the command.\n * @param rawArgMap base argument spec defining valid arguments and their types.\n * @param extraArgMap extra arguments and aliases that should be resolved as string or boolean.\n * - `'--flag': Boolean` → accepts any value\n * - `'--flag': [Boolean, 'a', 'b']` → restricted to 'true', 'false', 'a', 'b'\n * - `'-f': '--flag'` → alias\n * @returns parsed arguments and project root.\n */\nexport async function resolveStringOrBooleanArgsAsync(\n argv: string[],\n rawArgMap: arg.Spec,\n extraArgMap: ExtraArgsSpec\n) {\n let args = splitArgs(argv);\n\n const { spec: extraArgSpec, allowedValues } = parseExtraArgMap(extraArgMap);\n const combinedSpec = { ...rawArgMap, ...extraArgSpec };\n\n // Assert any missing arguments\n assertUnknownArgs(combinedSpec, args);\n\n // Collapse aliases into fully qualified arguments.\n args = collapseAliases(combinedSpec, args);\n\n // Filter out array-type arguments so _resolveStringOrBooleanArgs can process the rest.\n // This is necessary because _resolveStringOrBooleanArgs can't handle array-type args like --platform.\n const filteredArgs = filterOutArrayArgs(args, combinedSpec);\n\n // Resolve all of the string or boolean arguments and the project root.\n return _resolveStringOrBooleanArgs(combinedSpec, filteredArgs, allowedValues);\n}\n\n/**\n * Enables the resolution of boolean arguments that can be formatted like `--foo=true` or `--foo false`\n *\n * @param argv arguments that were passed to the command.\n * @param rawArgMap base argument spec defining valid arguments and their types.\n * @param extraArgMap extra arguments and aliases that should be resolved as string or boolean.\n * @returns parsed arguments and project root.\n */\nexport async function resolveCustomBooleanArgsAsync(\n argv: string[],\n rawArgMap: arg.Spec,\n extraArgMap: ExtraArgsSpec\n) {\n const results = await resolveStringOrBooleanArgsAsync(argv, rawArgMap, extraArgMap);\n\n return {\n ...results,\n args: Object.fromEntries(\n Object.entries(results.args).map(([key, value]) => {\n // Skip aliases (e.g. '-f': '--flag') - only process actual flags\n const extraArgValue = extraArgMap[key];\n if (extraArgValue && typeof extraArgValue !== 'string') {\n if (typeof value === 'string') {\n if (!['true', 'false'].includes(value)) {\n throw new CommandError(\n 'BAD_ARGS',\n `Invalid boolean argument: ${key}=${value}. Expected one of: true, false`\n );\n }\n return [key, value === 'true'];\n }\n }\n return [key, value];\n })\n ),\n };\n}\n\nexport function _resolveStringOrBooleanArgs(\n arg: Spec,\n args: string[],\n allowedValues?: Record<string, string[]>\n) {\n // Default project root, if a custom one is defined then it will overwrite this.\n let projectRoot: string = '.';\n // The resolved arguments.\n const settings: Record<string, string | boolean | undefined> = {};\n\n // Create a list of possible arguments, this will filter out aliases.\n const possibleArgs = Object.entries(arg)\n .filter(([, value]) => typeof value !== 'string')\n .map(([key]) => key);\n\n // Check if a value is allowed for a given flag\n const isAllowedValue = (flag: string, value: string): boolean => {\n if (!allowedValues || !allowedValues[flag]) {\n return true; // No restrictions, allow any value\n }\n return allowedValues[flag].includes(value);\n };\n\n // Loop over arguments in reverse order so we can resolve if a value belongs to a flag.\n for (let i = args.length - 1; i > -1; i--) {\n const value = args[i];\n // At this point we should have converted all aliases to fully qualified arguments.\n if (value.startsWith('--')) {\n // If we ever find an argument then it must be a boolean because we are checking in reverse\n // and removing arguments from the array if we find a string.\n // We don't override arguments that are already set\n if (!(value in settings)) {\n settings[value] = true;\n }\n } else {\n // Get the previous argument in the array.\n const nextValue = i > 0 ? args[i - 1] : null;\n if (nextValue && possibleArgs.includes(nextValue) && isAllowedValue(nextValue, value)) {\n // We don't override arguments that are already set\n if (!(nextValue in settings)) {\n settings[nextValue] = value;\n }\n i--;\n } else if (\n // If the last value is not a flag and it doesn't have a recognized flag before it (instead having a string value or nothing)\n // then it must be the project root.\n i ===\n args.length - 1\n ) {\n projectRoot = value;\n } else {\n // This will asserts if two strings are passed in a row and not at the end of the line.\n throw new CommandError('BAD_ARGS', `Unknown argument: ${value}`);\n }\n }\n }\n\n return {\n args: settings,\n projectRoot,\n };\n}\n\n/** Convert all aliases to fully qualified flag names. */\nexport function collapseAliases(arg: Spec, args: string[]): string[] {\n const aliasMap = getAliasTuples(arg);\n\n for (const [arg, alias] of aliasMap) {\n args = replaceAllValues(args, arg, alias);\n }\n\n // Assert if there are duplicate flags after we collapse the aliases.\n // Skip array-type arguments (like --platform) which can have multiple values.\n assertDuplicateArgs(args, aliasMap, arg);\n return args;\n}\n\n/** Assert that the spec has unknown arguments. */\nexport function assertUnknownArgs(arg: Spec, args: string[]) {\n const allowedArgs = Object.keys(arg);\n const unknownArgs = args.filter((arg) => !allowedArgs.includes(arg) && arg.startsWith('-'));\n if (unknownArgs.length > 0) {\n throw new CommandError(`Unknown arguments: ${unknownArgs.join(', ')}`);\n }\n}\n\nfunction getAliasTuples(arg: Spec): [string, string][] {\n return Object.entries(arg).filter(([, value]) => typeof value === 'string') as [string, string][];\n}\n\n/** Filter out array-type arguments from the spec (and their values).\n * This is needed because _resolveStringOrBooleanArgs can't handle array args like --platform.\n */\nfunction filterOutArrayArgs(args: string[], spec: Spec): string[] {\n // Get the set of flag names that are array types\n const arrayFlags = new Set(\n Object.entries(spec)\n .filter(([, value]) => Array.isArray(value))\n .map(([key]) => key)\n );\n\n if (arrayFlags.size === 0) {\n return args;\n }\n\n const result: string[] = [];\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arrayFlags.has(arg)) {\n // Skip this flag and its value if it has one\n if (i + 1 < args.length && !args[i + 1].startsWith('-')) {\n i++;\n }\n } else {\n result.push(arg);\n }\n }\n return result;\n}\n\n/** Asserts that a duplicate flag has been used, this naively throws without knowing if an alias or flag were used as the duplicate. */\nexport function assertDuplicateArgs(\n args: string[],\n argNameAliasTuple: [string, string][],\n spec?: Spec\n) {\n for (const [argName, argNameAlias] of argNameAliasTuple) {\n // Skip array-type arguments (like --platform) which can have multiple values\n if (spec && Array.isArray(spec[argNameAlias])) {\n continue;\n }\n if (args.filter((a) => [argName, argNameAlias].includes(a)).length > 1) {\n throw new CommandError(\n 'BAD_ARGS',\n `Can only provide one instance of ${argName} or ${argNameAlias}`\n );\n }\n }\n}\n\nexport function assertNonBooleanArg(argName: string, arg: any): asserts arg is string | string[] {\n if (arg == null || typeof arg === 'boolean') {\n throw new CommandError('BAD_ARGS', `Expected input for arg ${argName}`);\n }\n}\n"],"names":["_resolveStringOrBooleanArgs","assertDuplicateArgs","assertNonBooleanArg","assertUnknownArgs","collapseAliases","resolveCustomBooleanArgsAsync","resolveStringOrBooleanArgsAsync","parseExtraArgMap","extraArgMap","spec","allowedValues","key","value","Object","entries","Array","isArray","first","stringValues","Boolean","CommandError","splitArgs","args","result","arg","startsWith","props","split","push","length","join","argv","rawArgMap","extraArgSpec","combinedSpec","filteredArgs","filterOutArrayArgs","results","fromEntries","map","extraArgValue","includes","projectRoot","settings","possibleArgs","filter","isAllowedValue","flag","i","nextValue","aliasMap","getAliasTuples","alias","replaceAllValues","allowedArgs","keys","unknownArgs","arrayFlags","Set","size","has","argNameAliasTuple","argName","argNameAlias","a"],"mappings":"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"}
@@ -33,7 +33,7 @@ class FetchClient {
33
33
  this.headers = {
34
34
  accept: 'application/json',
35
35
  'content-type': 'application/json',
36
- 'user-agent': `expo-cli/${"55.0.2"}`,
36
+ 'user-agent': `expo-cli/${"55.0.4"}`,
37
37
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
38
38
  };
39
39
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "55.0.2"
86
+ version: "55.0.4"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "55.0.2",
3
+ "version": "55.0.4",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -43,21 +43,21 @@
43
43
  "dependencies": {
44
44
  "@0no-co/graphql.web": "^1.0.8",
45
45
  "@expo/code-signing-certificates": "^0.0.6",
46
- "@expo/config": "~55.0.2",
47
- "@expo/config-plugins": "~55.0.2",
46
+ "@expo/config": "~55.0.3",
47
+ "@expo/config-plugins": "~55.0.3",
48
48
  "@expo/devcert": "^1.2.1",
49
- "@expo/env": "~2.0.10",
50
- "@expo/image-utils": "^0.8.10",
51
- "@expo/json-file": "^10.0.10",
49
+ "@expo/env": "~2.0.11",
50
+ "@expo/image-utils": "^0.8.11",
51
+ "@expo/json-file": "^10.0.11",
52
52
  "@expo/metro": "~54.2.0",
53
- "@expo/metro-config": "~55.0.2",
54
- "@expo/osascript": "^2.4.1",
55
- "@expo/package-manager": "^1.10.1",
56
- "@expo/plist": "^0.5.1",
57
- "@expo/prebuild-config": "^55.0.2",
58
- "@expo/router-server": "^55.0.2",
59
- "@expo/log-box": "55.0.1",
60
- "@expo/schema-utils": "^55.0.1",
53
+ "@expo/metro-config": "~55.0.3",
54
+ "@expo/osascript": "^2.4.2",
55
+ "@expo/package-manager": "^1.10.2",
56
+ "@expo/plist": "^0.5.2",
57
+ "@expo/prebuild-config": "^55.0.3",
58
+ "@expo/router-server": "^55.0.3",
59
+ "@expo/log-box": "55.0.3",
60
+ "@expo/schema-utils": "^55.0.2",
61
61
  "@expo/spawn-async": "^1.7.2",
62
62
  "@expo/ws-tunnel": "^1.0.1",
63
63
  "@expo/xcpretty": "^4.3.0",
@@ -76,8 +76,7 @@
76
76
  "debug": "^4.3.4",
77
77
  "dnssd-advertise": "^1.1.1",
78
78
  "env-editor": "^0.4.1",
79
- "expo-server": "^55.0.1",
80
- "freeport-async": "^2.0.0",
79
+ "expo-server": "^55.0.2",
81
80
  "getenv": "^2.0.0",
82
81
  "glob": "^13.0.0",
83
82
  "lan-network": "^0.1.6",
@@ -86,7 +85,6 @@
86
85
  "npm-package-arg": "^11.0.0",
87
86
  "ora": "^3.4.0",
88
87
  "picomatch": "^3.0.1",
89
- "pretty-bytes": "^5.6.0",
90
88
  "pretty-format": "^29.7.0",
91
89
  "progress": "^2.0.3",
92
90
  "prompts": "^2.3.2",
@@ -172,5 +170,5 @@
172
170
  "tree-kill": "^1.2.2",
173
171
  "tsd": "^0.28.1"
174
172
  },
175
- "gitHead": "326a6b473b3d2a90f3f96e9eea8f995bb2677f30"
173
+ "gitHead": "220594d473a3100248087151004ae4acb7282d5f"
176
174
  }