@expo/cli 56.1.4 → 56.1.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 (74) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/api/user/actions.js +7 -0
  3. package/build/src/api/user/actions.js.map +1 -1
  4. package/build/src/api/user/expoSsoLauncher.js +2 -8
  5. package/build/src/api/user/expoSsoLauncher.js.map +1 -1
  6. package/build/src/api/user/user.js +12 -0
  7. package/build/src/api/user/user.js.map +1 -1
  8. package/build/src/events/index.js +1 -1
  9. package/build/src/export/embed/exportEmbedAsync.js +1 -1
  10. package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
  11. package/build/src/export/embed/exportServer.js +1 -1
  12. package/build/src/export/embed/exportServer.js.map +1 -1
  13. package/build/src/export/exportApp.js +1 -1
  14. package/build/src/export/exportApp.js.map +1 -1
  15. package/build/src/export/publicFolder.js +19 -1
  16. package/build/src/export/publicFolder.js.map +1 -1
  17. package/build/src/login/index.js +25 -5
  18. package/build/src/login/index.js.map +1 -1
  19. package/build/src/run/android/resolveLaunchProps.js +4 -1
  20. package/build/src/run/android/resolveLaunchProps.js.map +1 -1
  21. package/build/src/start/doctor/dependencies/reactNativeTv.js +149 -0
  22. package/build/src/start/doctor/dependencies/reactNativeTv.js.map +1 -0
  23. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js +28 -3
  24. package/build/src/start/doctor/dependencies/validateDependenciesVersions.js.map +1 -1
  25. package/build/src/start/platforms/ios/simctl.js +4 -0
  26. package/build/src/start/platforms/ios/simctl.js.map +1 -1
  27. package/build/src/start/server/DevToolsPlugin.js +26 -1
  28. package/build/src/start/server/DevToolsPlugin.js.map +1 -1
  29. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js +57 -22
  30. package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js.map +1 -1
  31. package/build/src/start/server/DevToolsPluginCliExtensionResults.js +29 -0
  32. package/build/src/start/server/DevToolsPluginCliExtensionResults.js.map +1 -1
  33. package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js +15 -5
  34. package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js.map +1 -1
  35. package/build/src/start/server/UrlCreator.js +4 -0
  36. package/build/src/start/server/UrlCreator.js.map +1 -1
  37. package/build/src/start/server/createMCPDevToolsExtensionSchema.js +13 -1
  38. package/build/src/start/server/createMCPDevToolsExtensionSchema.js.map +1 -1
  39. package/build/src/start/server/metro/MetroBundlerDevServer.js +95 -32
  40. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  41. package/build/src/start/server/metro/createServerComponentsMiddleware.js +13 -13
  42. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  43. package/build/src/start/server/metro/dev-server/createMessageSocket.js +13 -2
  44. package/build/src/start/server/metro/dev-server/createMessageSocket.js.map +1 -1
  45. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +2 -1
  46. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
  47. package/build/src/start/server/metro/instantiateMetro.js +5 -4
  48. package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
  49. package/build/src/start/server/metro/router.js +10 -1
  50. package/build/src/start/server/metro/router.js.map +1 -1
  51. package/build/src/start/server/metro/withMetroMultiPlatform.js +8 -4
  52. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  53. package/build/src/start/server/middleware/OpenMiddleware.js +150 -0
  54. package/build/src/start/server/middleware/OpenMiddleware.js.map +1 -0
  55. package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js +13 -4
  56. package/build/src/start/server/middleware/RuntimeRedirectMiddleware.js.map +1 -1
  57. package/build/src/start/server/middleware/ServeStaticMiddleware.js +2 -9
  58. package/build/src/start/server/middleware/ServeStaticMiddleware.js.map +1 -1
  59. package/build/src/start/server/middleware/openHandlers.js +157 -0
  60. package/build/src/start/server/middleware/openHandlers.js.map +1 -0
  61. package/build/src/start/server/type-generation/routes.js +1 -3
  62. package/build/src/start/server/type-generation/routes.js.map +1 -1
  63. package/build/src/start/server/webTemplate.js +3 -5
  64. package/build/src/start/server/webTemplate.js.map +1 -1
  65. package/build/src/utils/net.js +7 -1
  66. package/build/src/utils/net.js.map +1 -1
  67. package/build/src/utils/open.js +243 -11
  68. package/build/src/utils/open.js.map +1 -1
  69. package/build/src/utils/tar.js +2 -2
  70. package/build/src/utils/tar.js.map +1 -1
  71. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  72. package/build/src/utils/telemetry/utils/context.js +1 -1
  73. package/package.json +17 -18
  74. package/static/loading-page/index.html +35 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/export/exportApp.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport type { Platform } from '@expo/config';\nimport { resolveRelativeEntryPoint } from '@expo/config/paths';\nimport type { SerialAsset } from '@expo/metro-config/build/serializer/serializerAssets';\nimport assert from 'assert';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { type PlatformMetadata, createMetadataJson } from './createMetadataJson';\nimport { exportAssetsAsync } from './exportAssets';\nimport {\n addDomBundleToMetadataAsync,\n exportDomComponentAsync,\n transformNativeBundleForMd5Filename,\n transformDomEntryForMd5Filename,\n} from './exportDomComponents';\nimport { assertEngineMismatchAsync, isEnableHermesManaged } from './exportHermes';\nimport { exportApiRoutesStandaloneAsync, exportFromServerAsync } from './exportStaticAsync';\nimport { getVirtualFaviconAssetsAsync } from './favicon';\nimport { getPublicExpoManifestAsync } from './getPublicExpoManifest';\nimport { copyPublicFolderAsync } from './publicFolder';\nimport type { Options } from './resolveOptions';\nimport type { ExportAssetMap, BundleOutput, BundleAssetWithFileHashes } from './saveAssets';\nimport { getFilesFromSerialAssets, persistMetroFilesAsync } from './saveAssets';\nimport { createAssetMap } from './writeContents';\nimport * as Log from '../log';\nimport { WebSupportProjectPrerequisite } from '../start/doctor/web/WebSupportProjectPrerequisite';\nimport { DevServerManager } from '../start/server/DevServerManager';\nimport { MetroBundlerDevServer } from '../start/server/metro/MetroBundlerDevServer';\nimport { getRouterDirectoryModuleIdWithManifest } from '../start/server/metro/router';\nimport { serializeHtmlWithAssets } from '../start/server/metro/serializeHtml';\nimport { getBaseUrlFromExpoConfig } from '../start/server/middleware/metroOptions';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../start/server/webTemplate';\nimport { env } from '../utils/env';\nimport { CommandError } from '../utils/errors';\nimport { setNodeEnv, loadEnvFiles } from '../utils/nodeEnv';\n\nexport async function exportAppAsync(\n projectRoot: string,\n {\n platforms,\n outputDir,\n clear,\n dev,\n dumpAssetmap,\n sourceMaps,\n inlineSourceMaps,\n minify,\n bytecode,\n maxWorkers,\n skipSSG,\n hostedNative,\n }: Pick<\n Options,\n | 'dumpAssetmap'\n | 'sourceMaps'\n | 'inlineSourceMaps'\n | 'dev'\n | 'clear'\n | 'outputDir'\n | 'platforms'\n | 'minify'\n | 'bytecode'\n | 'maxWorkers'\n | 'skipSSG'\n | 'hostedNative'\n >\n): Promise<void> {\n // Force the environment during export and do not allow overriding it.\n const environment = dev ? 'development' : 'production';\n process.env.NODE_ENV = environment;\n setNodeEnv(environment);\n loadEnvFiles(projectRoot);\n\n const projectConfig = getConfig(projectRoot);\n const exp = await getPublicExpoManifestAsync(projectRoot, {\n // Web doesn't require validation.\n skipValidation: platforms.length === 1 && platforms[0] === 'web',\n });\n\n if (platforms.includes('web')) {\n await new WebSupportProjectPrerequisite(projectRoot).assertAsync();\n }\n\n const useServerRendering = ['static', 'server'].includes(exp.web?.output ?? '');\n\n if (skipSSG && exp.web?.output !== 'server') {\n throw new CommandError('--no-ssg can only be used with `web.output: server`');\n }\n\n const baseUrl = getBaseUrlFromExpoConfig(exp);\n\n if (!bytecode && (platforms.includes('ios') || platforms.includes('android'))) {\n Log.warn(\n `Bytecode makes the app startup faster, disabling bytecode is highly discouraged and should only be used for debugging purposes.`\n );\n }\n\n // Print out logs\n if (baseUrl) {\n Log.log();\n Log.log(chalk.gray`Using (experimental) base path: ${baseUrl}`);\n // Warn if not using an absolute path.\n if (!baseUrl.startsWith('/')) {\n Log.log(\n chalk.yellow` Base path does not start with a slash. Requests will not be absolute.`\n );\n }\n }\n\n const mode = dev ? 'development' : 'production';\n const publicPath = path.resolve(projectRoot, env.EXPO_PUBLIC_FOLDER);\n const outputPath = path.resolve(projectRoot, outputDir);\n\n // Write the JS bundles to disk, and get the bundle file names (this could change with async chunk loading support).\n\n const files: ExportAssetMap = new Map();\n\n const devServerManager = await DevServerManager.startMetroAsync(projectRoot, {\n minify,\n mode,\n port: 8081,\n isExporting: true,\n location: {},\n resetDevServer: clear,\n maxWorkers,\n });\n\n const devServer = devServerManager.getDefaultDevServer();\n assert(devServer instanceof MetroBundlerDevServer);\n\n const bundles: Partial<Record<Platform, BundleOutput>> = {};\n const domComponentAssetsMetadata: Partial<Record<Platform, PlatformMetadata['assets']>> = {};\n\n const spaPlatforms =\n // TODO: Support server and static rendering for server component exports.\n useServerRendering && !devServer.isReactServerComponentsEnabled\n ? platforms.filter((platform) => platform !== 'web')\n : platforms;\n\n try {\n if (devServer.isReactServerComponentsEnabled) {\n // In RSC mode, we only need these to be in the client dir.\n // TODO: Merge back with other copy after we add SSR.\n try {\n await copyPublicFolderAsync(publicPath, path.join(outputPath, 'client'));\n } catch (error) {\n Log.error('Failed to copy public directory to dist directory');\n throw error;\n }\n } else {\n // NOTE(kitten): The public folder is currently always copied, regardless of targetDomain\n // split. Hence, there's another separate `copyPublicFolderAsync` call below for `web`\n await copyPublicFolderAsync(publicPath, outputPath);\n }\n\n let templateHtml: string | undefined;\n // Can be empty during web-only SSG.\n if (spaPlatforms.length) {\n await Promise.all(\n spaPlatforms.map(async (platform) => {\n // Assert early so the user doesn't have to wait until bundling is complete to find out that\n // Hermes won't be available.\n const isHermes = isEnableHermesManaged(exp, platform);\n if (isHermes) {\n await assertEngineMismatchAsync(projectRoot, exp, platform);\n }\n\n let bundle: {\n artifacts: SerialAsset[];\n assets: readonly BundleAssetWithFileHashes[];\n files?: ExportAssetMap;\n };\n\n try {\n // Run metro bundler and create the JS bundles/source maps.\n bundle = await devServer.nativeExportBundleAsync(\n exp,\n {\n platform,\n splitChunks:\n !env.EXPO_NO_BUNDLE_SPLITTING &&\n ((devServer.isReactServerComponentsEnabled && !bytecode) || platform === 'web'),\n mainModuleName: resolveRelativeEntryPoint(projectRoot, {\n platform,\n pkg: projectConfig.pkg,\n }),\n mode: dev ? 'development' : 'production',\n engine: isHermes ? 'hermes' : undefined,\n serializerIncludeMaps: sourceMaps || inlineSourceMaps,\n inlineSourceMap: inlineSourceMaps,\n bytecode: bytecode && isHermes,\n reactCompiler: !!exp.experiments?.reactCompiler,\n hosted: hostedNative,\n },\n files\n );\n } catch (error) {\n Log.log('');\n if (error instanceof Error) {\n Log.exception(error);\n } else {\n Log.error('Failed to bundle the app');\n Log.log(error as any);\n }\n process.exit(1);\n }\n\n bundles[platform] = bundle;\n\n getFilesFromSerialAssets(bundle.artifacts, {\n includeSourceMaps: sourceMaps,\n files,\n isServerHosted: devServer.isReactServerComponentsEnabled || hostedNative,\n });\n\n const expoDomComponentReferences = [\n ...new Set(\n bundle.artifacts\n .map((artifact) =>\n Array.isArray(artifact.metadata.expoDomComponentReferences)\n ? artifact.metadata.expoDomComponentReferences\n : []\n )\n .flat()\n ),\n ];\n await Promise.all(\n // TODO: Make a version of this which uses `this.metro.getBundler().buildGraphForEntries([])` to bundle all the DOM components at once.\n expoDomComponentReferences.map(async (filePath) => {\n const { bundle: platformDomComponentsBundle, htmlOutputName } =\n await exportDomComponentAsync({\n filePath,\n projectRoot,\n dev,\n devServer,\n isHermes,\n includeSourceMaps: sourceMaps,\n exp,\n files,\n useMd5Filename: true,\n });\n\n // Merge the assets from the DOM component into the output assets, deduplicating by hash.\n const existingHashes = new Set(bundle.assets.map((a) => a.hash));\n (bundle.assets as (typeof bundle.assets)[0][]).push(\n ...platformDomComponentsBundle.assets.filter((a) => !existingHashes.has(a.hash))\n );\n\n transformNativeBundleForMd5Filename({\n domComponentReference: filePath,\n nativeBundle: bundle,\n files,\n htmlOutputName,\n });\n domComponentAssetsMetadata[platform] = [\n ...(domComponentAssetsMetadata[platform] || []),\n ...(await addDomBundleToMetadataAsync(platformDomComponentsBundle)),\n ...transformDomEntryForMd5Filename({\n files,\n htmlOutputName,\n }),\n ];\n })\n );\n\n if (platform === 'web') {\n // TODO: Unify with exportStaticAsync\n // TODO: Maybe move to the serializer.\n let html = await serializeHtmlWithAssets({\n isExporting: true,\n resources: bundle.artifacts,\n template: await createTemplateHtmlFromExpoConfigAsync(projectRoot, {\n scripts: [],\n cssLinks: [],\n exp: projectConfig.exp,\n }),\n baseUrl,\n });\n\n // Add the favicon assets to the HTML.\n const modifyHtml = await getVirtualFaviconAssetsAsync(projectRoot, {\n outputDir,\n baseUrl,\n files,\n exp: projectConfig.exp,\n });\n if (modifyHtml) {\n html = modifyHtml(html);\n }\n\n // HACK: This is used for adding SSR shims in React Server Components.\n templateHtml = html;\n\n // Generate SPA-styled HTML file.\n // If web exists, then write the template HTML file.\n files.set('index.html', {\n contents: html,\n targetDomain: devServer.isReactServerComponentsEnabled ? 'server' : 'client',\n });\n }\n })\n );\n\n if (devServer.isReactServerComponentsEnabled) {\n const isWeb = platforms.includes('web');\n\n await exportApiRoutesStandaloneAsync(devServer, {\n files,\n platform: 'web',\n apiRoutesOnly: !isWeb,\n templateHtml,\n });\n }\n\n // TODO: Use same asset system across platforms again.\n const { assets, embeddedHashSet } = await exportAssetsAsync(projectRoot, {\n files,\n exp,\n outputDir: outputPath,\n bundles,\n baseUrl,\n hostedNative,\n });\n\n if (dumpAssetmap) {\n Log.log('Creating asset map');\n files.set('assetmap.json', { contents: JSON.stringify(createAssetMap({ assets })) });\n }\n\n const targetDomain = devServer.isReactServerComponentsEnabled ? 'client/' : '';\n const fileNames = Object.fromEntries(\n Object.entries(bundles).map(([platform, bundle]) => [\n platform,\n bundle.artifacts\n .filter((asset) => asset.type === 'js')\n .map((asset) => targetDomain + asset.filename),\n ])\n );\n\n // Generate a `metadata.json` for EAS Update.\n const contents = createMetadataJson({\n bundles,\n fileNames,\n embeddedHashSet,\n domComponentAssetsMetadata,\n });\n files.set('metadata.json', { contents: JSON.stringify(contents) });\n }\n\n // Additional web-only steps...\n\n if (platforms.includes('web') && useServerRendering) {\n const exportServer = exp.web?.output === 'server';\n\n if (exportServer) {\n // TODO: Remove when this is abstracted into the files map\n await copyPublicFolderAsync(publicPath, path.resolve(outputPath, 'client'));\n }\n\n if (skipSSG) {\n Log.log('Skipping static site generation');\n await exportApiRoutesStandaloneAsync(devServer, {\n files,\n platform: 'web',\n apiRoutesOnly: true,\n });\n\n // Output a placeholder index.html if one doesn't exist in the public directory.\n // This ensures native + API routes have some content at the root URL.\n const placeholderIndex = path.resolve(outputPath, 'client/index.html');\n if (!fs.existsSync(placeholderIndex)) {\n files.set('index.html', {\n contents: `<html><body></body></html>`,\n targetDomain: 'client',\n });\n }\n } else if (\n // TODO: Support static export with RSC.\n !devServer.isReactServerComponentsEnabled\n ) {\n await exportFromServerAsync(projectRoot, devServer, {\n mode,\n files,\n clear: !!clear,\n outputDir: outputPath,\n minify,\n baseUrl,\n includeSourceMaps: sourceMaps,\n routerRoot: getRouterDirectoryModuleIdWithManifest(projectRoot, exp),\n reactCompiler: !!exp.experiments?.reactCompiler,\n exportServer,\n maxWorkers,\n isExporting: true,\n exp: projectConfig.exp,\n });\n }\n }\n } finally {\n await devServerManager.stopAsync();\n }\n\n // Write all files at the end for unified logging.\n await persistMetroFilesAsync(files, outputPath);\n}\n"],"names":["exportAppAsync","projectRoot","platforms","outputDir","clear","dev","dumpAssetmap","sourceMaps","inlineSourceMaps","minify","bytecode","maxWorkers","skipSSG","hostedNative","exp","environment","process","env","NODE_ENV","setNodeEnv","loadEnvFiles","projectConfig","getConfig","getPublicExpoManifestAsync","skipValidation","length","includes","WebSupportProjectPrerequisite","assertAsync","useServerRendering","web","output","CommandError","baseUrl","getBaseUrlFromExpoConfig","Log","warn","log","chalk","gray","startsWith","yellow","mode","publicPath","path","resolve","EXPO_PUBLIC_FOLDER","outputPath","files","Map","devServerManager","DevServerManager","startMetroAsync","port","isExporting","location","resetDevServer","devServer","getDefaultDevServer","assert","MetroBundlerDevServer","bundles","domComponentAssetsMetadata","spaPlatforms","isReactServerComponentsEnabled","filter","platform","copyPublicFolderAsync","join","error","templateHtml","Promise","all","map","isHermes","isEnableHermesManaged","assertEngineMismatchAsync","bundle","nativeExportBundleAsync","splitChunks","EXPO_NO_BUNDLE_SPLITTING","mainModuleName","resolveRelativeEntryPoint","pkg","engine","undefined","serializerIncludeMaps","inlineSourceMap","reactCompiler","experiments","hosted","Error","exception","exit","getFilesFromSerialAssets","artifacts","includeSourceMaps","isServerHosted","expoDomComponentReferences","Set","artifact","Array","isArray","metadata","flat","filePath","platformDomComponentsBundle","htmlOutputName","exportDomComponentAsync","useMd5Filename","existingHashes","assets","a","hash","push","has","transformNativeBundleForMd5Filename","domComponentReference","nativeBundle","addDomBundleToMetadataAsync","transformDomEntryForMd5Filename","html","serializeHtmlWithAssets","resources","template","createTemplateHtmlFromExpoConfigAsync","scripts","cssLinks","modifyHtml","getVirtualFaviconAssetsAsync","set","contents","targetDomain","isWeb","exportApiRoutesStandaloneAsync","apiRoutesOnly","embeddedHashSet","exportAssetsAsync","JSON","stringify","createAssetMap","fileNames","Object","fromEntries","entries","asset","type","filename","createMetadataJson","exportServer","placeholderIndex","fs","existsSync","exportFromServerAsync","routerRoot","getRouterDirectoryModuleIdWithManifest","stopAsync","persistMetroFilesAsync"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/export/exportApp.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport type { Platform } from '@expo/config';\nimport { resolveRelativeEntryPoint } from '@expo/config/paths';\nimport type { SerialAsset } from '@expo/metro-config/build/serializer/serializerAssets';\nimport assert from 'assert';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { type PlatformMetadata, createMetadataJson } from './createMetadataJson';\nimport { exportAssetsAsync } from './exportAssets';\nimport {\n addDomBundleToMetadataAsync,\n exportDomComponentAsync,\n transformNativeBundleForMd5Filename,\n transformDomEntryForMd5Filename,\n} from './exportDomComponents';\nimport { assertEngineMismatchAsync, isEnableHermesManaged } from './exportHermes';\nimport { exportApiRoutesStandaloneAsync, exportFromServerAsync } from './exportStaticAsync';\nimport { getVirtualFaviconAssetsAsync } from './favicon';\nimport { getPublicExpoManifestAsync } from './getPublicExpoManifest';\nimport { copyPublicFolderAsync, getPublicFolderPath } from './publicFolder';\nimport type { Options } from './resolveOptions';\nimport type { ExportAssetMap, BundleOutput, BundleAssetWithFileHashes } from './saveAssets';\nimport { getFilesFromSerialAssets, persistMetroFilesAsync } from './saveAssets';\nimport { createAssetMap } from './writeContents';\nimport * as Log from '../log';\nimport { WebSupportProjectPrerequisite } from '../start/doctor/web/WebSupportProjectPrerequisite';\nimport { DevServerManager } from '../start/server/DevServerManager';\nimport { MetroBundlerDevServer } from '../start/server/metro/MetroBundlerDevServer';\nimport { getRouterDirectoryModuleIdWithManifest } from '../start/server/metro/router';\nimport { serializeHtmlWithAssets } from '../start/server/metro/serializeHtml';\nimport { getBaseUrlFromExpoConfig } from '../start/server/middleware/metroOptions';\nimport { createTemplateHtmlFromExpoConfigAsync } from '../start/server/webTemplate';\nimport { env } from '../utils/env';\nimport { CommandError } from '../utils/errors';\nimport { setNodeEnv, loadEnvFiles } from '../utils/nodeEnv';\n\nexport async function exportAppAsync(\n projectRoot: string,\n {\n platforms,\n outputDir,\n clear,\n dev,\n dumpAssetmap,\n sourceMaps,\n inlineSourceMaps,\n minify,\n bytecode,\n maxWorkers,\n skipSSG,\n hostedNative,\n }: Pick<\n Options,\n | 'dumpAssetmap'\n | 'sourceMaps'\n | 'inlineSourceMaps'\n | 'dev'\n | 'clear'\n | 'outputDir'\n | 'platforms'\n | 'minify'\n | 'bytecode'\n | 'maxWorkers'\n | 'skipSSG'\n | 'hostedNative'\n >\n): Promise<void> {\n // Force the environment during export and do not allow overriding it.\n const environment = dev ? 'development' : 'production';\n process.env.NODE_ENV = environment;\n setNodeEnv(environment);\n loadEnvFiles(projectRoot);\n\n const projectConfig = getConfig(projectRoot);\n const exp = await getPublicExpoManifestAsync(projectRoot, {\n // Web doesn't require validation.\n skipValidation: platforms.length === 1 && platforms[0] === 'web',\n });\n\n if (platforms.includes('web')) {\n await new WebSupportProjectPrerequisite(projectRoot).assertAsync();\n }\n\n const useServerRendering = ['static', 'server'].includes(exp.web?.output ?? '');\n\n if (skipSSG && exp.web?.output !== 'server') {\n throw new CommandError('--no-ssg can only be used with `web.output: server`');\n }\n\n const baseUrl = getBaseUrlFromExpoConfig(exp);\n\n if (!bytecode && (platforms.includes('ios') || platforms.includes('android'))) {\n Log.warn(\n `Bytecode makes the app startup faster, disabling bytecode is highly discouraged and should only be used for debugging purposes.`\n );\n }\n\n // Print out logs\n if (baseUrl) {\n Log.log();\n Log.log(chalk.gray`Using (experimental) base path: ${baseUrl}`);\n // Warn if not using an absolute path.\n if (!baseUrl.startsWith('/')) {\n Log.log(\n chalk.yellow` Base path does not start with a slash. Requests will not be absolute.`\n );\n }\n }\n\n const mode = dev ? 'development' : 'production';\n const publicPath = getPublicFolderPath(projectRoot);\n const outputPath = path.resolve(projectRoot, outputDir);\n\n // Write the JS bundles to disk, and get the bundle file names (this could change with async chunk loading support).\n\n const files: ExportAssetMap = new Map();\n\n const devServerManager = await DevServerManager.startMetroAsync(projectRoot, {\n minify,\n mode,\n port: 8081,\n isExporting: true,\n location: {},\n resetDevServer: clear,\n maxWorkers,\n });\n\n const devServer = devServerManager.getDefaultDevServer();\n assert(devServer instanceof MetroBundlerDevServer);\n\n const bundles: Partial<Record<Platform, BundleOutput>> = {};\n const domComponentAssetsMetadata: Partial<Record<Platform, PlatformMetadata['assets']>> = {};\n\n const spaPlatforms =\n // TODO: Support server and static rendering for server component exports.\n useServerRendering && !devServer.isReactServerComponentsEnabled\n ? platforms.filter((platform) => platform !== 'web')\n : platforms;\n\n try {\n if (devServer.isReactServerComponentsEnabled) {\n // In RSC mode, we only need these to be in the client dir.\n // TODO: Merge back with other copy after we add SSR.\n try {\n await copyPublicFolderAsync(publicPath, path.join(outputPath, 'client'));\n } catch (error) {\n Log.error('Failed to copy public directory to dist directory');\n throw error;\n }\n } else {\n // NOTE(kitten): The public folder is currently always copied, regardless of targetDomain\n // split. Hence, there's another separate `copyPublicFolderAsync` call below for `web`\n await copyPublicFolderAsync(publicPath, outputPath);\n }\n\n let templateHtml: string | undefined;\n // Can be empty during web-only SSG.\n if (spaPlatforms.length) {\n await Promise.all(\n spaPlatforms.map(async (platform) => {\n // Assert early so the user doesn't have to wait until bundling is complete to find out that\n // Hermes won't be available.\n const isHermes = isEnableHermesManaged(exp, platform);\n if (isHermes) {\n await assertEngineMismatchAsync(projectRoot, exp, platform);\n }\n\n let bundle: {\n artifacts: SerialAsset[];\n assets: readonly BundleAssetWithFileHashes[];\n files?: ExportAssetMap;\n };\n\n try {\n // Run metro bundler and create the JS bundles/source maps.\n bundle = await devServer.nativeExportBundleAsync(\n exp,\n {\n platform,\n splitChunks:\n !env.EXPO_NO_BUNDLE_SPLITTING &&\n ((devServer.isReactServerComponentsEnabled && !bytecode) || platform === 'web'),\n mainModuleName: resolveRelativeEntryPoint(projectRoot, {\n platform,\n pkg: projectConfig.pkg,\n }),\n mode: dev ? 'development' : 'production',\n engine: isHermes ? 'hermes' : undefined,\n serializerIncludeMaps: sourceMaps || inlineSourceMaps,\n inlineSourceMap: inlineSourceMaps,\n bytecode: bytecode && isHermes,\n reactCompiler: !!exp.experiments?.reactCompiler,\n hosted: hostedNative,\n },\n files\n );\n } catch (error) {\n Log.log('');\n if (error instanceof Error) {\n Log.exception(error);\n } else {\n Log.error('Failed to bundle the app');\n Log.log(error as any);\n }\n process.exit(1);\n }\n\n bundles[platform] = bundle;\n\n getFilesFromSerialAssets(bundle.artifacts, {\n includeSourceMaps: sourceMaps,\n files,\n isServerHosted: devServer.isReactServerComponentsEnabled || hostedNative,\n });\n\n const expoDomComponentReferences = [\n ...new Set(\n bundle.artifacts\n .map((artifact) =>\n Array.isArray(artifact.metadata.expoDomComponentReferences)\n ? artifact.metadata.expoDomComponentReferences\n : []\n )\n .flat()\n ),\n ];\n await Promise.all(\n // TODO: Make a version of this which uses `this.metro.getBundler().buildGraphForEntries([])` to bundle all the DOM components at once.\n expoDomComponentReferences.map(async (filePath) => {\n const { bundle: platformDomComponentsBundle, htmlOutputName } =\n await exportDomComponentAsync({\n filePath,\n projectRoot,\n dev,\n devServer,\n isHermes,\n includeSourceMaps: sourceMaps,\n exp,\n files,\n useMd5Filename: true,\n });\n\n // Merge the assets from the DOM component into the output assets, deduplicating by hash.\n const existingHashes = new Set(bundle.assets.map((a) => a.hash));\n (bundle.assets as (typeof bundle.assets)[0][]).push(\n ...platformDomComponentsBundle.assets.filter((a) => !existingHashes.has(a.hash))\n );\n\n transformNativeBundleForMd5Filename({\n domComponentReference: filePath,\n nativeBundle: bundle,\n files,\n htmlOutputName,\n });\n domComponentAssetsMetadata[platform] = [\n ...(domComponentAssetsMetadata[platform] || []),\n ...(await addDomBundleToMetadataAsync(platformDomComponentsBundle)),\n ...transformDomEntryForMd5Filename({\n files,\n htmlOutputName,\n }),\n ];\n })\n );\n\n if (platform === 'web') {\n // TODO: Unify with exportStaticAsync\n // TODO: Maybe move to the serializer.\n let html = await serializeHtmlWithAssets({\n isExporting: true,\n resources: bundle.artifacts,\n template: await createTemplateHtmlFromExpoConfigAsync(projectRoot, {\n scripts: [],\n cssLinks: [],\n exp: projectConfig.exp,\n }),\n baseUrl,\n });\n\n // Add the favicon assets to the HTML.\n const modifyHtml = await getVirtualFaviconAssetsAsync(projectRoot, {\n outputDir,\n baseUrl,\n files,\n exp: projectConfig.exp,\n });\n if (modifyHtml) {\n html = modifyHtml(html);\n }\n\n // HACK: This is used for adding SSR shims in React Server Components.\n templateHtml = html;\n\n // Generate SPA-styled HTML file.\n // If web exists, then write the template HTML file.\n files.set('index.html', {\n contents: html,\n targetDomain: devServer.isReactServerComponentsEnabled ? 'server' : 'client',\n });\n }\n })\n );\n\n if (devServer.isReactServerComponentsEnabled) {\n const isWeb = platforms.includes('web');\n\n await exportApiRoutesStandaloneAsync(devServer, {\n files,\n platform: 'web',\n apiRoutesOnly: !isWeb,\n templateHtml,\n });\n }\n\n // TODO: Use same asset system across platforms again.\n const { assets, embeddedHashSet } = await exportAssetsAsync(projectRoot, {\n files,\n exp,\n outputDir: outputPath,\n bundles,\n baseUrl,\n hostedNative,\n });\n\n if (dumpAssetmap) {\n Log.log('Creating asset map');\n files.set('assetmap.json', { contents: JSON.stringify(createAssetMap({ assets })) });\n }\n\n const targetDomain = devServer.isReactServerComponentsEnabled ? 'client/' : '';\n const fileNames = Object.fromEntries(\n Object.entries(bundles).map(([platform, bundle]) => [\n platform,\n bundle.artifacts\n .filter((asset) => asset.type === 'js')\n .map((asset) => targetDomain + asset.filename),\n ])\n );\n\n // Generate a `metadata.json` for EAS Update.\n const contents = createMetadataJson({\n bundles,\n fileNames,\n embeddedHashSet,\n domComponentAssetsMetadata,\n });\n files.set('metadata.json', { contents: JSON.stringify(contents) });\n }\n\n // Additional web-only steps...\n\n if (platforms.includes('web') && useServerRendering) {\n const exportServer = exp.web?.output === 'server';\n\n if (exportServer) {\n // TODO: Remove when this is abstracted into the files map\n await copyPublicFolderAsync(publicPath, path.resolve(outputPath, 'client'));\n }\n\n if (skipSSG) {\n Log.log('Skipping static site generation');\n await exportApiRoutesStandaloneAsync(devServer, {\n files,\n platform: 'web',\n apiRoutesOnly: true,\n });\n\n // Output a placeholder index.html if one doesn't exist in the public directory.\n // This ensures native + API routes have some content at the root URL.\n const placeholderIndex = path.resolve(outputPath, 'client/index.html');\n if (!fs.existsSync(placeholderIndex)) {\n files.set('index.html', {\n contents: `<html><body></body></html>`,\n targetDomain: 'client',\n });\n }\n } else if (\n // TODO: Support static export with RSC.\n !devServer.isReactServerComponentsEnabled\n ) {\n await exportFromServerAsync(projectRoot, devServer, {\n mode,\n files,\n clear: !!clear,\n outputDir: outputPath,\n minify,\n baseUrl,\n includeSourceMaps: sourceMaps,\n routerRoot: getRouterDirectoryModuleIdWithManifest(projectRoot, exp),\n reactCompiler: !!exp.experiments?.reactCompiler,\n exportServer,\n maxWorkers,\n isExporting: true,\n exp: projectConfig.exp,\n });\n }\n }\n } finally {\n await devServerManager.stopAsync();\n }\n\n // Write all files at the end for unified logging.\n await persistMetroFilesAsync(files, outputPath);\n}\n"],"names":["exportAppAsync","projectRoot","platforms","outputDir","clear","dev","dumpAssetmap","sourceMaps","inlineSourceMaps","minify","bytecode","maxWorkers","skipSSG","hostedNative","exp","environment","process","env","NODE_ENV","setNodeEnv","loadEnvFiles","projectConfig","getConfig","getPublicExpoManifestAsync","skipValidation","length","includes","WebSupportProjectPrerequisite","assertAsync","useServerRendering","web","output","CommandError","baseUrl","getBaseUrlFromExpoConfig","Log","warn","log","chalk","gray","startsWith","yellow","mode","publicPath","getPublicFolderPath","outputPath","path","resolve","files","Map","devServerManager","DevServerManager","startMetroAsync","port","isExporting","location","resetDevServer","devServer","getDefaultDevServer","assert","MetroBundlerDevServer","bundles","domComponentAssetsMetadata","spaPlatforms","isReactServerComponentsEnabled","filter","platform","copyPublicFolderAsync","join","error","templateHtml","Promise","all","map","isHermes","isEnableHermesManaged","assertEngineMismatchAsync","bundle","nativeExportBundleAsync","splitChunks","EXPO_NO_BUNDLE_SPLITTING","mainModuleName","resolveRelativeEntryPoint","pkg","engine","undefined","serializerIncludeMaps","inlineSourceMap","reactCompiler","experiments","hosted","Error","exception","exit","getFilesFromSerialAssets","artifacts","includeSourceMaps","isServerHosted","expoDomComponentReferences","Set","artifact","Array","isArray","metadata","flat","filePath","platformDomComponentsBundle","htmlOutputName","exportDomComponentAsync","useMd5Filename","existingHashes","assets","a","hash","push","has","transformNativeBundleForMd5Filename","domComponentReference","nativeBundle","addDomBundleToMetadataAsync","transformDomEntryForMd5Filename","html","serializeHtmlWithAssets","resources","template","createTemplateHtmlFromExpoConfigAsync","scripts","cssLinks","modifyHtml","getVirtualFaviconAssetsAsync","set","contents","targetDomain","isWeb","exportApiRoutesStandaloneAsync","apiRoutesOnly","embeddedHashSet","exportAssetsAsync","JSON","stringify","createAssetMap","fileNames","Object","fromEntries","entries","asset","type","filename","createMetadataJson","exportServer","placeholderIndex","fs","existsSync","exportFromServerAsync","routerRoot","getRouterDirectoryModuleIdWithManifest","stopAsync","persistMetroFilesAsync"],"mappings":"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"}
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  get copyPublicFolderAsync () {
13
13
  return copyPublicFolderAsync;
14
14
  },
15
+ get getPublicFolderPath () {
16
+ return getPublicFolderPath;
17
+ },
15
18
  get getUserDefinedFile () {
16
19
  return getUserDefinedFile;
17
20
  }
@@ -32,14 +35,29 @@ function _path() {
32
35
  }
33
36
  const _dir = require("../utils/dir");
34
37
  const _env = require("../utils/env");
38
+ const _errors = require("../utils/errors");
35
39
  function _interop_require_default(obj) {
36
40
  return obj && obj.__esModule ? obj : {
37
41
  default: obj
38
42
  };
39
43
  }
40
44
  const debug = require('debug')('expo:public-folder');
45
+ const maybeRealpath = (target)=>{
46
+ try {
47
+ return _fs().default.realpathSync(target);
48
+ } catch {
49
+ return target;
50
+ }
51
+ };
52
+ function getPublicFolderPath(projectRoot) {
53
+ const publicPath = maybeRealpath(_path().default.resolve(projectRoot, _env.env.EXPO_PUBLIC_FOLDER));
54
+ if (!(0, _dir.isPathInside)(publicPath, projectRoot)) {
55
+ throw new _errors.CommandError('EXPO_PUBLIC_FOLDER', `EXPO_PUBLIC_FOLDER ("${_env.env.EXPO_PUBLIC_FOLDER}") resolves to "${publicPath}", which is outside the project root "${projectRoot}". Set EXPO_PUBLIC_FOLDER to a path inside your project (e.g. "public").`);
56
+ }
57
+ return publicPath;
58
+ }
41
59
  function getUserDefinedFile(projectRoot, possiblePaths) {
42
- const publicPath = _path().default.join(projectRoot, _env.env.EXPO_PUBLIC_FOLDER);
60
+ const publicPath = getPublicFolderPath(projectRoot);
43
61
  for (const possiblePath of possiblePaths){
44
62
  const fullPath = _path().default.join(publicPath, possiblePath);
45
63
  if (_fs().default.existsSync(fullPath)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/export/publicFolder.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { copyAsync } from '../utils/dir';\nimport { env } from '../utils/env';\n\nconst debug = require('debug')('expo:public-folder') as typeof console.log;\n\n/** @returns the file system path for a user-defined file in the public folder. */\nexport function getUserDefinedFile(projectRoot: string, possiblePaths: string[]): string | null {\n const publicPath = path.join(projectRoot, env.EXPO_PUBLIC_FOLDER);\n\n for (const possiblePath of possiblePaths) {\n const fullPath = path.join(publicPath, possiblePath);\n if (fs.existsSync(fullPath)) {\n debug(`Found user-defined public file: ` + possiblePath);\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Copy the contents of the public folder into the output folder.\n * This enables users to add static files like `favicon.ico`.\n *\n * The contents of this folder are completely universal since they refer to\n * static network requests which fall outside the scope of React Native's magic\n * platform resolution patterns.\n */\nexport async function copyPublicFolderAsync(publicFolder: string, outputFolder: string) {\n if (fs.existsSync(publicFolder)) {\n await fs.promises.mkdir(outputFolder, { recursive: true });\n await copyAsync(publicFolder, outputFolder);\n }\n}\n"],"names":["copyPublicFolderAsync","getUserDefinedFile","debug","require","projectRoot","possiblePaths","publicPath","path","join","env","EXPO_PUBLIC_FOLDER","possiblePath","fullPath","fs","existsSync","publicFolder","outputFolder","promises","mkdir","recursive","copyAsync"],"mappings":";;;;;;;;;;;QA+BsBA;eAAAA;;QAtBNC;eAAAA;;;;gEATD;;;;;;;gEACE;;;;;;qBAES;qBACN;;;;;;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAGxB,SAASF,mBAAmBG,WAAmB,EAAEC,aAAuB;IAC7E,MAAMC,aAAaC,eAAI,CAACC,IAAI,CAACJ,aAAaK,QAAG,CAACC,kBAAkB;IAEhE,KAAK,MAAMC,gBAAgBN,cAAe;QACxC,MAAMO,WAAWL,eAAI,CAACC,IAAI,CAACF,YAAYK;QACvC,IAAIE,aAAE,CAACC,UAAU,CAACF,WAAW;YAC3BV,MAAM,CAAC,gCAAgC,CAAC,GAAGS;YAC3C,OAAOC;QACT;IACF;IAEA,OAAO;AACT;AAUO,eAAeZ,sBAAsBe,YAAoB,EAAEC,YAAoB;IACpF,IAAIH,aAAE,CAACC,UAAU,CAACC,eAAe;QAC/B,MAAMF,aAAE,CAACI,QAAQ,CAACC,KAAK,CAACF,cAAc;YAAEG,WAAW;QAAK;QACxD,MAAMC,IAAAA,cAAS,EAACL,cAAcC;IAChC;AACF"}
1
+ {"version":3,"sources":["../../../src/export/publicFolder.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { copyAsync, isPathInside } from '../utils/dir';\nimport { env } from '../utils/env';\nimport { CommandError } from '../utils/errors';\n\nconst debug = require('debug')('expo:public-folder') as typeof console.log;\n\nconst maybeRealpath = (target: string) => {\n try {\n return fs.realpathSync(target);\n } catch {\n return target;\n }\n};\n\n/**\n * Resolve `EXPO_PUBLIC_FOLDER` against the project root and ensure the result\n * stays inside the project. An `EXPO_PUBLIC_FOLDER` value that escapes\n * (e.g. `../etc`, `/absolute/path`) almost always indicates a misconfigured\n * environment, and if honored would expose unrelated files via every consumer\n * that serves or copies the public folder.\n */\nexport function getPublicFolderPath(projectRoot: string): string {\n const publicPath = maybeRealpath(path.resolve(projectRoot, env.EXPO_PUBLIC_FOLDER));\n if (!isPathInside(publicPath, projectRoot)) {\n throw new CommandError(\n 'EXPO_PUBLIC_FOLDER',\n `EXPO_PUBLIC_FOLDER (\"${env.EXPO_PUBLIC_FOLDER}\") resolves to \"${publicPath}\", which is outside the project root \"${projectRoot}\". Set EXPO_PUBLIC_FOLDER to a path inside your project (e.g. \"public\").`\n );\n }\n return publicPath;\n}\n\n/** @returns the file system path for a user-defined file in the public folder. */\nexport function getUserDefinedFile(projectRoot: string, possiblePaths: string[]): string | null {\n const publicPath = getPublicFolderPath(projectRoot);\n\n for (const possiblePath of possiblePaths) {\n const fullPath = path.join(publicPath, possiblePath);\n if (fs.existsSync(fullPath)) {\n debug(`Found user-defined public file: ` + possiblePath);\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Copy the contents of the public folder into the output folder.\n * This enables users to add static files like `favicon.ico`.\n *\n * The contents of this folder are completely universal since they refer to\n * static network requests which fall outside the scope of React Native's magic\n * platform resolution patterns.\n */\nexport async function copyPublicFolderAsync(publicFolder: string, outputFolder: string) {\n if (fs.existsSync(publicFolder)) {\n await fs.promises.mkdir(outputFolder, { recursive: true });\n await copyAsync(publicFolder, outputFolder);\n }\n}\n"],"names":["copyPublicFolderAsync","getPublicFolderPath","getUserDefinedFile","debug","require","maybeRealpath","target","fs","realpathSync","projectRoot","publicPath","path","resolve","env","EXPO_PUBLIC_FOLDER","isPathInside","CommandError","possiblePaths","possiblePath","fullPath","join","existsSync","publicFolder","outputFolder","promises","mkdir","recursive","copyAsync"],"mappings":";;;;;;;;;;;QA0DsBA;eAAAA;;QAlCNC;eAAAA;;QAYAC;eAAAA;;;;gEApCD;;;;;;;gEACE;;;;;;qBAEuB;qBACpB;wBACS;;;;;;AAE7B,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,MAAMC,gBAAgB,CAACC;IACrB,IAAI;QACF,OAAOC,aAAE,CAACC,YAAY,CAACF;IACzB,EAAE,OAAM;QACN,OAAOA;IACT;AACF;AASO,SAASL,oBAAoBQ,WAAmB;IACrD,MAAMC,aAAaL,cAAcM,eAAI,CAACC,OAAO,CAACH,aAAaI,QAAG,CAACC,kBAAkB;IACjF,IAAI,CAACC,IAAAA,iBAAY,EAACL,YAAYD,cAAc;QAC1C,MAAM,IAAIO,oBAAY,CACpB,sBACA,CAAC,qBAAqB,EAAEH,QAAG,CAACC,kBAAkB,CAAC,gBAAgB,EAAEJ,WAAW,sCAAsC,EAAED,YAAY,wEAAwE,CAAC;IAE7M;IACA,OAAOC;AACT;AAGO,SAASR,mBAAmBO,WAAmB,EAAEQ,aAAuB;IAC7E,MAAMP,aAAaT,oBAAoBQ;IAEvC,KAAK,MAAMS,gBAAgBD,cAAe;QACxC,MAAME,WAAWR,eAAI,CAACS,IAAI,CAACV,YAAYQ;QACvC,IAAIX,aAAE,CAACc,UAAU,CAACF,WAAW;YAC3BhB,MAAM,CAAC,gCAAgC,CAAC,GAAGe;YAC3C,OAAOC;QACT;IACF;IAEA,OAAO;AACT;AAUO,eAAenB,sBAAsBsB,YAAoB,EAAEC,YAAoB;IACpF,IAAIhB,aAAE,CAACc,UAAU,CAACC,eAAe;QAC/B,MAAMf,aAAE,CAACiB,QAAQ,CAACC,KAAK,CAACF,cAAc;YAAEG,WAAW;QAAK;QACxD,MAAMC,IAAAA,cAAS,EAACL,cAAcC;IAChC;AACF"}
@@ -3,10 +3,18 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "expoLogin", {
7
- enumerable: true,
8
- get: function() {
6
+ function _export(target, all) {
7
+ for(var name in all)Object.defineProperty(target, name, {
8
+ enumerable: true,
9
+ get: Object.getOwnPropertyDescriptor(all, name).get
10
+ });
11
+ }
12
+ _export(exports, {
13
+ get expoLogin () {
9
14
  return expoLogin;
15
+ },
16
+ get readWordFromStdin () {
17
+ return readWordFromStdin;
10
18
  }
11
19
  });
12
20
  const _args = require("../utils/args");
@@ -71,22 +79,34 @@ const expoLogin = async (argv)=>{
71
79
  if (args['--help']) {
72
80
  (0, _args.printHelp)(`Log in to an Expo account`, `npx expo login`, [
73
81
  `-u, --username <string> Username`,
74
- `-p, --password <string> Password`,
82
+ `-p, --password <string> Password ("-" for stdin)`,
75
83
  `--otp <string> One-time password from your 2FA device`,
76
84
  `-s, --sso Log in with SSO`,
77
85
  `-b, --browser Log in with a browser`,
78
86
  `-h, --help Usage info`
79
87
  ].join('\n'));
80
88
  }
89
+ const password = args['--password'] === '-' ? await readWordFromStdin() : args['--password'];
81
90
  const { showLoginPromptAsync } = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../api/user/actions.js")));
82
91
  return showLoginPromptAsync({
83
92
  // Parsed options
84
93
  username: args['--username'],
85
- password: args['--password'],
94
+ password,
86
95
  otp: args['--otp'],
87
96
  sso: !!args['--sso'],
88
97
  browser: !!args['--browser']
89
98
  }).catch(_errors.logCmdError);
90
99
  };
100
+ async function readWordFromStdin() {
101
+ let buffer = '';
102
+ for await (const chunk of process.stdin){
103
+ buffer += chunk;
104
+ const newlineIndex = buffer.indexOf('\n');
105
+ if (newlineIndex !== -1) {
106
+ return buffer.slice(0, newlineIndex).replace(/\r$/, '');
107
+ }
108
+ }
109
+ return buffer;
110
+ }
91
111
 
92
112
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/login/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport type { Command } from '../../bin/cli';\nimport { assertArgs, printHelp } from '../utils/args';\nimport { logCmdError } from '../utils/errors';\n\nexport const expoLogin: Command = async (argv) => {\n const args = assertArgs(\n {\n // Types\n '--help': Boolean,\n '--username': String,\n '--password': String,\n '--otp': String,\n '--sso': Boolean,\n '--browser': Boolean,\n // Aliases\n '-h': '--help',\n '-u': '--username',\n '-p': '--password',\n '-s': '--sso',\n '-b': '--browser',\n },\n argv\n );\n\n if (args['--help']) {\n printHelp(\n `Log in to an Expo account`,\n `npx expo login`,\n [\n `-u, --username <string> Username`,\n `-p, --password <string> Password`,\n `--otp <string> One-time password from your 2FA device`,\n `-s, --sso Log in with SSO`,\n `-b, --browser Log in with a browser`,\n `-h, --help Usage info`,\n ].join('\\n')\n );\n }\n\n const { showLoginPromptAsync } = await import('../api/user/actions.js');\n return showLoginPromptAsync({\n // Parsed options\n username: args['--username'],\n password: args['--password'],\n otp: args['--otp'],\n sso: !!args['--sso'],\n browser: !!args['--browser'],\n }).catch(logCmdError);\n};\n"],"names":["expoLogin","argv","args","assertArgs","Boolean","String","printHelp","join","showLoginPromptAsync","username","password","otp","sso","browser","catch","logCmdError"],"mappings":";;;;;+BAKaA;;;eAAAA;;;sBAHyB;wBACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMA,YAAqB,OAAOC;IACvC,MAAMC,OAAOC,IAAAA,gBAAU,EACrB;QACE,QAAQ;QACR,UAAUC;QACV,cAAcC;QACd,cAAcA;QACd,SAASA;QACT,SAASD;QACT,aAAaA;QACb,UAAU;QACV,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;IACR,GACAH;IAGF,IAAIC,IAAI,CAAC,SAAS,EAAE;QAClBI,IAAAA,eAAS,EACP,CAAC,yBAAyB,CAAC,EAC3B,CAAC,cAAc,CAAC,EAChB;YACE,CAAC,iCAAiC,CAAC;YACnC,CAAC,iCAAiC,CAAC;YACnC,CAAC,+DAA+D,CAAC;YACjE,CAAC,wCAAwC,CAAC;YAC1C,CAAC,8CAA8C,CAAC;YAChD,CAAC,mCAAmC,CAAC;SACtC,CAACC,IAAI,CAAC;IAEX;IAEA,MAAM,EAAEC,oBAAoB,EAAE,GAAG,MAAM,mEAAA,QAAO;IAC9C,OAAOA,qBAAqB;QAC1B,iBAAiB;QACjBC,UAAUP,IAAI,CAAC,aAAa;QAC5BQ,UAAUR,IAAI,CAAC,aAAa;QAC5BS,KAAKT,IAAI,CAAC,QAAQ;QAClBU,KAAK,CAAC,CAACV,IAAI,CAAC,QAAQ;QACpBW,SAAS,CAAC,CAACX,IAAI,CAAC,YAAY;IAC9B,GAAGY,KAAK,CAACC,mBAAW;AACtB"}
1
+ {"version":3,"sources":["../../../src/login/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport type { Command } from '../../bin/cli';\nimport { assertArgs, printHelp } from '../utils/args';\nimport { logCmdError } from '../utils/errors';\n\nexport const expoLogin: Command = async (argv) => {\n const args = assertArgs(\n {\n // Types\n '--help': Boolean,\n '--username': String,\n '--password': String,\n '--otp': String,\n '--sso': Boolean,\n '--browser': Boolean,\n // Aliases\n '-h': '--help',\n '-u': '--username',\n '-p': '--password',\n '-s': '--sso',\n '-b': '--browser',\n },\n argv\n );\n\n if (args['--help']) {\n printHelp(\n `Log in to an Expo account`,\n `npx expo login`,\n [\n `-u, --username <string> Username`,\n `-p, --password <string> Password (\"-\" for stdin)`,\n `--otp <string> One-time password from your 2FA device`,\n `-s, --sso Log in with SSO`,\n `-b, --browser Log in with a browser`,\n `-h, --help Usage info`,\n ].join('\\n')\n );\n }\n\n const password = args['--password'] === '-' ? await readWordFromStdin() : args['--password'];\n\n const { showLoginPromptAsync } = await import('../api/user/actions.js');\n return showLoginPromptAsync({\n // Parsed options\n username: args['--username'],\n password,\n otp: args['--otp'],\n sso: !!args['--sso'],\n browser: !!args['--browser'],\n }).catch(logCmdError);\n};\n\nexport async function readWordFromStdin(): Promise<string> {\n let buffer = '';\n for await (const chunk of process.stdin) {\n buffer += chunk;\n const newlineIndex = buffer.indexOf('\\n');\n if (newlineIndex !== -1) {\n return buffer.slice(0, newlineIndex).replace(/\\r$/, '');\n }\n }\n return buffer;\n}\n"],"names":["expoLogin","readWordFromStdin","argv","args","assertArgs","Boolean","String","printHelp","join","password","showLoginPromptAsync","username","otp","sso","browser","catch","logCmdError","buffer","chunk","process","stdin","newlineIndex","indexOf","slice","replace"],"mappings":";;;;;;;;;;;;QAKaA;eAAAA;;QAgDSC;eAAAA;;;sBAnDgB;wBACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMD,YAAqB,OAAOE;IACvC,MAAMC,OAAOC,IAAAA,gBAAU,EACrB;QACE,QAAQ;QACR,UAAUC;QACV,cAAcC;QACd,cAAcA;QACd,SAASA;QACT,SAASD;QACT,aAAaA;QACb,UAAU;QACV,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;IACR,GACAH;IAGF,IAAIC,IAAI,CAAC,SAAS,EAAE;QAClBI,IAAAA,eAAS,EACP,CAAC,yBAAyB,CAAC,EAC3B,CAAC,cAAc,CAAC,EAChB;YACE,CAAC,iCAAiC,CAAC;YACnC,CAAC,iDAAiD,CAAC;YACnD,CAAC,+DAA+D,CAAC;YACjE,CAAC,wCAAwC,CAAC;YAC1C,CAAC,8CAA8C,CAAC;YAChD,CAAC,mCAAmC,CAAC;SACtC,CAACC,IAAI,CAAC;IAEX;IAEA,MAAMC,WAAWN,IAAI,CAAC,aAAa,KAAK,MAAM,MAAMF,sBAAsBE,IAAI,CAAC,aAAa;IAE5F,MAAM,EAAEO,oBAAoB,EAAE,GAAG,MAAM,mEAAA,QAAO;IAC9C,OAAOA,qBAAqB;QAC1B,iBAAiB;QACjBC,UAAUR,IAAI,CAAC,aAAa;QAC5BM;QACAG,KAAKT,IAAI,CAAC,QAAQ;QAClBU,KAAK,CAAC,CAACV,IAAI,CAAC,QAAQ;QACpBW,SAAS,CAAC,CAACX,IAAI,CAAC,YAAY;IAC9B,GAAGY,KAAK,CAACC,mBAAW;AACtB;AAEO,eAAef;IACpB,IAAIgB,SAAS;IACb,WAAW,MAAMC,SAASC,QAAQC,KAAK,CAAE;QACvCH,UAAUC;QACV,MAAMG,eAAeJ,OAAOK,OAAO,CAAC;QACpC,IAAID,iBAAiB,CAAC,GAAG;YACvB,OAAOJ,OAAOM,KAAK,CAAC,GAAGF,cAAcG,OAAO,CAAC,OAAO;QACtD;IACF;IACA,OAAOP;AACT"}
@@ -17,6 +17,9 @@ function _configplugins() {
17
17
  }
18
18
  const _AndroidAppIdResolver = require("../../start/platforms/android/AndroidAppIdResolver");
19
19
  const _errors = require("../../utils/errors");
20
+ function resolveCustomLaunchActivity(packageName, mainActivity) {
21
+ return mainActivity.startsWith('.') ? `${packageName}${mainActivity}` : mainActivity;
22
+ }
20
23
  async function getMainActivityAsync(projectRoot) {
21
24
  const filePath = await _configplugins().AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);
22
25
  const androidManifest = await _configplugins().AndroidConfig.Manifest.readAndroidManifestAsync(filePath);
@@ -34,7 +37,7 @@ async function resolveLaunchPropsAsync(projectRoot, options) {
34
37
  const mainActivity = await getMainActivityAsync(projectRoot);
35
38
  const packageName = await new _AndroidAppIdResolver.AndroidAppIdResolver(projectRoot).getAppIdFromNativeAsync();
36
39
  const customAppId = options.appId;
37
- const launchActivity = customAppId && customAppId !== packageName ? `${customAppId}/${packageName}${mainActivity}` : `${packageName}/${mainActivity}`;
40
+ const launchActivity = customAppId && customAppId !== packageName ? `${customAppId}/${resolveCustomLaunchActivity(packageName, mainActivity)}` : `${packageName}/${mainActivity}`;
38
41
  return {
39
42
  mainActivity,
40
43
  launchActivity,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/run/android/resolveLaunchProps.ts"],"sourcesContent":["import { AndroidConfig } from '@expo/config-plugins';\n\nimport { AndroidAppIdResolver } from '../../start/platforms/android/AndroidAppIdResolver';\nimport { CommandError } from '../../utils/errors';\n\nexport interface LaunchProps {\n /**\n * The \"common\" Android package name, configured through the app manifest.\n * @see https://source.android.com/docs/core/architecture/hidl/code-style#package-names\n */\n packageName: string;\n /**\n * Optional customized application ID, used in product flavors.\n * @see https://developer.android.com/build/build-variants#change-app-id\n */\n customAppId?: string;\n /**\n * The main activity to launch, by default this is `.MainActivity`.\n * @see https://github.com/expo/expo/blob/c0aec226a43c0f186258a063a6145c3e52246f8a/templates/expo-template-bare-minimum/android/app/src/main/AndroidManifest.xml#L22\n */\n mainActivity: string;\n /**\n * The full launch activity reference used in the app intent to launch the app with `adb am start -n <launchActivity>`.\n * Usually, this is structured as `<package-name>/.<activity-name>`.\n * For product flavors, this is structured as `<custom-app-id>/<package-name>.<activity-name>`.\n * @see https://developer.android.com/studio/command-line/adb#IntentSpec\n */\n launchActivity: string;\n}\n\nasync function getMainActivityAsync(projectRoot: string): Promise<string> {\n const filePath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);\n const androidManifest = await AndroidConfig.Manifest.readAndroidManifestAsync(filePath);\n const runnableActivity = AndroidConfig.Manifest.getRunnableActivity(androidManifest);\n if (runnableActivity) {\n return runnableActivity.$['android:name'];\n }\n const mainActivity = AndroidConfig.Manifest.getMainActivity(androidManifest);\n if (!mainActivity) {\n throw new CommandError(\n 'ANDROID_MALFORMED',\n `${filePath} is missing a runnable activity element.`\n );\n }\n return mainActivity.$['android:name'];\n}\n\nexport async function resolveLaunchPropsAsync(\n projectRoot: string,\n options: { appId?: string }\n): Promise<LaunchProps> {\n const mainActivity = await getMainActivityAsync(projectRoot);\n const packageName = await new AndroidAppIdResolver(projectRoot).getAppIdFromNativeAsync();\n const customAppId = options.appId;\n\n const launchActivity =\n customAppId && customAppId !== packageName\n ? `${customAppId}/${packageName}${mainActivity}`\n : `${packageName}/${mainActivity}`;\n\n return {\n mainActivity,\n launchActivity,\n packageName,\n customAppId,\n };\n}\n"],"names":["resolveLaunchPropsAsync","getMainActivityAsync","projectRoot","filePath","AndroidConfig","Paths","getAndroidManifestAsync","androidManifest","Manifest","readAndroidManifestAsync","runnableActivity","getRunnableActivity","$","mainActivity","getMainActivity","CommandError","options","packageName","AndroidAppIdResolver","getAppIdFromNativeAsync","customAppId","appId","launchActivity"],"mappings":";;;;+BA+CsBA;;;eAAAA;;;;yBA/CQ;;;;;;sCAEO;wBACR;AA2B7B,eAAeC,qBAAqBC,WAAmB;IACrD,MAAMC,WAAW,MAAMC,8BAAa,CAACC,KAAK,CAACC,uBAAuB,CAACJ;IACnE,MAAMK,kBAAkB,MAAMH,8BAAa,CAACI,QAAQ,CAACC,wBAAwB,CAACN;IAC9E,MAAMO,mBAAmBN,8BAAa,CAACI,QAAQ,CAACG,mBAAmB,CAACJ;IACpE,IAAIG,kBAAkB;QACpB,OAAOA,iBAAiBE,CAAC,CAAC,eAAe;IAC3C;IACA,MAAMC,eAAeT,8BAAa,CAACI,QAAQ,CAACM,eAAe,CAACP;IAC5D,IAAI,CAACM,cAAc;QACjB,MAAM,IAAIE,oBAAY,CACpB,qBACA,GAAGZ,SAAS,wCAAwC,CAAC;IAEzD;IACA,OAAOU,aAAaD,CAAC,CAAC,eAAe;AACvC;AAEO,eAAeZ,wBACpBE,WAAmB,EACnBc,OAA2B;IAE3B,MAAMH,eAAe,MAAMZ,qBAAqBC;IAChD,MAAMe,cAAc,MAAM,IAAIC,0CAAoB,CAAChB,aAAaiB,uBAAuB;IACvF,MAAMC,cAAcJ,QAAQK,KAAK;IAEjC,MAAMC,iBACJF,eAAeA,gBAAgBH,cAC3B,GAAGG,YAAY,CAAC,EAAEH,cAAcJ,cAAc,GAC9C,GAAGI,YAAY,CAAC,EAAEJ,cAAc;IAEtC,OAAO;QACLA;QACAS;QACAL;QACAG;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/run/android/resolveLaunchProps.ts"],"sourcesContent":["import { AndroidConfig } from '@expo/config-plugins';\n\nimport { AndroidAppIdResolver } from '../../start/platforms/android/AndroidAppIdResolver';\nimport { CommandError } from '../../utils/errors';\n\nexport interface LaunchProps {\n /**\n * The \"common\" Android package name, configured through the app manifest.\n * @see https://source.android.com/docs/core/architecture/hidl/code-style#package-names\n */\n packageName: string;\n /**\n * Optional customized application ID, used in product flavors.\n * @see https://developer.android.com/build/build-variants#change-app-id\n */\n customAppId?: string;\n /**\n * The main activity to launch, by default this is `.MainActivity`.\n * @see https://github.com/expo/expo/blob/c0aec226a43c0f186258a063a6145c3e52246f8a/templates/expo-template-bare-minimum/android/app/src/main/AndroidManifest.xml#L22\n */\n mainActivity: string;\n /**\n * The full launch activity reference used in the app intent to launch the app with `adb am start -n <launchActivity>`.\n * Usually, this is structured as `<package-name>/.<activity-name>`.\n * For product flavors, this is structured as `<custom-app-id>/<package-name>.<activity-name>`.\n * @see https://developer.android.com/studio/command-line/adb#IntentSpec\n */\n launchActivity: string;\n}\n\nfunction resolveCustomLaunchActivity(packageName: string, mainActivity: string): string {\n return mainActivity.startsWith('.') ? `${packageName}${mainActivity}` : mainActivity;\n}\n\nasync function getMainActivityAsync(projectRoot: string): Promise<string> {\n const filePath = await AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);\n const androidManifest = await AndroidConfig.Manifest.readAndroidManifestAsync(filePath);\n const runnableActivity = AndroidConfig.Manifest.getRunnableActivity(androidManifest);\n if (runnableActivity) {\n return runnableActivity.$['android:name'];\n }\n const mainActivity = AndroidConfig.Manifest.getMainActivity(androidManifest);\n if (!mainActivity) {\n throw new CommandError(\n 'ANDROID_MALFORMED',\n `${filePath} is missing a runnable activity element.`\n );\n }\n return mainActivity.$['android:name'];\n}\n\nexport async function resolveLaunchPropsAsync(\n projectRoot: string,\n options: { appId?: string }\n): Promise<LaunchProps> {\n const mainActivity = await getMainActivityAsync(projectRoot);\n const packageName = await new AndroidAppIdResolver(projectRoot).getAppIdFromNativeAsync();\n const customAppId = options.appId;\n\n const launchActivity =\n customAppId && customAppId !== packageName\n ? `${customAppId}/${resolveCustomLaunchActivity(packageName, mainActivity)}`\n : `${packageName}/${mainActivity}`;\n\n return {\n mainActivity,\n launchActivity,\n packageName,\n customAppId,\n };\n}\n"],"names":["resolveLaunchPropsAsync","resolveCustomLaunchActivity","packageName","mainActivity","startsWith","getMainActivityAsync","projectRoot","filePath","AndroidConfig","Paths","getAndroidManifestAsync","androidManifest","Manifest","readAndroidManifestAsync","runnableActivity","getRunnableActivity","$","getMainActivity","CommandError","options","AndroidAppIdResolver","getAppIdFromNativeAsync","customAppId","appId","launchActivity"],"mappings":";;;;+BAmDsBA;;;eAAAA;;;;yBAnDQ;;;;;;sCAEO;wBACR;AA2B7B,SAASC,4BAA4BC,WAAmB,EAAEC,YAAoB;IAC5E,OAAOA,aAAaC,UAAU,CAAC,OAAO,GAAGF,cAAcC,cAAc,GAAGA;AAC1E;AAEA,eAAeE,qBAAqBC,WAAmB;IACrD,MAAMC,WAAW,MAAMC,8BAAa,CAACC,KAAK,CAACC,uBAAuB,CAACJ;IACnE,MAAMK,kBAAkB,MAAMH,8BAAa,CAACI,QAAQ,CAACC,wBAAwB,CAACN;IAC9E,MAAMO,mBAAmBN,8BAAa,CAACI,QAAQ,CAACG,mBAAmB,CAACJ;IACpE,IAAIG,kBAAkB;QACpB,OAAOA,iBAAiBE,CAAC,CAAC,eAAe;IAC3C;IACA,MAAMb,eAAeK,8BAAa,CAACI,QAAQ,CAACK,eAAe,CAACN;IAC5D,IAAI,CAACR,cAAc;QACjB,MAAM,IAAIe,oBAAY,CACpB,qBACA,GAAGX,SAAS,wCAAwC,CAAC;IAEzD;IACA,OAAOJ,aAAaa,CAAC,CAAC,eAAe;AACvC;AAEO,eAAehB,wBACpBM,WAAmB,EACnBa,OAA2B;IAE3B,MAAMhB,eAAe,MAAME,qBAAqBC;IAChD,MAAMJ,cAAc,MAAM,IAAIkB,0CAAoB,CAACd,aAAae,uBAAuB;IACvF,MAAMC,cAAcH,QAAQI,KAAK;IAEjC,MAAMC,iBACJF,eAAeA,gBAAgBpB,cAC3B,GAAGoB,YAAY,CAAC,EAAErB,4BAA4BC,aAAaC,eAAe,GAC1E,GAAGD,YAAY,CAAC,EAAEC,cAAc;IAEtC,OAAO;QACLA;QACAqB;QACAtB;QACAoB;IACF;AACF"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get REACT_NATIVE_TVOS_PACKAGE_NAME () {
13
+ return REACT_NATIVE_TVOS_PACKAGE_NAME;
14
+ },
15
+ get correctReactNativeTvVersion () {
16
+ return correctReactNativeTvVersion;
17
+ },
18
+ get isReactNativeTvProjectAsync () {
19
+ return isReactNativeTvProjectAsync;
20
+ },
21
+ get reactNativeTvVersionMatchesBundled () {
22
+ return reactNativeTvVersionMatchesBundled;
23
+ }
24
+ });
25
+ function _jsonfile() {
26
+ const data = /*#__PURE__*/ _interop_require_default(require("@expo/json-file"));
27
+ _jsonfile = function() {
28
+ return data;
29
+ };
30
+ return data;
31
+ }
32
+ function _requireutils() {
33
+ const data = require("@expo/require-utils");
34
+ _requireutils = function() {
35
+ return data;
36
+ };
37
+ return data;
38
+ }
39
+ function _semver() {
40
+ const data = /*#__PURE__*/ _interop_require_default(require("semver"));
41
+ _semver = function() {
42
+ return data;
43
+ };
44
+ return data;
45
+ }
46
+ const _env = require("../../../utils/env");
47
+ const _fetch = require("../../../utils/fetch");
48
+ function _interop_require_default(obj) {
49
+ return obj && obj.__esModule ? obj : {
50
+ default: obj
51
+ };
52
+ }
53
+ const REACT_NATIVE_TVOS_PACKAGE_NAME = 'react-native-tvos';
54
+ const debug = require('debug')('expo:doctor:reactNativeTv');
55
+ const NPM_DIST_TAGS_URL = `https://registry.npmjs.org/-/package/${REACT_NATIVE_TVOS_PACKAGE_NAME}/dist-tags`;
56
+ const LATEST_FALLBACK_SPEC = `npm:${REACT_NATIVE_TVOS_PACKAGE_NAME}@latest`;
57
+ async function isReactNativeTvProjectAsync(projectRoot) {
58
+ const reactNativePackageJsonPath = (0, _requireutils().resolveFrom)(projectRoot, 'react-native/package.json');
59
+ if (!reactNativePackageJsonPath) {
60
+ return false;
61
+ }
62
+ try {
63
+ const installedPkg = await _jsonfile().default.readAsync(reactNativePackageJsonPath);
64
+ return installedPkg.name === REACT_NATIVE_TVOS_PACKAGE_NAME;
65
+ } catch {
66
+ return false;
67
+ }
68
+ }
69
+ async function correctReactNativeTvVersion(bundledReactNativeVersion) {
70
+ const derivedTag = deriveDistTag(bundledReactNativeVersion);
71
+ if (!derivedTag) {
72
+ debug(`Could not derive a react-native-tvos dist-tag from "${bundledReactNativeVersion}"; falling back to @latest`);
73
+ return LATEST_FALLBACK_SPEC;
74
+ }
75
+ // In offline mode skip the npm dist-tags lookup and trust the derived tag —
76
+ // any other CLI code path that needs a network request also bails on
77
+ // `EXPO_OFFLINE` (see `validateDependenciesVersionsAsync`).
78
+ if (_env.env.EXPO_OFFLINE) {
79
+ debug(`EXPO_OFFLINE is set; skipping npm dist-tags lookup for react-native-tvos`);
80
+ return `npm:${REACT_NATIVE_TVOS_PACKAGE_NAME}@${derivedTag}`;
81
+ }
82
+ const publishedTags = await fetchReactNativeTvDistTagsAsync();
83
+ if (publishedTags.has(derivedTag)) {
84
+ return `npm:${REACT_NATIVE_TVOS_PACKAGE_NAME}@${derivedTag}`;
85
+ }
86
+ debug(`Derived react-native-tvos dist-tag "${derivedTag}" is not published; falling back to @latest`);
87
+ return LATEST_FALLBACK_SPEC;
88
+ }
89
+ function reactNativeTvVersionMatchesBundled(actualVersion, bundledReactNativeVersion) {
90
+ const actual = _semver().default.coerce(actualVersion);
91
+ const bundled = _semver().default.coerce(bundledReactNativeVersion);
92
+ if (!actual || !bundled) {
93
+ return false;
94
+ }
95
+ return actual.major === bundled.major && actual.minor === bundled.minor;
96
+ }
97
+ function deriveDistTag(reactNativeVersion) {
98
+ if (!reactNativeVersion) {
99
+ return undefined;
100
+ }
101
+ let minVersion = null;
102
+ try {
103
+ minVersion = _semver().default.minVersion(reactNativeVersion);
104
+ } catch {
105
+ minVersion = null;
106
+ }
107
+ if (!minVersion) {
108
+ return undefined;
109
+ }
110
+ if (minVersion.prerelease.length > 0) {
111
+ return 'next';
112
+ }
113
+ return `${minVersion.major}.${minVersion.minor}-stable`;
114
+ }
115
+ async function fetchReactNativeTvDistTagsAsync() {
116
+ let response;
117
+ try {
118
+ response = await (0, _fetch.fetch)(NPM_DIST_TAGS_URL);
119
+ } catch (error) {
120
+ debug(`npm dist-tags lookup threw: ${(error == null ? void 0 : error.message) ?? error}`);
121
+ return new Set();
122
+ }
123
+ // Always read the body to release the underlying stream — even on a non-2xx —
124
+ // before deciding what to do with it. Parse JSON manually so a malformed
125
+ // body never escapes as a rejected promise.
126
+ let body = '';
127
+ try {
128
+ body = await response.text();
129
+ } catch (error) {
130
+ debug(`npm dist-tags body read threw: ${(error == null ? void 0 : error.message) ?? error}`);
131
+ return new Set();
132
+ }
133
+ if (!response.ok) {
134
+ debug(`npm dist-tags lookup failed with status ${response.status}`);
135
+ return new Set();
136
+ }
137
+ let json;
138
+ try {
139
+ json = JSON.parse(body);
140
+ } catch {
141
+ return new Set();
142
+ }
143
+ if (!json || typeof json !== 'object') {
144
+ return new Set();
145
+ }
146
+ return new Set(Object.keys(json));
147
+ }
148
+
149
+ //# sourceMappingURL=reactNativeTv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/start/doctor/dependencies/reactNativeTv.ts"],"sourcesContent":["import JsonFile from '@expo/json-file';\nimport { resolveFrom } from '@expo/require-utils';\nimport semver from 'semver';\n\nimport { env } from '../../../utils/env';\nimport { fetch } from '../../../utils/fetch';\n\nexport const REACT_NATIVE_TVOS_PACKAGE_NAME = 'react-native-tvos';\n\nconst debug = require('debug')('expo:doctor:reactNativeTv') as typeof console.log;\n\nconst NPM_DIST_TAGS_URL = `https://registry.npmjs.org/-/package/${REACT_NATIVE_TVOS_PACKAGE_NAME}/dist-tags`;\n\nconst LATEST_FALLBACK_SPEC = `npm:${REACT_NATIVE_TVOS_PACKAGE_NAME}@latest`;\n\n/**\n * Detects whether this is a TV project by inspecting the installed\n * `react-native` package's `name` field. When the project's `package.json`\n * aliases `react-native` to `react-native-tvos` (e.g.\n * `\"react-native\": \"npm:react-native-tvos@0.83.0-0\"`), the installed package\n * at `node_modules/react-native/package.json` is the upstream\n * `react-native-tvos` manifest, whose `name` is `\"react-native-tvos\"`.\n *\n * Reading the installed manifest is more reliable than reading the project's\n * `package.json` spec string, which can vary across package managers and\n * lockfile rewrites.\n */\nexport async function isReactNativeTvProjectAsync(projectRoot: string): Promise<boolean> {\n const reactNativePackageJsonPath = resolveFrom(projectRoot, 'react-native/package.json');\n if (!reactNativePackageJsonPath) {\n return false;\n }\n try {\n const installedPkg = await JsonFile.readAsync<{ name?: string }>(reactNativePackageJsonPath);\n return installedPkg.name === REACT_NATIVE_TVOS_PACKAGE_NAME;\n } catch {\n return false;\n }\n}\n\n/**\n * Returns the install spec to use for `react-native-tvos` given the bundled\n * `react-native` version.\n *\n * `react-native-tvos` ships a dist-tag per minor line in the form\n * `<major>.<minor>-stable` and a rolling `next` tag for prereleases. We derive\n * the expected tag from the bundled `react-native` version (stable → `-stable`,\n * prerelease → `next`) and then verify the tag is actually published by\n * fetching the package's `dist-tags` from the npm registry. If the derived tag\n * isn't published (or the registry can't be reached), we fall back to\n * `npm:react-native-tvos@latest` so the install still resolves to something\n * usable.\n */\nexport async function correctReactNativeTvVersion(\n bundledReactNativeVersion: string\n): Promise<string> {\n const derivedTag = deriveDistTag(bundledReactNativeVersion);\n if (!derivedTag) {\n debug(\n `Could not derive a react-native-tvos dist-tag from \"${bundledReactNativeVersion}\"; falling back to @latest`\n );\n return LATEST_FALLBACK_SPEC;\n }\n // In offline mode skip the npm dist-tags lookup and trust the derived tag —\n // any other CLI code path that needs a network request also bails on\n // `EXPO_OFFLINE` (see `validateDependenciesVersionsAsync`).\n if (env.EXPO_OFFLINE) {\n debug(`EXPO_OFFLINE is set; skipping npm dist-tags lookup for react-native-tvos`);\n return `npm:${REACT_NATIVE_TVOS_PACKAGE_NAME}@${derivedTag}`;\n }\n const publishedTags = await fetchReactNativeTvDistTagsAsync();\n if (publishedTags.has(derivedTag)) {\n return `npm:${REACT_NATIVE_TVOS_PACKAGE_NAME}@${derivedTag}`;\n }\n debug(\n `Derived react-native-tvos dist-tag \"${derivedTag}\" is not published; falling back to @latest`\n );\n return LATEST_FALLBACK_SPEC;\n}\n\n/**\n * Returns true when an installed `react-native` (aliased to `react-native-tvos`)\n * version's `major.minor` lines up with the expected bundled `react-native`\n * version. `react-native-tvos` releases follow the upstream minor versions, so a\n * matching `major.minor` means the TV variant is already current.\n */\nexport function reactNativeTvVersionMatchesBundled(\n actualVersion: string,\n bundledReactNativeVersion: string\n): boolean {\n const actual = semver.coerce(actualVersion);\n const bundled = semver.coerce(bundledReactNativeVersion);\n if (!actual || !bundled) {\n return false;\n }\n return actual.major === bundled.major && actual.minor === bundled.minor;\n}\n\nfunction deriveDistTag(reactNativeVersion: string): string | undefined {\n if (!reactNativeVersion) {\n return undefined;\n }\n let minVersion: semver.SemVer | null = null;\n try {\n minVersion = semver.minVersion(reactNativeVersion);\n } catch {\n minVersion = null;\n }\n if (!minVersion) {\n return undefined;\n }\n if (minVersion.prerelease.length > 0) {\n return 'next';\n }\n return `${minVersion.major}.${minVersion.minor}-stable`;\n}\n\nasync function fetchReactNativeTvDistTagsAsync(): Promise<Set<string>> {\n let response;\n try {\n response = await fetch(NPM_DIST_TAGS_URL);\n } catch (error: any) {\n debug(`npm dist-tags lookup threw: ${error?.message ?? error}`);\n return new Set();\n }\n // Always read the body to release the underlying stream — even on a non-2xx —\n // before deciding what to do with it. Parse JSON manually so a malformed\n // body never escapes as a rejected promise.\n let body = '';\n try {\n body = await response.text();\n } catch (error: any) {\n debug(`npm dist-tags body read threw: ${error?.message ?? error}`);\n return new Set();\n }\n if (!response.ok) {\n debug(`npm dist-tags lookup failed with status ${response.status}`);\n return new Set();\n }\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch {\n return new Set();\n }\n if (!json || typeof json !== 'object') {\n return new Set();\n }\n return new Set(Object.keys(json as Record<string, unknown>));\n}\n"],"names":["REACT_NATIVE_TVOS_PACKAGE_NAME","correctReactNativeTvVersion","isReactNativeTvProjectAsync","reactNativeTvVersionMatchesBundled","debug","require","NPM_DIST_TAGS_URL","LATEST_FALLBACK_SPEC","projectRoot","reactNativePackageJsonPath","resolveFrom","installedPkg","JsonFile","readAsync","name","bundledReactNativeVersion","derivedTag","deriveDistTag","env","EXPO_OFFLINE","publishedTags","fetchReactNativeTvDistTagsAsync","has","actualVersion","actual","semver","coerce","bundled","major","minor","reactNativeVersion","undefined","minVersion","prerelease","length","response","fetch","error","message","Set","body","text","ok","status","json","JSON","parse","Object","keys"],"mappings":"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"}
@@ -58,6 +58,7 @@ function _subset() {
58
58
  return data;
59
59
  }
60
60
  const _getVersionedPackages = require("./getVersionedPackages");
61
+ const _reactNativeTv = require("./reactNativeTv");
61
62
  const _resolvePackages = require("./resolvePackages");
62
63
  const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../../log"));
63
64
  const _env = require("../../../utils/env");
@@ -157,8 +158,12 @@ async function getVersionedDependenciesAsync(projectRoot, exp, pkg, packagesToCh
157
158
  // read package versions from the file system (node_modules)
158
159
  const packageVersions = await (0, _resolvePackages.resolveAllPackageVersionsAsync)(projectRoot, resolvedPackagesToCheck);
159
160
  debug(`Package versions: %O`, packageVersions);
161
+ // Detect TV projects via the installed `react-native` package's `name`, since
162
+ // `pkg.dependencies['react-native']` can vary across package managers.
163
+ const isReactNativeTvProject = await (0, _reactNativeTv.isReactNativeTvProjectAsync)(projectRoot);
164
+ debug(`react-native-tvos project: %O`, isReactNativeTvProject);
160
165
  // find incorrect dependencies by comparing the actual package versions with the bundled native module version ranges
161
- let incorrectDeps = findIncorrectDependencies(pkg, packageVersions, combinedKnownPackages);
166
+ let incorrectDeps = await findIncorrectDependencies(pkg, packageVersions, combinedKnownPackages, isReactNativeTvProject);
162
167
  debug(`Incorrect dependencies: %O`, incorrectDeps);
163
168
  if (pkg == null ? void 0 : (_pkg_expo = pkg.expo) == null ? void 0 : (_pkg_expo_install = _pkg_expo.install) == null ? void 0 : _pkg_expo_install.exclude) {
164
169
  const packagesToExclude = pkg.expo.install.exclude;
@@ -221,12 +226,32 @@ function getPackagesToCheck(bundledNativeModules, dependencies) {
221
226
  unknown
222
227
  };
223
228
  }
224
- function findIncorrectDependencies(pkg, packageVersions, bundledNativeModules) {
229
+ async function findIncorrectDependencies(pkg, packageVersions, bundledNativeModules, isReactNativeTvProject) {
230
+ // For TV projects, compare the installed `major.minor` against the bundled
231
+ // `react-native` `major.minor` — `react-native-tvos` follows the upstream
232
+ // minor lines via a `<major>.<minor>-stable` dist-tag, so a matching minor
233
+ // means the TV variant is up to date.
234
+ //
235
+ // Resolve the install spec for the TV variant once up front so the inner
236
+ // loop stays synchronous and we don't hit the npm registry per dependency.
237
+ const bundledReactNativeVersion = bundledNativeModules['react-native'];
238
+ const reactNativeTvExpectedVersionOrRange = isReactNativeTvProject && bundledReactNativeVersion ? await (0, _reactNativeTv.correctReactNativeTvVersion)(bundledReactNativeVersion) : undefined;
225
239
  const packages = Object.keys(packageVersions);
226
240
  const incorrectDeps = [];
227
241
  for (const packageName of packages){
228
- const expectedVersionOrRange = bundledNativeModules[packageName];
229
242
  const actualVersion = packageVersions[packageName];
243
+ if (isReactNativeTvProject && packageName === 'react-native') {
244
+ if (bundledReactNativeVersion && reactNativeTvExpectedVersionOrRange && !(0, _reactNativeTv.reactNativeTvVersionMatchesBundled)(actualVersion, bundledReactNativeVersion)) {
245
+ incorrectDeps.push({
246
+ packageName,
247
+ packageType: findDependencyType(pkg, packageName),
248
+ expectedVersionOrRange: reactNativeTvExpectedVersionOrRange,
249
+ actualVersion
250
+ });
251
+ }
252
+ continue;
253
+ }
254
+ const expectedVersionOrRange = bundledNativeModules[packageName];
230
255
  if (isDependencyVersionIncorrect(packageName, actualVersion, expectedVersionOrRange)) {
231
256
  incorrectDeps.push({
232
257
  packageName,