@expo/cli 55.0.4 → 55.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/api/graphql/client.js +133 -68
  3. package/build/src/api/graphql/client.js.map +1 -1
  4. package/build/src/api/graphql/queries/AppQuery.js +21 -25
  5. package/build/src/api/graphql/queries/AppQuery.js.map +1 -1
  6. package/build/src/api/graphql/queries/UserQuery.js +45 -38
  7. package/build/src/api/graphql/queries/UserQuery.js.map +1 -1
  8. package/build/src/api/rest/cache/FileSystemResponseCache.js.map +1 -1
  9. package/build/src/api/rest/cache/ResponseCache.js.map +1 -1
  10. package/build/src/api/rest/cache/wrapFetchWithCache.js +7 -7
  11. package/build/src/api/rest/cache/wrapFetchWithCache.js.map +1 -1
  12. package/build/src/api/rest/client.js +3 -7
  13. package/build/src/api/rest/client.js.map +1 -1
  14. package/build/src/api/rest/wrapFetchWithProgress.js +1 -8
  15. package/build/src/api/rest/wrapFetchWithProgress.js.map +1 -1
  16. package/build/src/api/user/user.js +6 -36
  17. package/build/src/api/user/user.js.map +1 -1
  18. package/build/src/prebuild/renameTemplateAppName.js +2 -6
  19. package/build/src/prebuild/renameTemplateAppName.js.map +1 -1
  20. package/build/src/prebuild/resolveLocalTemplate.js +2 -4
  21. package/build/src/prebuild/resolveLocalTemplate.js.map +1 -1
  22. package/build/src/prebuild/resolveTemplate.js +13 -17
  23. package/build/src/prebuild/resolveTemplate.js.map +1 -1
  24. package/build/src/prebuild/updateFromTemplate.js +4 -6
  25. package/build/src/prebuild/updateFromTemplate.js.map +1 -1
  26. package/build/src/start/doctor/ngrok/ExternalModule.js +2 -8
  27. package/build/src/start/doctor/ngrok/ExternalModule.js.map +1 -1
  28. package/build/src/start/platforms/android/AndroidSdk.js +15 -6
  29. package/build/src/start/platforms/android/AndroidSdk.js.map +1 -1
  30. package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js +1 -9
  31. package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js.map +1 -1
  32. package/build/src/start/server/metro/MetroBundlerDevServer.js +10 -4
  33. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  34. package/build/src/start/server/metro/createServerComponentsMiddleware.js +2 -12
  35. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  36. package/build/src/start/server/metro/createServerRouteMiddleware.js +17 -0
  37. package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
  38. package/build/src/start/server/metro/instantiateMetro.js +2 -3
  39. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  40. package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +47 -34
  41. package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
  42. package/build/src/start/server/middleware/ManifestMiddleware.js +27 -4
  43. package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
  44. package/build/src/start/server/type-generation/routes.js +2 -59
  45. package/build/src/start/server/type-generation/routes.js.map +1 -1
  46. package/build/src/start/server/webpack/WebpackBundlerDevServer.js +2 -1
  47. package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
  48. package/build/src/utils/codesigning.js +3 -17
  49. package/build/src/utils/codesigning.js.map +1 -1
  50. package/build/src/utils/createFileTransform.js +3 -38
  51. package/build/src/utils/createFileTransform.js.map +1 -1
  52. package/build/src/utils/downloadAppAsync.js +1 -12
  53. package/build/src/utils/downloadAppAsync.js.map +1 -1
  54. package/build/src/utils/fetch.js +23 -4
  55. package/build/src/utils/fetch.js.map +1 -1
  56. package/build/src/utils/getOrPromptApplicationId.js +2 -15
  57. package/build/src/utils/getOrPromptApplicationId.js.map +1 -1
  58. package/build/src/utils/npm.js +60 -65
  59. package/build/src/utils/npm.js.map +1 -1
  60. package/build/src/utils/resolveGlobal.js +195 -0
  61. package/build/src/utils/resolveGlobal.js.map +1 -0
  62. package/build/src/utils/tar.js +138 -69
  63. package/build/src/utils/tar.js.map +1 -1
  64. package/build/src/utils/telemetry/clients/FetchClient.js +12 -24
  65. package/build/src/utils/telemetry/clients/FetchClient.js.map +1 -1
  66. package/build/src/utils/telemetry/utils/context.js +1 -1
  67. package/package.json +16 -26
  68. package/build/src/api/graphql/types/App.js +0 -29
  69. package/build/src/api/graphql/types/App.js.map +0 -1
  70. package/build/src/api/rest/wrapFetchWithProxy.js +0 -31
  71. package/build/src/api/rest/wrapFetchWithProxy.js.map +0 -1
  72. package/build/src/graphql/generated.js +0 -1196
  73. package/build/src/graphql/generated.js.map +0 -1
  74. package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js +0 -85
  75. package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js.map +0 -1
  76. package/build/src/utils/multipartMixed.js +0 -56
  77. package/build/src/utils/multipartMixed.js.map +0 -1
@@ -221,8 +221,9 @@ class WebpackBundlerDevServer extends _BundlerDevServer.BundlerDevServer {
221
221
  // Create a webpack compiler that is configured with custom messages.
222
222
  const compiler = webpack(config);
223
223
  const server = new WebpackDevServer(compiler, config.devServer);
224
+ const host = _env.env.WEB_HOST ?? (options.location.hostType === 'localhost' ? 'localhost' : undefined);
224
225
  // Launch WebpackDevServer.
225
- server.listen(port, _env.env.WEB_HOST, function(error) {
226
+ server.listen(port, host, function(error) {
226
227
  if (error) {
227
228
  _log.error(error.message);
228
229
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/start/server/webpack/WebpackBundlerDevServer.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { Application } from 'express';\nimport fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\nimport type webpack from 'webpack';\nimport type WebpackDevServer from 'webpack-dev-server';\n\nimport { compileAsync } from './compile';\nimport {\n importExpoWebpackConfigFromProject,\n importWebpackDevServerFromProject,\n importWebpackFromProject,\n} from './resolveFromProject';\nimport { ensureEnvironmentSupportsTLSAsync } from './tls';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { getIpAddress } from '../../../utils/ip';\nimport { setNodeEnv } from '../../../utils/nodeEnv';\nimport { choosePortAsync } from '../../../utils/port';\nimport { createProgressBar } from '../../../utils/progress';\nimport { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo';\nimport { BundlerDevServer, BundlerStartOptions, DevServerInstance } from '../BundlerDevServer';\n\nconst debug = require('debug')('expo:start:server:webpack:devServer') as typeof console.log;\n\nexport type WebpackConfiguration = webpack.Configuration & {\n devServer?: {\n before?: (app: Application, server: WebpackDevServer, compiler: webpack.Compiler) => void;\n };\n};\n\nfunction assertIsWebpackDevServer(value: any): asserts value is WebpackDevServer {\n if (!value?.sockWrite && !value?.sendMessage) {\n throw new CommandError(\n 'WEBPACK',\n value\n ? 'Expected Webpack dev server, found: ' + (value.constructor?.name ?? value)\n : 'Webpack dev server not started yet.'\n );\n }\n}\n\nexport class WebpackBundlerDevServer extends BundlerDevServer {\n get name(): string {\n return 'webpack';\n }\n\n public async startTypeScriptServices(): Promise<void> {\n // noop -- this feature is Metro-only.\n }\n\n public broadcastMessage(\n method: string | 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ): void {\n if (!this.instance) {\n return;\n }\n\n assertIsWebpackDevServer(this.instance?.server);\n\n // TODO(EvanBacon): Custom Webpack overlay.\n // Default webpack-dev-server sockets use \"content-changed\" instead of \"reload\" (what we use on native).\n // For now, just manually convert the value so our CLI interface can be unified.\n const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;\n\n if (\n 'sendMessage' in this.instance.server &&\n typeof this.instance.server.sendMessage === 'function'\n ) {\n // NOTE: https://github.com/expo/expo/issues/21994#issuecomment-1517122501\n this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);\n } else {\n this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);\n }\n }\n\n isTargetingNative(): boolean {\n return false;\n }\n\n private async getAvailablePortAsync(options: { defaultPort?: number }): Promise<number> {\n try {\n const defaultPort = options?.defaultPort ?? 19006;\n const port = await choosePortAsync(this.projectRoot, {\n defaultPort,\n host: env.WEB_HOST,\n });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', `Port ${defaultPort} not available.`);\n }\n return port;\n } catch (error: any) {\n throw new CommandError('NO_PORT_FOUND', error.message);\n }\n }\n\n async bundleAsync({ mode, clear }: { mode: 'development' | 'production'; clear: boolean }) {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n\n if (clear) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n const config = await this.loadConfigAsync({\n isImageEditingEnabled: true,\n mode,\n });\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n const bar = createProgressBar(chalk`{bold Web} Bundling Javascript [:bar] :percent`, {\n width: 64,\n total: 100,\n clear: true,\n complete: '=',\n incomplete: ' ',\n });\n\n // NOTE(EvanBacon): Add a progress bar to the webpack logger if defined (e.g. not in CI).\n if (bar != null) {\n config.plugins.push(\n new webpack.ProgressPlugin((percent: number) => {\n bar?.update(percent);\n if (percent === 1) {\n bar?.terminate();\n }\n })\n );\n }\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n try {\n await compileAsync(compiler);\n } catch (error: any) {\n Log.error(chalk.red('Failed to compile'));\n throw error;\n } finally {\n bar?.terminate();\n }\n }\n\n protected async startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance> {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n const WebpackDevServer = importWebpackDevServerFromProject(this.projectRoot);\n\n await this.stopAsync();\n\n options.port = await this.getAvailablePortAsync({\n defaultPort: options.port,\n });\n const { resetDevServer, https, port, mode } = options;\n\n this.urlCreator = this.getUrlCreator({\n port,\n location: {\n scheme: https ? 'https' : 'http',\n },\n });\n\n debug('Starting webpack on port: ' + port);\n\n if (resetDevServer) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n if (https) {\n debug('Configuring TLS to enable HTTPS support');\n await ensureEnvironmentSupportsTLSAsync(this.projectRoot).catch((error) => {\n Log.error(`Error creating TLS certificates: ${error}`);\n });\n }\n\n const config = await this.loadConfigAsync(options);\n\n Log.log(chalk`Starting Webpack on port ${port} in {underline ${mode}} mode.`);\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n const server = new WebpackDevServer(compiler, config.devServer);\n // Launch WebpackDevServer.\n server.listen(port, env.WEB_HOST, function (this: http.Server, error) {\n if (error) {\n Log.error(error.message);\n }\n });\n\n // Extend the close method to ensure that we clean up the local info.\n const originalClose = server.close.bind(server);\n\n server.close = (callback?: (err?: Error) => void) => {\n return originalClose((err?: Error) => {\n this.instance = null;\n callback?.(err);\n });\n };\n\n const _host = getIpAddress();\n const protocol = https ? 'https' : 'http';\n\n return {\n // Server instance\n server,\n // URL Info\n location: {\n url: `${protocol}://${_host}:${port}`,\n port,\n protocol,\n host: _host,\n },\n middleware: null,\n // Match the native protocol.\n messageSocket: {\n broadcast: this.broadcastMessage,\n },\n };\n }\n\n /** Load the Webpack config. Exposed for testing. */\n getProjectConfigFilePath(): string | null {\n // Check if the project has a webpack.config.js in the root.\n return (\n this.getConfigModuleIds().reduce<string | null | undefined>(\n (prev, moduleId) => prev || resolveFrom.silent(this.projectRoot, moduleId),\n null\n ) ?? null\n );\n }\n\n async loadConfigAsync(\n options: Pick<BundlerStartOptions, 'mode' | 'isImageEditingEnabled' | 'https'>,\n argv?: string[]\n ): Promise<WebpackConfiguration> {\n // let bar: ProgressBar | null = null;\n\n const env = {\n projectRoot: this.projectRoot,\n pwa: !!options.isImageEditingEnabled,\n // TODO: Use a new loader in Webpack config...\n logger: {\n info() {},\n },\n mode: options.mode,\n https: options.https,\n };\n setNodeEnv(env.mode ?? 'development');\n require('@expo/env').load(env.projectRoot);\n // Check if the project has a webpack.config.js in the root.\n const projectWebpackConfig = this.getProjectConfigFilePath();\n let config: WebpackConfiguration;\n if (projectWebpackConfig) {\n const webpackConfig = require(projectWebpackConfig);\n if (typeof webpackConfig === 'function') {\n config = await webpackConfig(env, argv);\n } else {\n config = webpackConfig;\n }\n } else {\n // Fallback to the default expo webpack config.\n const loadDefaultConfigAsync = importExpoWebpackConfigFromProject(this.projectRoot);\n config = await loadDefaultConfigAsync(env, argv);\n }\n return config;\n }\n\n protected getConfigModuleIds(): string[] {\n return ['./webpack.config.js'];\n }\n\n protected async clearWebProjectCacheAsync(\n projectRoot: string,\n mode: string = 'development'\n ): Promise<void> {\n Log.log(chalk.dim(`Clearing Webpack ${mode} cache directory...`));\n\n const dir = await ensureDotExpoProjectDirectoryInitialized(projectRoot);\n const cacheFolder = path.join(dir, 'web/cache', mode);\n try {\n await fs.promises.rm(cacheFolder, { recursive: true, force: true });\n } catch (error: any) {\n Log.error(`Could not clear ${mode} web cache directory: ${error.message}`);\n }\n }\n}\n\nexport function getProjectWebpackConfigFilePath(projectRoot: string) {\n return resolveFrom.silent(projectRoot, './webpack.config.js');\n}\n"],"names":["WebpackBundlerDevServer","getProjectWebpackConfigFilePath","debug","require","assertIsWebpackDevServer","value","sockWrite","sendMessage","CommandError","constructor","name","BundlerDevServer","startTypeScriptServices","broadcastMessage","method","params","instance","server","hackyConvertedMessage","sockets","isTargetingNative","getAvailablePortAsync","options","defaultPort","port","choosePortAsync","projectRoot","host","env","WEB_HOST","error","message","bundleAsync","mode","clear","webpack","importWebpackFromProject","clearWebProjectCacheAsync","config","loadConfigAsync","isImageEditingEnabled","plugins","bar","createProgressBar","chalk","width","total","complete","incomplete","push","ProgressPlugin","percent","update","terminate","compiler","compileAsync","Log","red","startImplementationAsync","WebpackDevServer","importWebpackDevServerFromProject","stopAsync","resetDevServer","https","urlCreator","getUrlCreator","location","scheme","ensureEnvironmentSupportsTLSAsync","catch","log","devServer","listen","originalClose","close","bind","callback","err","_host","getIpAddress","protocol","url","middleware","messageSocket","broadcast","getProjectConfigFilePath","getConfigModuleIds","reduce","prev","moduleId","resolveFrom","silent","argv","pwa","logger","info","setNodeEnv","load","projectWebpackConfig","webpackConfig","loadDefaultConfigAsync","importExpoWebpackConfigFromProject","dim","dir","ensureDotExpoProjectDirectoryInitialized","cacheFolder","path","join","fs","promises","rm","recursive","force"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/start/server/webpack/WebpackBundlerDevServer.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { Application } from 'express';\nimport fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\nimport type webpack from 'webpack';\nimport type WebpackDevServer from 'webpack-dev-server';\n\nimport { compileAsync } from './compile';\nimport {\n importExpoWebpackConfigFromProject,\n importWebpackDevServerFromProject,\n importWebpackFromProject,\n} from './resolveFromProject';\nimport { ensureEnvironmentSupportsTLSAsync } from './tls';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { getIpAddress } from '../../../utils/ip';\nimport { setNodeEnv } from '../../../utils/nodeEnv';\nimport { choosePortAsync } from '../../../utils/port';\nimport { createProgressBar } from '../../../utils/progress';\nimport { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo';\nimport { BundlerDevServer, BundlerStartOptions, DevServerInstance } from '../BundlerDevServer';\n\nconst debug = require('debug')('expo:start:server:webpack:devServer') as typeof console.log;\n\nexport type WebpackConfiguration = webpack.Configuration & {\n devServer?: {\n before?: (app: Application, server: WebpackDevServer, compiler: webpack.Compiler) => void;\n };\n};\n\nfunction assertIsWebpackDevServer(value: any): asserts value is WebpackDevServer {\n if (!value?.sockWrite && !value?.sendMessage) {\n throw new CommandError(\n 'WEBPACK',\n value\n ? 'Expected Webpack dev server, found: ' + (value.constructor?.name ?? value)\n : 'Webpack dev server not started yet.'\n );\n }\n}\n\nexport class WebpackBundlerDevServer extends BundlerDevServer {\n get name(): string {\n return 'webpack';\n }\n\n public async startTypeScriptServices(): Promise<void> {\n // noop -- this feature is Metro-only.\n }\n\n public broadcastMessage(\n method: string | 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ): void {\n if (!this.instance) {\n return;\n }\n\n assertIsWebpackDevServer(this.instance?.server);\n\n // TODO(EvanBacon): Custom Webpack overlay.\n // Default webpack-dev-server sockets use \"content-changed\" instead of \"reload\" (what we use on native).\n // For now, just manually convert the value so our CLI interface can be unified.\n const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;\n\n if (\n 'sendMessage' in this.instance.server &&\n typeof this.instance.server.sendMessage === 'function'\n ) {\n // NOTE: https://github.com/expo/expo/issues/21994#issuecomment-1517122501\n this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);\n } else {\n this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);\n }\n }\n\n isTargetingNative(): boolean {\n return false;\n }\n\n private async getAvailablePortAsync(options: { defaultPort?: number }): Promise<number> {\n try {\n const defaultPort = options?.defaultPort ?? 19006;\n const port = await choosePortAsync(this.projectRoot, {\n defaultPort,\n host: env.WEB_HOST,\n });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', `Port ${defaultPort} not available.`);\n }\n return port;\n } catch (error: any) {\n throw new CommandError('NO_PORT_FOUND', error.message);\n }\n }\n\n async bundleAsync({ mode, clear }: { mode: 'development' | 'production'; clear: boolean }) {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n\n if (clear) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n const config = await this.loadConfigAsync({\n isImageEditingEnabled: true,\n mode,\n });\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n const bar = createProgressBar(chalk`{bold Web} Bundling Javascript [:bar] :percent`, {\n width: 64,\n total: 100,\n clear: true,\n complete: '=',\n incomplete: ' ',\n });\n\n // NOTE(EvanBacon): Add a progress bar to the webpack logger if defined (e.g. not in CI).\n if (bar != null) {\n config.plugins.push(\n new webpack.ProgressPlugin((percent: number) => {\n bar?.update(percent);\n if (percent === 1) {\n bar?.terminate();\n }\n })\n );\n }\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n try {\n await compileAsync(compiler);\n } catch (error: any) {\n Log.error(chalk.red('Failed to compile'));\n throw error;\n } finally {\n bar?.terminate();\n }\n }\n\n protected async startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance> {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n const WebpackDevServer = importWebpackDevServerFromProject(this.projectRoot);\n\n await this.stopAsync();\n\n options.port = await this.getAvailablePortAsync({\n defaultPort: options.port,\n });\n const { resetDevServer, https, port, mode } = options;\n\n this.urlCreator = this.getUrlCreator({\n port,\n location: {\n scheme: https ? 'https' : 'http',\n },\n });\n\n debug('Starting webpack on port: ' + port);\n\n if (resetDevServer) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n if (https) {\n debug('Configuring TLS to enable HTTPS support');\n await ensureEnvironmentSupportsTLSAsync(this.projectRoot).catch((error) => {\n Log.error(`Error creating TLS certificates: ${error}`);\n });\n }\n\n const config = await this.loadConfigAsync(options);\n\n Log.log(chalk`Starting Webpack on port ${port} in {underline ${mode}} mode.`);\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n const server = new WebpackDevServer(compiler, config.devServer);\n const host =\n env.WEB_HOST ?? (options.location.hostType === 'localhost' ? 'localhost' : undefined);\n\n // Launch WebpackDevServer.\n server.listen(port, host, function (this: http.Server, error) {\n if (error) {\n Log.error(error.message);\n }\n });\n\n // Extend the close method to ensure that we clean up the local info.\n const originalClose = server.close.bind(server);\n\n server.close = (callback?: (err?: Error) => void) => {\n return originalClose((err?: Error) => {\n this.instance = null;\n callback?.(err);\n });\n };\n\n const _host = getIpAddress();\n const protocol = https ? 'https' : 'http';\n\n return {\n // Server instance\n server,\n // URL Info\n location: {\n url: `${protocol}://${_host}:${port}`,\n port,\n protocol,\n host: _host,\n },\n middleware: null,\n // Match the native protocol.\n messageSocket: {\n broadcast: this.broadcastMessage,\n },\n };\n }\n\n /** Load the Webpack config. Exposed for testing. */\n getProjectConfigFilePath(): string | null {\n // Check if the project has a webpack.config.js in the root.\n return (\n this.getConfigModuleIds().reduce<string | null | undefined>(\n (prev, moduleId) => prev || resolveFrom.silent(this.projectRoot, moduleId),\n null\n ) ?? null\n );\n }\n\n async loadConfigAsync(\n options: Pick<BundlerStartOptions, 'mode' | 'isImageEditingEnabled' | 'https'>,\n argv?: string[]\n ): Promise<WebpackConfiguration> {\n // let bar: ProgressBar | null = null;\n\n const env = {\n projectRoot: this.projectRoot,\n pwa: !!options.isImageEditingEnabled,\n // TODO: Use a new loader in Webpack config...\n logger: {\n info() {},\n },\n mode: options.mode,\n https: options.https,\n };\n setNodeEnv(env.mode ?? 'development');\n require('@expo/env').load(env.projectRoot);\n // Check if the project has a webpack.config.js in the root.\n const projectWebpackConfig = this.getProjectConfigFilePath();\n let config: WebpackConfiguration;\n if (projectWebpackConfig) {\n const webpackConfig = require(projectWebpackConfig);\n if (typeof webpackConfig === 'function') {\n config = await webpackConfig(env, argv);\n } else {\n config = webpackConfig;\n }\n } else {\n // Fallback to the default expo webpack config.\n const loadDefaultConfigAsync = importExpoWebpackConfigFromProject(this.projectRoot);\n config = await loadDefaultConfigAsync(env, argv);\n }\n return config;\n }\n\n protected getConfigModuleIds(): string[] {\n return ['./webpack.config.js'];\n }\n\n protected async clearWebProjectCacheAsync(\n projectRoot: string,\n mode: string = 'development'\n ): Promise<void> {\n Log.log(chalk.dim(`Clearing Webpack ${mode} cache directory...`));\n\n const dir = await ensureDotExpoProjectDirectoryInitialized(projectRoot);\n const cacheFolder = path.join(dir, 'web/cache', mode);\n try {\n await fs.promises.rm(cacheFolder, { recursive: true, force: true });\n } catch (error: any) {\n Log.error(`Could not clear ${mode} web cache directory: ${error.message}`);\n }\n }\n}\n\nexport function getProjectWebpackConfigFilePath(projectRoot: string) {\n return resolveFrom.silent(projectRoot, './webpack.config.js');\n}\n"],"names":["WebpackBundlerDevServer","getProjectWebpackConfigFilePath","debug","require","assertIsWebpackDevServer","value","sockWrite","sendMessage","CommandError","constructor","name","BundlerDevServer","startTypeScriptServices","broadcastMessage","method","params","instance","server","hackyConvertedMessage","sockets","isTargetingNative","getAvailablePortAsync","options","defaultPort","port","choosePortAsync","projectRoot","host","env","WEB_HOST","error","message","bundleAsync","mode","clear","webpack","importWebpackFromProject","clearWebProjectCacheAsync","config","loadConfigAsync","isImageEditingEnabled","plugins","bar","createProgressBar","chalk","width","total","complete","incomplete","push","ProgressPlugin","percent","update","terminate","compiler","compileAsync","Log","red","startImplementationAsync","WebpackDevServer","importWebpackDevServerFromProject","stopAsync","resetDevServer","https","urlCreator","getUrlCreator","location","scheme","ensureEnvironmentSupportsTLSAsync","catch","log","devServer","hostType","undefined","listen","originalClose","close","bind","callback","err","_host","getIpAddress","protocol","url","middleware","messageSocket","broadcast","getProjectConfigFilePath","getConfigModuleIds","reduce","prev","moduleId","resolveFrom","silent","argv","pwa","logger","info","setNodeEnv","load","projectWebpackConfig","webpackConfig","loadDefaultConfigAsync","importExpoWebpackConfigFromProject","dim","dir","ensureDotExpoProjectDirectoryInitialized","cacheFolder","path","join","fs","promises","rm","recursive","force"],"mappings":"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"}
@@ -22,13 +22,6 @@ _export(exports, {
22
22
  return signManifestString;
23
23
  }
24
24
  });
25
- function _graphqlweb() {
26
- const data = require("@0no-co/graphql.web");
27
- _graphqlweb = function() {
28
- return data;
29
- };
30
- return data;
31
- }
32
25
  function _codesigningcertificates() {
33
26
  const data = require("@expo/code-signing-certificates");
34
27
  _codesigningcertificates = function() {
@@ -43,13 +36,6 @@ function _jsonfile() {
43
36
  };
44
37
  return data;
45
38
  }
46
- function _core() {
47
- const data = require("@urql/core");
48
- _core = function() {
49
- return data;
50
- };
51
- return data;
52
- }
53
39
  function _fs() {
54
40
  const data = require("fs");
55
41
  _fs = function() {
@@ -75,10 +61,10 @@ const _env = require("./env");
75
61
  const _errors = require("./errors");
76
62
  const _getExpoGoIntermediateCertificate = require("../api/getExpoGoIntermediateCertificate");
77
63
  const _getProjectDevelopmentCertificate = require("../api/getProjectDevelopmentCertificate");
64
+ const _client = require("../api/graphql/client");
78
65
  const _AppQuery = require("../api/graphql/queries/AppQuery");
79
66
  const _UserSettings = require("../api/user/UserSettings");
80
67
  const _actions = require("../api/user/actions");
81
- const _generated = require("../graphql/generated");
82
68
  const _log = /*#__PURE__*/ _interop_require_wildcard(require("../log"));
83
69
  const _link = require("../utils/link");
84
70
  function _interop_require_default(obj) {
@@ -352,7 +338,7 @@ function actorCanGetProjectDevelopmentCertificate(actor, app) {
352
338
  var _actor_accounts_find_users_find_permissions, _actor_accounts_find_users_find, _actor_accounts_find_users, _actor_accounts_find;
353
339
  const owningAccountId = app.ownerAccount.id;
354
340
  const owningAccountIsActorPrimaryAccount = actor.__typename === 'User' || actor.__typename === 'SSOUser' ? actor.primaryAccount.id === owningAccountId : false;
355
- const userHasPublishPermissionForOwningAccount = !!((_actor_accounts_find = actor.accounts.find((account)=>account.id === owningAccountId)) == null ? void 0 : (_actor_accounts_find_users = _actor_accounts_find.users) == null ? void 0 : (_actor_accounts_find_users_find = _actor_accounts_find_users.find((userPermission)=>userPermission.actor.id === actor.id)) == null ? void 0 : (_actor_accounts_find_users_find_permissions = _actor_accounts_find_users_find.permissions) == null ? void 0 : _actor_accounts_find_users_find_permissions.includes(_generated.Permission.Publish));
341
+ const userHasPublishPermissionForOwningAccount = !!((_actor_accounts_find = actor.accounts.find((account)=>account.id === owningAccountId)) == null ? void 0 : (_actor_accounts_find_users = _actor_accounts_find.users) == null ? void 0 : (_actor_accounts_find_users_find = _actor_accounts_find_users.find((userPermission)=>userPermission.actor.id === actor.id)) == null ? void 0 : (_actor_accounts_find_users_find_permissions = _actor_accounts_find_users_find.permissions) == null ? void 0 : _actor_accounts_find_users_find_permissions.includes('PUBLISH'));
356
342
  return owningAccountIsActorPrimaryAccount || userHasPublishPermissionForOwningAccount;
357
343
  }
358
344
  async function fetchAndCacheNewDevelopmentCodeSigningInfoAsync(easProjectId) {
@@ -364,7 +350,7 @@ async function fetchAndCacheNewDevelopmentCodeSigningInfoAsync(easProjectId) {
364
350
  try {
365
351
  app = await _AppQuery.AppQuery.byIdAsync(easProjectId);
366
352
  } catch (e) {
367
- if (e instanceof _graphqlweb().GraphQLError || e instanceof _core().CombinedError) {
353
+ if (e instanceof _client.UnexpectedServerError || e instanceof _client.UnexpectedServerData) {
368
354
  return null;
369
355
  }
370
356
  throw e;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/codesigning.ts"],"sourcesContent":["import { GraphQLError } from '@0no-co/graphql.web';\nimport {\n convertCertificatePEMToCertificate,\n convertKeyPairToPEM,\n convertCSRToCSRPEM,\n generateKeyPair,\n generateCSR,\n convertPrivateKeyPEMToPrivateKey,\n validateSelfSignedCertificate,\n signBufferRSASHA256AndVerify,\n} from '@expo/code-signing-certificates';\nimport { ExpoConfig } from '@expo/config';\nimport JsonFile, { JSONObject } from '@expo/json-file';\nimport { CombinedError } from '@urql/core';\nimport { promises as fs } from 'fs';\nimport { pki as PKI } from 'node-forge';\nimport path from 'path';\nimport { Dictionary, parseDictionary } from 'structured-headers';\n\nimport { env } from './env';\nimport { CommandError } from './errors';\nimport { getExpoGoIntermediateCertificateAsync } from '../api/getExpoGoIntermediateCertificate';\nimport { getProjectDevelopmentCertificateAsync } from '../api/getProjectDevelopmentCertificate';\nimport { AppQuery } from '../api/graphql/queries/AppQuery';\nimport { getExpoHomeDirectory } from '../api/user/UserSettings';\nimport { tryGetUserAsync } from '../api/user/actions';\nimport { Actor } from '../api/user/user';\nimport { AppByIdQuery, Permission } from '../graphql/generated';\nimport * as Log from '../log';\nimport { learnMore } from '../utils/link';\n\nconst debug = require('debug')('expo:codesigning') as typeof console.log;\n\nexport type CodeSigningInfo = {\n keyId: string;\n privateKey: string;\n certificateForPrivateKey: string;\n /**\n * Chain of certificates to serve in the manifest multipart body \"certificate_chain\" part.\n * The leaf certificate must be the 0th element of the array, followed by any intermediate certificates\n * necessary to evaluate the chain of trust ending in the implicitly trusted root certificate embedded in\n * the client.\n *\n * An empty array indicates that there is no need to serve the certificate chain in the multipart response.\n */\n certificateChainForResponse: string[];\n /**\n * Scope key cached for the project when certificate is development Expo Go code signing.\n * For project-specific code signing (keyId == the project's generated keyId) this is undefined.\n */\n scopeKey: string | null;\n};\n\ntype StoredDevelopmentExpoRootCodeSigningInfo = {\n easProjectId: string | null;\n scopeKey: string | null;\n privateKey: string | null;\n certificateChain: string[] | null;\n};\nconst DEVELOPMENT_CODE_SIGNING_SETTINGS_FILE_NAME = 'development-code-signing-settings-2.json';\n\nexport function getDevelopmentCodeSigningDirectory(): string {\n return path.join(getExpoHomeDirectory(), 'codesigning');\n}\n\nfunction getProjectDevelopmentCodeSigningInfoFile<T extends JSONObject>(defaults: T) {\n function getFile(easProjectId: string): JsonFile<T> {\n const filePath = path.join(\n getDevelopmentCodeSigningDirectory(),\n easProjectId,\n DEVELOPMENT_CODE_SIGNING_SETTINGS_FILE_NAME\n );\n return new JsonFile<T>(filePath);\n }\n\n async function readAsync(easProjectId: string): Promise<T> {\n let projectSettings;\n try {\n projectSettings = await getFile(easProjectId).readAsync();\n } catch {\n projectSettings = await getFile(easProjectId).writeAsync(defaults, { ensureDir: true });\n }\n // Set defaults for any missing fields\n return { ...defaults, ...projectSettings };\n }\n\n async function setAsync(easProjectId: string, json: Partial<T>): Promise<T> {\n try {\n return await getFile(easProjectId).mergeAsync(json, {\n cantReadFileDefault: defaults,\n });\n } catch {\n return await getFile(easProjectId).writeAsync(\n {\n ...defaults,\n ...json,\n },\n { ensureDir: true }\n );\n }\n }\n\n return {\n getFile,\n readAsync,\n setAsync,\n };\n}\n\nexport const DevelopmentCodeSigningInfoFile =\n getProjectDevelopmentCodeSigningInfoFile<StoredDevelopmentExpoRootCodeSigningInfo>({\n easProjectId: null,\n scopeKey: null,\n privateKey: null,\n certificateChain: null,\n });\n\n/**\n * Get info necessary to generate a response `expo-signature` header given a project and incoming request `expo-expect-signature` header.\n * This only knows how to serve two code signing keyids:\n * - `expo-root` indicates that it should use a development certificate in the `expo-root` chain. See {@link getExpoRootDevelopmentCodeSigningInfoAsync}\n * - <developer's expo-updates keyid> indicates that it should sign with the configured certificate. See {@link getProjectCodeSigningCertificateAsync}\n */\nexport async function getCodeSigningInfoAsync(\n exp: ExpoConfig,\n expectSignatureHeader: string | null,\n privateKeyPath: string | undefined\n): Promise<CodeSigningInfo | null> {\n if (!expectSignatureHeader) {\n return null;\n }\n\n let parsedExpectSignature: Dictionary;\n try {\n parsedExpectSignature = parseDictionary(expectSignatureHeader);\n } catch {\n throw new CommandError('Invalid value for expo-expect-signature header');\n }\n\n const expectedKeyIdOuter = parsedExpectSignature.get('keyid');\n if (!expectedKeyIdOuter) {\n throw new CommandError('keyid not present in expo-expect-signature header');\n }\n\n const expectedKeyId = expectedKeyIdOuter[0];\n if (typeof expectedKeyId !== 'string') {\n throw new CommandError(\n `Invalid value for keyid in expo-expect-signature header: ${expectedKeyId}`\n );\n }\n\n let expectedAlg: string | null = null;\n const expectedAlgOuter = parsedExpectSignature.get('alg');\n if (expectedAlgOuter) {\n const expectedAlgTemp = expectedAlgOuter[0];\n if (typeof expectedAlgTemp !== 'string') {\n throw new CommandError('Invalid value for alg in expo-expect-signature header');\n }\n expectedAlg = expectedAlgTemp;\n }\n\n if (expectedKeyId === 'expo-root') {\n return await getExpoRootDevelopmentCodeSigningInfoAsync(exp);\n } else if (expectedKeyId === 'expo-go') {\n throw new CommandError(\n 'Invalid certificate requested: cannot sign with embedded keyid=expo-go key'\n );\n } else {\n return await getProjectCodeSigningCertificateAsync(\n exp,\n privateKeyPath,\n expectedKeyId,\n expectedAlg\n );\n }\n}\n\n/**\n * Get a development code signing certificate for the expo-root -> expo-go -> (development certificate) certificate chain.\n * This requires the user be logged in and online, otherwise try to use the cached development certificate.\n */\nasync function getExpoRootDevelopmentCodeSigningInfoAsync(\n exp: ExpoConfig\n): Promise<CodeSigningInfo | null> {\n const easProjectId = exp.extra?.eas?.projectId;\n // can't check for scope key validity since scope key is derived on the server from projectId and we may be offline.\n // we rely upon the client certificate check to validate the scope key\n if (!easProjectId) {\n debug(\n `WARN: Expo Application Services (EAS) is not configured for your project. Configuring EAS enables a more secure development experience amongst many other benefits. ${learnMore(\n 'https://docs.expo.dev/eas/'\n )}`\n );\n return null;\n }\n\n const developmentCodeSigningInfoFromFile =\n await DevelopmentCodeSigningInfoFile.readAsync(easProjectId);\n const validatedCodeSigningInfo = validateStoredDevelopmentExpoRootCertificateCodeSigningInfo(\n developmentCodeSigningInfoFromFile,\n easProjectId\n );\n\n // 1. If online, ensure logged in, generate key pair and CSR, fetch and cache certificate chain for projectId\n // (overwriting existing dev cert in case projectId changed or it has expired)\n if (!env.EXPO_OFFLINE) {\n try {\n const newCodeSigningInfo =\n await fetchAndCacheNewDevelopmentCodeSigningInfoAsync(easProjectId);\n\n if (newCodeSigningInfo) {\n return newCodeSigningInfo;\n // fall back to cached certificate if we couldn't fetch a new one\n } else if (validatedCodeSigningInfo) {\n Log.warn(\n 'Could not fetch new Expo development certificate, falling back to cached certificate'\n );\n return validatedCodeSigningInfo;\n } else {\n return null;\n }\n } catch (e: any) {\n if (validatedCodeSigningInfo) {\n Log.warn(\n 'There was an error fetching the Expo development certificate, falling back to cached certificate'\n );\n return validatedCodeSigningInfo;\n } else {\n // need to return null here and say a message\n throw e;\n }\n }\n }\n\n // 2. check for cached cert/private key matching projectId and scopeKey of project, if found and valid return private key and cert chain including expo-go cert\n if (validatedCodeSigningInfo) {\n return validatedCodeSigningInfo;\n }\n\n // 3. if offline, return null\n Log.warn('Offline and no cached development certificate found, unable to sign manifest');\n return null;\n}\n\n/**\n * Get the certificate configured for expo-updates for this project.\n */\nasync function getProjectCodeSigningCertificateAsync(\n exp: ExpoConfig,\n privateKeyPath: string | undefined,\n expectedKeyId: string,\n expectedAlg: string | null\n): Promise<CodeSigningInfo | null> {\n const codeSigningCertificatePath = exp.updates?.codeSigningCertificate;\n if (!codeSigningCertificatePath) {\n return null;\n }\n\n if (!privateKeyPath) {\n throw new CommandError(\n 'Must specify --private-key-path argument to sign development manifest for requested code signing key'\n );\n }\n\n const codeSigningMetadata = exp.updates?.codeSigningMetadata;\n if (!codeSigningMetadata) {\n throw new CommandError(\n 'Must specify \"codeSigningMetadata\" under the \"updates\" field of your app config file to use EAS code signing'\n );\n }\n\n const { alg, keyid } = codeSigningMetadata;\n if (!alg || !keyid) {\n throw new CommandError(\n 'Must specify \"keyid\" and \"alg\" in the \"codeSigningMetadata\" field under the \"updates\" field of your app config file to use EAS code signing'\n );\n }\n\n if (expectedKeyId !== keyid) {\n throw new CommandError(`keyid mismatch: client=${expectedKeyId}, project=${keyid}`);\n }\n\n if (expectedAlg && expectedAlg !== alg) {\n throw new CommandError(`\"alg\" field mismatch (client=${expectedAlg}, project=${alg})`);\n }\n\n const { privateKeyPEM, certificatePEM } =\n await getProjectPrivateKeyAndCertificateFromFilePathsAsync({\n codeSigningCertificatePath,\n privateKeyPath,\n });\n\n return {\n keyId: keyid,\n privateKey: privateKeyPEM,\n certificateForPrivateKey: certificatePEM,\n certificateChainForResponse: [],\n scopeKey: null,\n };\n}\n\nasync function readFileWithErrorAsync(path: string, errorMessage: string): Promise<string> {\n try {\n return await fs.readFile(path, 'utf8');\n } catch {\n throw new CommandError(errorMessage);\n }\n}\n\nasync function getProjectPrivateKeyAndCertificateFromFilePathsAsync({\n codeSigningCertificatePath,\n privateKeyPath,\n}: {\n codeSigningCertificatePath: string;\n privateKeyPath: string;\n}): Promise<{ privateKeyPEM: string; certificatePEM: string }> {\n const [codeSigningCertificatePEM, privateKeyPEM] = await Promise.all([\n readFileWithErrorAsync(\n codeSigningCertificatePath,\n `Code signing certificate cannot be read from path: ${codeSigningCertificatePath}`\n ),\n readFileWithErrorAsync(\n privateKeyPath,\n `Code signing private key cannot be read from path: ${privateKeyPath}`\n ),\n ]);\n\n const privateKey = convertPrivateKeyPEMToPrivateKey(privateKeyPEM);\n const certificate = convertCertificatePEMToCertificate(codeSigningCertificatePEM);\n validateSelfSignedCertificate(certificate, {\n publicKey: certificate.publicKey as PKI.rsa.PublicKey,\n privateKey,\n });\n\n return { privateKeyPEM, certificatePEM: codeSigningCertificatePEM };\n}\n\n/**\n * Validate that the cached code signing info is still valid for the current project and\n * that it hasn't expired. If invalid, return null.\n */\nfunction validateStoredDevelopmentExpoRootCertificateCodeSigningInfo(\n codeSigningInfo: StoredDevelopmentExpoRootCodeSigningInfo,\n easProjectId: string\n): CodeSigningInfo | null {\n if (codeSigningInfo.easProjectId !== easProjectId) {\n return null;\n }\n\n const {\n privateKey: privateKeyPEM,\n certificateChain: certificatePEMs,\n scopeKey,\n } = codeSigningInfo;\n if (!privateKeyPEM || !certificatePEMs) {\n return null;\n }\n\n const certificateChain = certificatePEMs.map((certificatePEM) =>\n convertCertificatePEMToCertificate(certificatePEM)\n );\n\n // TODO(wschurman): maybe move to @expo/code-signing-certificates\n\n // ensure all intermediate certificates are valid\n for (const certificate of certificateChain) {\n const now = new Date();\n if (certificate.validity.notBefore > now || certificate.validity.notAfter < now) {\n return null;\n }\n }\n\n // TODO(wschurman): maybe do more validation, like validation of projectID and scopeKey within eas certificate extension\n\n return {\n keyId: 'expo-go',\n certificateChainForResponse: certificatePEMs,\n certificateForPrivateKey: certificatePEMs[0],\n privateKey: privateKeyPEM,\n scopeKey,\n };\n}\n\nfunction actorCanGetProjectDevelopmentCertificate(actor: Actor, app: AppByIdQuery['app']['byId']) {\n const owningAccountId = app.ownerAccount.id;\n\n const owningAccountIsActorPrimaryAccount =\n actor.__typename === 'User' || actor.__typename === 'SSOUser'\n ? actor.primaryAccount.id === owningAccountId\n : false;\n const userHasPublishPermissionForOwningAccount = !!actor.accounts\n .find((account) => account.id === owningAccountId)\n ?.users?.find((userPermission) => userPermission.actor.id === actor.id)\n ?.permissions?.includes(Permission.Publish);\n return owningAccountIsActorPrimaryAccount || userHasPublishPermissionForOwningAccount;\n}\n\nasync function fetchAndCacheNewDevelopmentCodeSigningInfoAsync(\n easProjectId: string\n): Promise<CodeSigningInfo | null> {\n const actor = await tryGetUserAsync();\n\n if (!actor) {\n return null;\n }\n\n let app: AppByIdQuery['app']['byId'];\n try {\n app = await AppQuery.byIdAsync(easProjectId);\n } catch (e) {\n if (e instanceof GraphQLError || e instanceof CombinedError) {\n return null;\n }\n throw e;\n }\n if (!actorCanGetProjectDevelopmentCertificate(actor, app)) {\n return null;\n }\n\n const keyPair = generateKeyPair();\n const keyPairPEM = convertKeyPairToPEM(keyPair);\n const csr = generateCSR(keyPair, `Development Certificate for ${easProjectId}`);\n const csrPEM = convertCSRToCSRPEM(csr);\n const [developmentSigningCertificate, expoGoIntermediateCertificate] = await Promise.all([\n getProjectDevelopmentCertificateAsync(easProjectId, csrPEM),\n getExpoGoIntermediateCertificateAsync(easProjectId),\n ]);\n\n await DevelopmentCodeSigningInfoFile.setAsync(easProjectId, {\n easProjectId,\n scopeKey: app.scopeKey,\n privateKey: keyPairPEM.privateKeyPEM,\n certificateChain: [developmentSigningCertificate, expoGoIntermediateCertificate],\n });\n\n return {\n keyId: 'expo-go',\n certificateChainForResponse: [developmentSigningCertificate, expoGoIntermediateCertificate],\n certificateForPrivateKey: developmentSigningCertificate,\n privateKey: keyPairPEM.privateKeyPEM,\n scopeKey: app.scopeKey,\n };\n}\n/**\n * Generate the `expo-signature` header for a manifest and code signing info.\n */\nexport function signManifestString(\n stringifiedManifest: string,\n codeSigningInfo: CodeSigningInfo\n): string {\n const privateKey = convertPrivateKeyPEMToPrivateKey(codeSigningInfo.privateKey);\n const certificate = convertCertificatePEMToCertificate(codeSigningInfo.certificateForPrivateKey);\n return signBufferRSASHA256AndVerify(\n privateKey,\n certificate,\n Buffer.from(stringifiedManifest, 'utf8')\n );\n}\n"],"names":["DevelopmentCodeSigningInfoFile","getCodeSigningInfoAsync","getDevelopmentCodeSigningDirectory","signManifestString","debug","require","DEVELOPMENT_CODE_SIGNING_SETTINGS_FILE_NAME","path","join","getExpoHomeDirectory","getProjectDevelopmentCodeSigningInfoFile","defaults","getFile","easProjectId","filePath","JsonFile","readAsync","projectSettings","writeAsync","ensureDir","setAsync","json","mergeAsync","cantReadFileDefault","scopeKey","privateKey","certificateChain","exp","expectSignatureHeader","privateKeyPath","parsedExpectSignature","parseDictionary","CommandError","expectedKeyIdOuter","get","expectedKeyId","expectedAlg","expectedAlgOuter","expectedAlgTemp","getExpoRootDevelopmentCodeSigningInfoAsync","getProjectCodeSigningCertificateAsync","extra","eas","projectId","learnMore","developmentCodeSigningInfoFromFile","validatedCodeSigningInfo","validateStoredDevelopmentExpoRootCertificateCodeSigningInfo","env","EXPO_OFFLINE","newCodeSigningInfo","fetchAndCacheNewDevelopmentCodeSigningInfoAsync","Log","warn","e","codeSigningCertificatePath","updates","codeSigningCertificate","codeSigningMetadata","alg","keyid","privateKeyPEM","certificatePEM","getProjectPrivateKeyAndCertificateFromFilePathsAsync","keyId","certificateForPrivateKey","certificateChainForResponse","readFileWithErrorAsync","errorMessage","fs","readFile","codeSigningCertificatePEM","Promise","all","convertPrivateKeyPEMToPrivateKey","certificate","convertCertificatePEMToCertificate","validateSelfSignedCertificate","publicKey","codeSigningInfo","certificatePEMs","map","now","Date","validity","notBefore","notAfter","actorCanGetProjectDevelopmentCertificate","actor","app","owningAccountId","ownerAccount","id","owningAccountIsActorPrimaryAccount","__typename","primaryAccount","userHasPublishPermissionForOwningAccount","accounts","find","account","users","userPermission","permissions","includes","Permission","Publish","tryGetUserAsync","AppQuery","byIdAsync","GraphQLError","CombinedError","keyPair","generateKeyPair","keyPairPEM","convertKeyPairToPEM","csr","generateCSR","csrPEM","convertCSRToCSRPEM","developmentSigningCertificate","expoGoIntermediateCertificate","getProjectDevelopmentCertificateAsync","getExpoGoIntermediateCertificateAsync","stringifiedManifest","signBufferRSASHA256AndVerify","Buffer","from"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/codesigning.ts"],"sourcesContent":["import {\n convertCertificatePEMToCertificate,\n convertKeyPairToPEM,\n convertCSRToCSRPEM,\n generateKeyPair,\n generateCSR,\n convertPrivateKeyPEMToPrivateKey,\n validateSelfSignedCertificate,\n signBufferRSASHA256AndVerify,\n} from '@expo/code-signing-certificates';\nimport { ExpoConfig } from '@expo/config';\nimport JsonFile, { JSONObject } from '@expo/json-file';\nimport { promises as fs } from 'fs';\nimport { pki as PKI } from 'node-forge';\nimport path from 'path';\nimport { Dictionary, parseDictionary } from 'structured-headers';\n\nimport { env } from './env';\nimport { CommandError } from './errors';\nimport { getExpoGoIntermediateCertificateAsync } from '../api/getExpoGoIntermediateCertificate';\nimport { getProjectDevelopmentCertificateAsync } from '../api/getProjectDevelopmentCertificate';\nimport { UnexpectedServerError, UnexpectedServerData } from '../api/graphql/client';\nimport { AppQuery, type App } from '../api/graphql/queries/AppQuery';\nimport { getExpoHomeDirectory } from '../api/user/UserSettings';\nimport { tryGetUserAsync } from '../api/user/actions';\nimport { Actor } from '../api/user/user';\nimport * as Log from '../log';\nimport { learnMore } from '../utils/link';\n\nconst debug = require('debug')('expo:codesigning') as typeof console.log;\n\nexport type CodeSigningInfo = {\n keyId: string;\n privateKey: string;\n certificateForPrivateKey: string;\n /**\n * Chain of certificates to serve in the manifest multipart body \"certificate_chain\" part.\n * The leaf certificate must be the 0th element of the array, followed by any intermediate certificates\n * necessary to evaluate the chain of trust ending in the implicitly trusted root certificate embedded in\n * the client.\n *\n * An empty array indicates that there is no need to serve the certificate chain in the multipart response.\n */\n certificateChainForResponse: string[];\n /**\n * Scope key cached for the project when certificate is development Expo Go code signing.\n * For project-specific code signing (keyId == the project's generated keyId) this is undefined.\n */\n scopeKey: string | null;\n};\n\ntype StoredDevelopmentExpoRootCodeSigningInfo = {\n easProjectId: string | null;\n scopeKey: string | null;\n privateKey: string | null;\n certificateChain: string[] | null;\n};\nconst DEVELOPMENT_CODE_SIGNING_SETTINGS_FILE_NAME = 'development-code-signing-settings-2.json';\n\nexport function getDevelopmentCodeSigningDirectory(): string {\n return path.join(getExpoHomeDirectory(), 'codesigning');\n}\n\nfunction getProjectDevelopmentCodeSigningInfoFile<T extends JSONObject>(defaults: T) {\n function getFile(easProjectId: string): JsonFile<T> {\n const filePath = path.join(\n getDevelopmentCodeSigningDirectory(),\n easProjectId,\n DEVELOPMENT_CODE_SIGNING_SETTINGS_FILE_NAME\n );\n return new JsonFile<T>(filePath);\n }\n\n async function readAsync(easProjectId: string): Promise<T> {\n let projectSettings;\n try {\n projectSettings = await getFile(easProjectId).readAsync();\n } catch {\n projectSettings = await getFile(easProjectId).writeAsync(defaults, { ensureDir: true });\n }\n // Set defaults for any missing fields\n return { ...defaults, ...projectSettings };\n }\n\n async function setAsync(easProjectId: string, json: Partial<T>): Promise<T> {\n try {\n return await getFile(easProjectId).mergeAsync(json, {\n cantReadFileDefault: defaults,\n });\n } catch {\n return await getFile(easProjectId).writeAsync(\n {\n ...defaults,\n ...json,\n },\n { ensureDir: true }\n );\n }\n }\n\n return {\n getFile,\n readAsync,\n setAsync,\n };\n}\n\nexport const DevelopmentCodeSigningInfoFile =\n getProjectDevelopmentCodeSigningInfoFile<StoredDevelopmentExpoRootCodeSigningInfo>({\n easProjectId: null,\n scopeKey: null,\n privateKey: null,\n certificateChain: null,\n });\n\n/**\n * Get info necessary to generate a response `expo-signature` header given a project and incoming request `expo-expect-signature` header.\n * This only knows how to serve two code signing keyids:\n * - `expo-root` indicates that it should use a development certificate in the `expo-root` chain. See {@link getExpoRootDevelopmentCodeSigningInfoAsync}\n * - <developer's expo-updates keyid> indicates that it should sign with the configured certificate. See {@link getProjectCodeSigningCertificateAsync}\n */\nexport async function getCodeSigningInfoAsync(\n exp: ExpoConfig,\n expectSignatureHeader: string | null,\n privateKeyPath: string | undefined\n): Promise<CodeSigningInfo | null> {\n if (!expectSignatureHeader) {\n return null;\n }\n\n let parsedExpectSignature: Dictionary;\n try {\n parsedExpectSignature = parseDictionary(expectSignatureHeader);\n } catch {\n throw new CommandError('Invalid value for expo-expect-signature header');\n }\n\n const expectedKeyIdOuter = parsedExpectSignature.get('keyid');\n if (!expectedKeyIdOuter) {\n throw new CommandError('keyid not present in expo-expect-signature header');\n }\n\n const expectedKeyId = expectedKeyIdOuter[0];\n if (typeof expectedKeyId !== 'string') {\n throw new CommandError(\n `Invalid value for keyid in expo-expect-signature header: ${expectedKeyId}`\n );\n }\n\n let expectedAlg: string | null = null;\n const expectedAlgOuter = parsedExpectSignature.get('alg');\n if (expectedAlgOuter) {\n const expectedAlgTemp = expectedAlgOuter[0];\n if (typeof expectedAlgTemp !== 'string') {\n throw new CommandError('Invalid value for alg in expo-expect-signature header');\n }\n expectedAlg = expectedAlgTemp;\n }\n\n if (expectedKeyId === 'expo-root') {\n return await getExpoRootDevelopmentCodeSigningInfoAsync(exp);\n } else if (expectedKeyId === 'expo-go') {\n throw new CommandError(\n 'Invalid certificate requested: cannot sign with embedded keyid=expo-go key'\n );\n } else {\n return await getProjectCodeSigningCertificateAsync(\n exp,\n privateKeyPath,\n expectedKeyId,\n expectedAlg\n );\n }\n}\n\n/**\n * Get a development code signing certificate for the expo-root -> expo-go -> (development certificate) certificate chain.\n * This requires the user be logged in and online, otherwise try to use the cached development certificate.\n */\nasync function getExpoRootDevelopmentCodeSigningInfoAsync(\n exp: ExpoConfig\n): Promise<CodeSigningInfo | null> {\n const easProjectId = exp.extra?.eas?.projectId;\n // can't check for scope key validity since scope key is derived on the server from projectId and we may be offline.\n // we rely upon the client certificate check to validate the scope key\n if (!easProjectId) {\n debug(\n `WARN: Expo Application Services (EAS) is not configured for your project. Configuring EAS enables a more secure development experience amongst many other benefits. ${learnMore(\n 'https://docs.expo.dev/eas/'\n )}`\n );\n return null;\n }\n\n const developmentCodeSigningInfoFromFile =\n await DevelopmentCodeSigningInfoFile.readAsync(easProjectId);\n const validatedCodeSigningInfo = validateStoredDevelopmentExpoRootCertificateCodeSigningInfo(\n developmentCodeSigningInfoFromFile,\n easProjectId\n );\n\n // 1. If online, ensure logged in, generate key pair and CSR, fetch and cache certificate chain for projectId\n // (overwriting existing dev cert in case projectId changed or it has expired)\n if (!env.EXPO_OFFLINE) {\n try {\n const newCodeSigningInfo =\n await fetchAndCacheNewDevelopmentCodeSigningInfoAsync(easProjectId);\n\n if (newCodeSigningInfo) {\n return newCodeSigningInfo;\n // fall back to cached certificate if we couldn't fetch a new one\n } else if (validatedCodeSigningInfo) {\n Log.warn(\n 'Could not fetch new Expo development certificate, falling back to cached certificate'\n );\n return validatedCodeSigningInfo;\n } else {\n return null;\n }\n } catch (e: any) {\n if (validatedCodeSigningInfo) {\n Log.warn(\n 'There was an error fetching the Expo development certificate, falling back to cached certificate'\n );\n return validatedCodeSigningInfo;\n } else {\n // need to return null here and say a message\n throw e;\n }\n }\n }\n\n // 2. check for cached cert/private key matching projectId and scopeKey of project, if found and valid return private key and cert chain including expo-go cert\n if (validatedCodeSigningInfo) {\n return validatedCodeSigningInfo;\n }\n\n // 3. if offline, return null\n Log.warn('Offline and no cached development certificate found, unable to sign manifest');\n return null;\n}\n\n/**\n * Get the certificate configured for expo-updates for this project.\n */\nasync function getProjectCodeSigningCertificateAsync(\n exp: ExpoConfig,\n privateKeyPath: string | undefined,\n expectedKeyId: string,\n expectedAlg: string | null\n): Promise<CodeSigningInfo | null> {\n const codeSigningCertificatePath = exp.updates?.codeSigningCertificate;\n if (!codeSigningCertificatePath) {\n return null;\n }\n\n if (!privateKeyPath) {\n throw new CommandError(\n 'Must specify --private-key-path argument to sign development manifest for requested code signing key'\n );\n }\n\n const codeSigningMetadata = exp.updates?.codeSigningMetadata;\n if (!codeSigningMetadata) {\n throw new CommandError(\n 'Must specify \"codeSigningMetadata\" under the \"updates\" field of your app config file to use EAS code signing'\n );\n }\n\n const { alg, keyid } = codeSigningMetadata;\n if (!alg || !keyid) {\n throw new CommandError(\n 'Must specify \"keyid\" and \"alg\" in the \"codeSigningMetadata\" field under the \"updates\" field of your app config file to use EAS code signing'\n );\n }\n\n if (expectedKeyId !== keyid) {\n throw new CommandError(`keyid mismatch: client=${expectedKeyId}, project=${keyid}`);\n }\n\n if (expectedAlg && expectedAlg !== alg) {\n throw new CommandError(`\"alg\" field mismatch (client=${expectedAlg}, project=${alg})`);\n }\n\n const { privateKeyPEM, certificatePEM } =\n await getProjectPrivateKeyAndCertificateFromFilePathsAsync({\n codeSigningCertificatePath,\n privateKeyPath,\n });\n\n return {\n keyId: keyid,\n privateKey: privateKeyPEM,\n certificateForPrivateKey: certificatePEM,\n certificateChainForResponse: [],\n scopeKey: null,\n };\n}\n\nasync function readFileWithErrorAsync(path: string, errorMessage: string): Promise<string> {\n try {\n return await fs.readFile(path, 'utf8');\n } catch {\n throw new CommandError(errorMessage);\n }\n}\n\nasync function getProjectPrivateKeyAndCertificateFromFilePathsAsync({\n codeSigningCertificatePath,\n privateKeyPath,\n}: {\n codeSigningCertificatePath: string;\n privateKeyPath: string;\n}): Promise<{ privateKeyPEM: string; certificatePEM: string }> {\n const [codeSigningCertificatePEM, privateKeyPEM] = await Promise.all([\n readFileWithErrorAsync(\n codeSigningCertificatePath,\n `Code signing certificate cannot be read from path: ${codeSigningCertificatePath}`\n ),\n readFileWithErrorAsync(\n privateKeyPath,\n `Code signing private key cannot be read from path: ${privateKeyPath}`\n ),\n ]);\n\n const privateKey = convertPrivateKeyPEMToPrivateKey(privateKeyPEM);\n const certificate = convertCertificatePEMToCertificate(codeSigningCertificatePEM);\n validateSelfSignedCertificate(certificate, {\n publicKey: certificate.publicKey as PKI.rsa.PublicKey,\n privateKey,\n });\n\n return { privateKeyPEM, certificatePEM: codeSigningCertificatePEM };\n}\n\n/**\n * Validate that the cached code signing info is still valid for the current project and\n * that it hasn't expired. If invalid, return null.\n */\nfunction validateStoredDevelopmentExpoRootCertificateCodeSigningInfo(\n codeSigningInfo: StoredDevelopmentExpoRootCodeSigningInfo,\n easProjectId: string\n): CodeSigningInfo | null {\n if (codeSigningInfo.easProjectId !== easProjectId) {\n return null;\n }\n\n const {\n privateKey: privateKeyPEM,\n certificateChain: certificatePEMs,\n scopeKey,\n } = codeSigningInfo;\n if (!privateKeyPEM || !certificatePEMs) {\n return null;\n }\n\n const certificateChain = certificatePEMs.map((certificatePEM) =>\n convertCertificatePEMToCertificate(certificatePEM)\n );\n\n // TODO(wschurman): maybe move to @expo/code-signing-certificates\n\n // ensure all intermediate certificates are valid\n for (const certificate of certificateChain) {\n const now = new Date();\n if (certificate.validity.notBefore > now || certificate.validity.notAfter < now) {\n return null;\n }\n }\n\n // TODO(wschurman): maybe do more validation, like validation of projectID and scopeKey within eas certificate extension\n\n return {\n keyId: 'expo-go',\n certificateChainForResponse: certificatePEMs,\n certificateForPrivateKey: certificatePEMs[0],\n privateKey: privateKeyPEM,\n scopeKey,\n };\n}\n\nfunction actorCanGetProjectDevelopmentCertificate(actor: Actor, app: App) {\n const owningAccountId = app.ownerAccount.id;\n\n const owningAccountIsActorPrimaryAccount =\n actor.__typename === 'User' || actor.__typename === 'SSOUser'\n ? actor.primaryAccount.id === owningAccountId\n : false;\n const userHasPublishPermissionForOwningAccount = !!actor.accounts\n .find((account) => account.id === owningAccountId)\n ?.users?.find((userPermission) => userPermission.actor.id === actor.id)\n ?.permissions?.includes('PUBLISH');\n return owningAccountIsActorPrimaryAccount || userHasPublishPermissionForOwningAccount;\n}\n\nasync function fetchAndCacheNewDevelopmentCodeSigningInfoAsync(\n easProjectId: string\n): Promise<CodeSigningInfo | null> {\n const actor = await tryGetUserAsync();\n\n if (!actor) {\n return null;\n }\n\n let app: App;\n try {\n app = await AppQuery.byIdAsync(easProjectId);\n } catch (e) {\n if (e instanceof UnexpectedServerError || e instanceof UnexpectedServerData) {\n return null;\n }\n throw e;\n }\n if (!actorCanGetProjectDevelopmentCertificate(actor, app)) {\n return null;\n }\n\n const keyPair = generateKeyPair();\n const keyPairPEM = convertKeyPairToPEM(keyPair);\n const csr = generateCSR(keyPair, `Development Certificate for ${easProjectId}`);\n const csrPEM = convertCSRToCSRPEM(csr);\n const [developmentSigningCertificate, expoGoIntermediateCertificate] = await Promise.all([\n getProjectDevelopmentCertificateAsync(easProjectId, csrPEM),\n getExpoGoIntermediateCertificateAsync(easProjectId),\n ]);\n\n await DevelopmentCodeSigningInfoFile.setAsync(easProjectId, {\n easProjectId,\n scopeKey: app.scopeKey,\n privateKey: keyPairPEM.privateKeyPEM,\n certificateChain: [developmentSigningCertificate, expoGoIntermediateCertificate],\n });\n\n return {\n keyId: 'expo-go',\n certificateChainForResponse: [developmentSigningCertificate, expoGoIntermediateCertificate],\n certificateForPrivateKey: developmentSigningCertificate,\n privateKey: keyPairPEM.privateKeyPEM,\n scopeKey: app.scopeKey,\n };\n}\n/**\n * Generate the `expo-signature` header for a manifest and code signing info.\n */\nexport function signManifestString(\n stringifiedManifest: string,\n codeSigningInfo: CodeSigningInfo\n): string {\n const privateKey = convertPrivateKeyPEMToPrivateKey(codeSigningInfo.privateKey);\n const certificate = convertCertificatePEMToCertificate(codeSigningInfo.certificateForPrivateKey);\n return signBufferRSASHA256AndVerify(\n privateKey,\n certificate,\n Buffer.from(stringifiedManifest, 'utf8')\n );\n}\n"],"names":["DevelopmentCodeSigningInfoFile","getCodeSigningInfoAsync","getDevelopmentCodeSigningDirectory","signManifestString","debug","require","DEVELOPMENT_CODE_SIGNING_SETTINGS_FILE_NAME","path","join","getExpoHomeDirectory","getProjectDevelopmentCodeSigningInfoFile","defaults","getFile","easProjectId","filePath","JsonFile","readAsync","projectSettings","writeAsync","ensureDir","setAsync","json","mergeAsync","cantReadFileDefault","scopeKey","privateKey","certificateChain","exp","expectSignatureHeader","privateKeyPath","parsedExpectSignature","parseDictionary","CommandError","expectedKeyIdOuter","get","expectedKeyId","expectedAlg","expectedAlgOuter","expectedAlgTemp","getExpoRootDevelopmentCodeSigningInfoAsync","getProjectCodeSigningCertificateAsync","extra","eas","projectId","learnMore","developmentCodeSigningInfoFromFile","validatedCodeSigningInfo","validateStoredDevelopmentExpoRootCertificateCodeSigningInfo","env","EXPO_OFFLINE","newCodeSigningInfo","fetchAndCacheNewDevelopmentCodeSigningInfoAsync","Log","warn","e","codeSigningCertificatePath","updates","codeSigningCertificate","codeSigningMetadata","alg","keyid","privateKeyPEM","certificatePEM","getProjectPrivateKeyAndCertificateFromFilePathsAsync","keyId","certificateForPrivateKey","certificateChainForResponse","readFileWithErrorAsync","errorMessage","fs","readFile","codeSigningCertificatePEM","Promise","all","convertPrivateKeyPEMToPrivateKey","certificate","convertCertificatePEMToCertificate","validateSelfSignedCertificate","publicKey","codeSigningInfo","certificatePEMs","map","now","Date","validity","notBefore","notAfter","actorCanGetProjectDevelopmentCertificate","actor","app","owningAccountId","ownerAccount","id","owningAccountIsActorPrimaryAccount","__typename","primaryAccount","userHasPublishPermissionForOwningAccount","accounts","find","account","users","userPermission","permissions","includes","tryGetUserAsync","AppQuery","byIdAsync","UnexpectedServerError","UnexpectedServerData","keyPair","generateKeyPair","keyPairPEM","convertKeyPairToPEM","csr","generateCSR","csrPEM","convertCSRToCSRPEM","developmentSigningCertificate","expoGoIntermediateCertificate","getProjectDevelopmentCertificateAsync","getExpoGoIntermediateCertificateAsync","stringifiedManifest","signBufferRSASHA256AndVerify","Buffer","from"],"mappings":"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"}
@@ -2,34 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
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
- createEntryResolver: function() {
13
- return createEntryResolver;
14
- },
15
- createGlobFilter: function() {
5
+ Object.defineProperty(exports, "createGlobFilter", {
6
+ enumerable: true,
7
+ get: function() {
16
8
  return createGlobFilter;
17
9
  }
18
10
  });
19
- function _configplugins() {
20
- const data = require("@expo/config-plugins");
21
- _configplugins = function() {
22
- return data;
23
- };
24
- return data;
25
- }
26
- function _path() {
27
- const data = /*#__PURE__*/ _interop_require_default(require("path"));
28
- _path = function() {
29
- return data;
30
- };
31
- return data;
32
- }
33
11
  function _picomatch() {
34
12
  const data = /*#__PURE__*/ _interop_require_default(require("picomatch"));
35
13
  _picomatch = function() {
@@ -43,19 +21,6 @@ function _interop_require_default(obj) {
43
21
  };
44
22
  }
45
23
  const debug = require('debug')('expo:file-transform');
46
- function createEntryResolver(name) {
47
- return (entry)=>{
48
- if (name) {
49
- // Rewrite paths for bare workflow
50
- entry.path = entry.path.replace(/HelloWorld/g, entry.path.includes('android') ? _configplugins().IOSConfig.XcodeUtils.sanitizedName(name.toLowerCase()) : _configplugins().IOSConfig.XcodeUtils.sanitizedName(name)).replace(/helloworld/g, _configplugins().IOSConfig.XcodeUtils.sanitizedName(name).toLowerCase());
51
- }
52
- if (entry.type && /^file$/i.test(entry.type) && _path().default.basename(entry.path) === 'gitignore') {
53
- // Rename `gitignore` because npm ignores files named `.gitignore` when publishing.
54
- // See: https://github.com/npm/npm/issues/1862
55
- entry.path = entry.path.replace(/gitignore$/, '.gitignore');
56
- }
57
- };
58
- }
59
24
  function createGlobFilter(globPattern, options) {
60
25
  const matcher = (0, _picomatch().default)(globPattern, options);
61
26
  debug('filter: created for pattern(s) "%s" (%s)', Array.isArray(globPattern) ? globPattern.join('", "') : globPattern, options);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/createFileTransform.ts"],"sourcesContent":["import { IOSConfig } from '@expo/config-plugins';\nimport path from 'path';\nimport picomatch from 'picomatch';\nimport { ReadEntry } from 'tar';\n\nconst debug = require('debug')('expo:file-transform') as typeof console.log;\n\nexport function createEntryResolver(name: string) {\n return (entry: ReadEntry) => {\n if (name) {\n // Rewrite paths for bare workflow\n entry.path = entry.path\n .replace(\n /HelloWorld/g,\n entry.path.includes('android')\n ? IOSConfig.XcodeUtils.sanitizedName(name.toLowerCase())\n : IOSConfig.XcodeUtils.sanitizedName(name)\n )\n .replace(/helloworld/g, IOSConfig.XcodeUtils.sanitizedName(name).toLowerCase());\n }\n if (entry.type && /^file$/i.test(entry.type) && path.basename(entry.path) === 'gitignore') {\n // Rename `gitignore` because npm ignores files named `.gitignore` when publishing.\n // See: https://github.com/npm/npm/issues/1862\n entry.path = entry.path.replace(/gitignore$/, '.gitignore');\n }\n };\n}\n\nexport function createGlobFilter(\n globPattern: picomatch.Glob,\n options?: picomatch.PicomatchOptions\n) {\n const matcher = picomatch(globPattern, options);\n\n debug(\n 'filter: created for pattern(s) \"%s\" (%s)',\n Array.isArray(globPattern) ? globPattern.join('\", \"') : globPattern,\n options\n );\n\n return (path: string) => {\n const included = matcher(path);\n debug('filter: %s - %s', included ? 'include' : 'exclude', path);\n return included;\n };\n}\n"],"names":["createEntryResolver","createGlobFilter","debug","require","name","entry","path","replace","includes","IOSConfig","XcodeUtils","sanitizedName","toLowerCase","type","test","basename","globPattern","options","matcher","picomatch","Array","isArray","join","included"],"mappings":";;;;;;;;;;;IAOgBA,mBAAmB;eAAnBA;;IAqBAC,gBAAgB;eAAhBA;;;;yBA5BU;;;;;;;gEACT;;;;;;;gEACK;;;;;;;;;;;AAGtB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,SAASH,oBAAoBI,IAAY;IAC9C,OAAO,CAACC;QACN,IAAID,MAAM;YACR,kCAAkC;YAClCC,MAAMC,IAAI,GAAGD,MAAMC,IAAI,CACpBC,OAAO,CACN,eACAF,MAAMC,IAAI,CAACE,QAAQ,CAAC,aAChBC,0BAAS,CAACC,UAAU,CAACC,aAAa,CAACP,KAAKQ,WAAW,MACnDH,0BAAS,CAACC,UAAU,CAACC,aAAa,CAACP,OAExCG,OAAO,CAAC,eAAeE,0BAAS,CAACC,UAAU,CAACC,aAAa,CAACP,MAAMQ,WAAW;QAChF;QACA,IAAIP,MAAMQ,IAAI,IAAI,UAAUC,IAAI,CAACT,MAAMQ,IAAI,KAAKP,eAAI,CAACS,QAAQ,CAACV,MAAMC,IAAI,MAAM,aAAa;YACzF,mFAAmF;YACnF,8CAA8C;YAC9CD,MAAMC,IAAI,GAAGD,MAAMC,IAAI,CAACC,OAAO,CAAC,cAAc;QAChD;IACF;AACF;AAEO,SAASN,iBACde,WAA2B,EAC3BC,OAAoC;IAEpC,MAAMC,UAAUC,IAAAA,oBAAS,EAACH,aAAaC;IAEvCf,MACE,4CACAkB,MAAMC,OAAO,CAACL,eAAeA,YAAYM,IAAI,CAAC,UAAUN,aACxDC;IAGF,OAAO,CAACX;QACN,MAAMiB,WAAWL,QAAQZ;QACzBJ,MAAM,mBAAmBqB,WAAW,YAAY,WAAWjB;QAC3D,OAAOiB;IACT;AACF"}
1
+ {"version":3,"sources":["../../../src/utils/createFileTransform.ts"],"sourcesContent":["import picomatch from 'picomatch';\n\nconst debug = require('debug')('expo:file-transform') as typeof console.log;\n\nexport function createGlobFilter(\n globPattern: picomatch.Glob,\n options?: picomatch.PicomatchOptions\n) {\n const matcher = picomatch(globPattern, options);\n\n debug(\n 'filter: created for pattern(s) \"%s\" (%s)',\n Array.isArray(globPattern) ? globPattern.join('\", \"') : globPattern,\n options\n );\n\n return (path: string) => {\n const included = matcher(path);\n debug('filter: %s - %s', included ? 'include' : 'exclude', path);\n return included;\n };\n}\n"],"names":["createGlobFilter","debug","require","globPattern","options","matcher","picomatch","Array","isArray","join","path","included"],"mappings":";;;;+BAIgBA;;;eAAAA;;;;gEAJM;;;;;;;;;;;AAEtB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,SAASF,iBACdG,WAA2B,EAC3BC,OAAoC;IAEpC,MAAMC,UAAUC,IAAAA,oBAAS,EAACH,aAAaC;IAEvCH,MACE,4CACAM,MAAMC,OAAO,CAACL,eAAeA,YAAYM,IAAI,CAAC,UAAUN,aACxDC;IAGF,OAAO,CAACM;QACN,MAAMC,WAAWN,QAAQK;QACzBT,MAAM,mBAAmBU,WAAW,YAAY,WAAWD;QAC3D,OAAOC;IACT;AACF"}
@@ -29,13 +29,6 @@ function _stream() {
29
29
  };
30
30
  return data;
31
31
  }
32
- function _undici() {
33
- const data = require("undici");
34
- _undici = function() {
35
- return data;
36
- };
37
- return data;
38
- }
39
32
  function _util() {
40
33
  const data = require("util");
41
34
  _util = function() {
@@ -54,7 +47,6 @@ function _interop_require_default(obj) {
54
47
  };
55
48
  }
56
49
  const debug = require('debug')('expo:utils:downloadAppAsync');
57
- const TIMER_DURATION = 30000;
58
50
  const pipeline = (0, _util().promisify)(_stream().Stream.pipeline);
59
51
  async function downloadAsync({ url, outputPath, cacheDirectory, onProgress }) {
60
52
  let fetchInstance = _client.fetchAsync;
@@ -69,10 +61,7 @@ async function downloadAsync({ url, outputPath, cacheDirectory, onProgress }) {
69
61
  }
70
62
  debug(`Downloading ${url} to ${outputPath}`);
71
63
  const res = await fetchInstance(url, {
72
- onProgress,
73
- dispatcher: new (_undici()).Agent({
74
- connectTimeout: TIMER_DURATION
75
- })
64
+ onProgress
76
65
  });
77
66
  if (!res.ok || !res.body) {
78
67
  throw new _errors.CommandError('FILE_DOWNLOAD', `Unexpected response: ${res.statusText}. From url: ${url}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/downloadAppAsync.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { Readable, Stream } from 'stream';\nimport { Agent } from 'undici';\nimport { promisify } from 'util';\n\nimport { createTempFilePath } from './createTempPath';\nimport { ensureDirectoryAsync } from './dir';\nimport { CommandError } from './errors';\nimport { extractAsync } from './tar';\nimport { createCachedFetch, fetchAsync } from '../api/rest/client';\nimport { FetchLike, ProgressCallback } from '../api/rest/client.types';\n\nconst debug = require('debug')('expo:utils:downloadAppAsync') as typeof console.log;\n\nconst TIMER_DURATION = 30000;\n\nconst pipeline = promisify(Stream.pipeline);\n\nasync function downloadAsync({\n url,\n outputPath,\n cacheDirectory,\n onProgress,\n}: {\n url: string;\n outputPath: string;\n cacheDirectory?: string;\n onProgress?: ProgressCallback;\n}) {\n let fetchInstance: FetchLike = fetchAsync;\n if (cacheDirectory) {\n // Reconstruct the cached fetch since caching could be disabled.\n fetchInstance = createCachedFetch({\n // We'll use a 1 week cache for versions so older values get flushed out eventually.\n ttl: 1000 * 60 * 60 * 24 * 7,\n // Users can also nuke their `~/.expo` directory to clear the cache.\n cacheDirectory,\n });\n }\n\n debug(`Downloading ${url} to ${outputPath}`);\n const res = await fetchInstance(url, {\n onProgress,\n dispatcher: new Agent({ connectTimeout: TIMER_DURATION }),\n });\n if (!res.ok || !res.body) {\n throw new CommandError(\n 'FILE_DOWNLOAD',\n `Unexpected response: ${res.statusText}. From url: ${url}`\n );\n }\n return pipeline(Readable.fromWeb(res.body), fs.createWriteStream(outputPath));\n}\n\nexport async function downloadAppAsync({\n url,\n outputPath,\n extract = false,\n cacheDirectory,\n onProgress,\n}: {\n url: string;\n outputPath: string;\n extract?: boolean;\n cacheDirectory?: string;\n onProgress?: ProgressCallback;\n}): Promise<void> {\n if (extract) {\n // For iOS we download the ipa to a file then pass that file into the extractor.\n // In the future we should just pipe the `res.body -> tar.extract` directly.\n // I tried this and it created some weird errors where observing the data stream\n // would corrupt the file causing tar to fail with `TAR_BAD_ARCHIVE`.\n const tmpPath = createTempFilePath(path.basename(outputPath));\n await downloadAsync({ url, outputPath: tmpPath, cacheDirectory, onProgress });\n debug(`Extracting ${tmpPath} to ${outputPath}`);\n await ensureDirectoryAsync(outputPath);\n await extractAsync(tmpPath, outputPath);\n } else {\n await ensureDirectoryAsync(path.dirname(outputPath));\n await downloadAsync({ url, outputPath, cacheDirectory, onProgress });\n }\n}\n"],"names":["downloadAppAsync","debug","require","TIMER_DURATION","pipeline","promisify","Stream","downloadAsync","url","outputPath","cacheDirectory","onProgress","fetchInstance","fetchAsync","createCachedFetch","ttl","res","dispatcher","Agent","connectTimeout","ok","body","CommandError","statusText","Readable","fromWeb","fs","createWriteStream","extract","tmpPath","createTempFilePath","path","basename","ensureDirectoryAsync","extractAsync","dirname"],"mappings":";;;;+BAuDsBA;;;eAAAA;;;;gEAvDP;;;;;;;gEACE;;;;;;;yBACgB;;;;;;;yBACX;;;;;;;yBACI;;;;;;gCAES;qBACE;wBACR;qBACA;wBACiB;;;;;;AAG9C,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,MAAMC,iBAAiB;AAEvB,MAAMC,WAAWC,IAAAA,iBAAS,EAACC,gBAAM,CAACF,QAAQ;AAE1C,eAAeG,cAAc,EAC3BC,GAAG,EACHC,UAAU,EACVC,cAAc,EACdC,UAAU,EAMX;IACC,IAAIC,gBAA2BC,kBAAU;IACzC,IAAIH,gBAAgB;QAClB,gEAAgE;QAChEE,gBAAgBE,IAAAA,yBAAiB,EAAC;YAChC,oFAAoF;YACpFC,KAAK,OAAO,KAAK,KAAK,KAAK;YAC3B,oEAAoE;YACpEL;QACF;IACF;IAEAT,MAAM,CAAC,YAAY,EAAEO,IAAI,IAAI,EAAEC,YAAY;IAC3C,MAAMO,MAAM,MAAMJ,cAAcJ,KAAK;QACnCG;QACAM,YAAY,IAAIC,CAAAA,SAAI,OAAC,CAAC;YAAEC,gBAAgBhB;QAAe;IACzD;IACA,IAAI,CAACa,IAAII,EAAE,IAAI,CAACJ,IAAIK,IAAI,EAAE;QACxB,MAAM,IAAIC,oBAAY,CACpB,iBACA,CAAC,qBAAqB,EAAEN,IAAIO,UAAU,CAAC,YAAY,EAAEf,KAAK;IAE9D;IACA,OAAOJ,SAASoB,kBAAQ,CAACC,OAAO,CAACT,IAAIK,IAAI,GAAGK,aAAE,CAACC,iBAAiB,CAAClB;AACnE;AAEO,eAAeT,iBAAiB,EACrCQ,GAAG,EACHC,UAAU,EACVmB,UAAU,KAAK,EACflB,cAAc,EACdC,UAAU,EAOX;IACC,IAAIiB,SAAS;QACX,gFAAgF;QAChF,4EAA4E;QAC5E,gFAAgF;QAChF,qEAAqE;QACrE,MAAMC,UAAUC,IAAAA,kCAAkB,EAACC,eAAI,CAACC,QAAQ,CAACvB;QACjD,MAAMF,cAAc;YAAEC;YAAKC,YAAYoB;YAASnB;YAAgBC;QAAW;QAC3EV,MAAM,CAAC,WAAW,EAAE4B,QAAQ,IAAI,EAAEpB,YAAY;QAC9C,MAAMwB,IAAAA,yBAAoB,EAACxB;QAC3B,MAAMyB,IAAAA,iBAAY,EAACL,SAASpB;IAC9B,OAAO;QACL,MAAMwB,IAAAA,yBAAoB,EAACF,eAAI,CAACI,OAAO,CAAC1B;QACxC,MAAMF,cAAc;YAAEC;YAAKC;YAAYC;YAAgBC;QAAW;IACpE;AACF"}
1
+ {"version":3,"sources":["../../../src/utils/downloadAppAsync.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { Readable, Stream } from 'stream';\nimport type { ReadableStream } from 'stream/web';\nimport { promisify } from 'util';\n\nimport { createTempFilePath } from './createTempPath';\nimport { ensureDirectoryAsync } from './dir';\nimport { CommandError } from './errors';\nimport { extractAsync } from './tar';\nimport { createCachedFetch, fetchAsync } from '../api/rest/client';\nimport { FetchLike, ProgressCallback } from '../api/rest/client.types';\n\nconst debug = require('debug')('expo:utils:downloadAppAsync') as typeof console.log;\n\nconst pipeline = promisify(Stream.pipeline);\n\nasync function downloadAsync({\n url,\n outputPath,\n cacheDirectory,\n onProgress,\n}: {\n url: string;\n outputPath: string;\n cacheDirectory?: string;\n onProgress?: ProgressCallback;\n}) {\n let fetchInstance: FetchLike = fetchAsync;\n if (cacheDirectory) {\n // Reconstruct the cached fetch since caching could be disabled.\n fetchInstance = createCachedFetch({\n // We'll use a 1 week cache for versions so older values get flushed out eventually.\n ttl: 1000 * 60 * 60 * 24 * 7,\n // Users can also nuke their `~/.expo` directory to clear the cache.\n cacheDirectory,\n });\n }\n\n debug(`Downloading ${url} to ${outputPath}`);\n const res = await fetchInstance(url, {\n onProgress,\n });\n if (!res.ok || !res.body) {\n throw new CommandError(\n 'FILE_DOWNLOAD',\n `Unexpected response: ${res.statusText}. From url: ${url}`\n );\n }\n return pipeline(Readable.fromWeb(res.body as ReadableStream), fs.createWriteStream(outputPath));\n}\n\nexport async function downloadAppAsync({\n url,\n outputPath,\n extract = false,\n cacheDirectory,\n onProgress,\n}: {\n url: string;\n outputPath: string;\n extract?: boolean;\n cacheDirectory?: string;\n onProgress?: ProgressCallback;\n}): Promise<void> {\n if (extract) {\n // For iOS we download the ipa to a file then pass that file into the extractor.\n // In the future we should just pipe the `res.body -> tar.extract` directly.\n // I tried this and it created some weird errors where observing the data stream\n // would corrupt the file causing tar to fail with `TAR_BAD_ARCHIVE`.\n const tmpPath = createTempFilePath(path.basename(outputPath));\n await downloadAsync({ url, outputPath: tmpPath, cacheDirectory, onProgress });\n debug(`Extracting ${tmpPath} to ${outputPath}`);\n await ensureDirectoryAsync(outputPath);\n await extractAsync(tmpPath, outputPath);\n } else {\n await ensureDirectoryAsync(path.dirname(outputPath));\n await downloadAsync({ url, outputPath, cacheDirectory, onProgress });\n }\n}\n"],"names":["downloadAppAsync","debug","require","pipeline","promisify","Stream","downloadAsync","url","outputPath","cacheDirectory","onProgress","fetchInstance","fetchAsync","createCachedFetch","ttl","res","ok","body","CommandError","statusText","Readable","fromWeb","fs","createWriteStream","extract","tmpPath","createTempFilePath","path","basename","ensureDirectoryAsync","extractAsync","dirname"],"mappings":";;;;+BAoDsBA;;;eAAAA;;;;gEApDP;;;;;;;gEACE;;;;;;;yBACgB;;;;;;;yBAEP;;;;;;gCAES;qBACE;wBACR;qBACA;wBACiB;;;;;;AAG9C,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,MAAMC,WAAWC,IAAAA,iBAAS,EAACC,gBAAM,CAACF,QAAQ;AAE1C,eAAeG,cAAc,EAC3BC,GAAG,EACHC,UAAU,EACVC,cAAc,EACdC,UAAU,EAMX;IACC,IAAIC,gBAA2BC,kBAAU;IACzC,IAAIH,gBAAgB;QAClB,gEAAgE;QAChEE,gBAAgBE,IAAAA,yBAAiB,EAAC;YAChC,oFAAoF;YACpFC,KAAK,OAAO,KAAK,KAAK,KAAK;YAC3B,oEAAoE;YACpEL;QACF;IACF;IAEAR,MAAM,CAAC,YAAY,EAAEM,IAAI,IAAI,EAAEC,YAAY;IAC3C,MAAMO,MAAM,MAAMJ,cAAcJ,KAAK;QACnCG;IACF;IACA,IAAI,CAACK,IAAIC,EAAE,IAAI,CAACD,IAAIE,IAAI,EAAE;QACxB,MAAM,IAAIC,oBAAY,CACpB,iBACA,CAAC,qBAAqB,EAAEH,IAAII,UAAU,CAAC,YAAY,EAAEZ,KAAK;IAE9D;IACA,OAAOJ,SAASiB,kBAAQ,CAACC,OAAO,CAACN,IAAIE,IAAI,GAAqBK,aAAE,CAACC,iBAAiB,CAACf;AACrF;AAEO,eAAeR,iBAAiB,EACrCO,GAAG,EACHC,UAAU,EACVgB,UAAU,KAAK,EACff,cAAc,EACdC,UAAU,EAOX;IACC,IAAIc,SAAS;QACX,gFAAgF;QAChF,4EAA4E;QAC5E,gFAAgF;QAChF,qEAAqE;QACrE,MAAMC,UAAUC,IAAAA,kCAAkB,EAACC,eAAI,CAACC,QAAQ,CAACpB;QACjD,MAAMF,cAAc;YAAEC;YAAKC,YAAYiB;YAAShB;YAAgBC;QAAW;QAC3ET,MAAM,CAAC,WAAW,EAAEwB,QAAQ,IAAI,EAAEjB,YAAY;QAC9C,MAAMqB,IAAAA,yBAAoB,EAACrB;QAC3B,MAAMsB,IAAAA,iBAAY,EAACL,SAASjB;IAC9B,OAAO;QACL,MAAMqB,IAAAA,yBAAoB,EAACF,eAAI,CAACI,OAAO,CAACvB;QACxC,MAAMF,cAAc;YAAEC;YAAKC;YAAYC;YAAgBC;QAAW;IACpE;AACF"}
@@ -10,13 +10,32 @@ function _export(target, all) {
10
10
  }
11
11
  _export(exports, {
12
12
  Headers: function() {
13
- return Headers;
13
+ return _fetchnodeshim().Headers;
14
+ },
15
+ Response: function() {
16
+ return _fetchnodeshim().Response;
14
17
  },
15
18
  fetch: function() {
16
- return fetch;
19
+ return _fetchnodeshim().fetch;
17
20
  }
18
21
  });
19
- const fetch = typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : require('undici').fetch;
20
- const Headers = typeof globalThis.Headers !== 'undefined' ? globalThis.Headers : require('undici').Headers;
22
+ function _fetchnodeshim() {
23
+ const data = require("fetch-nodeshim");
24
+ _fetchnodeshim = function() {
25
+ return data;
26
+ };
27
+ return data;
28
+ }
29
+ // NOTE(@kitten): Protect against accidental use of globals that don't match `fetch-nodeshim`
30
+ Object.assign(globalThis, {
31
+ fetch: _fetchnodeshim().fetch,
32
+ Blob: _fetchnodeshim().Blob,
33
+ URL: _fetchnodeshim().URL,
34
+ URLSearchParams: _fetchnodeshim().URLSearchParams,
35
+ Request: _fetchnodeshim().Request,
36
+ Response: _fetchnodeshim().Response,
37
+ Headers: _fetchnodeshim().Headers,
38
+ FormData: _fetchnodeshim().FormData
39
+ });
21
40
 
22
41
  //# sourceMappingURL=fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/fetch.ts"],"sourcesContent":["import type { FetchLike } from '../api/rest/client.types';\n\n/**\n * The Node's built-in fetch API, but polyfilled from `undici` if necessary.\n * @todo(cedric): remove this once we min-support a Node version where fetch can't be disabled\n */\nexport const fetch: FetchLike =\n typeof globalThis.fetch !== 'undefined' ? globalThis.fetch : require('undici').fetch;\n\n/**\n * Node's built-in fetch Headers class, or the polyfilled Headers from `undici` when unavailable.\n * @todo(cedric): remove this once we min-support a Node version where fetch can't be disabled\n */\nexport const Headers: typeof import('undici').Headers =\n typeof globalThis.Headers !== 'undefined' ? globalThis.Headers : require('undici').Headers;\n"],"names":["Headers","fetch","globalThis","require"],"mappings":";;;;;;;;;;;IAaaA,OAAO;eAAPA;;IAPAC,KAAK;eAALA;;;AAAN,MAAMA,QACX,OAAOC,WAAWD,KAAK,KAAK,cAAcC,WAAWD,KAAK,GAAGE,QAAQ,UAAUF,KAAK;AAM/E,MAAMD,UACX,OAAOE,WAAWF,OAAO,KAAK,cAAcE,WAAWF,OAAO,GAAGG,QAAQ,UAAUH,OAAO"}
1
+ {"version":3,"sources":["../../../src/utils/fetch.ts"],"sourcesContent":["import {\n fetch,\n Blob,\n URL,\n URLSearchParams,\n Request,\n Response,\n Headers,\n FormData,\n} from 'fetch-nodeshim';\n\n// NOTE(@kitten): Protect against accidental use of globals that don't match `fetch-nodeshim`\nObject.assign(globalThis, {\n fetch,\n Blob,\n URL,\n URLSearchParams,\n Request,\n Response,\n Headers,\n FormData,\n});\n\nexport { fetch, Headers, Response };\n"],"names":["Headers","Response","fetch","Object","assign","globalThis","Blob","URL","URLSearchParams","Request","FormData"],"mappings":";;;;;;;;;;;IAuBgBA,OAAO;eAAPA,wBAAO;;IAAEC,QAAQ;eAARA,yBAAQ;;IAAxBC,KAAK;eAALA,sBAAK;;;;yBAdP;;;;;;AAEP,6FAA6F;AAC7FC,OAAOC,MAAM,CAACC,YAAY;IACxBH,OAAAA,sBAAK;IACLI,MAAAA,qBAAI;IACJC,KAAAA,oBAAG;IACHC,iBAAAA,gCAAe;IACfC,SAAAA,wBAAO;IACPR,UAAAA,yBAAQ;IACRD,SAAAA,wBAAO;IACPU,UAAAA,yBAAQ;AACV"}
@@ -16,13 +16,6 @@ _export(exports, {
16
16
  return getOrPromptForPackageAsync;
17
17
  }
18
18
  });
19
- function _graphqlweb() {
20
- const data = require("@0no-co/graphql.web");
21
- _graphqlweb = function() {
22
- return data;
23
- };
24
- return data;
25
- }
26
19
  function _config() {
27
20
  const data = require("@expo/config");
28
21
  _config = function() {
@@ -30,13 +23,6 @@ function _config() {
30
23
  };
31
24
  return data;
32
25
  }
33
- function _core() {
34
- const data = require("@urql/core");
35
- _core = function() {
36
- return data;
37
- };
38
- return data;
39
- }
40
26
  function _chalk() {
41
27
  const data = /*#__PURE__*/ _interop_require_default(require("chalk"));
42
28
  _chalk = function() {
@@ -49,6 +35,7 @@ const _link = require("./link");
49
35
  const _modifyConfigAsync = require("./modifyConfigAsync");
50
36
  const _prompts = /*#__PURE__*/ _interop_require_wildcard(require("./prompts"));
51
37
  const _validateApplicationId = require("./validateApplicationId");
38
+ const _client = require("../api/graphql/client");
52
39
  const _AppQuery = require("../api/graphql/queries/AppQuery");
53
40
  const _UserSettings = require("../api/user/UserSettings");
54
41
  const _log = /*#__PURE__*/ _interop_require_wildcard(require("../log"));
@@ -115,7 +102,7 @@ async function getRecommendedReverseDomainNameSecondPartAsync(exp) {
115
102
  const app = await _AppQuery.AppQuery.byIdAsync(easProjectId);
116
103
  return app.ownerAccount.name;
117
104
  } catch (e) {
118
- if (e instanceof _graphqlweb().GraphQLError || e instanceof _core().CombinedError) {
105
+ if (e instanceof _client.UnexpectedServerData || e instanceof _client.UnexpectedServerError) {
119
106
  return null;
120
107
  }
121
108
  throw e;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/getOrPromptApplicationId.ts"],"sourcesContent":["import { GraphQLError } from '@0no-co/graphql.web';\nimport { ExpoConfig, getConfig } from '@expo/config';\nimport { CombinedError } from '@urql/core';\nimport chalk from 'chalk';\n\nimport { memoize } from './fn';\nimport { learnMore } from './link';\nimport { attemptModification } from './modifyConfigAsync';\nimport prompt, { confirmAsync } from './prompts';\nimport {\n assertValidBundleId,\n assertValidPackage,\n getBundleIdWarningAsync,\n getPackageNameWarningAsync,\n getSanitizedBundleIdentifier,\n getSanitizedPackage,\n validateBundleId,\n validatePackage,\n validatePackageWithWarning,\n} from './validateApplicationId';\nimport { AppQuery } from '../api/graphql/queries/AppQuery';\nimport { getSettings } from '../api/user/UserSettings';\nimport * as Log from '../log';\n\nconst debug = require('debug')('expo:app-id') as typeof console.log;\n\nconst ANONYMOUS_USERNAME = 'anonymous';\n\nasync function getRecommendedReverseDomainNameSecondPartAsync(\n exp: ExpoConfig\n): Promise<string | null> {\n // Get the cached username.\n const cachedUsername = getSettings().read().auth?.username;\n if (cachedUsername) {\n return cachedUsername;\n }\n const easProjectId = exp.extra?.eas?.projectId;\n if (!easProjectId) {\n return null;\n }\n\n try {\n const app = await AppQuery.byIdAsync(easProjectId);\n return app.ownerAccount.name;\n } catch (e) {\n if (e instanceof GraphQLError || e instanceof CombinedError) {\n return null;\n }\n throw e;\n }\n}\n\nconst NO_BUNDLE_ID_MESSAGE = `Project must have a \\`ios.bundleIdentifier\\` set in the Expo config (app.json or app.config.js).`;\n\nconst NO_PACKAGE_MESSAGE = `Project must have a \\`android.package\\` set in the Expo config (app.json or app.config.js).`;\n\n/**\n * Get the bundle identifier from the Expo config or prompt the user to choose a new bundle identifier.\n * Prompted value will be validated against the App Store and a local regex.\n * If the project Expo config is a static JSON file, the bundle identifier will be updated in the config automatically.\n */\nexport async function getOrPromptForBundleIdentifierAsync(\n projectRoot: string,\n exp: ExpoConfig = getConfig(projectRoot).exp\n): Promise<string> {\n const current = exp.ios?.bundleIdentifier;\n if (current) {\n assertValidBundleId(current);\n return current;\n }\n\n return promptForBundleIdWithInitialAsync(\n projectRoot,\n exp,\n await getRecommendedBundleIdAsync(exp)\n );\n}\n\nconst memoLog = memoize(Log.log);\n\nasync function promptForBundleIdWithInitialAsync(\n projectRoot: string,\n exp: ExpoConfig,\n bundleIdentifier?: string\n): Promise<string> {\n if (!bundleIdentifier) {\n memoLog(\n chalk`\\n{bold 📝 iOS Bundle Identifier} {dim ${learnMore(\n 'https://expo.fyi/bundle-identifier'\n )}}\\n`\n );\n\n // Prompt the user for the bundle ID.\n // Even if the project is using a dynamic config we can still\n // prompt a better error message, recommend a default value, and help the user\n // validate their custom bundle ID upfront.\n const { input } = await prompt(\n {\n type: 'text',\n name: 'input',\n // The Apple helps people know this isn't an EAS feature.\n message: `What would you like your iOS bundle identifier to be?`,\n validate: validateBundleId,\n },\n {\n nonInteractiveHelp: NO_BUNDLE_ID_MESSAGE,\n }\n );\n bundleIdentifier = input as string;\n }\n\n // Warn the user if the bundle ID is already in use.\n const warning = await getBundleIdWarningAsync(bundleIdentifier);\n\n if (warning && !(await warnAndConfirmAsync(warning))) {\n // Cycle the Bundle ID prompt to try again.\n return await promptForBundleIdWithInitialAsync(projectRoot, exp);\n }\n\n // Apply the changes to the config.\n if (\n await attemptModification(\n projectRoot,\n {\n ios: { ...(exp.ios || {}), bundleIdentifier },\n },\n { ios: { bundleIdentifier } }\n )\n ) {\n Log.log(chalk.gray`\\u203A Apple bundle identifier: ${bundleIdentifier}`);\n }\n\n return bundleIdentifier;\n}\n\nasync function warnAndConfirmAsync(warning: string): Promise<boolean> {\n Log.log();\n Log.warn(warning);\n Log.log();\n if (\n !(await confirmAsync({\n message: `Continue?`,\n initial: true,\n }))\n ) {\n return false;\n }\n return true;\n}\n\n// Recommend a bundle identifier based on the account name of the owner of the project and project slug.\nasync function getRecommendedBundleIdAsync(exp: ExpoConfig): Promise<string | undefined> {\n const possibleIdFromAndroid = exp.android?.package\n ? getSanitizedBundleIdentifier(exp.android.package)\n : undefined;\n // Attempt to use the android package name first since it's convenient to have them aligned.\n if (possibleIdFromAndroid && validateBundleId(possibleIdFromAndroid)) {\n return possibleIdFromAndroid;\n } else {\n const recommendedReverseDomainNameSecondPart =\n (await getRecommendedReverseDomainNameSecondPartAsync(exp)) ?? ANONYMOUS_USERNAME;\n const possibleId = getSanitizedBundleIdentifier(\n `com.${recommendedReverseDomainNameSecondPart}.${exp.slug}`\n );\n if (validateBundleId(possibleId)) {\n return possibleId;\n }\n }\n\n return undefined;\n}\n\n// Recommend a package name based on the account name of the owner of the project and project slug.\nasync function getRecommendedPackageNameAsync(exp: ExpoConfig): Promise<string | undefined> {\n const possibleIdFromApple = exp.ios?.bundleIdentifier\n ? getSanitizedPackage(exp.ios.bundleIdentifier)\n : undefined;\n\n // Attempt to use the ios bundle id first since it's convenient to have them aligned.\n if (possibleIdFromApple && validatePackage(possibleIdFromApple)) {\n return possibleIdFromApple;\n } else {\n const recommendedReverseDomainNameSecondPart =\n (await getRecommendedReverseDomainNameSecondPartAsync(exp)) ?? ANONYMOUS_USERNAME;\n\n const possibleId = getSanitizedPackage(\n `com.${recommendedReverseDomainNameSecondPart}.${exp.slug}`\n );\n if (validatePackage(possibleId)) {\n return possibleId;\n } else {\n debug(\n `Recommended package name is invalid: \"${possibleId}\" (owner: ${recommendedReverseDomainNameSecondPart}, slug: ${exp.slug})`\n );\n }\n }\n return undefined;\n}\n\n/**\n * Get the package name from the Expo config or prompt the user to choose a new package name.\n * Prompted value will be validated against the Play Store and a local regex.\n * If the project Expo config is a static JSON file, the package name will be updated in the config automatically.\n */\nexport async function getOrPromptForPackageAsync(\n projectRoot: string,\n exp: ExpoConfig = getConfig(projectRoot).exp\n): Promise<string> {\n const current = exp.android?.package;\n if (current) {\n assertValidPackage(current);\n return current;\n }\n\n return await promptForPackageAsync(projectRoot, exp);\n}\n\nasync function promptForPackageAsync(projectRoot: string, exp: ExpoConfig): Promise<string> {\n return promptForPackageWithInitialAsync(\n projectRoot,\n exp,\n await getRecommendedPackageNameAsync(exp)\n );\n}\n\nasync function promptForPackageWithInitialAsync(\n projectRoot: string,\n exp: ExpoConfig,\n packageName?: string\n): Promise<string> {\n if (!packageName) {\n memoLog(\n chalk`\\n{bold 📝 Android package} {dim ${learnMore('https://expo.fyi/android-package')}}\\n`\n );\n\n // Prompt the user for the android package.\n // Even if the project is using a dynamic config we can still\n // prompt a better error message, recommend a default value, and help the user\n // validate their custom android package upfront.\n const { input } = await prompt(\n {\n type: 'text',\n name: 'input',\n message: `What would you like your Android package name to be?`,\n validate: validatePackageWithWarning,\n },\n {\n nonInteractiveHelp: NO_PACKAGE_MESSAGE,\n }\n );\n packageName = input as string;\n }\n\n // Warn the user if the package name is already in use.\n const warning = await getPackageNameWarningAsync(packageName);\n if (warning && !(await warnAndConfirmAsync(warning))) {\n // Cycle the Package name prompt to try again.\n return promptForPackageWithInitialAsync(projectRoot, exp);\n }\n\n // Apply the changes to the config.\n if (\n await attemptModification(\n projectRoot,\n {\n android: { ...(exp.android || {}), package: packageName },\n },\n {\n android: { package: packageName },\n }\n )\n ) {\n Log.log(chalk.gray`\\u203A Android package name: ${packageName}`);\n }\n\n return packageName;\n}\n"],"names":["getOrPromptForBundleIdentifierAsync","getOrPromptForPackageAsync","debug","require","ANONYMOUS_USERNAME","getRecommendedReverseDomainNameSecondPartAsync","exp","getSettings","cachedUsername","read","auth","username","easProjectId","extra","eas","projectId","app","AppQuery","byIdAsync","ownerAccount","name","e","GraphQLError","CombinedError","NO_BUNDLE_ID_MESSAGE","NO_PACKAGE_MESSAGE","projectRoot","getConfig","current","ios","bundleIdentifier","assertValidBundleId","promptForBundleIdWithInitialAsync","getRecommendedBundleIdAsync","memoLog","memoize","Log","log","chalk","learnMore","input","prompt","type","message","validate","validateBundleId","nonInteractiveHelp","warning","getBundleIdWarningAsync","warnAndConfirmAsync","attemptModification","gray","warn","confirmAsync","initial","possibleIdFromAndroid","android","package","getSanitizedBundleIdentifier","undefined","recommendedReverseDomainNameSecondPart","possibleId","slug","getRecommendedPackageNameAsync","possibleIdFromApple","getSanitizedPackage","validatePackage","assertValidPackage","promptForPackageAsync","promptForPackageWithInitialAsync","packageName","validatePackageWithWarning","getPackageNameWarningAsync"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/getOrPromptApplicationId.ts"],"sourcesContent":["import { ExpoConfig, getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { memoize } from './fn';\nimport { learnMore } from './link';\nimport { attemptModification } from './modifyConfigAsync';\nimport prompt, { confirmAsync } from './prompts';\nimport {\n assertValidBundleId,\n assertValidPackage,\n getBundleIdWarningAsync,\n getPackageNameWarningAsync,\n getSanitizedBundleIdentifier,\n getSanitizedPackage,\n validateBundleId,\n validatePackage,\n validatePackageWithWarning,\n} from './validateApplicationId';\nimport { UnexpectedServerError, UnexpectedServerData } from '../api/graphql/client';\nimport { AppQuery } from '../api/graphql/queries/AppQuery';\nimport { getSettings } from '../api/user/UserSettings';\nimport * as Log from '../log';\n\nconst debug = require('debug')('expo:app-id') as typeof console.log;\n\nconst ANONYMOUS_USERNAME = 'anonymous';\n\nasync function getRecommendedReverseDomainNameSecondPartAsync(\n exp: ExpoConfig\n): Promise<string | null> {\n // Get the cached username.\n const cachedUsername = getSettings().read().auth?.username;\n if (cachedUsername) {\n return cachedUsername;\n }\n const easProjectId = exp.extra?.eas?.projectId;\n if (!easProjectId) {\n return null;\n }\n\n try {\n const app = await AppQuery.byIdAsync(easProjectId);\n return app.ownerAccount.name;\n } catch (e) {\n if (e instanceof UnexpectedServerData || e instanceof UnexpectedServerError) {\n return null;\n }\n throw e;\n }\n}\n\nconst NO_BUNDLE_ID_MESSAGE = `Project must have a \\`ios.bundleIdentifier\\` set in the Expo config (app.json or app.config.js).`;\n\nconst NO_PACKAGE_MESSAGE = `Project must have a \\`android.package\\` set in the Expo config (app.json or app.config.js).`;\n\n/**\n * Get the bundle identifier from the Expo config or prompt the user to choose a new bundle identifier.\n * Prompted value will be validated against the App Store and a local regex.\n * If the project Expo config is a static JSON file, the bundle identifier will be updated in the config automatically.\n */\nexport async function getOrPromptForBundleIdentifierAsync(\n projectRoot: string,\n exp: ExpoConfig = getConfig(projectRoot).exp\n): Promise<string> {\n const current = exp.ios?.bundleIdentifier;\n if (current) {\n assertValidBundleId(current);\n return current;\n }\n\n return promptForBundleIdWithInitialAsync(\n projectRoot,\n exp,\n await getRecommendedBundleIdAsync(exp)\n );\n}\n\nconst memoLog = memoize(Log.log);\n\nasync function promptForBundleIdWithInitialAsync(\n projectRoot: string,\n exp: ExpoConfig,\n bundleIdentifier?: string\n): Promise<string> {\n if (!bundleIdentifier) {\n memoLog(\n chalk`\\n{bold 📝 iOS Bundle Identifier} {dim ${learnMore(\n 'https://expo.fyi/bundle-identifier'\n )}}\\n`\n );\n\n // Prompt the user for the bundle ID.\n // Even if the project is using a dynamic config we can still\n // prompt a better error message, recommend a default value, and help the user\n // validate their custom bundle ID upfront.\n const { input } = await prompt(\n {\n type: 'text',\n name: 'input',\n // The Apple helps people know this isn't an EAS feature.\n message: `What would you like your iOS bundle identifier to be?`,\n validate: validateBundleId,\n },\n {\n nonInteractiveHelp: NO_BUNDLE_ID_MESSAGE,\n }\n );\n bundleIdentifier = input as string;\n }\n\n // Warn the user if the bundle ID is already in use.\n const warning = await getBundleIdWarningAsync(bundleIdentifier);\n\n if (warning && !(await warnAndConfirmAsync(warning))) {\n // Cycle the Bundle ID prompt to try again.\n return await promptForBundleIdWithInitialAsync(projectRoot, exp);\n }\n\n // Apply the changes to the config.\n if (\n await attemptModification(\n projectRoot,\n {\n ios: { ...(exp.ios || {}), bundleIdentifier },\n },\n { ios: { bundleIdentifier } }\n )\n ) {\n Log.log(chalk.gray`\\u203A Apple bundle identifier: ${bundleIdentifier}`);\n }\n\n return bundleIdentifier;\n}\n\nasync function warnAndConfirmAsync(warning: string): Promise<boolean> {\n Log.log();\n Log.warn(warning);\n Log.log();\n if (\n !(await confirmAsync({\n message: `Continue?`,\n initial: true,\n }))\n ) {\n return false;\n }\n return true;\n}\n\n// Recommend a bundle identifier based on the account name of the owner of the project and project slug.\nasync function getRecommendedBundleIdAsync(exp: ExpoConfig): Promise<string | undefined> {\n const possibleIdFromAndroid = exp.android?.package\n ? getSanitizedBundleIdentifier(exp.android.package)\n : undefined;\n // Attempt to use the android package name first since it's convenient to have them aligned.\n if (possibleIdFromAndroid && validateBundleId(possibleIdFromAndroid)) {\n return possibleIdFromAndroid;\n } else {\n const recommendedReverseDomainNameSecondPart =\n (await getRecommendedReverseDomainNameSecondPartAsync(exp)) ?? ANONYMOUS_USERNAME;\n const possibleId = getSanitizedBundleIdentifier(\n `com.${recommendedReverseDomainNameSecondPart}.${exp.slug}`\n );\n if (validateBundleId(possibleId)) {\n return possibleId;\n }\n }\n\n return undefined;\n}\n\n// Recommend a package name based on the account name of the owner of the project and project slug.\nasync function getRecommendedPackageNameAsync(exp: ExpoConfig): Promise<string | undefined> {\n const possibleIdFromApple = exp.ios?.bundleIdentifier\n ? getSanitizedPackage(exp.ios.bundleIdentifier)\n : undefined;\n\n // Attempt to use the ios bundle id first since it's convenient to have them aligned.\n if (possibleIdFromApple && validatePackage(possibleIdFromApple)) {\n return possibleIdFromApple;\n } else {\n const recommendedReverseDomainNameSecondPart =\n (await getRecommendedReverseDomainNameSecondPartAsync(exp)) ?? ANONYMOUS_USERNAME;\n\n const possibleId = getSanitizedPackage(\n `com.${recommendedReverseDomainNameSecondPart}.${exp.slug}`\n );\n if (validatePackage(possibleId)) {\n return possibleId;\n } else {\n debug(\n `Recommended package name is invalid: \"${possibleId}\" (owner: ${recommendedReverseDomainNameSecondPart}, slug: ${exp.slug})`\n );\n }\n }\n return undefined;\n}\n\n/**\n * Get the package name from the Expo config or prompt the user to choose a new package name.\n * Prompted value will be validated against the Play Store and a local regex.\n * If the project Expo config is a static JSON file, the package name will be updated in the config automatically.\n */\nexport async function getOrPromptForPackageAsync(\n projectRoot: string,\n exp: ExpoConfig = getConfig(projectRoot).exp\n): Promise<string> {\n const current = exp.android?.package;\n if (current) {\n assertValidPackage(current);\n return current;\n }\n\n return await promptForPackageAsync(projectRoot, exp);\n}\n\nasync function promptForPackageAsync(projectRoot: string, exp: ExpoConfig): Promise<string> {\n return promptForPackageWithInitialAsync(\n projectRoot,\n exp,\n await getRecommendedPackageNameAsync(exp)\n );\n}\n\nasync function promptForPackageWithInitialAsync(\n projectRoot: string,\n exp: ExpoConfig,\n packageName?: string\n): Promise<string> {\n if (!packageName) {\n memoLog(\n chalk`\\n{bold 📝 Android package} {dim ${learnMore('https://expo.fyi/android-package')}}\\n`\n );\n\n // Prompt the user for the android package.\n // Even if the project is using a dynamic config we can still\n // prompt a better error message, recommend a default value, and help the user\n // validate their custom android package upfront.\n const { input } = await prompt(\n {\n type: 'text',\n name: 'input',\n message: `What would you like your Android package name to be?`,\n validate: validatePackageWithWarning,\n },\n {\n nonInteractiveHelp: NO_PACKAGE_MESSAGE,\n }\n );\n packageName = input as string;\n }\n\n // Warn the user if the package name is already in use.\n const warning = await getPackageNameWarningAsync(packageName);\n if (warning && !(await warnAndConfirmAsync(warning))) {\n // Cycle the Package name prompt to try again.\n return promptForPackageWithInitialAsync(projectRoot, exp);\n }\n\n // Apply the changes to the config.\n if (\n await attemptModification(\n projectRoot,\n {\n android: { ...(exp.android || {}), package: packageName },\n },\n {\n android: { package: packageName },\n }\n )\n ) {\n Log.log(chalk.gray`\\u203A Android package name: ${packageName}`);\n }\n\n return packageName;\n}\n"],"names":["getOrPromptForBundleIdentifierAsync","getOrPromptForPackageAsync","debug","require","ANONYMOUS_USERNAME","getRecommendedReverseDomainNameSecondPartAsync","exp","getSettings","cachedUsername","read","auth","username","easProjectId","extra","eas","projectId","app","AppQuery","byIdAsync","ownerAccount","name","e","UnexpectedServerData","UnexpectedServerError","NO_BUNDLE_ID_MESSAGE","NO_PACKAGE_MESSAGE","projectRoot","getConfig","current","ios","bundleIdentifier","assertValidBundleId","promptForBundleIdWithInitialAsync","getRecommendedBundleIdAsync","memoLog","memoize","Log","log","chalk","learnMore","input","prompt","type","message","validate","validateBundleId","nonInteractiveHelp","warning","getBundleIdWarningAsync","warnAndConfirmAsync","attemptModification","gray","warn","confirmAsync","initial","possibleIdFromAndroid","android","package","getSanitizedBundleIdentifier","undefined","recommendedReverseDomainNameSecondPart","possibleId","slug","getRecommendedPackageNameAsync","possibleIdFromApple","getSanitizedPackage","validatePackage","assertValidPackage","promptForPackageAsync","promptForPackageWithInitialAsync","packageName","validatePackageWithWarning","getPackageNameWarningAsync"],"mappings":"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"}