@expo/cli 55.0.0-canary-20260105-6b962e6 → 55.0.0-canary-20260119-70f7c28
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.
- package/build/bin/cli +1 -1
- package/build/src/export/embed/exportEmbedAsync.js +1 -2
- package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
- package/build/src/export/exportStaticAsync.js +117 -7
- package/build/src/export/exportStaticAsync.js.map +1 -1
- package/build/src/export/saveAssets.js +6 -4
- package/build/src/export/saveAssets.js.map +1 -1
- package/build/src/start/interface/interactiveActions.js +0 -1
- package/build/src/start/interface/interactiveActions.js.map +1 -1
- package/build/src/start/server/Bonjour.js +100 -0
- package/build/src/start/server/Bonjour.js.map +1 -0
- package/build/src/start/server/BundlerDevServer.js +22 -4
- package/build/src/start/server/BundlerDevServer.js.map +1 -1
- package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js +2 -2
- package/build/src/start/server/DevToolsPluginCliExtensionExecutor.js.map +1 -1
- package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js +86 -0
- package/build/src/start/server/MCPDevToolsPluginCLIExtensions.js.map +1 -0
- package/build/src/start/server/createMCPDevToolsExtensionSchema.js +67 -0
- package/build/src/start/server/createMCPDevToolsExtensionSchema.js.map +1 -0
- package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js +10 -2
- package/build/src/start/server/metro/DevToolsPluginWebsocketEndpoint.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +103 -31
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js +25 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/debugging/createDebugMiddleware.js +22 -8
- package/build/src/start/server/metro/debugging/createDebugMiddleware.js.map +1 -1
- package/build/src/start/server/metro/dev-server/compression.js +45 -0
- package/build/src/start/server/metro/dev-server/compression.js.map +1 -0
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +2 -2
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +19 -7
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/resolveLoader.js +2 -1
- package/build/src/start/server/metro/resolveLoader.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +3 -2
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/start/startAsync.js +6 -1
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/env.js +15 -1
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/git.js +1 -1
- package/build/src/utils/git.js.map +1 -1
- package/build/src/utils/net.js +43 -0
- package/build/src/utils/net.js.map +1 -0
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +22 -21
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js +0 -75
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/saveAssets.ts"],"sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport type { AssetData } from '@expo/metro/metro';\nimport type { SerialAsset } from '@expo/metro-config/build/serializer/serializerAssets';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport prettyBytes from 'pretty-bytes';\n\nimport { Log } from '../log';\nimport { env } from '../utils/env';\n\nconst BLT = '\\u203A';\n\nexport type BundleOptions = {\n entryPoint: string;\n platform: 'android' | 'ios' | 'web';\n dev?: boolean;\n minify?: boolean;\n bytecode: boolean;\n sourceMapUrl?: string;\n sourcemaps?: boolean;\n};\n\nexport type BundleAssetWithFileHashes = AssetData & {\n fileHashes: string[]; // added by the hashAssets asset plugin\n};\n\nexport type BundleOutput = {\n artifacts: SerialAsset[];\n assets: readonly BundleAssetWithFileHashes[];\n};\n\nexport type ManifestAsset = { fileHashes: string[]; files: string[]; hash: string };\n\nexport type Asset = ManifestAsset | BundleAssetWithFileHashes;\n\nexport type ExportAssetDescriptor = {\n contents: string | Buffer;\n originFilename?: string;\n /** An identifier for grouping together variations of the same asset. */\n assetId?: string;\n /** Expo Router route path for formatting the HTML output. */\n routeId?: string;\n /** Expo Router route path for formatting the middleware function output. */\n middlewareId?: string;\n /** Expo Router API route path for formatting the server function output. */\n apiRouteId?: string;\n /** Expo Router route path for formatting the RSC output. */\n rscId?: string;\n /** Expo Router route path for formatting the loader module output. */\n loaderId?: string;\n /** A key for grouping together output files by server- or client-side. */\n targetDomain?: 'server' | 'client';\n};\n\nexport type ExportAssetMap = Map<string, ExportAssetDescriptor>;\n\nexport async function persistMetroFilesAsync(files: ExportAssetMap, outputDir: string) {\n if (!files.size) {\n return;\n }\n await fs.promises.mkdir(path.join(outputDir), { recursive: true });\n\n // Test fixtures:\n // Log.log(\n // JSON.stringify(\n // Object.fromEntries([...files.entries()].map(([k, v]) => [k, { ...v, contents: '' }]))\n // )\n // );\n\n const assetEntries: [string, ExportAssetDescriptor][] = [];\n const apiRouteEntries: [string, ExportAssetDescriptor][] = [];\n const middlewareEntries: [string, ExportAssetDescriptor][] = [];\n const routeEntries: [string, ExportAssetDescriptor][] = [];\n const rscEntries: [string, ExportAssetDescriptor][] = [];\n const loaderEntries: [string, ExportAssetDescriptor][] = [];\n const remainingEntries: [string, ExportAssetDescriptor][] = [];\n\n let hasServerOutput = false;\n for (const asset of files.entries()) {\n hasServerOutput = hasServerOutput || asset[1].targetDomain === 'server';\n if (asset[1].assetId) assetEntries.push(asset);\n else if (asset[1].routeId != null) routeEntries.push(asset);\n else if (asset[1].middlewareId != null) middlewareEntries.push(asset);\n else if (asset[1].apiRouteId != null) apiRouteEntries.push(asset);\n else if (asset[1].rscId != null) rscEntries.push(asset);\n else if (asset[1].loaderId != null) loaderEntries.push(asset);\n else remainingEntries.push(asset);\n }\n\n const groups = groupBy(assetEntries, ([, { assetId }]) => assetId!);\n\n const contentSize = (contents: string | Buffer) => {\n const length =\n typeof contents === 'string' ? Buffer.byteLength(contents, 'utf8') : contents.length;\n return length;\n };\n\n const sizeStr = (contents: string | Buffer) => {\n const length = contentSize(contents);\n const size = chalk.gray`(${prettyBytes(length)})`;\n return size;\n };\n\n // TODO: If any Expo Router is used, then use a new style which is more simple:\n // `chalk.gray(/path/to/) + chalk.cyan('route')`\n // | index.html (1.2kb)\n // | /path\n // | other.html (1.2kb)\n\n const isExpoRouter = routeEntries.length;\n\n // Phase out printing all the assets as users can simply check the file system for more info.\n const showAdditionalInfo = !isExpoRouter || env.EXPO_DEBUG;\n\n const assetGroups = [...groups.entries()].sort((a, b) => a[0].localeCompare(b[0])) as [\n string,\n [string, ExportAssetDescriptor][],\n ][];\n\n if (showAdditionalInfo) {\n if (assetGroups.length) {\n const totalAssets = assetGroups.reduce((sum, [, assets]) => sum + assets.length, 0);\n\n Log.log('');\n Log.log(chalk.bold`${BLT} Assets (${totalAssets}):`);\n\n for (const [assetId, assets] of assetGroups) {\n const averageContentSize =\n assets.reduce((sum, [, { contents }]) => sum + contentSize(contents), 0) / assets.length;\n Log.log(\n assetId,\n chalk.gray(\n `(${[\n assets.length > 1 ? `${assets.length} variations` : '',\n `${prettyBytes(averageContentSize)}`,\n ]\n .filter(Boolean)\n .join(' | ')})`\n )\n );\n }\n }\n }\n\n const bundles: Map<string, [string, ExportAssetDescriptor][]> = new Map();\n const other: [string, ExportAssetDescriptor][] = [];\n\n remainingEntries.forEach(([filepath, asset]) => {\n if (!filepath.match(/_expo\\/static\\//)) {\n other.push([filepath, asset]);\n } else {\n const platform = filepath.match(/_expo\\/static\\/js\\/([^/]+)\\//)?.[1] ?? 'web';\n if (!bundles.has(platform)) bundles.set(platform, []);\n\n bundles.get(platform)!.push([filepath, asset]);\n }\n });\n\n [...bundles.entries()].forEach(([platform, assets]) => {\n Log.log('');\n Log.log(chalk.bold`${BLT} ${platform} bundles (${assets.length}):`);\n\n const allAssets = assets.sort((a, b) => a[0].localeCompare(b[0]));\n while (allAssets.length) {\n const [filePath, asset] = allAssets.shift()!;\n Log.log(filePath, sizeStr(asset.contents));\n if (filePath.match(/\\.(js|hbc)$/)) {\n // Get source map\n const sourceMapIndex = allAssets.findIndex(([fp]) => fp === filePath + '.map');\n if (sourceMapIndex !== -1) {\n const [sourceMapFilePath, sourceMapAsset] = allAssets.splice(sourceMapIndex, 1)[0];\n Log.log(chalk.gray(sourceMapFilePath), sizeStr(sourceMapAsset.contents));\n }\n }\n }\n });\n\n if (showAdditionalInfo && other.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} Files (${other.length}):`);\n\n for (const [filePath, asset] of other.sort((a, b) => a[0].localeCompare(b[0]))) {\n Log.log(filePath, sizeStr(asset.contents));\n }\n }\n\n if (rscEntries.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} React Server Components (${rscEntries.length}):`);\n\n for (const [filePath, assets] of rscEntries.sort((a, b) => a[0].length - b[0].length)) {\n const id = assets.rscId!;\n Log.log(\n '/' + (id === '' ? chalk.gray(' (index)') : id),\n sizeStr(assets.contents),\n chalk.gray(filePath)\n );\n }\n }\n\n if (routeEntries.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} Static routes (${routeEntries.length}):`);\n\n for (const [, assets] of routeEntries.sort((a, b) => a[0].length - b[0].length)) {\n const id = assets.routeId!;\n Log.log('/' + (id === '' ? chalk.gray(' (index)') : id), sizeStr(assets.contents));\n }\n }\n\n if (apiRouteEntries.length) {\n const apiRoutesWithoutSourcemaps = apiRouteEntries.filter(\n (route) => !route[0].endsWith('.map')\n );\n Log.log('');\n Log.log(chalk.bold`${BLT} API routes (${apiRoutesWithoutSourcemaps.length}):`);\n\n for (const [apiRouteFilename, assets] of apiRoutesWithoutSourcemaps.sort(\n (a, b) => a[0].length - b[0].length\n )) {\n const id = assets.apiRouteId!;\n const hasSourceMap = apiRouteEntries.find(\n ([filename, route]) =>\n filename !== apiRouteFilename &&\n route.apiRouteId === assets.apiRouteId &&\n filename.endsWith('.map')\n );\n Log.log(\n id === '' ? chalk.gray(' (index)') : id,\n sizeStr(assets.contents),\n hasSourceMap ? chalk.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : ''\n );\n }\n }\n\n if (middlewareEntries.length) {\n const middlewareWithoutSourcemaps = middlewareEntries.filter(\n (route) => !route[0].endsWith('.map')\n );\n Log.log('');\n Log.log(chalk.bold`${BLT} Middleware:`);\n\n for (const [middlewareFilename, assets] of middlewareWithoutSourcemaps.sort(\n (a, b) => a[0].length - b[0].length\n )) {\n const id = assets.middlewareId!;\n const hasSourceMap = middlewareEntries.find(\n ([filename, route]) =>\n filename !== middlewareFilename &&\n route.middlewareId === assets.middlewareId &&\n filename.endsWith('.map')\n );\n Log.log(\n id,\n sizeStr(assets.contents),\n hasSourceMap ? chalk.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : ''\n );\n }\n }\n\n if (loaderEntries.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} Loader outputs (${loaderEntries.length}):`);\n\n for (const [loaderFilename, assets] of loaderEntries.sort(\n (a, b) => a[0].length - b[0].length\n )) {\n const id = assets.loaderId!;\n Log.log(id === '/' ? '/ ' + chalk.gray('(index)') : id, sizeStr(assets.contents));\n }\n }\n\n // Decouple logging from writing for better performance.\n\n await Promise.all(\n [...files.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(async ([file, { contents, targetDomain }]) => {\n // NOTE: Only use `targetDomain` if we have at least one server asset\n const domain = (hasServerOutput && targetDomain) || '';\n const outputPath = path.join(outputDir, domain, file);\n await fs.promises.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.promises.writeFile(outputPath, contents);\n })\n );\n\n Log.log('');\n}\n\nfunction groupBy<T>(array: T[], key: (item: T) => string): Map<string, T[]> {\n const map = new Map<string, T[]>();\n array.forEach((item) => {\n const group = key(item);\n const list = map.get(group) ?? [];\n list.push(item);\n map.set(group, list);\n });\n return map;\n}\n\n// TODO: Move source map modification to the serializer\nexport function getFilesFromSerialAssets(\n resources: SerialAsset[],\n {\n includeSourceMaps,\n files = new Map(),\n platform,\n isServerHosted = platform === 'web',\n }: {\n includeSourceMaps: boolean;\n files?: ExportAssetMap;\n platform?: string;\n isServerHosted?: boolean;\n }\n) {\n resources.forEach((resource) => {\n if (resource.type === 'css-external') {\n return;\n }\n files.set(resource.filename, {\n contents: resource.source,\n originFilename: resource.originFilename,\n targetDomain: isServerHosted ? 'client' : undefined,\n });\n });\n\n return files;\n}\n"],"names":["getFilesFromSerialAssets","persistMetroFilesAsync","BLT","files","outputDir","size","fs","promises","mkdir","path","join","recursive","assetEntries","apiRouteEntries","middlewareEntries","routeEntries","rscEntries","loaderEntries","remainingEntries","hasServerOutput","asset","entries","targetDomain","assetId","push","routeId","middlewareId","apiRouteId","rscId","loaderId","groups","groupBy","contentSize","contents","length","Buffer","byteLength","sizeStr","chalk","gray","prettyBytes","isExpoRouter","showAdditionalInfo","env","EXPO_DEBUG","assetGroups","sort","a","b","localeCompare","totalAssets","reduce","sum","assets","Log","log","bold","averageContentSize","filter","Boolean","bundles","Map","other","forEach","filepath","match","platform","has","set","get","allAssets","filePath","shift","sourceMapIndex","findIndex","fp","sourceMapFilePath","sourceMapAsset","splice","id","apiRoutesWithoutSourcemaps","route","endsWith","apiRouteFilename","hasSourceMap","find","filename","middlewareWithoutSourcemaps","middlewareFilename","loaderFilename","Promise","all","map","file","domain","outputPath","dirname","writeFile","array","key","item","group","list","resources","includeSourceMaps","isServerHosted","resource","type","source","originFilename","undefined"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/export/saveAssets.ts"],"sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport type { AssetData } from '@expo/metro/metro';\nimport type { SerialAsset } from '@expo/metro-config/build/serializer/serializerAssets';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport prettyBytes from 'pretty-bytes';\n\nimport { Log } from '../log';\nimport { env } from '../utils/env';\n\nconst BLT = '\\u203A';\n\nexport type BundleOptions = {\n entryPoint: string;\n platform: 'android' | 'ios' | 'web';\n dev?: boolean;\n minify?: boolean;\n bytecode: boolean;\n sourceMapUrl?: string;\n sourcemaps?: boolean;\n};\n\nexport type BundleAssetWithFileHashes = AssetData & {\n fileHashes: string[]; // added by the hashAssets asset plugin\n};\n\nexport type BundleOutput = {\n artifacts: SerialAsset[];\n assets: readonly BundleAssetWithFileHashes[];\n};\n\nexport type ManifestAsset = { fileHashes: string[]; files: string[]; hash: string };\n\nexport type Asset = ManifestAsset | BundleAssetWithFileHashes;\n\nexport type ExportAssetDescriptor = {\n contents: string | Buffer;\n originFilename?: string;\n /** An identifier for grouping together variations of the same asset. */\n assetId?: string;\n /** Expo Router route path for formatting the HTML output. */\n routeId?: string;\n /** Expo Router route path for formatting the middleware function output. */\n middlewareId?: string;\n /** Expo Router API route path for formatting the server function output. */\n apiRouteId?: string;\n /** Expo Router route path for formatting the RSC output. */\n rscId?: string;\n /** Expo Router route path for formatting the loader module output. */\n loaderId?: string;\n /** A key for grouping together output files by server- or client-side. */\n targetDomain?: 'server' | 'client';\n};\n\nexport type ExportAssetMap = Map<string, ExportAssetDescriptor>;\n\nexport async function persistMetroFilesAsync(files: ExportAssetMap, outputDir: string) {\n if (!files.size) {\n return;\n }\n await fs.promises.mkdir(path.join(outputDir), { recursive: true });\n\n // Test fixtures:\n // Log.log(\n // JSON.stringify(\n // Object.fromEntries([...files.entries()].map(([k, v]) => [k, { ...v, contents: '' }]))\n // )\n // );\n\n const assetEntries: [string, ExportAssetDescriptor][] = [];\n const apiRouteEntries: [string, ExportAssetDescriptor][] = [];\n const middlewareEntries: [string, ExportAssetDescriptor][] = [];\n const routeEntries: [string, ExportAssetDescriptor][] = [];\n const rscEntries: [string, ExportAssetDescriptor][] = [];\n const loaderEntries: [string, ExportAssetDescriptor][] = [];\n const remainingEntries: [string, ExportAssetDescriptor][] = [];\n\n let hasServerOutput = false;\n for (const asset of files.entries()) {\n hasServerOutput = hasServerOutput || asset[1].targetDomain === 'server';\n if (asset[1].assetId) assetEntries.push(asset);\n else if (asset[1].routeId != null) routeEntries.push(asset);\n else if (asset[1].middlewareId != null) middlewareEntries.push(asset);\n else if (asset[1].apiRouteId != null) apiRouteEntries.push(asset);\n else if (asset[1].rscId != null) rscEntries.push(asset);\n else if (asset[1].loaderId != null) loaderEntries.push(asset);\n else remainingEntries.push(asset);\n }\n\n const groups = groupBy(assetEntries, ([, { assetId }]) => assetId!);\n\n const contentSize = (contents: string | Buffer) => {\n const length =\n typeof contents === 'string' ? Buffer.byteLength(contents, 'utf8') : contents.length;\n return length;\n };\n\n const sizeStr = (contents: string | Buffer) => {\n const length = contentSize(contents);\n const size = chalk.gray`(${prettyBytes(length)})`;\n return size;\n };\n\n // TODO: If any Expo Router is used, then use a new style which is more simple:\n // `chalk.gray(/path/to/) + chalk.cyan('route')`\n // | index.html (1.2kb)\n // | /path\n // | other.html (1.2kb)\n\n const isExpoRouter = routeEntries.length;\n\n // Phase out printing all the assets as users can simply check the file system for more info.\n const showAdditionalInfo = !isExpoRouter || env.EXPO_DEBUG;\n\n const assetGroups = [...groups.entries()].sort((a, b) => a[0].localeCompare(b[0])) as [\n string,\n [string, ExportAssetDescriptor][],\n ][];\n\n if (showAdditionalInfo) {\n if (assetGroups.length) {\n const totalAssets = assetGroups.reduce((sum, [, assets]) => sum + assets.length, 0);\n\n Log.log('');\n Log.log(chalk.bold`${BLT} Assets (${totalAssets}):`);\n\n for (const [assetId, assets] of assetGroups) {\n const averageContentSize =\n assets.reduce((sum, [, { contents }]) => sum + contentSize(contents), 0) / assets.length;\n Log.log(\n assetId,\n chalk.gray(\n `(${[\n assets.length > 1 ? `${assets.length} variations` : '',\n `${prettyBytes(averageContentSize)}`,\n ]\n .filter(Boolean)\n .join(' | ')})`\n )\n );\n }\n }\n }\n\n const bundles: Map<string, [string, ExportAssetDescriptor][]> = new Map();\n const other: [string, ExportAssetDescriptor][] = [];\n\n remainingEntries.forEach(([filepath, asset]) => {\n if (!filepath.match(/_expo\\/(server|static)\\//)) {\n other.push([filepath, asset]);\n } else {\n const platform = filepath.match(/_expo\\/static\\/js\\/([^/]+)\\//)?.[1] ?? 'web';\n if (!bundles.has(platform)) bundles.set(platform, []);\n\n bundles.get(platform)!.push([filepath, asset]);\n }\n });\n\n [...bundles.entries()].forEach(([platform, assets]) => {\n Log.log('');\n Log.log(chalk.bold`${BLT} ${platform} bundles (${assets.length}):`);\n\n const allAssets = assets.sort((a, b) => a[0].localeCompare(b[0]));\n while (allAssets.length) {\n const [filePath, asset] = allAssets.shift()!;\n Log.log(filePath, sizeStr(asset.contents));\n if (filePath.match(/\\.(js|hbc)$/)) {\n // Get source map\n const sourceMapIndex = allAssets.findIndex(([fp]) => fp === filePath + '.map');\n if (sourceMapIndex !== -1) {\n const [sourceMapFilePath, sourceMapAsset] = allAssets.splice(sourceMapIndex, 1)[0];\n Log.log(chalk.gray(sourceMapFilePath), sizeStr(sourceMapAsset.contents));\n }\n }\n }\n });\n\n if (showAdditionalInfo && other.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} Files (${other.length}):`);\n\n for (const [filePath, asset] of other.sort((a, b) => a[0].localeCompare(b[0]))) {\n Log.log(filePath, sizeStr(asset.contents));\n }\n }\n\n if (rscEntries.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} React Server Components (${rscEntries.length}):`);\n\n for (const [filePath, assets] of rscEntries.sort((a, b) => a[0].length - b[0].length)) {\n const id = assets.rscId!;\n Log.log(\n '/' + (id === '' ? chalk.gray(' (index)') : id),\n sizeStr(assets.contents),\n chalk.gray(filePath)\n );\n }\n }\n\n if (routeEntries.length) {\n Log.log('');\n Log.log(chalk.bold`${BLT} Static routes (${routeEntries.length}):`);\n\n for (const [, assets] of routeEntries.sort((a, b) => a[0].length - b[0].length)) {\n const id = assets.routeId!;\n Log.log('/' + (id === '' ? chalk.gray(' (index)') : id), sizeStr(assets.contents));\n }\n }\n\n if (apiRouteEntries.length) {\n const apiRoutesWithoutSourcemaps = apiRouteEntries.filter(\n (route) => !route[0].endsWith('.map')\n );\n Log.log('');\n Log.log(chalk.bold`${BLT} API routes (${apiRoutesWithoutSourcemaps.length}):`);\n\n for (const [apiRouteFilename, assets] of apiRoutesWithoutSourcemaps.sort(\n (a, b) => a[0].length - b[0].length\n )) {\n const id = assets.apiRouteId!;\n const hasSourceMap = apiRouteEntries.find(\n ([filename, route]) =>\n filename !== apiRouteFilename &&\n route.apiRouteId === assets.apiRouteId &&\n filename.endsWith('.map')\n );\n Log.log(\n id === '' ? chalk.gray(' (index)') : id,\n sizeStr(assets.contents),\n hasSourceMap ? chalk.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : ''\n );\n }\n }\n\n if (middlewareEntries.length) {\n const middlewareWithoutSourcemaps = middlewareEntries.filter(\n (route) => !route[0].endsWith('.map')\n );\n Log.log('');\n Log.log(chalk.bold`${BLT} Middleware:`);\n\n for (const [middlewareFilename, assets] of middlewareWithoutSourcemaps.sort(\n (a, b) => a[0].length - b[0].length\n )) {\n const id = assets.middlewareId!;\n const hasSourceMap = middlewareEntries.find(\n ([filename, route]) =>\n filename !== middlewareFilename &&\n route.middlewareId === assets.middlewareId &&\n filename.endsWith('.map')\n );\n Log.log(\n id,\n sizeStr(assets.contents),\n hasSourceMap ? chalk.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : ''\n );\n }\n }\n\n if (loaderEntries.length) {\n const loadersWithoutSourcemaps = loaderEntries.filter((entry) => !entry[0].endsWith('.map'));\n Log.log('');\n Log.log(chalk.bold`${BLT} Loaders (${loadersWithoutSourcemaps.length}):`);\n\n for (const [loaderFilename, assets] of loadersWithoutSourcemaps.sort(\n (a, b) => a[0].length - b[0].length\n )) {\n const id = assets.loaderId!;\n const hasSourceMap = loaderEntries.find(\n ([filename, entry]) =>\n filename !== loaderFilename &&\n entry.loaderId === assets.loaderId &&\n filename.endsWith('.map')\n );\n Log.log(\n id === '/' ? '/ ' + chalk.gray('(index)') : id,\n sizeStr(assets.contents),\n hasSourceMap ? chalk.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : ''\n );\n }\n }\n\n // Decouple logging from writing for better performance.\n\n await Promise.all(\n [...files.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(async ([file, { contents, targetDomain }]) => {\n // NOTE: Only use `targetDomain` if we have at least one server asset\n const domain = (hasServerOutput && targetDomain) || '';\n const outputPath = path.join(outputDir, domain, file);\n await fs.promises.mkdir(path.dirname(outputPath), { recursive: true });\n await fs.promises.writeFile(outputPath, contents);\n })\n );\n\n Log.log('');\n}\n\nfunction groupBy<T>(array: T[], key: (item: T) => string): Map<string, T[]> {\n const map = new Map<string, T[]>();\n array.forEach((item) => {\n const group = key(item);\n const list = map.get(group) ?? [];\n list.push(item);\n map.set(group, list);\n });\n return map;\n}\n\n// TODO: Move source map modification to the serializer\nexport function getFilesFromSerialAssets(\n resources: SerialAsset[],\n {\n includeSourceMaps,\n files = new Map(),\n platform,\n isServerHosted = platform === 'web',\n }: {\n includeSourceMaps: boolean;\n files?: ExportAssetMap;\n platform?: string;\n isServerHosted?: boolean;\n }\n) {\n resources.forEach((resource) => {\n if (resource.type === 'css-external') {\n return;\n }\n files.set(resource.filename, {\n contents: resource.source,\n originFilename: resource.originFilename,\n targetDomain: isServerHosted ? 'client' : undefined,\n });\n });\n\n return files;\n}\n"],"names":["getFilesFromSerialAssets","persistMetroFilesAsync","BLT","files","outputDir","size","fs","promises","mkdir","path","join","recursive","assetEntries","apiRouteEntries","middlewareEntries","routeEntries","rscEntries","loaderEntries","remainingEntries","hasServerOutput","asset","entries","targetDomain","assetId","push","routeId","middlewareId","apiRouteId","rscId","loaderId","groups","groupBy","contentSize","contents","length","Buffer","byteLength","sizeStr","chalk","gray","prettyBytes","isExpoRouter","showAdditionalInfo","env","EXPO_DEBUG","assetGroups","sort","a","b","localeCompare","totalAssets","reduce","sum","assets","Log","log","bold","averageContentSize","filter","Boolean","bundles","Map","other","forEach","filepath","match","platform","has","set","get","allAssets","filePath","shift","sourceMapIndex","findIndex","fp","sourceMapFilePath","sourceMapAsset","splice","id","apiRoutesWithoutSourcemaps","route","endsWith","apiRouteFilename","hasSourceMap","find","filename","middlewareWithoutSourcemaps","middlewareFilename","loadersWithoutSourcemaps","entry","loaderFilename","Promise","all","map","file","domain","outputPath","dirname","writeFile","array","key","item","group","list","resources","includeSourceMaps","isServerHosted","resource","type","source","originFilename","undefined"],"mappings":"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"}
|
|
@@ -179,7 +179,6 @@ class DevServerManagerActions {
|
|
|
179
179
|
});
|
|
180
180
|
const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();
|
|
181
181
|
const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();
|
|
182
|
-
_log.log();
|
|
183
182
|
const menuItems = [
|
|
184
183
|
...defaultMenuItems,
|
|
185
184
|
...(0, _createDevToolsMenuItems.createDevToolsMenuItems)(plugins, defaultServerUrl, metroServerOrigin)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { BLT, printHelp, printItem, printQRCode, printUsage, StartOptions } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport { openBrowserAsync } from '../../utils/open';\nimport { ExpoChoice, selectAsync } from '../../utils/prompts';\nimport { DevServerManager } from '../server/DevServerManager';\nimport {\n openJsInspector,\n queryAllInspectorAppsAsync,\n promptInspectorAppAsync,\n} from '../server/middleware/inspector/JsInspector';\n\nconst debug = require('debug')('expo:start:interface:interactiveActions') as typeof console.log;\n\ninterface MoreToolMenuItem extends ExpoChoice<string> {\n action?: () => unknown;\n}\n\n/** Wraps the DevServerManager and adds an interface for user actions. */\nexport class DevServerManagerActions {\n constructor(\n private devServerManager: DevServerManager,\n private options: Pick<StartOptions, 'devClient' | 'platforms'>\n ) {}\n\n printDevServerInfo(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>\n ) {\n // If native dev server is running, print its URL.\n if (this.devServerManager.getNativeDevServerPort()) {\n const devServer = this.devServerManager.getDefaultDevServer();\n try {\n const nativeRuntimeUrl = devServer.getNativeRuntimeUrl()!;\n const interstitialPageUrl = devServer.getRedirectUrl();\n\n printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n\n if (interstitialPageUrl) {\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n }\n\n Log.log(printItem(chalk`Metro waiting on {underline ${nativeRuntimeUrl}}`));\n if (options.devClient === false) {\n // TODO: if development build, change this message!\n Log.log(printItem('Scan the QR code above to open the project in Expo Go.'));\n } else {\n Log.log(\n printItem(\n 'Scan the QR code above to open the project in a development build. ' +\n learnMore('https://expo.fyi/start')\n )\n );\n }\n } catch (error) {\n console.log('err', error);\n // @ts-ignore: If there is no development build scheme, then skip the QR code.\n if (error.code !== 'NO_DEV_CLIENT_SCHEME') {\n throw error;\n } else {\n const serverUrl = devServer.getDevServerUrl();\n Log.log(printItem(chalk`Metro waiting on {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\n }\n }\n }\n\n if (this.options.platforms?.includes('web')) {\n const webDevServer = this.devServerManager.getWebDevServer();\n const webUrl = webDevServer?.getDevServerUrl({ hostType: 'localhost' });\n if (webUrl) {\n Log.log();\n Log.log(printItem(chalk`Web is waiting on {underline ${webUrl}}`));\n }\n }\n\n printUsage(options, { verbose: false });\n printHelp();\n Log.log();\n }\n\n async openJsInspectorAsync() {\n try {\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n if (!apps.length) {\n return Log.warn(\n chalk`{bold Debug:} No compatible apps connected, React Native DevTools can only be used with Hermes. ${learnMore(\n 'https://docs.expo.dev/guides/using-hermes/'\n )}`\n );\n }\n\n const app = await promptInspectorAppAsync(apps);\n if (!app) {\n return Log.error(chalk`{bold Debug:} No inspectable device selected`);\n }\n\n if (!(await openJsInspector(metroServerOrigin, app))) {\n Log.warn(\n chalk`{bold Debug:} Failed to open the React Native DevTools, see debug logs for more info.`\n );\n }\n } catch (error: any) {\n // Handle aborting prompt\n if (error.code === 'ABORTED') return;\n\n Log.error('Failed to open the React Native DevTools.');\n Log.exception(error);\n }\n }\n\n reloadApp() {\n Log.log(`${BLT} Reloading apps`);\n // Send reload requests over the dev servers\n this.devServerManager.broadcastMessage('reload');\n }\n\n async openMoreToolsAsync() {\n // Options match: Chrome > View > Developer\n try {\n const defaultMenuItems: MoreToolMenuItem[] = [\n { title: 'Inspect elements', value: 'toggleElementInspector' },\n { title: 'Toggle performance monitor', value: 'togglePerformanceMonitor' },\n { title: 'Toggle developer menu', value: 'toggleDevMenu' },\n { title: 'Reload app', value: 'reload' },\n // TODO: Maybe a \"View Source\" option to open code.\n ];\n\n const defaultServerUrl = this.devServerManager\n .getDefaultDevServer()\n .getUrlCreator()\n .constructUrl({ scheme: 'http' });\n\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();\n Log.log();\n const menuItems = [\n ...defaultMenuItems,\n ...createDevToolsMenuItems(plugins, defaultServerUrl, metroServerOrigin),\n ];\n\n const value = await selectAsync(chalk`Dev tools {dim (native only)}`, menuItems);\n const menuItem = menuItems.find((item) => item.value === value);\n if (menuItem?.action) {\n menuItem.action();\n } else if (menuItem?.value) {\n this.devServerManager.broadcastMessage('sendDevCommand', { name: menuItem.value });\n }\n } catch (error: any) {\n debug(error);\n // do nothing\n } finally {\n printHelp();\n }\n }\n\n toggleDevMenu() {\n Log.log(`${BLT} Toggling dev menu`);\n this.devServerManager.broadcastMessage('devMenu');\n }\n}\n"],"names":["DevServerManagerActions","debug","require","constructor","devServerManager","options","printDevServerInfo","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","printQRCode","Log","log","printItem","chalk","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","devClient","learnMore","error","code","serverUrl","platforms","includes","webDevServer","getWebDevServer","webUrl","hostType","printUsage","verbose","printHelp","openJsInspectorAsync","metroServerOrigin","getJsInspectorBaseUrl","apps","queryAllInspectorAppsAsync","length","warn","app","promptInspectorAppAsync","openJsInspector","exception","reloadApp","BLT","broadcastMessage","openMoreToolsAsync","defaultMenuItems","title","value","defaultServerUrl","getUrlCreator","constructUrl","scheme","plugins","devtoolsPluginManager","queryPluginsAsync","menuItems","createDevToolsMenuItems","selectAsync","menuItem","find","item","action","name","toggleDevMenu"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/interface/interactiveActions.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { BLT, printHelp, printItem, printQRCode, printUsage, StartOptions } from './commandsTable';\nimport { createDevToolsMenuItems } from './createDevToolsMenuItems';\nimport * as Log from '../../log';\nimport { env } from '../../utils/env';\nimport { learnMore } from '../../utils/link';\nimport { openBrowserAsync } from '../../utils/open';\nimport { ExpoChoice, selectAsync } from '../../utils/prompts';\nimport { DevServerManager } from '../server/DevServerManager';\nimport {\n openJsInspector,\n queryAllInspectorAppsAsync,\n promptInspectorAppAsync,\n} from '../server/middleware/inspector/JsInspector';\n\nconst debug = require('debug')('expo:start:interface:interactiveActions') as typeof console.log;\n\ninterface MoreToolMenuItem extends ExpoChoice<string> {\n action?: () => unknown;\n}\n\n/** Wraps the DevServerManager and adds an interface for user actions. */\nexport class DevServerManagerActions {\n constructor(\n private devServerManager: DevServerManager,\n private options: Pick<StartOptions, 'devClient' | 'platforms'>\n ) {}\n\n printDevServerInfo(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>\n ) {\n // If native dev server is running, print its URL.\n if (this.devServerManager.getNativeDevServerPort()) {\n const devServer = this.devServerManager.getDefaultDevServer();\n try {\n const nativeRuntimeUrl = devServer.getNativeRuntimeUrl()!;\n const interstitialPageUrl = devServer.getRedirectUrl();\n\n printQRCode(interstitialPageUrl ?? nativeRuntimeUrl);\n\n if (interstitialPageUrl) {\n Log.log(\n printItem(\n chalk`Choose an app to open your project at {underline ${interstitialPageUrl}}`\n )\n );\n }\n\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(\n `[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: devServer.getDevServerUrl() })}`\n );\n }\n\n Log.log(printItem(chalk`Metro waiting on {underline ${nativeRuntimeUrl}}`));\n if (options.devClient === false) {\n // TODO: if development build, change this message!\n Log.log(printItem('Scan the QR code above to open the project in Expo Go.'));\n } else {\n Log.log(\n printItem(\n 'Scan the QR code above to open the project in a development build. ' +\n learnMore('https://expo.fyi/start')\n )\n );\n }\n } catch (error) {\n console.log('err', error);\n // @ts-ignore: If there is no development build scheme, then skip the QR code.\n if (error.code !== 'NO_DEV_CLIENT_SCHEME') {\n throw error;\n } else {\n const serverUrl = devServer.getDevServerUrl();\n Log.log(printItem(chalk`Metro waiting on {underline ${serverUrl}}`));\n Log.log(printItem(`Linking is disabled because the client scheme cannot be resolved.`));\n }\n }\n }\n\n if (this.options.platforms?.includes('web')) {\n const webDevServer = this.devServerManager.getWebDevServer();\n const webUrl = webDevServer?.getDevServerUrl({ hostType: 'localhost' });\n if (webUrl) {\n Log.log();\n Log.log(printItem(chalk`Web is waiting on {underline ${webUrl}}`));\n }\n }\n\n printUsage(options, { verbose: false });\n printHelp();\n Log.log();\n }\n\n async openJsInspectorAsync() {\n try {\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const apps = await queryAllInspectorAppsAsync(metroServerOrigin);\n if (!apps.length) {\n return Log.warn(\n chalk`{bold Debug:} No compatible apps connected, React Native DevTools can only be used with Hermes. ${learnMore(\n 'https://docs.expo.dev/guides/using-hermes/'\n )}`\n );\n }\n\n const app = await promptInspectorAppAsync(apps);\n if (!app) {\n return Log.error(chalk`{bold Debug:} No inspectable device selected`);\n }\n\n if (!(await openJsInspector(metroServerOrigin, app))) {\n Log.warn(\n chalk`{bold Debug:} Failed to open the React Native DevTools, see debug logs for more info.`\n );\n }\n } catch (error: any) {\n // Handle aborting prompt\n if (error.code === 'ABORTED') return;\n\n Log.error('Failed to open the React Native DevTools.');\n Log.exception(error);\n }\n }\n\n reloadApp() {\n Log.log(`${BLT} Reloading apps`);\n // Send reload requests over the dev servers\n this.devServerManager.broadcastMessage('reload');\n }\n\n async openMoreToolsAsync() {\n // Options match: Chrome > View > Developer\n try {\n const defaultMenuItems: MoreToolMenuItem[] = [\n { title: 'Inspect elements', value: 'toggleElementInspector' },\n { title: 'Toggle performance monitor', value: 'togglePerformanceMonitor' },\n { title: 'Toggle developer menu', value: 'toggleDevMenu' },\n { title: 'Reload app', value: 'reload' },\n // TODO: Maybe a \"View Source\" option to open code.\n ];\n\n const defaultServerUrl = this.devServerManager\n .getDefaultDevServer()\n .getUrlCreator()\n .constructUrl({ scheme: 'http' });\n\n const metroServerOrigin = this.devServerManager.getDefaultDevServer().getJsInspectorBaseUrl();\n const plugins = await this.devServerManager.devtoolsPluginManager.queryPluginsAsync();\n\n const menuItems = [\n ...defaultMenuItems,\n ...createDevToolsMenuItems(plugins, defaultServerUrl, metroServerOrigin),\n ];\n\n const value = await selectAsync(chalk`Dev tools {dim (native only)}`, menuItems);\n const menuItem = menuItems.find((item) => item.value === value);\n if (menuItem?.action) {\n menuItem.action();\n } else if (menuItem?.value) {\n this.devServerManager.broadcastMessage('sendDevCommand', { name: menuItem.value });\n }\n } catch (error: any) {\n debug(error);\n // do nothing\n } finally {\n printHelp();\n }\n }\n\n toggleDevMenu() {\n Log.log(`${BLT} Toggling dev menu`);\n this.devServerManager.broadcastMessage('devMenu');\n }\n}\n"],"names":["DevServerManagerActions","debug","require","constructor","devServerManager","options","printDevServerInfo","getNativeDevServerPort","devServer","getDefaultDevServer","nativeRuntimeUrl","getNativeRuntimeUrl","interstitialPageUrl","getRedirectUrl","printQRCode","Log","log","printItem","chalk","env","__EXPO_E2E_TEST","console","info","JSON","stringify","url","getDevServerUrl","devClient","learnMore","error","code","serverUrl","platforms","includes","webDevServer","getWebDevServer","webUrl","hostType","printUsage","verbose","printHelp","openJsInspectorAsync","metroServerOrigin","getJsInspectorBaseUrl","apps","queryAllInspectorAppsAsync","length","warn","app","promptInspectorAppAsync","openJsInspector","exception","reloadApp","BLT","broadcastMessage","openMoreToolsAsync","defaultMenuItems","title","value","defaultServerUrl","getUrlCreator","constructUrl","scheme","plugins","devtoolsPluginManager","queryPluginsAsync","menuItems","createDevToolsMenuItems","selectAsync","menuItem","find","item","action","name","toggleDevMenu"],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "Bonjour", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return Bonjour;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
function _config() {
|
|
12
|
+
const data = require("@expo/config");
|
|
13
|
+
_config = function() {
|
|
14
|
+
return data;
|
|
15
|
+
};
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
const _env = require("../../utils/env");
|
|
19
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
20
|
+
if (typeof WeakMap !== "function") return null;
|
|
21
|
+
var cacheBabelInterop = new WeakMap();
|
|
22
|
+
var cacheNodeInterop = new WeakMap();
|
|
23
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
24
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
25
|
+
})(nodeInterop);
|
|
26
|
+
}
|
|
27
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
28
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
32
|
+
return {
|
|
33
|
+
default: obj
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
37
|
+
if (cache && cache.has(obj)) {
|
|
38
|
+
return cache.get(obj);
|
|
39
|
+
}
|
|
40
|
+
var newObj = {
|
|
41
|
+
__proto__: null
|
|
42
|
+
};
|
|
43
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
44
|
+
for(var key in obj){
|
|
45
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
46
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
47
|
+
if (desc && (desc.get || desc.set)) {
|
|
48
|
+
Object.defineProperty(newObj, key, desc);
|
|
49
|
+
} else {
|
|
50
|
+
newObj[key] = obj[key];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
newObj.default = obj;
|
|
55
|
+
if (cache) {
|
|
56
|
+
cache.set(obj, newObj);
|
|
57
|
+
}
|
|
58
|
+
return newObj;
|
|
59
|
+
}
|
|
60
|
+
const debug = require('debug')('expo:start:server:bonjour');
|
|
61
|
+
class Bonjour {
|
|
62
|
+
constructor(/** Project root directory */ projectRoot, /** Port to advertise, if any */ port){
|
|
63
|
+
this.projectRoot = projectRoot;
|
|
64
|
+
this.port = port;
|
|
65
|
+
}
|
|
66
|
+
async announceAsync({ exp = (0, _config().getConfig)(this.projectRoot).exp }) {
|
|
67
|
+
if (_env.env.CI || !_env.env.EXPO_UNSTABLE_BONJOUR) {
|
|
68
|
+
return;
|
|
69
|
+
} else if (!this.port) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const dnssd = await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("dnssd-advertise")));
|
|
73
|
+
if (this.stopAdvertising) {
|
|
74
|
+
await this.stopAdvertising();
|
|
75
|
+
}
|
|
76
|
+
debug('Started Bonjour service');
|
|
77
|
+
this.stopAdvertising = dnssd.advertise({
|
|
78
|
+
name: `${exp.name}`,
|
|
79
|
+
type: 'expo',
|
|
80
|
+
protocol: 'tcp',
|
|
81
|
+
hostname: exp.slug,
|
|
82
|
+
port: this.port,
|
|
83
|
+
txt: {
|
|
84
|
+
slug: exp.slug
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async closeAsync() {
|
|
89
|
+
if (!this.stopAdvertising) {
|
|
90
|
+
return false;
|
|
91
|
+
} else {
|
|
92
|
+
debug('Stopped Bonjour service');
|
|
93
|
+
await (this.stopAdvertising == null ? void 0 : this.stopAdvertising.call(this));
|
|
94
|
+
this.stopAdvertising = undefined;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//# sourceMappingURL=Bonjour.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/Bonjour.ts"],"sourcesContent":["import { ExpoConfig, getConfig } from '@expo/config';\n\nimport { env } from '../../utils/env';\n\nconst debug = require('debug')('expo:start:server:bonjour') as typeof console.log;\n\nexport class Bonjour {\n private stopAdvertising?: () => Promise<void>;\n\n constructor(\n /** Project root directory */\n private projectRoot: string,\n /** Port to advertise, if any */\n private port: number | undefined\n ) {}\n\n public async announceAsync({\n exp = getConfig(this.projectRoot).exp,\n }: {\n exp?: Pick<ExpoConfig, 'name' | 'description' | 'slug' | 'primaryColor'>;\n }) {\n if (env.CI || !env.EXPO_UNSTABLE_BONJOUR) {\n return;\n } else if (!this.port) {\n return;\n }\n\n const dnssd: typeof import('dnssd-advertise') = await import('dnssd-advertise');\n if (this.stopAdvertising) {\n await this.stopAdvertising();\n }\n\n debug('Started Bonjour service');\n this.stopAdvertising = dnssd.advertise({\n name: `${exp.name}`,\n type: 'expo',\n protocol: 'tcp',\n hostname: exp.slug,\n port: this.port,\n txt: {\n slug: exp.slug,\n },\n });\n }\n\n public async closeAsync(): Promise<boolean> {\n if (!this.stopAdvertising) {\n return false;\n } else {\n debug('Stopped Bonjour service');\n await this.stopAdvertising?.();\n this.stopAdvertising = undefined;\n return true;\n }\n }\n}\n"],"names":["Bonjour","debug","require","constructor","projectRoot","port","announceAsync","exp","getConfig","env","CI","EXPO_UNSTABLE_BONJOUR","dnssd","stopAdvertising","advertise","name","type","protocol","hostname","slug","txt","closeAsync","undefined"],"mappings":";;;;+BAMaA;;;eAAAA;;;;yBANyB;;;;;;qBAElB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEpB,MAAMC,QAAQC,QAAQ,SAAS;AAExB,MAAMF;IAGXG,YACE,2BAA2B,GAC3B,AAAQC,WAAmB,EAC3B,8BAA8B,GAC9B,AAAQC,IAAwB,CAChC;aAHQD,cAAAA;aAEAC,OAAAA;IACP;IAEH,MAAaC,cAAc,EACzBC,MAAMC,IAAAA,mBAAS,EAAC,IAAI,CAACJ,WAAW,EAAEG,GAAG,EAGtC,EAAE;QACD,IAAIE,QAAG,CAACC,EAAE,IAAI,CAACD,QAAG,CAACE,qBAAqB,EAAE;YACxC;QACF,OAAO,IAAI,CAAC,IAAI,CAACN,IAAI,EAAE;YACrB;QACF;QAEA,MAAMO,QAA0C,MAAM,mEAAA,QAAO;QAC7D,IAAI,IAAI,CAACC,eAAe,EAAE;YACxB,MAAM,IAAI,CAACA,eAAe;QAC5B;QAEAZ,MAAM;QACN,IAAI,CAACY,eAAe,GAAGD,MAAME,SAAS,CAAC;YACrCC,MAAM,GAAGR,IAAIQ,IAAI,EAAE;YACnBC,MAAM;YACNC,UAAU;YACVC,UAAUX,IAAIY,IAAI;YAClBd,MAAM,IAAI,CAACA,IAAI;YACfe,KAAK;gBACHD,MAAMZ,IAAIY,IAAI;YAChB;QACF;IACF;IAEA,MAAaE,aAA+B;QAC1C,IAAI,CAAC,IAAI,CAACR,eAAe,EAAE;YACzB,OAAO;QACT,OAAO;YACLZ,MAAM;YACN,OAAM,IAAI,CAACY,eAAe,oBAApB,IAAI,CAACA,eAAe,MAApB,IAAI;YACV,IAAI,CAACA,eAAe,GAAGS;YACvB,OAAO;QACT;IACF;AACF"}
|
|
@@ -24,6 +24,7 @@ function _resolvefrom() {
|
|
|
24
24
|
}
|
|
25
25
|
const _AsyncNgrok = require("./AsyncNgrok");
|
|
26
26
|
const _AsyncWsTunnel = require("./AsyncWsTunnel");
|
|
27
|
+
const _Bonjour = require("./Bonjour");
|
|
27
28
|
const _DevToolsPluginManager = /*#__PURE__*/ _interop_require_default(require("./DevToolsPluginManager"));
|
|
28
29
|
const _DevelopmentSession = require("./DevelopmentSession");
|
|
29
30
|
const _UrlCreator = require("./UrlCreator");
|
|
@@ -90,6 +91,7 @@ class BundlerDevServer {
|
|
|
90
91
|
this.platformBundlers = platformBundlers;
|
|
91
92
|
this.tunnel = null;
|
|
92
93
|
this.devSession = null;
|
|
94
|
+
this.bonjour = null;
|
|
93
95
|
this.instance = null;
|
|
94
96
|
this.platformManagers = {};
|
|
95
97
|
this.urlCreator = null;
|
|
@@ -173,7 +175,10 @@ class BundlerDevServer {
|
|
|
173
175
|
await this._startTunnelAsync();
|
|
174
176
|
}
|
|
175
177
|
if (!options.isExporting) {
|
|
176
|
-
await
|
|
178
|
+
await Promise.all([
|
|
179
|
+
this.startDevSessionAsync(),
|
|
180
|
+
this.startBonjourAsync()
|
|
181
|
+
]);
|
|
177
182
|
this.watchConfig();
|
|
178
183
|
}
|
|
179
184
|
}
|
|
@@ -203,6 +208,15 @@ class BundlerDevServer {
|
|
|
203
208
|
runtime: this.isTargetingNative() ? 'native' : 'web'
|
|
204
209
|
});
|
|
205
210
|
}
|
|
211
|
+
async startBonjourAsync() {
|
|
212
|
+
// This is used to make Expo Go open the project in either Expo Go, or the web browser.
|
|
213
|
+
// Must come after ngrok (`startTunnelAsync`) setup.
|
|
214
|
+
if (!this.bonjour) {
|
|
215
|
+
var _this_getInstance;
|
|
216
|
+
this.bonjour = new _Bonjour.Bonjour(this.projectRoot, (_this_getInstance = this.getInstance()) == null ? void 0 : _this_getInstance.location.port);
|
|
217
|
+
}
|
|
218
|
+
await this.bonjour.announceAsync({});
|
|
219
|
+
}
|
|
206
220
|
isTargetingNative() {
|
|
207
221
|
// Temporary hack while we implement multi-bundler dev server proxy.
|
|
208
222
|
return true;
|
|
@@ -225,10 +239,14 @@ class BundlerDevServer {
|
|
|
225
239
|
}
|
|
226
240
|
/** Stop the running dev server instance. */ async stopAsync() {
|
|
227
241
|
var // Stop file watching.
|
|
228
|
-
_this_notifier,
|
|
242
|
+
_this_notifier, // Stop the bonjour advertiser
|
|
243
|
+
_this_bonjour, // Stop the dev session timer and tell Expo API to remove dev session.
|
|
244
|
+
_this_devSession, _this_tunnel;
|
|
229
245
|
(_this_notifier = this.notifier) == null ? void 0 : _this_notifier.stopObserving();
|
|
230
|
-
|
|
231
|
-
|
|
246
|
+
await Promise.all([
|
|
247
|
+
(_this_bonjour = this.bonjour) == null ? void 0 : _this_bonjour.closeAsync(),
|
|
248
|
+
(_this_devSession = this.devSession) == null ? void 0 : _this_devSession.closeAsync()
|
|
249
|
+
]);
|
|
232
250
|
// Stop tunnel if running.
|
|
233
251
|
await ((_this_tunnel = this.tunnel) == null ? void 0 : _this_tunnel.stopAsync().catch((e)=>{
|
|
234
252
|
_log.error(`Error stopping tunnel:`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/server/BundlerDevServer.ts"],"sourcesContent":["import assert from 'assert';\nimport resolveFrom from 'resolve-from';\n\nimport { AsyncNgrok } from './AsyncNgrok';\nimport { AsyncWsTunnel } from './AsyncWsTunnel';\nimport DevToolsPluginManager from './DevToolsPluginManager';\nimport { DevelopmentSession } from './DevelopmentSession';\nimport { CreateURLOptions, UrlCreator } from './UrlCreator';\nimport { PlatformBundlers } from './platformBundlers';\nimport * as Log from '../../log';\nimport { FileNotifier } from '../../utils/FileNotifier';\nimport { resolveWithTimeout } from '../../utils/delay';\nimport { env, envIsWebcontainer } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { openBrowserAsync } from '../../utils/open';\nimport {\n BaseOpenInCustomProps,\n BaseResolveDeviceProps,\n PlatformManager,\n} from '../platforms/PlatformManager';\n\nconst debug = require('debug')('expo:start:server:devServer') as typeof console.log;\n\nexport type MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\nexport type ServerLike = {\n close(callback?: (err?: Error) => void): void;\n addListener?(event: string, listener: (...args: any[]) => void): unknown;\n};\n\nexport type DevServerInstance = {\n /** Bundler dev server instance. */\n server: ServerLike;\n /** Dev server URL location properties. */\n location: {\n url: string;\n port: number;\n protocol: 'http' | 'https';\n host?: string;\n };\n /** Additional middleware that's attached to the `server`. */\n middleware: any;\n /** Message socket for communicating with the runtime. */\n messageSocket: MessageSocket;\n};\n\nexport interface BundlerStartOptions {\n /** Should the dev server use `https` protocol. */\n https?: boolean;\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Is dev client enabled. */\n devClient?: boolean;\n /** Should run dev servers with clean caches. */\n resetDevServer?: boolean;\n /** Code signing private key path (defaults to same directory as certificate) */\n privateKeyPath?: string;\n\n /** Max amount of workers (threads) to use with Metro bundler, defaults to undefined for max workers. */\n maxWorkers?: number;\n /** Port to start the dev server on. */\n port?: number;\n\n /** Should start a headless dev server e.g. mock representation to approximate info from a server running in a different process. */\n headless?: boolean;\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n\n /** Will the bundler be used for exporting. NOTE: This is an odd option to pass to the dev server. */\n isExporting?: boolean;\n\n // Webpack options\n /** Should modify and create PWA icons. */\n isImageEditingEnabled?: boolean;\n\n location: CreateURLOptions;\n}\n\nconst PLATFORM_MANAGERS = {\n simulator: () =>\n require('../platforms/ios/ApplePlatformManager')\n .ApplePlatformManager as typeof import('../platforms/ios/ApplePlatformManager').ApplePlatformManager,\n emulator: () =>\n require('../platforms/android/AndroidPlatformManager')\n .AndroidPlatformManager as typeof import('../platforms/android/AndroidPlatformManager').AndroidPlatformManager,\n};\n\nexport abstract class BundlerDevServer {\n /** Name of the bundler. */\n abstract get name(): string;\n\n /** Tunnel instance for managing tunnel connections. */\n protected tunnel: AsyncNgrok | AsyncWsTunnel | null = null;\n /** Interfaces with the Expo 'Development Session' API. */\n protected devSession: DevelopmentSession | null = null;\n /** Http server and related info. */\n protected instance: DevServerInstance | null = null;\n /** Native platform interfaces for opening projects. */\n private platformManagers: Record<string, PlatformManager<any>> = {};\n /** Manages the creation of dev server URLs. */\n protected urlCreator?: UrlCreator | null = null;\n\n private notifier: FileNotifier | null = null;\n protected readonly devToolsPluginManager: DevToolsPluginManager;\n public isDevClient: boolean;\n\n constructor(\n /** Project root folder. */\n public projectRoot: string,\n /** A mapping of bundlers to platforms. */\n public platformBundlers: PlatformBundlers,\n /** Advanced options */\n options?: {\n /**\n * The instance of DevToolsPluginManager\n * @default new DevToolsPluginManager(projectRoot)\n */\n devToolsPluginManager?: DevToolsPluginManager;\n // TODO: Replace with custom scheme maybe...\n isDevClient?: boolean;\n }\n ) {\n this.devToolsPluginManager =\n options?.devToolsPluginManager ?? new DevToolsPluginManager(projectRoot);\n this.isDevClient = options?.isDevClient ?? false;\n }\n\n protected setInstance(instance: DevServerInstance) {\n this.instance = instance;\n }\n\n /** Get the manifest middleware function. */\n protected async getManifestMiddlewareAsync(\n options: Pick<BundlerStartOptions, 'minify' | 'mode' | 'privateKeyPath'> = {}\n ) {\n const Middleware = require('./middleware/ExpoGoManifestHandlerMiddleware')\n .ExpoGoManifestHandlerMiddleware as typeof import('./middleware/ExpoGoManifestHandlerMiddleware').ExpoGoManifestHandlerMiddleware;\n\n const urlCreator = this.getUrlCreator();\n const middleware = new Middleware(this.projectRoot, {\n constructUrl: urlCreator.constructUrl.bind(urlCreator),\n mode: options.mode,\n minify: options.minify,\n isNativeWebpack: this.name === 'webpack' && this.isTargetingNative(),\n privateKeyPath: options.privateKeyPath,\n });\n return middleware;\n }\n\n /** Start the dev server using settings defined in the start command. */\n public async startAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n await this.stopAsync();\n\n let instance: DevServerInstance;\n if (options.headless) {\n instance = await this.startHeadlessAsync(options);\n } else {\n instance = await this.startImplementationAsync(options);\n }\n\n this.setInstance(instance);\n await this.postStartAsync(options);\n return instance;\n }\n\n protected abstract startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance>;\n\n public async waitForTypeScriptAsync(): Promise<boolean> {\n return false;\n }\n\n public abstract startTypeScriptServices(): Promise<void>;\n\n public async watchEnvironmentVariables(): Promise<void> {\n // noop -- We've only implemented this functionality in Metro.\n }\n\n /**\n * Creates a mock server representation that can be used to estimate URLs for a server started in another process.\n * This is used for the run commands where you can reuse the server from a previous run.\n */\n private async startHeadlessAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n if (!options.port)\n throw new CommandError('HEADLESS_SERVER', 'headless dev server requires a port option');\n this.urlCreator = this.getUrlCreator(options);\n\n return {\n // Create a mock server\n server: {\n close: (callback: () => void) => {\n this.instance = null;\n callback?.();\n },\n addListener() {},\n },\n location: {\n // The port is the main thing we want to send back.\n port: options.port,\n // localhost isn't always correct.\n host: 'localhost',\n // http is the only supported protocol on native.\n url: `http://localhost:${options.port}`,\n protocol: 'http',\n },\n middleware: {},\n messageSocket: {\n broadcast: () => {\n throw new CommandError('HEADLESS_SERVER', 'Cannot broadcast messages to headless server');\n },\n },\n };\n }\n\n /**\n * Runs after the `startAsync` function, performing any additional common operations.\n * You can assume the dev server is started by the time this function is called.\n */\n protected async postStartAsync(options: BundlerStartOptions) {\n if (\n options.location.hostType === 'tunnel' &&\n !env.EXPO_OFFLINE &&\n // This is a hack to prevent using tunnel on web since we block it upstream for some reason.\n this.isTargetingNative()\n ) {\n await this._startTunnelAsync();\n } else if (envIsWebcontainer()) {\n await this._startTunnelAsync();\n }\n\n if (!options.isExporting) {\n await this.startDevSessionAsync();\n this.watchConfig();\n }\n }\n\n protected abstract getConfigModuleIds(): string[];\n\n protected watchConfig() {\n this.notifier?.stopObserving();\n this.notifier = new FileNotifier(this.projectRoot, this.getConfigModuleIds());\n this.notifier.startObserving();\n }\n\n /** Create ngrok instance and start the tunnel server. Exposed for testing. */\n public async _startTunnelAsync(): Promise<AsyncNgrok | AsyncWsTunnel | null> {\n const port = this.getInstance()?.location.port;\n if (!port) return null;\n debug('[tunnel] connect to port: ' + port);\n this.tunnel = envIsWebcontainer()\n ? new AsyncWsTunnel(this.projectRoot, port)\n : new AsyncNgrok(this.projectRoot, port);\n await this.tunnel.startAsync();\n return this.tunnel;\n }\n\n protected async startDevSessionAsync() {\n // This is used to make Expo Go open the project in either Expo Go, or the web browser.\n // Must come after ngrok (`startTunnelAsync`) setup.\n this.devSession = new DevelopmentSession(\n this.projectRoot,\n // This URL will be used on external devices so the computer IP won't be relevant.\n this.isTargetingNative()\n ? this.getNativeRuntimeUrl()\n : this.getDevServerUrl({ hostType: 'localhost' })\n );\n\n await this.devSession.startAsync({\n runtime: this.isTargetingNative() ? 'native' : 'web',\n });\n }\n\n public isTargetingNative() {\n // Temporary hack while we implement multi-bundler dev server proxy.\n return true;\n }\n\n public isTargetingWeb() {\n return this.platformBundlers.web === this.name;\n }\n\n /**\n * Sends a message over web sockets to any connected device,\n * does nothing when the dev server is not running.\n *\n * @param method name of the command. In RN projects `reload`, and `devMenu` are available. In Expo Go, `sendDevCommand` is available.\n * @param params\n */\n public broadcastMessage(\n method: 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ) {\n this.getInstance()?.messageSocket.broadcast(method, params);\n }\n\n /** Get the running dev server instance. */\n public getInstance() {\n return this.instance;\n }\n\n /** Stop the running dev server instance. */\n async stopAsync() {\n // Stop file watching.\n this.notifier?.stopObserving();\n\n // Stop the dev session timer and tell Expo API to remove dev session.\n await this.devSession?.closeAsync();\n\n // Stop tunnel if running.\n await this.tunnel?.stopAsync().catch((e) => {\n Log.error(`Error stopping tunnel:`);\n Log.exception(e);\n });\n\n return resolveWithTimeout(\n () =>\n new Promise<void>((resolve, reject) => {\n // Close the server.\n debug(`Stopping dev server (bundler: ${this.name})`);\n\n if (this.instance?.server) {\n // Check if server is even running.\n this.instance.server.close((error) => {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n if (error) {\n if ('code' in error && error.code === 'ERR_SERVER_NOT_RUNNING') {\n resolve();\n } else {\n reject(error);\n }\n } else {\n resolve();\n }\n });\n } else {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n resolve();\n }\n }),\n {\n // NOTE(Bacon): Metro dev server doesn't seem to be closing in time.\n timeout: 1000,\n errorMessage: `Timeout waiting for '${this.name}' dev server to close`,\n }\n );\n }\n\n public getUrlCreator(options: Partial<Pick<BundlerStartOptions, 'port' | 'location'>> = {}) {\n if (!this.urlCreator) {\n assert(options?.port, 'Dev server instance not found');\n this.urlCreator = new UrlCreator(options.location, {\n port: options.port,\n getTunnelUrl: this.getTunnelUrl.bind(this),\n });\n }\n return this.urlCreator;\n }\n\n public getNativeRuntimeUrl(opts: Partial<CreateURLOptions> = {}) {\n return this.isDevClient\n ? (this.getUrlCreator().constructDevClientUrl(opts) ?? this.getDevServerUrl())\n : this.getUrlCreator().constructUrl({ ...opts, scheme: 'exp' });\n }\n\n /** Get the URL for the running instance of the dev server. */\n public getDevServerUrl(options: { hostType?: 'localhost' } = {}): string | null {\n const instance = this.getInstance();\n if (!instance?.location) {\n return null;\n }\n\n // If we have an active WS tunnel instance, we always need to return the tunnel location.\n if (this.tunnel && this.tunnel instanceof AsyncWsTunnel) {\n return this.getUrlCreator().constructUrl();\n }\n\n const { location } = instance;\n if (options.hostType === 'localhost') {\n return `${location.protocol}://localhost:${location.port}`;\n }\n\n return location.url ?? null;\n }\n\n public getDevServerUrlOrAssert(options: { hostType?: 'localhost' } = {}): string {\n const instance = this.getDevServerUrl(options);\n if (!instance) {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the dev server URL before the server has started - bundler[${this.name}]`\n );\n }\n\n return instance;\n }\n\n /** Get the base URL for JS inspector */\n public getJsInspectorBaseUrl(): string {\n if (this.name !== 'metro') {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the JS inspector base url - bundler[${this.name}]`\n );\n }\n return this.getUrlCreator().constructUrl({ scheme: 'http' });\n }\n\n /** Get the tunnel URL from the tunnel. */\n public getTunnelUrl(): string | null {\n return this.tunnel?.getActiveUrl() ?? null;\n }\n\n /** Open the dev server in a runtime. */\n public async openPlatformAsync(\n launchTarget: keyof typeof PLATFORM_MANAGERS | 'desktop',\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n if (launchTarget === 'desktop') {\n const serverUrl = this.getDevServerUrl({ hostType: 'localhost' });\n // Allow opening the tunnel URL when using Metro web.\n const url = this.name === 'metro' ? (this.getTunnelUrl() ?? serverUrl) : serverUrl;\n await openBrowserAsync(url!);\n return { url };\n }\n\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime }, resolver);\n }\n\n /** Open the dev server in a runtime. */\n public async openCustomRuntimeAsync<T extends BaseOpenInCustomProps = BaseOpenInCustomProps>(\n launchTarget: keyof typeof PLATFORM_MANAGERS,\n launchProps: Partial<T> = {},\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n if (runtime !== 'custom') {\n throw new CommandError(\n `dev server cannot open custom runtimes either because it does not target native platforms or because it is not targeting dev clients. (target: ${runtime})`\n );\n }\n\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime: 'custom', props: launchProps }, resolver);\n }\n\n /** Get the URL for opening in Expo Go. */\n protected getExpoGoUrl(): string {\n return this.getUrlCreator().constructUrl({ scheme: 'exp' });\n }\n\n /** Should use the interstitial page for selecting which runtime to use. */\n protected isRedirectPageEnabled(): boolean {\n return (\n !env.EXPO_NO_REDIRECT_PAGE &&\n // if user passed --dev-client flag, skip interstitial page\n !this.isDevClient &&\n // Checks if dev client is installed.\n !!resolveFrom.silent(this.projectRoot, 'expo-dev-client')\n );\n }\n\n /** Get the redirect URL when redirecting is enabled. */\n public getRedirectUrl(platform: keyof typeof PLATFORM_MANAGERS | null = null): string | null {\n if (!this.isRedirectPageEnabled()) {\n debug('Redirect page is disabled');\n return null;\n }\n\n return (\n this.getUrlCreator().constructLoadingUrl(\n {},\n platform === 'emulator' ? 'android' : platform === 'simulator' ? 'ios' : null\n ) ?? null\n );\n }\n\n protected async getPlatformManagerAsync(platform: keyof typeof PLATFORM_MANAGERS) {\n if (!this.platformManagers[platform]) {\n const Manager = PLATFORM_MANAGERS[platform]();\n const port = this.getInstance()?.location.port;\n if (!port || !this.urlCreator) {\n throw new CommandError(\n 'DEV_SERVER',\n 'Cannot interact with native platforms until dev server has started'\n );\n }\n debug(`Creating platform manager (platform: ${platform}, port: ${port})`);\n this.platformManagers[platform] = new Manager(this.projectRoot, port, {\n getCustomRuntimeUrl: this.urlCreator.constructDevClientUrl.bind(this.urlCreator),\n getExpoGoUrl: this.getExpoGoUrl.bind(this),\n getRedirectUrl: this.getRedirectUrl.bind(this, platform),\n getDevServerUrl: this.getDevServerUrl.bind(this, { hostType: 'localhost' }),\n });\n }\n return this.platformManagers[platform];\n }\n}\n"],"names":["BundlerDevServer","debug","require","PLATFORM_MANAGERS","simulator","ApplePlatformManager","emulator","AndroidPlatformManager","constructor","projectRoot","platformBundlers","options","tunnel","devSession","instance","platformManagers","urlCreator","notifier","devToolsPluginManager","DevToolsPluginManager","isDevClient","setInstance","getManifestMiddlewareAsync","Middleware","ExpoGoManifestHandlerMiddleware","getUrlCreator","middleware","constructUrl","bind","mode","minify","isNativeWebpack","name","isTargetingNative","privateKeyPath","startAsync","stopAsync","headless","startHeadlessAsync","startImplementationAsync","postStartAsync","waitForTypeScriptAsync","watchEnvironmentVariables","port","CommandError","server","close","callback","addListener","location","host","url","protocol","messageSocket","broadcast","hostType","env","EXPO_OFFLINE","_startTunnelAsync","envIsWebcontainer","isExporting","startDevSessionAsync","watchConfig","stopObserving","FileNotifier","getConfigModuleIds","startObserving","getInstance","AsyncWsTunnel","AsyncNgrok","DevelopmentSession","getNativeRuntimeUrl","getDevServerUrl","runtime","isTargetingWeb","web","broadcastMessage","method","params","closeAsync","catch","e","Log","error","exception","resolveWithTimeout","Promise","resolve","reject","code","timeout","errorMessage","assert","UrlCreator","getTunnelUrl","opts","constructDevClientUrl","scheme","getDevServerUrlOrAssert","getJsInspectorBaseUrl","getActiveUrl","openPlatformAsync","launchTarget","resolver","serverUrl","openBrowserAsync","manager","getPlatformManagerAsync","openAsync","openCustomRuntimeAsync","launchProps","props","getExpoGoUrl","isRedirectPageEnabled","EXPO_NO_REDIRECT_PAGE","resolveFrom","silent","getRedirectUrl","platform","constructLoadingUrl","Manager","getCustomRuntimeUrl"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/BundlerDevServer.ts"],"sourcesContent":["import assert from 'assert';\nimport resolveFrom from 'resolve-from';\n\nimport { AsyncNgrok } from './AsyncNgrok';\nimport { AsyncWsTunnel } from './AsyncWsTunnel';\nimport { Bonjour } from './Bonjour';\nimport DevToolsPluginManager from './DevToolsPluginManager';\nimport { DevelopmentSession } from './DevelopmentSession';\nimport { CreateURLOptions, UrlCreator } from './UrlCreator';\nimport { PlatformBundlers } from './platformBundlers';\nimport * as Log from '../../log';\nimport { FileNotifier } from '../../utils/FileNotifier';\nimport { resolveWithTimeout } from '../../utils/delay';\nimport { env, envIsWebcontainer } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { openBrowserAsync } from '../../utils/open';\nimport {\n BaseOpenInCustomProps,\n BaseResolveDeviceProps,\n PlatformManager,\n} from '../platforms/PlatformManager';\n\nconst debug = require('debug')('expo:start:server:devServer') as typeof console.log;\n\nexport type MessageSocket = {\n broadcast: (method: string, params?: Record<string, any> | undefined) => void;\n};\n\nexport type ServerLike = {\n close(callback?: (err?: Error) => void): void;\n addListener?(event: string, listener: (...args: any[]) => void): unknown;\n};\n\nexport type DevServerInstance = {\n /** Bundler dev server instance. */\n server: ServerLike;\n /** Dev server URL location properties. */\n location: {\n url: string;\n port: number;\n protocol: 'http' | 'https';\n host?: string;\n };\n /** Additional middleware that's attached to the `server`. */\n middleware: any;\n /** Message socket for communicating with the runtime. */\n messageSocket: MessageSocket;\n};\n\nexport interface BundlerStartOptions {\n /** Should the dev server use `https` protocol. */\n https?: boolean;\n /** Should start the dev servers in development mode (minify). */\n mode?: 'development' | 'production';\n /** Is dev client enabled. */\n devClient?: boolean;\n /** Should run dev servers with clean caches. */\n resetDevServer?: boolean;\n /** Code signing private key path (defaults to same directory as certificate) */\n privateKeyPath?: string;\n\n /** Max amount of workers (threads) to use with Metro bundler, defaults to undefined for max workers. */\n maxWorkers?: number;\n /** Port to start the dev server on. */\n port?: number;\n\n /** Should start a headless dev server e.g. mock representation to approximate info from a server running in a different process. */\n headless?: boolean;\n /** Should instruct the bundler to create minified bundles. */\n minify?: boolean;\n\n /** Will the bundler be used for exporting. NOTE: This is an odd option to pass to the dev server. */\n isExporting?: boolean;\n\n // Webpack options\n /** Should modify and create PWA icons. */\n isImageEditingEnabled?: boolean;\n\n location: CreateURLOptions;\n}\n\nconst PLATFORM_MANAGERS = {\n simulator: () =>\n require('../platforms/ios/ApplePlatformManager')\n .ApplePlatformManager as typeof import('../platforms/ios/ApplePlatformManager').ApplePlatformManager,\n emulator: () =>\n require('../platforms/android/AndroidPlatformManager')\n .AndroidPlatformManager as typeof import('../platforms/android/AndroidPlatformManager').AndroidPlatformManager,\n};\n\nexport abstract class BundlerDevServer {\n /** Name of the bundler. */\n abstract get name(): string;\n\n /** Tunnel instance for managing tunnel connections. */\n protected tunnel: AsyncNgrok | AsyncWsTunnel | null = null;\n /** Interfaces with the Expo 'Development Session' API. */\n protected devSession: DevelopmentSession | null = null;\n /** Announces dev server via Bonjour */\n protected bonjour: Bonjour | null = null;\n /** Http server and related info. */\n protected instance: DevServerInstance | null = null;\n /** Native platform interfaces for opening projects. */\n private platformManagers: Record<string, PlatformManager<any>> = {};\n /** Manages the creation of dev server URLs. */\n protected urlCreator?: UrlCreator | null = null;\n\n private notifier: FileNotifier | null = null;\n protected readonly devToolsPluginManager: DevToolsPluginManager;\n public isDevClient: boolean;\n\n constructor(\n /** Project root folder. */\n public projectRoot: string,\n /** A mapping of bundlers to platforms. */\n public platformBundlers: PlatformBundlers,\n /** Advanced options */\n options?: {\n /**\n * The instance of DevToolsPluginManager\n * @default new DevToolsPluginManager(projectRoot)\n */\n devToolsPluginManager?: DevToolsPluginManager;\n // TODO: Replace with custom scheme maybe...\n isDevClient?: boolean;\n }\n ) {\n this.devToolsPluginManager =\n options?.devToolsPluginManager ?? new DevToolsPluginManager(projectRoot);\n this.isDevClient = options?.isDevClient ?? false;\n }\n\n protected setInstance(instance: DevServerInstance) {\n this.instance = instance;\n }\n\n /** Get the manifest middleware function. */\n protected async getManifestMiddlewareAsync(\n options: Pick<BundlerStartOptions, 'minify' | 'mode' | 'privateKeyPath'> = {}\n ) {\n const Middleware = require('./middleware/ExpoGoManifestHandlerMiddleware')\n .ExpoGoManifestHandlerMiddleware as typeof import('./middleware/ExpoGoManifestHandlerMiddleware').ExpoGoManifestHandlerMiddleware;\n\n const urlCreator = this.getUrlCreator();\n const middleware = new Middleware(this.projectRoot, {\n constructUrl: urlCreator.constructUrl.bind(urlCreator),\n mode: options.mode,\n minify: options.minify,\n isNativeWebpack: this.name === 'webpack' && this.isTargetingNative(),\n privateKeyPath: options.privateKeyPath,\n });\n return middleware;\n }\n\n /** Start the dev server using settings defined in the start command. */\n public async startAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n await this.stopAsync();\n\n let instance: DevServerInstance;\n if (options.headless) {\n instance = await this.startHeadlessAsync(options);\n } else {\n instance = await this.startImplementationAsync(options);\n }\n\n this.setInstance(instance);\n await this.postStartAsync(options);\n return instance;\n }\n\n protected abstract startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance>;\n\n public async waitForTypeScriptAsync(): Promise<boolean> {\n return false;\n }\n\n public abstract startTypeScriptServices(): Promise<void>;\n\n public async watchEnvironmentVariables(): Promise<void> {\n // noop -- We've only implemented this functionality in Metro.\n }\n\n /**\n * Creates a mock server representation that can be used to estimate URLs for a server started in another process.\n * This is used for the run commands where you can reuse the server from a previous run.\n */\n private async startHeadlessAsync(options: BundlerStartOptions): Promise<DevServerInstance> {\n if (!options.port)\n throw new CommandError('HEADLESS_SERVER', 'headless dev server requires a port option');\n this.urlCreator = this.getUrlCreator(options);\n\n return {\n // Create a mock server\n server: {\n close: (callback: () => void) => {\n this.instance = null;\n callback?.();\n },\n addListener() {},\n },\n location: {\n // The port is the main thing we want to send back.\n port: options.port,\n // localhost isn't always correct.\n host: 'localhost',\n // http is the only supported protocol on native.\n url: `http://localhost:${options.port}`,\n protocol: 'http',\n },\n middleware: {},\n messageSocket: {\n broadcast: () => {\n throw new CommandError('HEADLESS_SERVER', 'Cannot broadcast messages to headless server');\n },\n },\n };\n }\n\n /**\n * Runs after the `startAsync` function, performing any additional common operations.\n * You can assume the dev server is started by the time this function is called.\n */\n protected async postStartAsync(options: BundlerStartOptions) {\n if (\n options.location.hostType === 'tunnel' &&\n !env.EXPO_OFFLINE &&\n // This is a hack to prevent using tunnel on web since we block it upstream for some reason.\n this.isTargetingNative()\n ) {\n await this._startTunnelAsync();\n } else if (envIsWebcontainer()) {\n await this._startTunnelAsync();\n }\n\n if (!options.isExporting) {\n await Promise.all([this.startDevSessionAsync(), this.startBonjourAsync()]);\n this.watchConfig();\n }\n }\n\n protected abstract getConfigModuleIds(): string[];\n\n protected watchConfig() {\n this.notifier?.stopObserving();\n this.notifier = new FileNotifier(this.projectRoot, this.getConfigModuleIds());\n this.notifier.startObserving();\n }\n\n /** Create ngrok instance and start the tunnel server. Exposed for testing. */\n public async _startTunnelAsync(): Promise<AsyncNgrok | AsyncWsTunnel | null> {\n const port = this.getInstance()?.location.port;\n if (!port) return null;\n debug('[tunnel] connect to port: ' + port);\n this.tunnel = envIsWebcontainer()\n ? new AsyncWsTunnel(this.projectRoot, port)\n : new AsyncNgrok(this.projectRoot, port);\n await this.tunnel.startAsync();\n return this.tunnel;\n }\n\n protected async startDevSessionAsync() {\n // This is used to make Expo Go open the project in either Expo Go, or the web browser.\n // Must come after ngrok (`startTunnelAsync`) setup.\n this.devSession = new DevelopmentSession(\n this.projectRoot,\n // This URL will be used on external devices so the computer IP won't be relevant.\n this.isTargetingNative()\n ? this.getNativeRuntimeUrl()\n : this.getDevServerUrl({ hostType: 'localhost' })\n );\n\n await this.devSession.startAsync({\n runtime: this.isTargetingNative() ? 'native' : 'web',\n });\n }\n\n protected async startBonjourAsync() {\n // This is used to make Expo Go open the project in either Expo Go, or the web browser.\n // Must come after ngrok (`startTunnelAsync`) setup.\n if (!this.bonjour) {\n this.bonjour = new Bonjour(this.projectRoot, this.getInstance()?.location.port);\n }\n\n await this.bonjour.announceAsync({});\n }\n\n public isTargetingNative() {\n // Temporary hack while we implement multi-bundler dev server proxy.\n return true;\n }\n\n public isTargetingWeb() {\n return this.platformBundlers.web === this.name;\n }\n\n /**\n * Sends a message over web sockets to any connected device,\n * does nothing when the dev server is not running.\n *\n * @param method name of the command. In RN projects `reload`, and `devMenu` are available. In Expo Go, `sendDevCommand` is available.\n * @param params\n */\n public broadcastMessage(\n method: 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ) {\n this.getInstance()?.messageSocket.broadcast(method, params);\n }\n\n /** Get the running dev server instance. */\n public getInstance() {\n return this.instance;\n }\n\n /** Stop the running dev server instance. */\n async stopAsync() {\n // Stop file watching.\n this.notifier?.stopObserving();\n\n await Promise.all([\n // Stop the bonjour advertiser\n this.bonjour?.closeAsync(),\n // Stop the dev session timer and tell Expo API to remove dev session.\n this.devSession?.closeAsync(),\n ]);\n\n // Stop tunnel if running.\n await this.tunnel?.stopAsync().catch((e) => {\n Log.error(`Error stopping tunnel:`);\n Log.exception(e);\n });\n\n return resolveWithTimeout(\n () =>\n new Promise<void>((resolve, reject) => {\n // Close the server.\n debug(`Stopping dev server (bundler: ${this.name})`);\n\n if (this.instance?.server) {\n // Check if server is even running.\n this.instance.server.close((error) => {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n if (error) {\n if ('code' in error && error.code === 'ERR_SERVER_NOT_RUNNING') {\n resolve();\n } else {\n reject(error);\n }\n } else {\n resolve();\n }\n });\n } else {\n debug(`Stopped dev server (bundler: ${this.name})`);\n this.instance = null;\n resolve();\n }\n }),\n {\n // NOTE(Bacon): Metro dev server doesn't seem to be closing in time.\n timeout: 1000,\n errorMessage: `Timeout waiting for '${this.name}' dev server to close`,\n }\n );\n }\n\n public getUrlCreator(options: Partial<Pick<BundlerStartOptions, 'port' | 'location'>> = {}) {\n if (!this.urlCreator) {\n assert(options?.port, 'Dev server instance not found');\n this.urlCreator = new UrlCreator(options.location, {\n port: options.port,\n getTunnelUrl: this.getTunnelUrl.bind(this),\n });\n }\n return this.urlCreator;\n }\n\n public getNativeRuntimeUrl(opts: Partial<CreateURLOptions> = {}) {\n return this.isDevClient\n ? (this.getUrlCreator().constructDevClientUrl(opts) ?? this.getDevServerUrl())\n : this.getUrlCreator().constructUrl({ ...opts, scheme: 'exp' });\n }\n\n /** Get the URL for the running instance of the dev server. */\n public getDevServerUrl(options: { hostType?: 'localhost' } = {}): string | null {\n const instance = this.getInstance();\n if (!instance?.location) {\n return null;\n }\n\n // If we have an active WS tunnel instance, we always need to return the tunnel location.\n if (this.tunnel && this.tunnel instanceof AsyncWsTunnel) {\n return this.getUrlCreator().constructUrl();\n }\n\n const { location } = instance;\n if (options.hostType === 'localhost') {\n return `${location.protocol}://localhost:${location.port}`;\n }\n\n return location.url ?? null;\n }\n\n public getDevServerUrlOrAssert(options: { hostType?: 'localhost' } = {}): string {\n const instance = this.getDevServerUrl(options);\n if (!instance) {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the dev server URL before the server has started - bundler[${this.name}]`\n );\n }\n\n return instance;\n }\n\n /** Get the base URL for JS inspector */\n public getJsInspectorBaseUrl(): string {\n if (this.name !== 'metro') {\n throw new CommandError(\n 'DEV_SERVER',\n `Cannot get the JS inspector base url - bundler[${this.name}]`\n );\n }\n return this.getUrlCreator().constructUrl({ scheme: 'http' });\n }\n\n /** Get the tunnel URL from the tunnel. */\n public getTunnelUrl(): string | null {\n return this.tunnel?.getActiveUrl() ?? null;\n }\n\n /** Open the dev server in a runtime. */\n public async openPlatformAsync(\n launchTarget: keyof typeof PLATFORM_MANAGERS | 'desktop',\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n if (launchTarget === 'desktop') {\n const serverUrl = this.getDevServerUrl({ hostType: 'localhost' });\n // Allow opening the tunnel URL when using Metro web.\n const url = this.name === 'metro' ? (this.getTunnelUrl() ?? serverUrl) : serverUrl;\n await openBrowserAsync(url!);\n return { url };\n }\n\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime }, resolver);\n }\n\n /** Open the dev server in a runtime. */\n public async openCustomRuntimeAsync<T extends BaseOpenInCustomProps = BaseOpenInCustomProps>(\n launchTarget: keyof typeof PLATFORM_MANAGERS,\n launchProps: Partial<T> = {},\n resolver: BaseResolveDeviceProps<any> = {}\n ) {\n const runtime = this.isTargetingNative() ? (this.isDevClient ? 'custom' : 'expo') : 'web';\n if (runtime !== 'custom') {\n throw new CommandError(\n `dev server cannot open custom runtimes either because it does not target native platforms or because it is not targeting dev clients. (target: ${runtime})`\n );\n }\n\n const manager = await this.getPlatformManagerAsync(launchTarget);\n return manager.openAsync({ runtime: 'custom', props: launchProps }, resolver);\n }\n\n /** Get the URL for opening in Expo Go. */\n protected getExpoGoUrl(): string {\n return this.getUrlCreator().constructUrl({ scheme: 'exp' });\n }\n\n /** Should use the interstitial page for selecting which runtime to use. */\n protected isRedirectPageEnabled(): boolean {\n return (\n !env.EXPO_NO_REDIRECT_PAGE &&\n // if user passed --dev-client flag, skip interstitial page\n !this.isDevClient &&\n // Checks if dev client is installed.\n !!resolveFrom.silent(this.projectRoot, 'expo-dev-client')\n );\n }\n\n /** Get the redirect URL when redirecting is enabled. */\n public getRedirectUrl(platform: keyof typeof PLATFORM_MANAGERS | null = null): string | null {\n if (!this.isRedirectPageEnabled()) {\n debug('Redirect page is disabled');\n return null;\n }\n\n return (\n this.getUrlCreator().constructLoadingUrl(\n {},\n platform === 'emulator' ? 'android' : platform === 'simulator' ? 'ios' : null\n ) ?? null\n );\n }\n\n protected async getPlatformManagerAsync(platform: keyof typeof PLATFORM_MANAGERS) {\n if (!this.platformManagers[platform]) {\n const Manager = PLATFORM_MANAGERS[platform]();\n const port = this.getInstance()?.location.port;\n if (!port || !this.urlCreator) {\n throw new CommandError(\n 'DEV_SERVER',\n 'Cannot interact with native platforms until dev server has started'\n );\n }\n debug(`Creating platform manager (platform: ${platform}, port: ${port})`);\n this.platformManagers[platform] = new Manager(this.projectRoot, port, {\n getCustomRuntimeUrl: this.urlCreator.constructDevClientUrl.bind(this.urlCreator),\n getExpoGoUrl: this.getExpoGoUrl.bind(this),\n getRedirectUrl: this.getRedirectUrl.bind(this, platform),\n getDevServerUrl: this.getDevServerUrl.bind(this, { hostType: 'localhost' }),\n });\n }\n return this.platformManagers[platform];\n }\n}\n"],"names":["BundlerDevServer","debug","require","PLATFORM_MANAGERS","simulator","ApplePlatformManager","emulator","AndroidPlatformManager","constructor","projectRoot","platformBundlers","options","tunnel","devSession","bonjour","instance","platformManagers","urlCreator","notifier","devToolsPluginManager","DevToolsPluginManager","isDevClient","setInstance","getManifestMiddlewareAsync","Middleware","ExpoGoManifestHandlerMiddleware","getUrlCreator","middleware","constructUrl","bind","mode","minify","isNativeWebpack","name","isTargetingNative","privateKeyPath","startAsync","stopAsync","headless","startHeadlessAsync","startImplementationAsync","postStartAsync","waitForTypeScriptAsync","watchEnvironmentVariables","port","CommandError","server","close","callback","addListener","location","host","url","protocol","messageSocket","broadcast","hostType","env","EXPO_OFFLINE","_startTunnelAsync","envIsWebcontainer","isExporting","Promise","all","startDevSessionAsync","startBonjourAsync","watchConfig","stopObserving","FileNotifier","getConfigModuleIds","startObserving","getInstance","AsyncWsTunnel","AsyncNgrok","DevelopmentSession","getNativeRuntimeUrl","getDevServerUrl","runtime","Bonjour","announceAsync","isTargetingWeb","web","broadcastMessage","method","params","closeAsync","catch","e","Log","error","exception","resolveWithTimeout","resolve","reject","code","timeout","errorMessage","assert","UrlCreator","getTunnelUrl","opts","constructDevClientUrl","scheme","getDevServerUrlOrAssert","getJsInspectorBaseUrl","getActiveUrl","openPlatformAsync","launchTarget","resolver","serverUrl","openBrowserAsync","manager","getPlatformManagerAsync","openAsync","openCustomRuntimeAsync","launchProps","props","getExpoGoUrl","isRedirectPageEnabled","EXPO_NO_REDIRECT_PAGE","resolveFrom","silent","getRedirectUrl","platform","constructLoadingUrl","Manager","getCustomRuntimeUrl"],"mappings":"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"}
|
|
@@ -51,8 +51,8 @@ class DevToolsPluginCliExtensionExecutor {
|
|
|
51
51
|
const child = this.spawnFunc('node', [
|
|
52
52
|
tool,
|
|
53
53
|
command,
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
`${JSON.stringify(args)}`,
|
|
55
|
+
`${metroServerOrigin}`
|
|
56
56
|
], {
|
|
57
57
|
cwd: this.projectRoot,
|
|
58
58
|
env: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/server/DevToolsPluginCliExtensionExecutor.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport path from 'path';\n\nimport {\n DevToolsPluginExecutorArguments,\n DevToolsPluginInfo,\n DevToolsPluginOutput,\n} from './DevToolsPlugin.schema';\nimport { DevToolsPluginCliExtensionResults } from './DevToolsPluginCliExtensionResults';\n\nconst DEFAULT_TIMEOUT_MS = 10_000; // 10 seconds\n\n/**\n * Class that executes CLI Extension commands for a given plugin\n *\n * ## Responsibilities:\n * - Verifies that requested commands exist and have correct parameters\n * - Validates that provided arguments match expected parameter schema\n * - Spawns and manages child processes for command execution\n * - Captures and streams stdout/stderr data from executed commands\n * - Manages process errors, timeouts, and unexpected failures\n * - Enforces execution time limits to prevent hanging processes\n * - Configures proper execution environment with color support\n * - Ensures proper cleanup of processes and timeouts\n * - Provides structured output with exit codes and error states\n */\nexport class DevToolsPluginCliExtensionExecutor {\n constructor(\n private plugin: DevToolsPluginInfo,\n private projectRoot: string,\n private spawnFunc: typeof spawn = spawn, // Used for injection when testing,\n private timeoutMs = DEFAULT_TIMEOUT_MS // Timeout for command execution\n ) {\n // Validate that this is a plugin with cli extensions\n if (!this.plugin.cliExtensions?.entryPoint) {\n throw new Error(`Plugin ${this.plugin.packageName} has no CLI extensions`);\n }\n }\n\n public validate({ command, args }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) {\n const commandElement = this.plugin.cliExtensions?.commands.find((c) => c.name === command);\n if (!commandElement) {\n throw new Error(`Command \"${command}\" not found in plugin ${this.plugin.packageName}`);\n }\n\n const paramLength = commandElement.parameters?.length ?? 0;\n const argsLength = Object.keys(args ?? {}).length;\n if (paramLength !== argsLength) {\n // Quick check to see if the lengths match\n throw new Error(\n `Expected ${paramLength} parameter(s), but got ${argsLength} argument(s) for the command \"${command}\".`\n );\n }\n\n const argsKeys = Object.keys(args ?? {});\n for (const param of commandElement.parameters ?? []) {\n const found = argsKeys.find((key) => key === param.name);\n if (!found) {\n throw new Error(\n `Parameter \"${param.name}\" not found in command \"${command}\" of plugin ${this.plugin.packageName}`\n );\n }\n }\n }\n\n /** this function is used for testing and showing the command in UI */\n public getCommandString = ({\n command,\n args,\n }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) => {\n return `node ${this.plugin.cliExtensions!.entryPoint} ${command}${Object.keys(args ?? {}).length > 0 ? ' ' + JSON.stringify(args) : ''}`;\n };\n\n public execute = async ({\n command,\n args,\n metroServerOrigin,\n onOutput,\n }: DevToolsPluginExecutorArguments): Promise<DevToolsPluginOutput> => {\n this.validate({ command, args });\n return new Promise<DevToolsPluginOutput>(async (resolve) => {\n // Set up the command and its arguments\n const tool = path.join(this.plugin.packageRoot, this.plugin.cliExtensions!.entryPoint);\n const child = this.spawnFunc(\n 'node',\n [tool, command,
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/DevToolsPluginCliExtensionExecutor.ts"],"sourcesContent":["import { spawn } from 'child_process';\nimport path from 'path';\n\nimport {\n DevToolsPluginExecutorArguments,\n DevToolsPluginInfo,\n DevToolsPluginOutput,\n} from './DevToolsPlugin.schema';\nimport { DevToolsPluginCliExtensionResults } from './DevToolsPluginCliExtensionResults';\n\nconst DEFAULT_TIMEOUT_MS = 10_000; // 10 seconds\n\n/**\n * Class that executes CLI Extension commands for a given plugin\n *\n * ## Responsibilities:\n * - Verifies that requested commands exist and have correct parameters\n * - Validates that provided arguments match expected parameter schema\n * - Spawns and manages child processes for command execution\n * - Captures and streams stdout/stderr data from executed commands\n * - Manages process errors, timeouts, and unexpected failures\n * - Enforces execution time limits to prevent hanging processes\n * - Configures proper execution environment with color support\n * - Ensures proper cleanup of processes and timeouts\n * - Provides structured output with exit codes and error states\n */\nexport class DevToolsPluginCliExtensionExecutor {\n constructor(\n private plugin: DevToolsPluginInfo,\n private projectRoot: string,\n private spawnFunc: typeof spawn = spawn, // Used for injection when testing,\n private timeoutMs = DEFAULT_TIMEOUT_MS // Timeout for command execution\n ) {\n // Validate that this is a plugin with cli extensions\n if (!this.plugin.cliExtensions?.entryPoint) {\n throw new Error(`Plugin ${this.plugin.packageName} has no CLI extensions`);\n }\n }\n\n public validate({ command, args }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) {\n const commandElement = this.plugin.cliExtensions?.commands.find((c) => c.name === command);\n if (!commandElement) {\n throw new Error(`Command \"${command}\" not found in plugin ${this.plugin.packageName}`);\n }\n\n const paramLength = commandElement.parameters?.length ?? 0;\n const argsLength = Object.keys(args ?? {}).length;\n if (paramLength !== argsLength) {\n // Quick check to see if the lengths match\n throw new Error(\n `Expected ${paramLength} parameter(s), but got ${argsLength} argument(s) for the command \"${command}\".`\n );\n }\n\n const argsKeys = Object.keys(args ?? {});\n for (const param of commandElement.parameters ?? []) {\n const found = argsKeys.find((key) => key === param.name);\n if (!found) {\n throw new Error(\n `Parameter \"${param.name}\" not found in command \"${command}\" of plugin ${this.plugin.packageName}`\n );\n }\n }\n }\n\n /** this function is used for testing and showing the command in UI */\n public getCommandString = ({\n command,\n args,\n }: Omit<DevToolsPluginExecutorArguments, 'metroServerOrigin'>) => {\n return `node ${this.plugin.cliExtensions!.entryPoint} ${command}${Object.keys(args ?? {}).length > 0 ? ' ' + JSON.stringify(args) : ''}`;\n };\n\n public execute = async ({\n command,\n args,\n metroServerOrigin,\n onOutput,\n }: DevToolsPluginExecutorArguments): Promise<DevToolsPluginOutput> => {\n this.validate({ command, args });\n return new Promise<DevToolsPluginOutput>(async (resolve) => {\n // Set up the command and its arguments\n const tool = path.join(this.plugin.packageRoot, this.plugin.cliExtensions!.entryPoint);\n const child = this.spawnFunc(\n 'node',\n [tool, command, `${JSON.stringify(args)}`, `${metroServerOrigin}`],\n {\n cwd: this.projectRoot,\n env: { ...process.env },\n }\n );\n\n let finished = false;\n const pluginResults = new DevToolsPluginCliExtensionResults(onOutput);\n\n // Collect output/error data\n child.stdout.on('data', (data) => pluginResults.append(data.toString()));\n child.stderr.on('data', (data) => pluginResults.append(data.toString(), 'error'));\n\n // Setup timeout\n const timeout = setTimeout(() => {\n if (!finished) {\n finished = true;\n child.kill('SIGKILL');\n pluginResults.append('Command timed out', 'error');\n resolve(pluginResults.getOutput());\n }\n }, this.timeoutMs);\n\n child.on('close', (code: number) => {\n if (finished) return;\n clearTimeout(timeout);\n finished = true;\n pluginResults.exit(code);\n resolve(pluginResults.getOutput());\n });\n\n child.on('error', (err: Error) => {\n if (finished) return;\n clearTimeout(timeout);\n finished = true;\n pluginResults.append(err.toString(), 'error');\n resolve(pluginResults.getOutput());\n });\n });\n };\n}\n"],"names":["DevToolsPluginCliExtensionExecutor","DEFAULT_TIMEOUT_MS","constructor","plugin","projectRoot","spawnFunc","spawn","timeoutMs","getCommandString","command","args","cliExtensions","entryPoint","Object","keys","length","JSON","stringify","execute","metroServerOrigin","onOutput","validate","Promise","resolve","tool","path","join","packageRoot","child","cwd","env","process","finished","pluginResults","DevToolsPluginCliExtensionResults","stdout","on","data","append","toString","stderr","timeout","setTimeout","kill","getOutput","code","clearTimeout","exit","err","Error","packageName","commandElement","commands","find","c","name","paramLength","parameters","argsLength","argsKeys","param","found","key"],"mappings":"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"}
|