@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
@@ -19,6 +19,13 @@ _export(exports, {
19
19
  return envIsWebcontainer;
20
20
  }
21
21
  });
22
+ function _env() {
23
+ const data = require("@expo/env");
24
+ _env = function() {
25
+ return data;
26
+ };
27
+ return data;
28
+ }
22
29
  function _getenv() {
23
30
  const data = require("getenv");
24
31
  _getenv = function() {
@@ -69,7 +76,9 @@ class Env {
69
76
  return (0, _getenv().boolish)('EXPO_NO_TELEMETRY_DETACH', false);
70
77
  }
71
78
  /** local directory to the universe repo for testing locally */ get EXPO_UNIVERSE_DIR() {
72
- return (0, _getenv().string)('EXPO_UNIVERSE_DIR', '');
79
+ // Read from the pre-dotenv env — this is a filesystem path used by internal
80
+ // tooling; a project `.env` overriding it could redirect file access.
81
+ return (0, _env().getOriginalEnvValue)('EXPO_UNIVERSE_DIR') || '';
73
82
  }
74
83
  /** @deprecated Default Webpack host string */ get WEB_HOST() {
75
84
  return (0, _getenv().string)('WEB_HOST', '0.0.0.0');
@@ -92,6 +101,9 @@ class Env {
92
101
  /** Disable printing the QR code in the interactive Terminal UI. */ get EXPO_NO_QR_CODE() {
93
102
  return (0, _getenv().boolish)('EXPO_NO_QR_CODE', false);
94
103
  }
104
+ /** Resolve application IDs from Expo app config before native files in `expo start`. */ get EXPO_RUN_PREFER_APP_CONFIG_ID() {
105
+ return (0, _getenv().boolish)('EXPO_RUN_PREFER_APP_CONFIG_ID', false);
106
+ }
95
107
  /** The React Metro port that's baked into react-native scripts and tools. */ get RCT_METRO_PORT() {
96
108
  return (0, _getenv().int)('RCT_METRO_PORT', 0);
97
109
  }
@@ -108,7 +120,8 @@ class Env {
108
120
  * Overwrite the dev server URL, disregarding the `--port`, `--host`, `--tunnel`, `--lan`, `--localhost` arguments.
109
121
  * This is useful for browser editors that require custom proxy URLs.
110
122
  */ get EXPO_PACKAGER_PROXY_URL() {
111
- return (0, _getenv().string)('EXPO_PACKAGER_PROXY_URL', '');
123
+ // Read from the pre-dotenv env — overrides dev server URL served to clients.
124
+ return (0, _env().getOriginalEnvValue)('EXPO_PACKAGER_PROXY_URL') || '';
112
125
  }
113
126
  /**
114
127
  * **Experimental** - Disable using `exp.direct` as the hostname for
@@ -152,8 +165,10 @@ class Env {
152
165
  * This flag is internal and was added for external tools.
153
166
  * @internal
154
167
  */ get EXPO_OVERRIDE_METRO_CONFIG() {
155
- var _process_env_EXPO_OVERRIDE_METRO_CONFIG;
156
- return ((_process_env_EXPO_OVERRIDE_METRO_CONFIG = _nodeprocess().default.env.EXPO_OVERRIDE_METRO_CONFIG) == null ? void 0 : _process_env_EXPO_OVERRIDE_METRO_CONFIG.trim()) || undefined;
168
+ var _getOriginalEnvValue;
169
+ // Read from the pre-dotenv env this path is `require()`d as Metro config,
170
+ // so a project `.env` overriding it would execute attacker code in-process.
171
+ return ((_getOriginalEnvValue = (0, _env().getOriginalEnvValue)('EXPO_OVERRIDE_METRO_CONFIG')) == null ? void 0 : _getOriginalEnvValue.trim()) || undefined;
157
172
  }
158
173
  /**
159
174
  * Use the network inspector by overriding the metro inspector proxy with a custom version.
@@ -198,7 +213,7 @@ class Env {
198
213
  return (0, _getenv().boolish)('EXPO_USE_METRO_REQUIRE', false);
199
214
  }
200
215
  /** Internal key used to pass eager bundle data from the CLI to the native run scripts during `npx expo run` commands. */ get __EXPO_EAGER_BUNDLE_OPTIONS() {
201
- return (0, _getenv().string)('__EXPO_EAGER_BUNDLE_OPTIONS', '');
216
+ return (0, _env().getOriginalEnvValue)('__EXPO_EAGER_BUNDLE_OPTIONS') || '';
202
217
  }
203
218
  /** Disable server deployment during production builds (during `expo export:embed`). This is useful for testing API routes and server components against a local server. */ get EXPO_NO_DEPLOY() {
204
219
  return (0, _getenv().boolish)('EXPO_NO_DEPLOY', false);
@@ -230,6 +245,13 @@ class Env {
230
245
  /** Disable @react-navigation checks for expo-router projects */ get EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK() {
231
246
  return (0, _getenv().boolish)('EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK', false);
232
247
  }
248
+ /**
249
+ * Disable Material Symbols (`md`) icon support in expo-router's NativeTabs on Android.
250
+ * When enabled, the Metro resolver swaps the Android-specific md icon converter for a no-op
251
+ * stub, so the `expo-symbols` dependency is tree-shaken out of the Android bundle.
252
+ */ get EXPO_ROUTER_DISABLE_NATIVE_TABS_MD() {
253
+ return (0, _getenv().boolish)('EXPO_ROUTER_DISABLE_NATIVE_TABS_MD', false);
254
+ }
233
255
  /** Disable by falsy value live binding in experimental import export support. Enabled by default. */ get EXPO_UNSTABLE_LIVE_BINDINGS() {
234
256
  return (0, _getenv().boolish)('EXPO_UNSTABLE_LIVE_BINDINGS', true);
235
257
  }
@@ -240,7 +262,8 @@ class Env {
240
262
  if (value === '1' || value.toLowerCase() === 'true') {
241
263
  return this.EXPO_STAGING ? 'staging-mcp.expo.dev' : 'mcp.expo.dev';
242
264
  }
243
- return value;
265
+ // Re-read from the pre-dotenv env — overrides dev server URL served to clients.
266
+ return (0, _env().getOriginalEnvValue)('EXPO_UNSTABLE_MCP_SERVER') || '';
244
267
  }
245
268
  /** Enable Expo Log Box for iOS and Android (Web is enabled by default) */ get EXPO_UNSTABLE_LOG_BOX() {
246
269
  return (0, _getenv().boolish)('EXPO_UNSTABLE_LOG_BOX', false);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/env.ts"],"sourcesContent":["import { boolish, int, string } from 'getenv';\nimport process from 'node:process';\n\n// @expo/webpack-config -> expo-pwa -> @expo/image-utils: EXPO_IMAGE_UTILS_NO_SHARP\n\n// TODO: EXPO_CLI_USERNAME, EXPO_CLI_PASSWORD\n\nclass Env {\n /** Enable profiling metrics */\n get EXPO_PROFILE() {\n return boolish('EXPO_PROFILE', false);\n }\n\n /** Enable debug logging */\n get EXPO_DEBUG() {\n return boolish('EXPO_DEBUG', false);\n }\n\n /** Disable all network requests */\n get EXPO_OFFLINE() {\n return boolish('EXPO_OFFLINE', false);\n }\n\n /** Enable the beta version of Expo (TODO: Should this just be in the beta version of expo releases?) */\n get EXPO_BETA() {\n return boolish('EXPO_BETA', false);\n }\n\n /** Enable staging API environment */\n get EXPO_STAGING() {\n return boolish('EXPO_STAGING', false);\n }\n\n /** Enable local API environment */\n get EXPO_LOCAL() {\n return boolish('EXPO_LOCAL', false);\n }\n\n /** Is running in non-interactive CI mode */\n get CI() {\n return boolish('CI', false);\n }\n\n /** Disable telemetry (analytics) */\n get EXPO_NO_TELEMETRY() {\n return boolish('EXPO_NO_TELEMETRY', false);\n }\n\n /** Disable detaching telemetry to separate process */\n get EXPO_NO_TELEMETRY_DETACH() {\n return boolish('EXPO_NO_TELEMETRY_DETACH', false);\n }\n\n /** local directory to the universe repo for testing locally */\n get EXPO_UNIVERSE_DIR() {\n return string('EXPO_UNIVERSE_DIR', '');\n }\n\n /** @deprecated Default Webpack host string */\n get WEB_HOST() {\n return string('WEB_HOST', '0.0.0.0');\n }\n\n /** Skip warning users about a dirty git status */\n get EXPO_NO_GIT_STATUS() {\n return boolish('EXPO_NO_GIT_STATUS', true);\n }\n /** Disable auto web setup */\n get EXPO_NO_WEB_SETUP() {\n return boolish('EXPO_NO_WEB_SETUP', envIsHeadless());\n }\n /** Disable auto TypeScript setup */\n get EXPO_NO_TYPESCRIPT_SETUP() {\n return boolish('EXPO_NO_TYPESCRIPT_SETUP', false);\n }\n /** Disable all API caches. Does not disable bundler caches. */\n get EXPO_NO_CACHE() {\n return boolish('EXPO_NO_CACHE', false);\n }\n /** Disable the app select redirect page. */\n get EXPO_NO_REDIRECT_PAGE() {\n return boolish('EXPO_NO_REDIRECT_PAGE', false);\n }\n /** Disable printing the QR code in the interactive Terminal UI. */\n get EXPO_NO_QR_CODE(): boolean {\n return boolish('EXPO_NO_QR_CODE', false);\n }\n /** The React Metro port that's baked into react-native scripts and tools. */\n get RCT_METRO_PORT() {\n return int('RCT_METRO_PORT', 0);\n }\n /** Skip validating the manifest during `export`. */\n get EXPO_SKIP_MANIFEST_VALIDATION_TOKEN(): boolean {\n return !!string('EXPO_SKIP_MANIFEST_VALIDATION_TOKEN', '');\n }\n\n /** Public folder path relative to the project root. Default to `public` */\n get EXPO_PUBLIC_FOLDER(): string {\n return string('EXPO_PUBLIC_FOLDER', 'public');\n }\n\n /** Higher priority `$EDIOTR` variable for indicating which editor to use when pressing `o` in the Terminal UI. */\n get EXPO_EDITOR(): string {\n return string('EXPO_EDITOR', '');\n }\n\n /**\n * Overwrite the dev server URL, disregarding the `--port`, `--host`, `--tunnel`, `--lan`, `--localhost` arguments.\n * This is useful for browser editors that require custom proxy URLs.\n */\n get EXPO_PACKAGER_PROXY_URL(): string {\n return string('EXPO_PACKAGER_PROXY_URL', '');\n }\n\n /**\n * **Experimental** - Disable using `exp.direct` as the hostname for\n * `--tunnel` connections. This enables **https://** forwarding which\n * can be used to test universal links on iOS.\n *\n * This may cause issues with `expo-linking` and Expo Go.\n *\n * Select the exact subdomain by passing a string value that is not one of: `true`, `false`, `1`, `0`.\n */\n get EXPO_TUNNEL_SUBDOMAIN(): string | boolean {\n const subdomain = string('EXPO_TUNNEL_SUBDOMAIN', '');\n if (['0', 'false', ''].includes(subdomain)) {\n return false;\n } else if (['1', 'true'].includes(subdomain)) {\n return true;\n }\n return subdomain;\n }\n\n /**\n * Force Expo CLI to use the [`resolver.resolverMainFields`](https://facebook.github.io/metro/docs/configuration/#resolvermainfields) from the project `metro.config.js` for all platforms.\n *\n * By default, Expo CLI will use `['browser', 'module', 'main']` (default for Webpack) for web and the user-defined main fields for other platforms.\n */\n get EXPO_METRO_NO_MAIN_FIELD_OVERRIDE(): boolean {\n return boolish('EXPO_METRO_NO_MAIN_FIELD_OVERRIDE', false);\n }\n\n /**\n * HTTP/HTTPS proxy to connect to for network requests. Configures [https-proxy-agent](https://www.npmjs.com/package/https-proxy-agent).\n */\n get HTTP_PROXY(): string {\n return process.env.HTTP_PROXY || process.env.http_proxy || '';\n }\n\n /**\n * Instructs a different Metro config to be loaded.\n * The path, according to metro-config, should be a path relative to the current working directory.\n * This flag is internal and was added for external tools.\n * @internal\n */\n get EXPO_OVERRIDE_METRO_CONFIG(): string | undefined {\n return process.env.EXPO_OVERRIDE_METRO_CONFIG?.trim() || undefined;\n }\n\n /**\n * Use the network inspector by overriding the metro inspector proxy with a custom version.\n * @deprecated This has been replaced by `@react-native/dev-middleware` and is now unused.\n */\n get EXPO_NO_INSPECTOR_PROXY(): boolean {\n return boolish('EXPO_NO_INSPECTOR_PROXY', false);\n }\n\n /** Disable lazy bundling in Metro bundler. */\n get EXPO_NO_METRO_LAZY() {\n return boolish('EXPO_NO_METRO_LAZY', false);\n }\n\n /**\n * Enable the unstable inverse dependency stack trace for Metro bundling errors.\n * @deprecated This will be removed in the future.\n */\n get EXPO_METRO_UNSTABLE_ERRORS() {\n return boolish('EXPO_METRO_UNSTABLE_ERRORS', true);\n }\n\n /** Disable Environment Variable injection in client bundles. */\n get EXPO_NO_CLIENT_ENV_VARS(): boolean {\n return boolish('EXPO_NO_CLIENT_ENV_VARS', false);\n }\n\n /** Set the default `user` that should be passed to `--user` with ADB commands. Used for installing APKs on Android devices with multiple profiles. Defaults to `0`. */\n get EXPO_ADB_USER(): string {\n return string('EXPO_ADB_USER', '0');\n }\n\n /** Used internally to enable E2E utilities. This behavior is not stable to external users. */\n get __EXPO_E2E_TEST(): boolean {\n return boolish('__EXPO_E2E_TEST', false);\n }\n\n /** Unstable: Force single-bundle exports in production. */\n get EXPO_NO_BUNDLE_SPLITTING(): boolean {\n return boolish('EXPO_NO_BUNDLE_SPLITTING', false);\n }\n\n /**\n * Enable Atlas to gather bundle information during development or export.\n * Note, because this used to be an experimental feature, both `EXPO_ATLAS` and `EXPO_UNSTABLE_ATLAS` are supported.\n */\n get EXPO_ATLAS() {\n return boolish('EXPO_ATLAS', boolish('EXPO_UNSTABLE_ATLAS', false));\n }\n\n /** Unstable: Enable tree shaking for Metro. */\n get EXPO_UNSTABLE_TREE_SHAKING() {\n return boolish('EXPO_UNSTABLE_TREE_SHAKING', false);\n }\n\n /** Unstable: Enable eager bundling where transformation runs uncached after the entire bundle has been created. This is required for production tree shaking and less optimized for development bundling. */\n get EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH() {\n return boolish('EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH', false);\n }\n\n /** Enable the use of Expo's custom metro require implementation. The custom require supports better debugging, tree shaking, and React Server Components. */\n get EXPO_USE_METRO_REQUIRE() {\n return boolish('EXPO_USE_METRO_REQUIRE', false);\n }\n\n /** Internal key used to pass eager bundle data from the CLI to the native run scripts during `npx expo run` commands. */\n get __EXPO_EAGER_BUNDLE_OPTIONS() {\n return string('__EXPO_EAGER_BUNDLE_OPTIONS', '');\n }\n\n /** Disable server deployment during production builds (during `expo export:embed`). This is useful for testing API routes and server components against a local server. */\n get EXPO_NO_DEPLOY(): boolean {\n return boolish('EXPO_NO_DEPLOY', false);\n }\n\n /** Enable hydration during development when rendering Expo Web */\n get EXPO_WEB_DEV_HYDRATE(): boolean {\n return boolish('EXPO_WEB_DEV_HYDRATE', false);\n }\n\n /** Enable experimental React Server Functions support. */\n get EXPO_UNSTABLE_SERVER_FUNCTIONS(): boolean {\n return boolish('EXPO_UNSTABLE_SERVER_FUNCTIONS', false);\n }\n\n /** Enable unstable/experimental support for deploying the native server in `npx expo run` commands. */\n get EXPO_UNSTABLE_DEPLOY_SERVER(): boolean {\n return boolish('EXPO_UNSTABLE_DEPLOY_SERVER', false);\n }\n\n /** Is running in EAS Build. This is set by EAS: https://docs.expo.dev/eas/environment-variables/ */\n get EAS_BUILD(): boolean {\n return boolish('EAS_BUILD', false);\n }\n\n /** Disable the React Native Directory compatibility check for new architecture when installing packages */\n get EXPO_NO_NEW_ARCH_COMPAT_CHECK(): boolean {\n return boolish('EXPO_NO_NEW_ARCH_COMPAT_CHECK', envIsHeadless());\n }\n\n /** Disable the dependency validation when installing other dependencies and starting the project */\n get EXPO_NO_DEPENDENCY_VALIDATION(): boolean {\n return boolish('EXPO_NO_DEPENDENCY_VALIDATION', envIsHeadless());\n }\n\n /** Force Expo CLI to run in webcontainer mode, this has impact on which URL Expo is using by default */\n get EXPO_FORCE_WEBCONTAINER_ENV(): boolean {\n return boolish('EXPO_FORCE_WEBCONTAINER_ENV', false);\n }\n\n /** Force Expo CLI to run in webcontainer mode, this has impact on which URL Expo is using by default */\n get EXPO_UNSTABLE_WEB_MODAL(): boolean {\n return boolish('EXPO_UNSTABLE_WEB_MODAL', false);\n }\n\n /** Disable @react-navigation checks for expo-router projects */\n get EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK(): boolean {\n return boolish('EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK', false);\n }\n\n /** Disable by falsy value live binding in experimental import export support. Enabled by default. */\n get EXPO_UNSTABLE_LIVE_BINDINGS(): boolean {\n return boolish('EXPO_UNSTABLE_LIVE_BINDINGS', true);\n }\n\n /**\n * Enable the experimental MCP integration or further specify the MCP server URL.\n */\n get EXPO_UNSTABLE_MCP_SERVER(): string {\n const value = string('EXPO_UNSTABLE_MCP_SERVER', '');\n if (value === '1' || value.toLowerCase() === 'true') {\n return this.EXPO_STAGING ? 'staging-mcp.expo.dev' : 'mcp.expo.dev';\n }\n return value;\n }\n\n /** Enable Expo Log Box for iOS and Android (Web is enabled by default) */\n get EXPO_UNSTABLE_LOG_BOX(): boolean {\n return boolish('EXPO_UNSTABLE_LOG_BOX', false);\n }\n\n /**\n * Enable Bonjour advertising of the Expo CLI on local networks\n */\n get EXPO_UNSTABLE_BONJOUR(): boolean {\n return boolish('EXPO_UNSTABLE_BONJOUR', !envIsHeadless());\n }\n\n /** @internal Configure other environment variables for headless operations */\n get EXPO_UNSTABLE_HEADLESS() {\n return boolish('EXPO_UNSTABLE_HEADLESS', envIsWebcontainer());\n }\n}\n\nexport const env = new Env();\n\nexport function envIsWebcontainer() {\n // See: https://github.com/unjs/std-env/blob/4b1e03c4efce58249858efc2cc5f5eac727d0adb/src/providers.ts#L134-L143\n return (\n env.EXPO_FORCE_WEBCONTAINER_ENV ||\n (process.env.SHELL === '/bin/jsh' && !!process.versions.webcontainer)\n );\n}\n\nexport function envIsHeadless() {\n return env.EXPO_UNSTABLE_HEADLESS;\n}\n"],"names":["env","envIsHeadless","envIsWebcontainer","Env","EXPO_PROFILE","boolish","EXPO_DEBUG","EXPO_OFFLINE","EXPO_BETA","EXPO_STAGING","EXPO_LOCAL","CI","EXPO_NO_TELEMETRY","EXPO_NO_TELEMETRY_DETACH","EXPO_UNIVERSE_DIR","string","WEB_HOST","EXPO_NO_GIT_STATUS","EXPO_NO_WEB_SETUP","EXPO_NO_TYPESCRIPT_SETUP","EXPO_NO_CACHE","EXPO_NO_REDIRECT_PAGE","EXPO_NO_QR_CODE","RCT_METRO_PORT","int","EXPO_SKIP_MANIFEST_VALIDATION_TOKEN","EXPO_PUBLIC_FOLDER","EXPO_EDITOR","EXPO_PACKAGER_PROXY_URL","EXPO_TUNNEL_SUBDOMAIN","subdomain","includes","EXPO_METRO_NO_MAIN_FIELD_OVERRIDE","HTTP_PROXY","process","http_proxy","EXPO_OVERRIDE_METRO_CONFIG","trim","undefined","EXPO_NO_INSPECTOR_PROXY","EXPO_NO_METRO_LAZY","EXPO_METRO_UNSTABLE_ERRORS","EXPO_NO_CLIENT_ENV_VARS","EXPO_ADB_USER","__EXPO_E2E_TEST","EXPO_NO_BUNDLE_SPLITTING","EXPO_ATLAS","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","EXPO_USE_METRO_REQUIRE","__EXPO_EAGER_BUNDLE_OPTIONS","EXPO_NO_DEPLOY","EXPO_WEB_DEV_HYDRATE","EXPO_UNSTABLE_SERVER_FUNCTIONS","EXPO_UNSTABLE_DEPLOY_SERVER","EAS_BUILD","EXPO_NO_NEW_ARCH_COMPAT_CHECK","EXPO_NO_DEPENDENCY_VALIDATION","EXPO_FORCE_WEBCONTAINER_ENV","EXPO_UNSTABLE_WEB_MODAL","EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK","EXPO_UNSTABLE_LIVE_BINDINGS","EXPO_UNSTABLE_MCP_SERVER","value","toLowerCase","EXPO_UNSTABLE_LOG_BOX","EXPO_UNSTABLE_BONJOUR","EXPO_UNSTABLE_HEADLESS","SHELL","versions","webcontainer"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/env.ts"],"sourcesContent":["import { getOriginalEnvValue } from '@expo/env';\nimport { boolish, int, string } from 'getenv';\nimport process from 'node:process';\n\n// @expo/webpack-config -> expo-pwa -> @expo/image-utils: EXPO_IMAGE_UTILS_NO_SHARP\n\n// TODO: EXPO_CLI_USERNAME, EXPO_CLI_PASSWORD\n\nclass Env {\n /** Enable profiling metrics */\n get EXPO_PROFILE() {\n return boolish('EXPO_PROFILE', false);\n }\n\n /** Enable debug logging */\n get EXPO_DEBUG() {\n return boolish('EXPO_DEBUG', false);\n }\n\n /** Disable all network requests */\n get EXPO_OFFLINE() {\n return boolish('EXPO_OFFLINE', false);\n }\n\n /** Enable the beta version of Expo (TODO: Should this just be in the beta version of expo releases?) */\n get EXPO_BETA() {\n return boolish('EXPO_BETA', false);\n }\n\n /** Enable staging API environment */\n get EXPO_STAGING() {\n return boolish('EXPO_STAGING', false);\n }\n\n /** Enable local API environment */\n get EXPO_LOCAL() {\n return boolish('EXPO_LOCAL', false);\n }\n\n /** Is running in non-interactive CI mode */\n get CI() {\n return boolish('CI', false);\n }\n\n /** Disable telemetry (analytics) */\n get EXPO_NO_TELEMETRY() {\n return boolish('EXPO_NO_TELEMETRY', false);\n }\n\n /** Disable detaching telemetry to separate process */\n get EXPO_NO_TELEMETRY_DETACH() {\n return boolish('EXPO_NO_TELEMETRY_DETACH', false);\n }\n\n /** local directory to the universe repo for testing locally */\n get EXPO_UNIVERSE_DIR() {\n // Read from the pre-dotenv env — this is a filesystem path used by internal\n // tooling; a project `.env` overriding it could redirect file access.\n return getOriginalEnvValue('EXPO_UNIVERSE_DIR') || '';\n }\n\n /** @deprecated Default Webpack host string */\n get WEB_HOST() {\n return string('WEB_HOST', '0.0.0.0');\n }\n\n /** Skip warning users about a dirty git status */\n get EXPO_NO_GIT_STATUS() {\n return boolish('EXPO_NO_GIT_STATUS', true);\n }\n /** Disable auto web setup */\n get EXPO_NO_WEB_SETUP() {\n return boolish('EXPO_NO_WEB_SETUP', envIsHeadless());\n }\n /** Disable auto TypeScript setup */\n get EXPO_NO_TYPESCRIPT_SETUP() {\n return boolish('EXPO_NO_TYPESCRIPT_SETUP', false);\n }\n /** Disable all API caches. Does not disable bundler caches. */\n get EXPO_NO_CACHE() {\n return boolish('EXPO_NO_CACHE', false);\n }\n /** Disable the app select redirect page. */\n get EXPO_NO_REDIRECT_PAGE() {\n return boolish('EXPO_NO_REDIRECT_PAGE', false);\n }\n /** Disable printing the QR code in the interactive Terminal UI. */\n get EXPO_NO_QR_CODE(): boolean {\n return boolish('EXPO_NO_QR_CODE', false);\n }\n /** Resolve application IDs from Expo app config before native files in `expo start`. */\n get EXPO_RUN_PREFER_APP_CONFIG_ID(): boolean {\n return boolish('EXPO_RUN_PREFER_APP_CONFIG_ID', false);\n }\n /** The React Metro port that's baked into react-native scripts and tools. */\n get RCT_METRO_PORT() {\n return int('RCT_METRO_PORT', 0);\n }\n /** Skip validating the manifest during `export`. */\n get EXPO_SKIP_MANIFEST_VALIDATION_TOKEN(): boolean {\n return !!string('EXPO_SKIP_MANIFEST_VALIDATION_TOKEN', '');\n }\n\n /** Public folder path relative to the project root. Default to `public` */\n get EXPO_PUBLIC_FOLDER(): string {\n return string('EXPO_PUBLIC_FOLDER', 'public');\n }\n\n /** Higher priority `$EDIOTR` variable for indicating which editor to use when pressing `o` in the Terminal UI. */\n get EXPO_EDITOR(): string {\n return string('EXPO_EDITOR', '');\n }\n\n /**\n * Overwrite the dev server URL, disregarding the `--port`, `--host`, `--tunnel`, `--lan`, `--localhost` arguments.\n * This is useful for browser editors that require custom proxy URLs.\n */\n get EXPO_PACKAGER_PROXY_URL(): string {\n // Read from the pre-dotenv env — overrides dev server URL served to clients.\n return getOriginalEnvValue('EXPO_PACKAGER_PROXY_URL') || '';\n }\n\n /**\n * **Experimental** - Disable using `exp.direct` as the hostname for\n * `--tunnel` connections. This enables **https://** forwarding which\n * can be used to test universal links on iOS.\n *\n * This may cause issues with `expo-linking` and Expo Go.\n *\n * Select the exact subdomain by passing a string value that is not one of: `true`, `false`, `1`, `0`.\n */\n get EXPO_TUNNEL_SUBDOMAIN(): string | boolean {\n const subdomain = string('EXPO_TUNNEL_SUBDOMAIN', '');\n if (['0', 'false', ''].includes(subdomain)) {\n return false;\n } else if (['1', 'true'].includes(subdomain)) {\n return true;\n }\n return subdomain;\n }\n\n /**\n * Force Expo CLI to use the [`resolver.resolverMainFields`](https://facebook.github.io/metro/docs/configuration/#resolvermainfields) from the project `metro.config.js` for all platforms.\n *\n * By default, Expo CLI will use `['browser', 'module', 'main']` (default for Webpack) for web and the user-defined main fields for other platforms.\n */\n get EXPO_METRO_NO_MAIN_FIELD_OVERRIDE(): boolean {\n return boolish('EXPO_METRO_NO_MAIN_FIELD_OVERRIDE', false);\n }\n\n /**\n * HTTP/HTTPS proxy to connect to for network requests. Configures [https-proxy-agent](https://www.npmjs.com/package/https-proxy-agent).\n */\n get HTTP_PROXY(): string {\n return process.env.HTTP_PROXY || process.env.http_proxy || '';\n }\n\n /**\n * Instructs a different Metro config to be loaded.\n * The path, according to metro-config, should be a path relative to the current working directory.\n * This flag is internal and was added for external tools.\n * @internal\n */\n get EXPO_OVERRIDE_METRO_CONFIG(): string | undefined {\n // Read from the pre-dotenv env — this path is `require()`d as Metro config,\n // so a project `.env` overriding it would execute attacker code in-process.\n return getOriginalEnvValue('EXPO_OVERRIDE_METRO_CONFIG')?.trim() || undefined;\n }\n\n /**\n * Use the network inspector by overriding the metro inspector proxy with a custom version.\n * @deprecated This has been replaced by `@react-native/dev-middleware` and is now unused.\n */\n get EXPO_NO_INSPECTOR_PROXY(): boolean {\n return boolish('EXPO_NO_INSPECTOR_PROXY', false);\n }\n\n /** Disable lazy bundling in Metro bundler. */\n get EXPO_NO_METRO_LAZY() {\n return boolish('EXPO_NO_METRO_LAZY', false);\n }\n\n /**\n * Enable the unstable inverse dependency stack trace for Metro bundling errors.\n * @deprecated This will be removed in the future.\n */\n get EXPO_METRO_UNSTABLE_ERRORS() {\n return boolish('EXPO_METRO_UNSTABLE_ERRORS', true);\n }\n\n /** Disable Environment Variable injection in client bundles. */\n get EXPO_NO_CLIENT_ENV_VARS(): boolean {\n return boolish('EXPO_NO_CLIENT_ENV_VARS', false);\n }\n\n /** Set the default `user` that should be passed to `--user` with ADB commands. Used for installing APKs on Android devices with multiple profiles. Defaults to `0`. */\n get EXPO_ADB_USER(): string {\n return string('EXPO_ADB_USER', '0');\n }\n\n /** Used internally to enable E2E utilities. This behavior is not stable to external users. */\n get __EXPO_E2E_TEST(): boolean {\n return boolish('__EXPO_E2E_TEST', false);\n }\n\n /** Unstable: Force single-bundle exports in production. */\n get EXPO_NO_BUNDLE_SPLITTING(): boolean {\n return boolish('EXPO_NO_BUNDLE_SPLITTING', false);\n }\n\n /**\n * Enable Atlas to gather bundle information during development or export.\n * Note, because this used to be an experimental feature, both `EXPO_ATLAS` and `EXPO_UNSTABLE_ATLAS` are supported.\n */\n get EXPO_ATLAS() {\n return boolish('EXPO_ATLAS', boolish('EXPO_UNSTABLE_ATLAS', false));\n }\n\n /** Unstable: Enable tree shaking for Metro. */\n get EXPO_UNSTABLE_TREE_SHAKING() {\n return boolish('EXPO_UNSTABLE_TREE_SHAKING', false);\n }\n\n /** Unstable: Enable eager bundling where transformation runs uncached after the entire bundle has been created. This is required for production tree shaking and less optimized for development bundling. */\n get EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH() {\n return boolish('EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH', false);\n }\n\n /** Enable the use of Expo's custom metro require implementation. The custom require supports better debugging, tree shaking, and React Server Components. */\n get EXPO_USE_METRO_REQUIRE() {\n return boolish('EXPO_USE_METRO_REQUIRE', false);\n }\n\n /** Internal key used to pass eager bundle data from the CLI to the native run scripts during `npx expo run` commands. */\n get __EXPO_EAGER_BUNDLE_OPTIONS() {\n return getOriginalEnvValue('__EXPO_EAGER_BUNDLE_OPTIONS') || '';\n }\n\n /** Disable server deployment during production builds (during `expo export:embed`). This is useful for testing API routes and server components against a local server. */\n get EXPO_NO_DEPLOY(): boolean {\n return boolish('EXPO_NO_DEPLOY', false);\n }\n\n /** Enable hydration during development when rendering Expo Web */\n get EXPO_WEB_DEV_HYDRATE(): boolean {\n return boolish('EXPO_WEB_DEV_HYDRATE', false);\n }\n\n /** Enable experimental React Server Functions support. */\n get EXPO_UNSTABLE_SERVER_FUNCTIONS(): boolean {\n return boolish('EXPO_UNSTABLE_SERVER_FUNCTIONS', false);\n }\n\n /** Enable unstable/experimental support for deploying the native server in `npx expo run` commands. */\n get EXPO_UNSTABLE_DEPLOY_SERVER(): boolean {\n return boolish('EXPO_UNSTABLE_DEPLOY_SERVER', false);\n }\n\n /** Is running in EAS Build. This is set by EAS: https://docs.expo.dev/eas/environment-variables/ */\n get EAS_BUILD(): boolean {\n return boolish('EAS_BUILD', false);\n }\n\n /** Disable the React Native Directory compatibility check for new architecture when installing packages */\n get EXPO_NO_NEW_ARCH_COMPAT_CHECK(): boolean {\n return boolish('EXPO_NO_NEW_ARCH_COMPAT_CHECK', envIsHeadless());\n }\n\n /** Disable the dependency validation when installing other dependencies and starting the project */\n get EXPO_NO_DEPENDENCY_VALIDATION(): boolean {\n return boolish('EXPO_NO_DEPENDENCY_VALIDATION', envIsHeadless());\n }\n\n /** Force Expo CLI to run in webcontainer mode, this has impact on which URL Expo is using by default */\n get EXPO_FORCE_WEBCONTAINER_ENV(): boolean {\n return boolish('EXPO_FORCE_WEBCONTAINER_ENV', false);\n }\n\n /** Force Expo CLI to run in webcontainer mode, this has impact on which URL Expo is using by default */\n get EXPO_UNSTABLE_WEB_MODAL(): boolean {\n return boolish('EXPO_UNSTABLE_WEB_MODAL', false);\n }\n\n /** Disable @react-navigation checks for expo-router projects */\n get EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK(): boolean {\n return boolish('EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK', false);\n }\n\n /**\n * Disable Material Symbols (`md`) icon support in expo-router's NativeTabs on Android.\n * When enabled, the Metro resolver swaps the Android-specific md icon converter for a no-op\n * stub, so the `expo-symbols` dependency is tree-shaken out of the Android bundle.\n */\n get EXPO_ROUTER_DISABLE_NATIVE_TABS_MD(): boolean {\n return boolish('EXPO_ROUTER_DISABLE_NATIVE_TABS_MD', false);\n }\n\n /** Disable by falsy value live binding in experimental import export support. Enabled by default. */\n get EXPO_UNSTABLE_LIVE_BINDINGS(): boolean {\n return boolish('EXPO_UNSTABLE_LIVE_BINDINGS', true);\n }\n\n /**\n * Enable the experimental MCP integration or further specify the MCP server URL.\n */\n get EXPO_UNSTABLE_MCP_SERVER(): string {\n const value = string('EXPO_UNSTABLE_MCP_SERVER', '');\n if (value === '1' || value.toLowerCase() === 'true') {\n return this.EXPO_STAGING ? 'staging-mcp.expo.dev' : 'mcp.expo.dev';\n }\n // Re-read from the pre-dotenv env — overrides dev server URL served to clients.\n return getOriginalEnvValue('EXPO_UNSTABLE_MCP_SERVER') || '';\n }\n\n /** Enable Expo Log Box for iOS and Android (Web is enabled by default) */\n get EXPO_UNSTABLE_LOG_BOX(): boolean {\n return boolish('EXPO_UNSTABLE_LOG_BOX', false);\n }\n\n /**\n * Enable Bonjour advertising of the Expo CLI on local networks\n */\n get EXPO_UNSTABLE_BONJOUR(): boolean {\n return boolish('EXPO_UNSTABLE_BONJOUR', !envIsHeadless());\n }\n\n /** @internal Configure other environment variables for headless operations */\n get EXPO_UNSTABLE_HEADLESS() {\n return boolish('EXPO_UNSTABLE_HEADLESS', envIsWebcontainer());\n }\n}\n\nexport const env = new Env();\n\nexport function envIsWebcontainer() {\n // See: https://github.com/unjs/std-env/blob/4b1e03c4efce58249858efc2cc5f5eac727d0adb/src/providers.ts#L134-L143\n return (\n env.EXPO_FORCE_WEBCONTAINER_ENV ||\n (process.env.SHELL === '/bin/jsh' && !!process.versions.webcontainer)\n );\n}\n\nexport function envIsHeadless() {\n return env.EXPO_UNSTABLE_HEADLESS;\n}\n"],"names":["env","envIsHeadless","envIsWebcontainer","Env","EXPO_PROFILE","boolish","EXPO_DEBUG","EXPO_OFFLINE","EXPO_BETA","EXPO_STAGING","EXPO_LOCAL","CI","EXPO_NO_TELEMETRY","EXPO_NO_TELEMETRY_DETACH","EXPO_UNIVERSE_DIR","getOriginalEnvValue","WEB_HOST","string","EXPO_NO_GIT_STATUS","EXPO_NO_WEB_SETUP","EXPO_NO_TYPESCRIPT_SETUP","EXPO_NO_CACHE","EXPO_NO_REDIRECT_PAGE","EXPO_NO_QR_CODE","EXPO_RUN_PREFER_APP_CONFIG_ID","RCT_METRO_PORT","int","EXPO_SKIP_MANIFEST_VALIDATION_TOKEN","EXPO_PUBLIC_FOLDER","EXPO_EDITOR","EXPO_PACKAGER_PROXY_URL","EXPO_TUNNEL_SUBDOMAIN","subdomain","includes","EXPO_METRO_NO_MAIN_FIELD_OVERRIDE","HTTP_PROXY","process","http_proxy","EXPO_OVERRIDE_METRO_CONFIG","trim","undefined","EXPO_NO_INSPECTOR_PROXY","EXPO_NO_METRO_LAZY","EXPO_METRO_UNSTABLE_ERRORS","EXPO_NO_CLIENT_ENV_VARS","EXPO_ADB_USER","__EXPO_E2E_TEST","EXPO_NO_BUNDLE_SPLITTING","EXPO_ATLAS","EXPO_UNSTABLE_TREE_SHAKING","EXPO_UNSTABLE_METRO_OPTIMIZE_GRAPH","EXPO_USE_METRO_REQUIRE","__EXPO_EAGER_BUNDLE_OPTIONS","EXPO_NO_DEPLOY","EXPO_WEB_DEV_HYDRATE","EXPO_UNSTABLE_SERVER_FUNCTIONS","EXPO_UNSTABLE_DEPLOY_SERVER","EAS_BUILD","EXPO_NO_NEW_ARCH_COMPAT_CHECK","EXPO_NO_DEPENDENCY_VALIDATION","EXPO_FORCE_WEBCONTAINER_ENV","EXPO_UNSTABLE_WEB_MODAL","EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK","EXPO_ROUTER_DISABLE_NATIVE_TABS_MD","EXPO_UNSTABLE_LIVE_BINDINGS","EXPO_UNSTABLE_MCP_SERVER","value","toLowerCase","EXPO_UNSTABLE_LOG_BOX","EXPO_UNSTABLE_BONJOUR","EXPO_UNSTABLE_HEADLESS","SHELL","versions","webcontainer"],"mappings":"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"}
@@ -14,6 +14,9 @@ _export(exports, {
14
14
  },
15
15
  get isMatchingOrigin () {
16
16
  return isMatchingOrigin;
17
+ },
18
+ get shouldThrottleRemoteDevCall () {
19
+ return shouldThrottleRemoteDevCall;
17
20
  }
18
21
  });
19
22
  const ipv6To4Prefix = '::ffff:';
@@ -35,9 +38,25 @@ const isMatchingOrigin = (request, serverBaseUrl)=>{
35
38
  if (!request.headers.origin) {
36
39
  return true;
37
40
  }
38
- const actualHost = new URL(`${request.headers.origin}`).host;
41
+ let actualHost;
42
+ try {
43
+ actualHost = new URL(`${request.headers.origin}`).host;
44
+ } catch {
45
+ // Malformed Origin — treat as untrusted.
46
+ return false;
47
+ }
39
48
  const expectedHost = new URL(serverBaseUrl).host;
40
49
  return actualHost === expectedHost;
41
50
  };
51
+ const DEV_CALL_THROTTLE_MS = 2000;
52
+ let lastRemoteDevCallAt = 0;
53
+ const shouldThrottleRemoteDevCall = ()=>{
54
+ const now = Date.now();
55
+ if (now - lastRemoteDevCallAt < DEV_CALL_THROTTLE_MS) {
56
+ return true;
57
+ }
58
+ lastRemoteDevCallAt = now;
59
+ return false;
60
+ };
42
61
 
43
62
  //# sourceMappingURL=net.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/net.ts"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http';\nimport type { Socket } from 'node:net';\n\nconst ipv6To4Prefix = '::ffff:';\n\nexport const isLocalSocket = (socket: Socket): boolean => {\n let { localAddress, remoteAddress, remoteFamily } = socket;\n\n const isLoopbackRequest = localAddress && localAddress === remoteAddress;\n if (isLoopbackRequest) {\n return true;\n } else if (!remoteAddress || !remoteFamily) {\n return false;\n }\n\n if (remoteFamily === 'IPv6' && remoteAddress.startsWith(ipv6To4Prefix)) {\n remoteAddress = remoteAddress.slice(ipv6To4Prefix.length);\n }\n\n return remoteAddress === '::1' || remoteAddress.startsWith('127.');\n};\n\ninterface AbstractIncomingMessage {\n headers: IncomingHttpHeaders | Record<string, string | string[]>;\n}\n\nexport const isMatchingOrigin = (\n request: AbstractIncomingMessage,\n serverBaseUrl: string\n): boolean => {\n // NOTE(@kitten): The browser will always send an origin header for websocket upgrade connections\n if (!request.headers.origin) {\n return true;\n }\n const actualHost = new URL(`${request.headers.origin}`).host;\n const expectedHost = new URL(serverBaseUrl).host;\n return actualHost === expectedHost;\n};\n"],"names":["isLocalSocket","isMatchingOrigin","ipv6To4Prefix","socket","localAddress","remoteAddress","remoteFamily","isLoopbackRequest","startsWith","slice","length","request","serverBaseUrl","headers","origin","actualHost","URL","host","expectedHost"],"mappings":";;;;;;;;;;;QAKaA;eAAAA;;QAqBAC;eAAAA;;;AAvBb,MAAMC,gBAAgB;AAEf,MAAMF,gBAAgB,CAACG;IAC5B,IAAI,EAAEC,YAAY,EAAEC,aAAa,EAAEC,YAAY,EAAE,GAAGH;IAEpD,MAAMI,oBAAoBH,gBAAgBA,iBAAiBC;IAC3D,IAAIE,mBAAmB;QACrB,OAAO;IACT,OAAO,IAAI,CAACF,iBAAiB,CAACC,cAAc;QAC1C,OAAO;IACT;IAEA,IAAIA,iBAAiB,UAAUD,cAAcG,UAAU,CAACN,gBAAgB;QACtEG,gBAAgBA,cAAcI,KAAK,CAACP,cAAcQ,MAAM;IAC1D;IAEA,OAAOL,kBAAkB,SAASA,cAAcG,UAAU,CAAC;AAC7D;AAMO,MAAMP,mBAAmB,CAC9BU,SACAC;IAEA,iGAAiG;IACjG,IAAI,CAACD,QAAQE,OAAO,CAACC,MAAM,EAAE;QAC3B,OAAO;IACT;IACA,MAAMC,aAAa,IAAIC,IAAI,GAAGL,QAAQE,OAAO,CAACC,MAAM,EAAE,EAAEG,IAAI;IAC5D,MAAMC,eAAe,IAAIF,IAAIJ,eAAeK,IAAI;IAChD,OAAOF,eAAeG;AACxB"}
1
+ {"version":3,"sources":["../../../src/utils/net.ts"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http';\nimport type { Socket } from 'node:net';\n\nconst ipv6To4Prefix = '::ffff:';\n\nexport const isLocalSocket = (socket: Socket): boolean => {\n let { localAddress, remoteAddress, remoteFamily } = socket;\n\n const isLoopbackRequest = localAddress && localAddress === remoteAddress;\n if (isLoopbackRequest) {\n return true;\n } else if (!remoteAddress || !remoteFamily) {\n return false;\n }\n\n if (remoteFamily === 'IPv6' && remoteAddress.startsWith(ipv6To4Prefix)) {\n remoteAddress = remoteAddress.slice(ipv6To4Prefix.length);\n }\n\n return remoteAddress === '::1' || remoteAddress.startsWith('127.');\n};\n\ninterface AbstractIncomingMessage {\n headers: IncomingHttpHeaders | Record<string, string | string[]>;\n}\n\nexport const isMatchingOrigin = (\n request: AbstractIncomingMessage,\n serverBaseUrl: string\n): boolean => {\n // NOTE(@kitten): The browser will always send an origin header for websocket upgrade connections\n if (!request.headers.origin) {\n return true;\n }\n let actualHost: string;\n try {\n actualHost = new URL(`${request.headers.origin}`).host;\n } catch {\n // Malformed Origin — treat as untrusted.\n return false;\n }\n const expectedHost = new URL(serverBaseUrl).host;\n return actualHost === expectedHost;\n};\n\nconst DEV_CALL_THROTTLE_MS = 2_000;\nlet lastRemoteDevCallAt = 0;\n\n/** Process-wide throttle. Returns `true` if another call fired within the cooldown window. */\nexport const shouldThrottleRemoteDevCall = (): boolean => {\n const now = Date.now();\n if (now - lastRemoteDevCallAt < DEV_CALL_THROTTLE_MS) {\n return true;\n }\n lastRemoteDevCallAt = now;\n return false;\n};\n"],"names":["isLocalSocket","isMatchingOrigin","shouldThrottleRemoteDevCall","ipv6To4Prefix","socket","localAddress","remoteAddress","remoteFamily","isLoopbackRequest","startsWith","slice","length","request","serverBaseUrl","headers","origin","actualHost","URL","host","expectedHost","DEV_CALL_THROTTLE_MS","lastRemoteDevCallAt","now","Date"],"mappings":";;;;;;;;;;;QAKaA;eAAAA;;QAqBAC;eAAAA;;QAuBAC;eAAAA;;;AA9Cb,MAAMC,gBAAgB;AAEf,MAAMH,gBAAgB,CAACI;IAC5B,IAAI,EAAEC,YAAY,EAAEC,aAAa,EAAEC,YAAY,EAAE,GAAGH;IAEpD,MAAMI,oBAAoBH,gBAAgBA,iBAAiBC;IAC3D,IAAIE,mBAAmB;QACrB,OAAO;IACT,OAAO,IAAI,CAACF,iBAAiB,CAACC,cAAc;QAC1C,OAAO;IACT;IAEA,IAAIA,iBAAiB,UAAUD,cAAcG,UAAU,CAACN,gBAAgB;QACtEG,gBAAgBA,cAAcI,KAAK,CAACP,cAAcQ,MAAM;IAC1D;IAEA,OAAOL,kBAAkB,SAASA,cAAcG,UAAU,CAAC;AAC7D;AAMO,MAAMR,mBAAmB,CAC9BW,SACAC;IAEA,iGAAiG;IACjG,IAAI,CAACD,QAAQE,OAAO,CAACC,MAAM,EAAE;QAC3B,OAAO;IACT;IACA,IAAIC;IACJ,IAAI;QACFA,aAAa,IAAIC,IAAI,GAAGL,QAAQE,OAAO,CAACC,MAAM,EAAE,EAAEG,IAAI;IACxD,EAAE,OAAM;QACN,yCAAyC;QACzC,OAAO;IACT;IACA,MAAMC,eAAe,IAAIF,IAAIJ,eAAeK,IAAI;IAChD,OAAOF,eAAeG;AACxB;AAEA,MAAMC,uBAAuB;AAC7B,IAAIC,sBAAsB;AAGnB,MAAMnB,8BAA8B;IACzC,MAAMoB,MAAMC,KAAKD,GAAG;IACpB,IAAIA,MAAMD,sBAAsBD,sBAAsB;QACpD,OAAO;IACT;IACAC,sBAAsBC;IACtB,OAAO;AACT"}
@@ -89,12 +89,9 @@ function _interop_require_wildcard(obj, nodeInterop) {
89
89
  }
90
90
  return raw.split('\n').map((line)=>line.trim()).filter((line)=>line.length > 0);
91
91
  }
92
- /** Escapes a value for safe interpolation inside an AppleScript double-quoted string. */ function escapeAppleScriptString(value) {
93
- return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\r/g, '\\r').replace(/\n/g, '\\n');
94
- }
95
92
  function buildOpenChromiumTabScript(target, matchUrl) {
96
- const theURL = escapeAppleScriptString(target);
97
- const matchURL = escapeAppleScriptString(matchUrl);
93
+ const theURL = _osascript().escapeString(target);
94
+ const matchURL = _osascript().escapeString(matchUrl);
98
95
  return applescript`
99
96
  property targetTab: null
100
97
  property targetTabIndex: -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/open.ts"],"sourcesContent":["import * as osascript from '@expo/osascript';\nimport spawnAsync from '@expo/spawn-async';\nimport os from 'os';\nimport path from 'path';\n\n/** Splits an inline script into trimmed, non-empty lines for `osascript -e <line>`. */\nfunction applescript(strings: TemplateStringsArray, ...values: unknown[]): string[] {\n let raw = strings[0]!;\n for (let i = 0; i < values.length; i++) {\n raw += String(values[i]) + strings[i + 1];\n }\n return raw\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\n/** Escapes a value for safe interpolation inside an AppleScript double-quoted string. */\nfunction escapeAppleScriptString(value: string): string {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\n/g, '\\\\n');\n}\n\nfunction buildOpenChromiumTabScript(target: string, matchUrl: string): string[] {\n const theURL = escapeAppleScriptString(target);\n const matchURL = escapeAppleScriptString(matchUrl);\n return applescript`\n property targetTab: null\n property targetTabIndex: -1\n property targetWindow: null\n property theProgram: \"\"\n\n on run\n set theProgram to my findRunningChromium()\n if theProgram is \"\" then error \"No Chromium browser is running.\"\n set theURL to \"${theURL}\"\n set matchURL to \"${matchURL}\"\n using terms from application \"Google Chrome\"\n tell application theProgram\n if (count every window) = 0 then\n make new window\n end if\n set found to my lookupTabWithUrl(matchURL)\n if found then\n set targetWindow's active tab index to targetTabIndex\n tell targetTab to reload\n tell targetWindow to activate\n set index of targetWindow to 1\n return\n end if\n set found to my lookupTabWithUrl(\"chrome://newtab/\")\n if found then\n set targetWindow's active tab index to targetTabIndex\n set URL of targetTab to theURL\n tell targetWindow to activate\n return\n end if\n tell window 1\n activate\n make new tab with properties {URL:theURL}\n end tell\n end tell\n end using terms from\n end run\n\n on findRunningChromium()\n set candidates to {\"Google Chrome Canary\", \"Google Chrome\", \"Microsoft Edge\", \"Brave Browser\", \"Vivaldi\", \"Chromium\"}\n tell application \"System Events\"\n set runningNames to name of every process\n end tell\n repeat with candidate in candidates\n set candidateName to candidate as string\n if candidateName is in runningNames then return candidateName\n end repeat\n return \"\"\n end findRunningChromium\n\n on lookupTabWithUrl(lookupUrl)\n using terms from application \"Google Chrome\"\n tell application theProgram\n set found to false\n set theTabIndex to -1\n repeat with theWindow in every window\n set theTabIndex to 0\n repeat with theTab in every tab of theWindow\n set theTabIndex to theTabIndex + 1\n if (theTab's URL as string) contains lookupUrl then\n set targetTab to theTab\n set targetTabIndex to theTabIndex\n set targetWindow to theWindow\n set found to true\n exit repeat\n end if\n end repeat\n if found then exit repeat\n end repeat\n end tell\n end using terms from\n return found\n end lookupTabWithUrl\n `;\n}\n\nfunction safeOrigin(target: string): string {\n try {\n return new URL(target).origin;\n } catch {\n return target;\n }\n}\n\nasync function tryOpenInChromiumTabAsync(target: string): Promise<boolean> {\n const matchUrl = process.env.OPEN_MATCH_HOST_ONLY === 'true' ? safeOrigin(target) : target;\n try {\n await osascript.spawnAsync(buildOpenChromiumTabScript(target, matchUrl), {\n stdio: 'ignore',\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Opens a URL in the user's browser. Honors `BROWSER` (set to `none` to disable) and\n * `BROWSER_ARGS` environment variables. On macOS, reuses an existing tab in a running\n * Chromium-based browser when possible.\n *\n * @returns `true` when a browser was launched, `false` when `BROWSER=none`.\n */\nexport async function openBrowserAsync(target: string): Promise<boolean> {\n const browserEnv = process.env.BROWSER?.trim();\n if (browserEnv?.toLowerCase() === 'none') {\n return false;\n }\n\n // On macOS, `BROWSER=open` historically meant \"use the default handler\" rather than\n // \"launch an app called open\" — treat it as if BROWSER were unset.\n const browserApp =\n browserEnv && !(process.platform === 'darwin' && browserEnv.toLowerCase() === 'open')\n ? browserEnv\n : undefined;\n const browserArgs = process.env.BROWSER_ARGS ? process.env.BROWSER_ARGS.split(' ') : [];\n\n if (process.platform === 'darwin') {\n const isDefaultOrChrome = !browserApp || browserApp.toLowerCase() === 'google chrome';\n if (isDefaultOrChrome && (await tryOpenInChromiumTabAsync(target))) {\n return true;\n }\n const openArgs: string[] = [];\n if (browserApp) openArgs.push('-a', browserApp);\n // Per `open(1)`, everything following `--args` is forwarded to the launched app,\n // so the target URL must come after the args block to reach the app alongside them.\n if (browserArgs.length > 0) openArgs.push('--args', ...browserArgs);\n openArgs.push(target);\n await spawnAsync('open', openArgs, { stdio: 'ignore' });\n return true;\n }\n\n if (process.platform === 'win32') {\n await spawnWindowsStartAsync(target, browserApp, browserArgs);\n return true;\n }\n\n // WSL: when the user hasn't overridden BROWSER, route through Windows `cmd.exe` so\n // the URL opens in the user's Windows browser. Falls through to `xdg-open` otherwise.\n if (!browserApp && isWsl()) {\n await spawnAsync('/mnt/c/Windows/System32/cmd.exe', ['/c', 'start', '\"\"', target], {\n stdio: 'ignore',\n });\n return true;\n }\n\n const command = browserApp ?? 'xdg-open';\n await spawnAsync(command, [...browserArgs, target], { stdio: 'ignore' });\n return true;\n}\n\nasync function spawnWindowsStartAsync(\n target: string,\n browserApp: string | undefined,\n browserArgs: string[]\n): Promise<void> {\n // Windows preserves env var case in Node, but the OS variable is `SystemRoot`.\n const systemRoot = process.env.SYSTEMROOT ?? process.env.SystemRoot ?? 'C:\\\\Windows';\n const cmd = path.join(systemRoot, 'System32', 'cmd.exe');\n // `start \"\"` — the empty quoted string is the window title, so the URL isn't\n // interpreted as a title argument.\n const startArgs = ['/c', 'start', '\"\"'];\n if (browserApp) startArgs.push(browserApp);\n startArgs.push(target, ...browserArgs);\n await spawnAsync(cmd, startArgs, { stdio: 'ignore' });\n}\n\nfunction isWsl(): boolean {\n if (process.platform !== 'linux') return false;\n if (process.env.WSL_DISTRO_NAME) return true;\n const release = os.release().toLowerCase();\n return release.includes('microsoft') || release.includes('wsl');\n}\n"],"names":["openBrowserAsync","applescript","strings","values","raw","i","length","String","split","map","line","trim","filter","escapeAppleScriptString","value","replace","buildOpenChromiumTabScript","target","matchUrl","theURL","matchURL","safeOrigin","URL","origin","tryOpenInChromiumTabAsync","process","env","OPEN_MATCH_HOST_ONLY","osascript","spawnAsync","stdio","browserEnv","BROWSER","toLowerCase","browserApp","platform","undefined","browserArgs","BROWSER_ARGS","isDefaultOrChrome","openArgs","push","spawnWindowsStartAsync","isWsl","command","systemRoot","SYSTEMROOT","SystemRoot","cmd","path","join","startArgs","WSL_DISTRO_NAME","release","os","includes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/open.ts"],"sourcesContent":["import * as osascript from '@expo/osascript';\nimport spawnAsync from '@expo/spawn-async';\nimport os from 'os';\nimport path from 'path';\n\n/** Splits an inline script into trimmed, non-empty lines for `osascript -e <line>`. */\nfunction applescript(strings: TemplateStringsArray, ...values: unknown[]): string[] {\n let raw = strings[0]!;\n for (let i = 0; i < values.length; i++) {\n raw += String(values[i]) + strings[i + 1];\n }\n return raw\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n}\n\nfunction buildOpenChromiumTabScript(target: string, matchUrl: string): string[] {\n const theURL = osascript.escapeString(target);\n const matchURL = osascript.escapeString(matchUrl);\n return applescript`\n property targetTab: null\n property targetTabIndex: -1\n property targetWindow: null\n property theProgram: \"\"\n\n on run\n set theProgram to my findRunningChromium()\n if theProgram is \"\" then error \"No Chromium browser is running.\"\n set theURL to \"${theURL}\"\n set matchURL to \"${matchURL}\"\n using terms from application \"Google Chrome\"\n tell application theProgram\n if (count every window) = 0 then\n make new window\n end if\n set found to my lookupTabWithUrl(matchURL)\n if found then\n set targetWindow's active tab index to targetTabIndex\n tell targetTab to reload\n tell targetWindow to activate\n set index of targetWindow to 1\n return\n end if\n set found to my lookupTabWithUrl(\"chrome://newtab/\")\n if found then\n set targetWindow's active tab index to targetTabIndex\n set URL of targetTab to theURL\n tell targetWindow to activate\n return\n end if\n tell window 1\n activate\n make new tab with properties {URL:theURL}\n end tell\n end tell\n end using terms from\n end run\n\n on findRunningChromium()\n set candidates to {\"Google Chrome Canary\", \"Google Chrome\", \"Microsoft Edge\", \"Brave Browser\", \"Vivaldi\", \"Chromium\"}\n tell application \"System Events\"\n set runningNames to name of every process\n end tell\n repeat with candidate in candidates\n set candidateName to candidate as string\n if candidateName is in runningNames then return candidateName\n end repeat\n return \"\"\n end findRunningChromium\n\n on lookupTabWithUrl(lookupUrl)\n using terms from application \"Google Chrome\"\n tell application theProgram\n set found to false\n set theTabIndex to -1\n repeat with theWindow in every window\n set theTabIndex to 0\n repeat with theTab in every tab of theWindow\n set theTabIndex to theTabIndex + 1\n if (theTab's URL as string) contains lookupUrl then\n set targetTab to theTab\n set targetTabIndex to theTabIndex\n set targetWindow to theWindow\n set found to true\n exit repeat\n end if\n end repeat\n if found then exit repeat\n end repeat\n end tell\n end using terms from\n return found\n end lookupTabWithUrl\n `;\n}\n\nfunction safeOrigin(target: string): string {\n try {\n return new URL(target).origin;\n } catch {\n return target;\n }\n}\n\nasync function tryOpenInChromiumTabAsync(target: string): Promise<boolean> {\n const matchUrl = process.env.OPEN_MATCH_HOST_ONLY === 'true' ? safeOrigin(target) : target;\n try {\n await osascript.spawnAsync(buildOpenChromiumTabScript(target, matchUrl), {\n stdio: 'ignore',\n });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Opens a URL in the user's browser. Honors `BROWSER` (set to `none` to disable) and\n * `BROWSER_ARGS` environment variables. On macOS, reuses an existing tab in a running\n * Chromium-based browser when possible.\n *\n * @returns `true` when a browser was launched, `false` when `BROWSER=none`.\n */\nexport async function openBrowserAsync(target: string): Promise<boolean> {\n const browserEnv = process.env.BROWSER?.trim();\n if (browserEnv?.toLowerCase() === 'none') {\n return false;\n }\n\n // On macOS, `BROWSER=open` historically meant \"use the default handler\" rather than\n // \"launch an app called open\" — treat it as if BROWSER were unset.\n const browserApp =\n browserEnv && !(process.platform === 'darwin' && browserEnv.toLowerCase() === 'open')\n ? browserEnv\n : undefined;\n const browserArgs = process.env.BROWSER_ARGS ? process.env.BROWSER_ARGS.split(' ') : [];\n\n if (process.platform === 'darwin') {\n const isDefaultOrChrome = !browserApp || browserApp.toLowerCase() === 'google chrome';\n if (isDefaultOrChrome && (await tryOpenInChromiumTabAsync(target))) {\n return true;\n }\n const openArgs: string[] = [];\n if (browserApp) openArgs.push('-a', browserApp);\n // Per `open(1)`, everything following `--args` is forwarded to the launched app,\n // so the target URL must come after the args block to reach the app alongside them.\n if (browserArgs.length > 0) openArgs.push('--args', ...browserArgs);\n openArgs.push(target);\n await spawnAsync('open', openArgs, { stdio: 'ignore' });\n return true;\n }\n\n if (process.platform === 'win32') {\n await spawnWindowsStartAsync(target, browserApp, browserArgs);\n return true;\n }\n\n // WSL: when the user hasn't overridden BROWSER, route through Windows `cmd.exe` so\n // the URL opens in the user's Windows browser. Falls through to `xdg-open` otherwise.\n if (!browserApp && isWsl()) {\n await spawnAsync('/mnt/c/Windows/System32/cmd.exe', ['/c', 'start', '\"\"', target], {\n stdio: 'ignore',\n });\n return true;\n }\n\n const command = browserApp ?? 'xdg-open';\n await spawnAsync(command, [...browserArgs, target], { stdio: 'ignore' });\n return true;\n}\n\nasync function spawnWindowsStartAsync(\n target: string,\n browserApp: string | undefined,\n browserArgs: string[]\n): Promise<void> {\n // Windows preserves env var case in Node, but the OS variable is `SystemRoot`.\n const systemRoot = process.env.SYSTEMROOT ?? process.env.SystemRoot ?? 'C:\\\\Windows';\n const cmd = path.join(systemRoot, 'System32', 'cmd.exe');\n // `start \"\"` — the empty quoted string is the window title, so the URL isn't\n // interpreted as a title argument.\n const startArgs = ['/c', 'start', '\"\"'];\n if (browserApp) startArgs.push(browserApp);\n startArgs.push(target, ...browserArgs);\n await spawnAsync(cmd, startArgs, { stdio: 'ignore' });\n}\n\nfunction isWsl(): boolean {\n if (process.platform !== 'linux') return false;\n if (process.env.WSL_DISTRO_NAME) return true;\n const release = os.release().toLowerCase();\n return release.includes('microsoft') || release.includes('wsl');\n}\n"],"names":["openBrowserAsync","applescript","strings","values","raw","i","length","String","split","map","line","trim","filter","buildOpenChromiumTabScript","target","matchUrl","theURL","osascript","escapeString","matchURL","safeOrigin","URL","origin","tryOpenInChromiumTabAsync","process","env","OPEN_MATCH_HOST_ONLY","spawnAsync","stdio","browserEnv","BROWSER","toLowerCase","browserApp","platform","undefined","browserArgs","BROWSER_ARGS","isDefaultOrChrome","openArgs","push","spawnWindowsStartAsync","isWsl","command","systemRoot","SYSTEMROOT","SystemRoot","cmd","path","join","startArgs","WSL_DISTRO_NAME","release","os","includes"],"mappings":"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"}
@@ -71,8 +71,8 @@ class ChecksumStream extends TransformStream {
71
71
  return this.hash.digest(encoding);
72
72
  }
73
73
  }
74
- async function extractStream(input, output, options = {}) {
75
- output = _nodepath().default.resolve(output);
74
+ async function extractStream(input, targetOutput, options = {}) {
75
+ const output = _nodepath().default.resolve(targetOutput) + _nodepath().default.sep;
76
76
  await _nodefs().default.promises.mkdir(output, {
77
77
  recursive: true
78
78
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/tar.ts"],"sourcesContent":["import { streamToAsyncIterable, TarTypeFlag, untar } from 'multitars';\nimport crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nconst debug = require('debug')('expo:utils:tar') as typeof console.log;\n\nclass ChecksumStream extends TransformStream {\n hash: crypto.Hash;\n constructor(algorithm: string) {\n super({\n transform: (chunk, controller) => {\n this.hash.update(chunk);\n controller.enqueue(chunk);\n },\n });\n this.hash = crypto.createHash(algorithm);\n }\n\n digest(): Buffer;\n digest(encoding: crypto.BinaryToTextEncoding): string;\n digest(encoding?: crypto.BinaryToTextEncoding): string | Buffer {\n return this.hash.digest(encoding!);\n }\n}\n\nexport interface ExtractOptions {\n strip?: number;\n filter?(name: string, type: TarTypeFlag): boolean | null | undefined;\n rename?(name: string, type: TarTypeFlag): string | null | undefined;\n checksumAlgorithm?: string;\n}\n\nexport async function extractStream(\n input: ReadableStream,\n output: string,\n options: ExtractOptions = {}\n): Promise<string> {\n output = path.resolve(output);\n await fs.promises.mkdir(output, { recursive: true });\n\n const { checksumAlgorithm, strip = 0, rename, filter } = options;\n\n const checksumStream = new ChecksumStream(checksumAlgorithm || 'md5');\n const decompressionStream = new DecompressionStream('gzip');\n\n const body = input.pipeThrough(checksumStream).pipeThrough(decompressionStream);\n\n for await (const file of untar(body)) {\n let name = path.normalize(file.name);\n if (filter && !filter(name, file.typeflag)) {\n debug(`filtered: ${path.resolve(output, name)}`);\n continue;\n } else if (rename) {\n name = rename(name, file.typeflag) ?? name;\n }\n\n for (let idx = 0; idx < strip; idx++) {\n const sepIdx = name.indexOf(path.sep);\n if (sepIdx > -1) {\n name = name.slice(sepIdx + 1);\n } else {\n break;\n }\n }\n\n const resolved = path.resolve(output, name);\n if (!resolved.startsWith(output)) {\n debug(`skip: ${resolved}`);\n continue;\n }\n\n const parent = path.dirname(resolved);\n if (parent !== output) {\n let exists = false;\n try {\n const stat = await fs.promises.lstat(parent);\n if (stat.isSymbolicLink() || (!stat.isDirectory() && !stat.isFile())) {\n debug(`skip: ${resolved}`);\n continue;\n } else if (stat.isDirectory()) {\n exists = true;\n }\n } catch {}\n\n if (!exists) {\n debug(`mkdir(p): ${parent}`);\n await fs.promises.mkdir(parent, { recursive: true });\n }\n }\n\n switch (file.typeflag) {\n case TarTypeFlag.FILE:\n debug(`write(${file.mode.toString(8)}): ${resolved}`);\n await fs.promises.writeFile(resolved, streamToAsyncIterable(file.stream()), {\n mode: file.mode,\n });\n break;\n case TarTypeFlag.DIRECTORY:\n debug(`mkdir(${file.mode.toString(8)}): ${resolved}`);\n try {\n await fs.promises.mkdir(resolved, { mode: file.mode });\n } catch (error: any) {\n if (error.code !== 'EEXIST') {\n throw error;\n }\n }\n break;\n case TarTypeFlag.SYMLINK:\n case TarTypeFlag.LINK: {\n const target = path.resolve(parent, file.linkname ?? '');\n if (!target.startsWith(output) || target === parent) {\n debug(`skip: ${resolved} -> ${target}`);\n continue;\n }\n\n if (file.typeflag === TarTypeFlag.LINK) {\n debug(`link: ${resolved} -> ${target}`);\n await fs.promises.link(target, resolved);\n } else {\n const stat = await fs.promises.lstat(target).catch(() => null);\n const type = stat?.isDirectory() ? 'dir' : 'file';\n debug(`symlink(${type}): ${resolved} -> ${target}`);\n await fs.promises.symlink(target, resolved, type);\n }\n break;\n }\n }\n }\n\n return checksumStream.digest('hex');\n}\n\n/** Extract a tar using built-in tools if available and falling back on Node.js. */\nexport async function extractAsync(\n input: string,\n output: string,\n options?: ExtractOptions\n): Promise<void> {\n await extractStream(\n Readable.toWeb(fs.createReadStream(input)) as ReadableStream,\n output,\n options\n );\n}\n"],"names":["extractAsync","extractStream","debug","require","ChecksumStream","TransformStream","algorithm","transform","chunk","controller","hash","update","enqueue","crypto","createHash","digest","encoding","input","output","options","path","resolve","fs","promises","mkdir","recursive","checksumAlgorithm","strip","rename","filter","checksumStream","decompressionStream","DecompressionStream","body","pipeThrough","file","untar","name","normalize","typeflag","idx","sepIdx","indexOf","sep","slice","resolved","startsWith","parent","dirname","exists","stat","lstat","isSymbolicLink","isDirectory","isFile","TarTypeFlag","FILE","mode","toString","writeFile","streamToAsyncIterable","stream","DIRECTORY","error","code","SYMLINK","LINK","target","linkname","link","catch","type","symlink","Readable","toWeb","createReadStream"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/tar.ts"],"sourcesContent":["import { streamToAsyncIterable, TarTypeFlag, untar } from 'multitars';\nimport crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { Readable } from 'node:stream';\n\nconst debug = require('debug')('expo:utils:tar') as typeof console.log;\n\nclass ChecksumStream extends TransformStream {\n hash: crypto.Hash;\n constructor(algorithm: string) {\n super({\n transform: (chunk, controller) => {\n this.hash.update(chunk);\n controller.enqueue(chunk);\n },\n });\n this.hash = crypto.createHash(algorithm);\n }\n\n digest(): Buffer;\n digest(encoding: crypto.BinaryToTextEncoding): string;\n digest(encoding?: crypto.BinaryToTextEncoding): string | Buffer {\n return this.hash.digest(encoding!);\n }\n}\n\nexport interface ExtractOptions {\n strip?: number;\n filter?(name: string, type: TarTypeFlag): boolean | null | undefined;\n rename?(name: string, type: TarTypeFlag): string | null | undefined;\n checksumAlgorithm?: string;\n}\n\nexport async function extractStream(\n input: ReadableStream,\n targetOutput: string,\n options: ExtractOptions = {}\n): Promise<string> {\n const output = path.resolve(targetOutput) + path.sep;\n await fs.promises.mkdir(output, { recursive: true });\n\n const { checksumAlgorithm, strip = 0, rename, filter } = options;\n\n const checksumStream = new ChecksumStream(checksumAlgorithm || 'md5');\n const decompressionStream = new DecompressionStream('gzip');\n\n const body = input.pipeThrough(checksumStream).pipeThrough(decompressionStream);\n\n for await (const file of untar(body)) {\n let name = path.normalize(file.name);\n if (filter && !filter(name, file.typeflag)) {\n debug(`filtered: ${path.resolve(output, name)}`);\n continue;\n } else if (rename) {\n name = rename(name, file.typeflag) ?? name;\n }\n\n for (let idx = 0; idx < strip; idx++) {\n const sepIdx = name.indexOf(path.sep);\n if (sepIdx > -1) {\n name = name.slice(sepIdx + 1);\n } else {\n break;\n }\n }\n\n const resolved = path.resolve(output, name);\n if (!resolved.startsWith(output)) {\n debug(`skip: ${resolved}`);\n continue;\n }\n\n const parent = path.dirname(resolved);\n if (parent !== output) {\n let exists = false;\n try {\n const stat = await fs.promises.lstat(parent);\n if (stat.isSymbolicLink() || (!stat.isDirectory() && !stat.isFile())) {\n debug(`skip: ${resolved}`);\n continue;\n } else if (stat.isDirectory()) {\n exists = true;\n }\n } catch {}\n\n if (!exists) {\n debug(`mkdir(p): ${parent}`);\n await fs.promises.mkdir(parent, { recursive: true });\n }\n }\n\n switch (file.typeflag) {\n case TarTypeFlag.FILE:\n debug(`write(${file.mode.toString(8)}): ${resolved}`);\n await fs.promises.writeFile(resolved, streamToAsyncIterable(file.stream()), {\n mode: file.mode,\n });\n break;\n case TarTypeFlag.DIRECTORY:\n debug(`mkdir(${file.mode.toString(8)}): ${resolved}`);\n try {\n await fs.promises.mkdir(resolved, { mode: file.mode });\n } catch (error: any) {\n if (error.code !== 'EEXIST') {\n throw error;\n }\n }\n break;\n case TarTypeFlag.SYMLINK:\n case TarTypeFlag.LINK: {\n const target = path.resolve(parent, file.linkname ?? '');\n if (!target.startsWith(output) || target === parent) {\n debug(`skip: ${resolved} -> ${target}`);\n continue;\n }\n\n if (file.typeflag === TarTypeFlag.LINK) {\n debug(`link: ${resolved} -> ${target}`);\n await fs.promises.link(target, resolved);\n } else {\n const stat = await fs.promises.lstat(target).catch(() => null);\n const type = stat?.isDirectory() ? 'dir' : 'file';\n debug(`symlink(${type}): ${resolved} -> ${target}`);\n await fs.promises.symlink(target, resolved, type);\n }\n break;\n }\n }\n }\n\n return checksumStream.digest('hex');\n}\n\n/** Extract a tar using built-in tools if available and falling back on Node.js. */\nexport async function extractAsync(\n input: string,\n output: string,\n options?: ExtractOptions\n): Promise<void> {\n await extractStream(\n Readable.toWeb(fs.createReadStream(input)) as ReadableStream,\n output,\n options\n );\n}\n"],"names":["extractAsync","extractStream","debug","require","ChecksumStream","TransformStream","algorithm","transform","chunk","controller","hash","update","enqueue","crypto","createHash","digest","encoding","input","targetOutput","options","output","path","resolve","sep","fs","promises","mkdir","recursive","checksumAlgorithm","strip","rename","filter","checksumStream","decompressionStream","DecompressionStream","body","pipeThrough","file","untar","name","normalize","typeflag","idx","sepIdx","indexOf","slice","resolved","startsWith","parent","dirname","exists","stat","lstat","isSymbolicLink","isDirectory","isFile","TarTypeFlag","FILE","mode","toString","writeFile","streamToAsyncIterable","stream","DIRECTORY","error","code","SYMLINK","LINK","target","linkname","link","catch","type","symlink","Readable","toWeb","createReadStream"],"mappings":"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"}
@@ -26,7 +26,7 @@ class FetchClient {
26
26
  this.headers = {
27
27
  accept: 'application/json',
28
28
  'content-type': 'application/json',
29
- 'user-agent': `expo-cli/${"56.1.5"}`,
29
+ 'user-agent': `expo-cli/${"56.1.7"}`,
30
30
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
31
31
  };
32
32
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "56.1.5"
86
+ version: "56.1.7"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
@@ -12,9 +12,6 @@ _export(exports, {
12
12
  get isUrlAvailableAsync () {
13
13
  return isUrlAvailableAsync;
14
14
  },
15
- get isUrlOk () {
16
- return isUrlOk;
17
- },
18
15
  get stripExtension () {
19
16
  return stripExtension;
20
17
  },
@@ -39,7 +36,6 @@ function _url() {
39
36
  };
40
37
  return data;
41
38
  }
42
- const _client = require("../api/rest/client");
43
39
  function _interop_require_default(obj) {
44
40
  return obj && obj.__esModule ? obj : {
45
41
  default: obj
@@ -52,14 +48,6 @@ function isUrlAvailableAsync(url) {
52
48
  });
53
49
  });
54
50
  }
55
- async function isUrlOk(url) {
56
- try {
57
- const res = await (0, _client.fetchAsync)(url);
58
- return res.ok;
59
- } catch {
60
- return false;
61
- }
62
- }
63
51
  function validateUrl(urlString, { protocols, requireProtocol } = {}) {
64
52
  try {
65
53
  const results = new (_url()).URL(urlString);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/url.ts"],"sourcesContent":["import dns from 'dns';\nimport { URL } from 'url';\n\nimport { fetchAsync } from '../api/rest/client';\n\n/** Check if a server is available based on the URL. */\nexport function isUrlAvailableAsync(url: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n dns.lookup(url, (err) => {\n resolve(!err);\n });\n });\n}\n\n/** Check if a request to the given URL is `ok` (status 200). */\nexport async function isUrlOk(url: string): Promise<boolean> {\n try {\n const res = await fetchAsync(url);\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** Determine if a string is a valid URL, can optionally ensure certain protocols (like `https` or `exp`) are adhered to. */\nexport function validateUrl(\n urlString: string,\n {\n protocols,\n requireProtocol,\n }: {\n /** Set of allowed protocols for the string to adhere to. @example ['exp', 'https'] */\n protocols?: string[];\n /** Ensure the URL has a protocol component (prefix before `://`). */\n requireProtocol?: boolean;\n } = {}\n) {\n try {\n const results = new URL(urlString);\n if (!results.protocol && !requireProtocol) {\n return true;\n }\n return protocols\n ? results.protocol\n ? protocols.map((x) => `${x.toLowerCase()}:`).includes(results.protocol)\n : false\n : true;\n } catch {\n return false;\n }\n}\n\n/** Remove the port from a given `host` URL string. */\nexport function stripPort(host?: string): string | null {\n return coerceUrl(host)?.hostname ?? null;\n}\n\nfunction coerceUrl(urlString?: string): URL | null {\n if (!urlString) {\n return null;\n }\n try {\n return new URL('/', urlString);\n } catch {\n return new URL('/', `http://${urlString}`);\n }\n}\n\n/** Strip a given extension from a URL string. */\nexport function stripExtension(url: string, extension: string): string {\n return url.replace(new RegExp(`.${extension}$`), '');\n}\n"],"names":["isUrlAvailableAsync","isUrlOk","stripExtension","stripPort","validateUrl","url","Promise","resolve","dns","lookup","err","res","fetchAsync","ok","urlString","protocols","requireProtocol","results","URL","protocol","map","x","toLowerCase","includes","host","coerceUrl","hostname","extension","replace","RegExp"],"mappings":";;;;;;;;;;;QAMgBA;eAAAA;;QASMC;eAAAA;;QAsDNC;eAAAA;;QAhBAC;eAAAA;;QA5BAC;eAAAA;;;;gEAzBA;;;;;;;yBACI;;;;;;wBAEO;;;;;;AAGpB,SAASJ,oBAAoBK,GAAW;IAC7C,OAAO,IAAIC,QAAiB,CAACC;QAC3BC,cAAG,CAACC,MAAM,CAACJ,KAAK,CAACK;YACfH,QAAQ,CAACG;QACX;IACF;AACF;AAGO,eAAeT,QAAQI,GAAW;IACvC,IAAI;QACF,MAAMM,MAAM,MAAMC,IAAAA,kBAAU,EAACP;QAC7B,OAAOM,IAAIE,EAAE;IACf,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAGO,SAAST,YACdU,SAAiB,EACjB,EACEC,SAAS,EACTC,eAAe,EAMhB,GAAG,CAAC,CAAC;IAEN,IAAI;QACF,MAAMC,UAAU,IAAIC,CAAAA,MAAE,KAAC,CAACJ;QACxB,IAAI,CAACG,QAAQE,QAAQ,IAAI,CAACH,iBAAiB;YACzC,OAAO;QACT;QACA,OAAOD,YACHE,QAAQE,QAAQ,GACdJ,UAAUK,GAAG,CAAC,CAACC,IAAM,GAAGA,EAAEC,WAAW,GAAG,CAAC,CAAC,EAAEC,QAAQ,CAACN,QAAQE,QAAQ,IACrE,QACF;IACN,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAGO,SAAShB,UAAUqB,IAAa;QAC9BC;IAAP,OAAOA,EAAAA,aAAAA,UAAUD,0BAAVC,WAAiBC,QAAQ,KAAI;AACtC;AAEA,SAASD,UAAUX,SAAkB;IACnC,IAAI,CAACA,WAAW;QACd,OAAO;IACT;IACA,IAAI;QACF,OAAO,IAAII,CAAAA,MAAE,KAAC,CAAC,KAAKJ;IACtB,EAAE,OAAM;QACN,OAAO,IAAII,CAAAA,MAAE,KAAC,CAAC,KAAK,CAAC,OAAO,EAAEJ,WAAW;IAC3C;AACF;AAGO,SAASZ,eAAeG,GAAW,EAAEsB,SAAiB;IAC3D,OAAOtB,IAAIuB,OAAO,CAAC,IAAIC,OAAO,CAAC,CAAC,EAAEF,UAAU,CAAC,CAAC,GAAG;AACnD"}
1
+ {"version":3,"sources":["../../../src/utils/url.ts"],"sourcesContent":["import dns from 'dns';\nimport { URL } from 'url';\n\n/** Check if a server is available based on the URL. */\nexport function isUrlAvailableAsync(url: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n dns.lookup(url, (err) => {\n resolve(!err);\n });\n });\n}\n\n/** Determine if a string is a valid URL, can optionally ensure certain protocols (like `https` or `exp`) are adhered to. */\nexport function validateUrl(\n urlString: string,\n {\n protocols,\n requireProtocol,\n }: {\n /** Set of allowed protocols for the string to adhere to. @example ['exp', 'https'] */\n protocols?: string[];\n /** Ensure the URL has a protocol component (prefix before `://`). */\n requireProtocol?: boolean;\n } = {}\n) {\n try {\n const results = new URL(urlString);\n if (!results.protocol && !requireProtocol) {\n return true;\n }\n return protocols\n ? results.protocol\n ? protocols.map((x) => `${x.toLowerCase()}:`).includes(results.protocol)\n : false\n : true;\n } catch {\n return false;\n }\n}\n\n/** Remove the port from a given `host` URL string. */\nexport function stripPort(host?: string): string | null {\n return coerceUrl(host)?.hostname ?? null;\n}\n\nfunction coerceUrl(urlString?: string): URL | null {\n if (!urlString) {\n return null;\n }\n try {\n return new URL('/', urlString);\n } catch {\n return new URL('/', `http://${urlString}`);\n }\n}\n\n/** Strip a given extension from a URL string. */\nexport function stripExtension(url: string, extension: string): string {\n return url.replace(new RegExp(`.${extension}$`), '');\n}\n"],"names":["isUrlAvailableAsync","stripExtension","stripPort","validateUrl","url","Promise","resolve","dns","lookup","err","urlString","protocols","requireProtocol","results","URL","protocol","map","x","toLowerCase","includes","host","coerceUrl","hostname","extension","replace","RegExp"],"mappings":";;;;;;;;;;;QAIgBA;eAAAA;;QAqDAC;eAAAA;;QAhBAC;eAAAA;;QA5BAC;eAAAA;;;;gEAbA;;;;;;;yBACI;;;;;;;;;;;AAGb,SAASH,oBAAoBI,GAAW;IAC7C,OAAO,IAAIC,QAAiB,CAACC;QAC3BC,cAAG,CAACC,MAAM,CAACJ,KAAK,CAACK;YACfH,QAAQ,CAACG;QACX;IACF;AACF;AAGO,SAASN,YACdO,SAAiB,EACjB,EACEC,SAAS,EACTC,eAAe,EAMhB,GAAG,CAAC,CAAC;IAEN,IAAI;QACF,MAAMC,UAAU,IAAIC,CAAAA,MAAE,KAAC,CAACJ;QACxB,IAAI,CAACG,QAAQE,QAAQ,IAAI,CAACH,iBAAiB;YACzC,OAAO;QACT;QACA,OAAOD,YACHE,QAAQE,QAAQ,GACdJ,UAAUK,GAAG,CAAC,CAACC,IAAM,GAAGA,EAAEC,WAAW,GAAG,CAAC,CAAC,EAAEC,QAAQ,CAACN,QAAQE,QAAQ,IACrE,QACF;IACN,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAGO,SAASb,UAAUkB,IAAa;QAC9BC;IAAP,OAAOA,EAAAA,aAAAA,UAAUD,0BAAVC,WAAiBC,QAAQ,KAAI;AACtC;AAEA,SAASD,UAAUX,SAAkB;IACnC,IAAI,CAACA,WAAW;QACd,OAAO;IACT;IACA,IAAI;QACF,OAAO,IAAII,CAAAA,MAAE,KAAC,CAAC,KAAKJ;IACtB,EAAE,OAAM;QACN,OAAO,IAAII,CAAAA,MAAE,KAAC,CAAC,KAAK,CAAC,OAAO,EAAEJ,WAAW;IAC3C;AACF;AAGO,SAAST,eAAeG,GAAW,EAAEmB,SAAiB;IAC3D,OAAOnB,IAAIoB,OAAO,CAAC,IAAIC,OAAO,CAAC,CAAC,EAAEF,UAAU,CAAC,CAAC,GAAG;AACnD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "56.1.5",
3
+ "version": "56.1.7",
4
4
  "description": "The Expo CLI",
5
5
  "main": "main.js",
6
6
  "bin": {
@@ -39,25 +39,25 @@
39
39
  "homepage": "https://github.com/expo/expo/tree/main/packages/@expo/cli",
40
40
  "dependencies": {
41
41
  "@expo/code-signing-certificates": "^0.0.6",
42
- "@expo/config": "~56.0.6",
43
- "@expo/config-plugins": "~56.0.5",
42
+ "@expo/config": "~56.0.8",
43
+ "@expo/config-plugins": "~56.0.7",
44
44
  "@expo/devcert": "^1.2.1",
45
- "@expo/env": "~2.2.0",
46
- "@expo/image-utils": "^0.9.3",
47
- "@expo/inline-modules": "^0.0.7",
48
- "@expo/json-file": "^10.1.0",
49
- "@expo/log-box": "^56.0.10",
45
+ "@expo/env": "~2.3.0",
46
+ "@expo/image-utils": "^0.10.0",
47
+ "@expo/inline-modules": "^0.0.9",
48
+ "@expo/json-file": "^10.2.0",
49
+ "@expo/log-box": "^56.0.12",
50
50
  "@expo/metro": "~56.0.0",
51
- "@expo/metro-config": "~56.0.9",
51
+ "@expo/metro-config": "~56.0.11",
52
52
  "@expo/metro-file-map": "^56.0.3",
53
- "@expo/osascript": "^2.5.0",
54
- "@expo/package-manager": "^1.11.0",
55
- "@expo/plist": "^0.6.0",
56
- "@expo/prebuild-config": "^56.0.8",
57
- "@expo/require-utils": "^56.1.1",
58
- "@expo/router-server": "^56.0.8",
53
+ "@expo/osascript": "^2.6.0",
54
+ "@expo/package-manager": "^1.12.0",
55
+ "@expo/plist": "^0.7.0",
56
+ "@expo/prebuild-config": "^56.0.10",
57
+ "@expo/require-utils": "^56.1.2",
58
+ "@expo/router-server": "^56.0.10",
59
59
  "@expo/schema-utils": "^56.0.0",
60
- "@expo/spawn-async": "^1.7.2",
60
+ "@expo/spawn-async": "^1.8.0",
61
61
  "@expo/ws-tunnel": "^1.0.1",
62
62
  "@expo/xcpretty": "^4.4.4",
63
63
  "@react-native/dev-middleware": "0.85.3",
@@ -71,7 +71,7 @@
71
71
  "connect": "^3.7.0",
72
72
  "debug": "^4.3.4",
73
73
  "dnssd-advertise": "^1.1.4",
74
- "expo-server": "^56.0.2",
74
+ "expo-server": "^56.0.4",
75
75
  "fetch-nodeshim": "^0.4.10",
76
76
  "getenv": "^2.0.0",
77
77
  "glob": "^13.0.0",
@@ -156,13 +156,13 @@
156
156
  "playwright": "^1.59.0",
157
157
  "taskr": "^1.1.0",
158
158
  "tree-kill": "^1.2.2",
159
- "expo": "56.0.0-preview.12",
160
- "expo-modules-autolinking": "56.0.7",
159
+ "@expo/fingerprint": "0.19.0",
160
+ "expo": "56.0.0",
161
161
  "expo-module-scripts": "56.0.2",
162
- "expo-router": "56.2.1",
163
- "@expo/fingerprint": "0.18.2"
162
+ "expo-router": "56.2.3",
163
+ "expo-modules-autolinking": "56.0.9"
164
164
  },
165
- "gitHead": "f26be3dd9396bf7c399a1d607865d0fabdbc0d64",
165
+ "gitHead": "c4c9867a0bcbb188e55ecaec4998e38d33108a5d",
166
166
  "scripts": {
167
167
  "build": "taskr",
168
168
  "clean": "expo-module clean",
@@ -237,7 +237,7 @@
237
237
  <title>Expo Start | Loading Page</title>
238
238
  </head>
239
239
  <body>
240
- <div id="alert"></div>
240
+ <div id="alert" data-scheme="{{ Scheme }}"></div>
241
241
  <div class="logo-box">
242
242
  <div class="logo-background-box">
243
243
 
@@ -297,12 +297,20 @@
297
297
  <script>
298
298
  const alertElement = document.getElementById("alert");
299
299
 
300
+ const escapeHtml = (value) => value
301
+ .replace(/&/g, '&amp;')
302
+ .replace(/</g, '&lt;')
303
+ .replace(/>/g, '&gt;')
304
+ .replace(/"/g, '&quot;')
305
+ .replace(/'/g, '&#39;');
306
+
300
307
  const showAlert = (isExpoGo) => {
301
308
  if (isExpoGo) {
302
309
  alertElement.innerHTML = 'Unable to open in Expo Go. Please install <b>Expo Go</b> to continue.' +
303
310
  '<br><a href="https://expo.dev/client">Learn more.</a>';
304
311
  } else {
305
- alertElement.innerHTML = 'Unable to open in Development Build with the <b>{{ Scheme }}</b> scheme. Please build and install a compatible <b>Development Build</b> to continue.' +
312
+ const scheme = escapeHtml(alertElement.dataset.scheme || 'Unknown');
313
+ alertElement.innerHTML = 'Unable to open in Development Build with the <b>' + scheme + '</b> scheme. Please build and install a compatible <b>Development Build</b> to continue.' +
306
314
  '<br><a href="https://docs.expo.dev/development/build/">Learn more.</a>';
307
315
  }
308
316