@expo/cli 54.1.0-canary-20251023-4c86f95 → 54.1.0-canary-20251031-b135dff
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/exportStaticAsync.js.map +1 -1
- package/build/src/start/interface/commandsTable.js.map +1 -1
- package/build/src/start/interface/startInterface.js +3 -0
- package/build/src/start/interface/startInterface.js.map +1 -1
- package/build/src/start/server/MCP.js +15 -4
- package/build/src/start/server/MCP.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +16 -16
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +19 -2
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/inspector/CdpClient.js +2 -0
- package/build/src/start/server/middleware/inspector/CdpClient.js.map +1 -1
- package/build/src/start/server/type-generation/routes.js +3 -1
- package/build/src/start/server/type-generation/routes.js.map +1 -1
- package/build/src/start/startAsync.js +11 -8
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +19 -19
- package/static/template/[...rsc]+api.ts +1 -1
package/build/bin/cli
CHANGED
|
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
|
|
|
123
123
|
});
|
|
124
124
|
if (args['--version']) {
|
|
125
125
|
// Version is added in the build script.
|
|
126
|
-
console.log("54.1.0-canary-
|
|
126
|
+
console.log("54.1.0-canary-20251031-b135dff");
|
|
127
127
|
process.exit(0);
|
|
128
128
|
}
|
|
129
129
|
if (args['--non-interactive']) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/exportStaticAsync.ts"],"sourcesContent":["/**\n * Copyright © 2022 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 { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport { RouteNode } from 'expo-router/build/Route';\nimport { stripGroupSegmentsFromPath } from 'expo-router/build/matchers';\nimport { shouldLinkExternally } from 'expo-router/build/utils/url';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport { inspect } from 'util';\n\nimport { getVirtualFaviconAssetsAsync } from './favicon';\nimport { persistMetroAssetsAsync } from './persistMetroAssets';\nimport { ExportAssetMap, getFilesFromSerialAssets } from './saveAssets';\nimport { Log } from '../log';\nimport {\n ExpoRouterRuntimeManifest,\n MetroBundlerDevServer,\n} from '../start/server/metro/MetroBundlerDevServer';\nimport { ExpoRouterServerManifestV1 } from '../start/server/metro/fetchRouterManifest';\nimport { logMetroErrorAsync } from '../start/server/metro/metroErrorInterface';\nimport { getApiRoutesForDirectory, getMiddlewareForDirectory } from '../start/server/metro/router';\nimport { serializeHtmlWithAssets } from '../start/server/metro/serializeHtml';\nimport { learnMore } from '../utils/link';\n\nconst debug = require('debug')('expo:export:generateStaticRoutes') as typeof console.log;\n\ntype ExtraScriptTag = {\n platform: string;\n src: string;\n};\n\ntype Options = {\n mode: 'production' | 'development';\n files?: ExportAssetMap;\n outputDir: string;\n minify: boolean;\n exportServer: boolean;\n baseUrl: string;\n includeSourceMaps: boolean;\n entryPoint?: string;\n clear: boolean;\n routerRoot: string;\n reactCompiler: boolean;\n maxWorkers?: number;\n isExporting: boolean;\n exp?: ExpoConfig;\n // <script type=\"type/expo\" data-platform=\"ios\" src=\"...\" />\n scriptTags?: ExtraScriptTag[];\n};\n\ntype HtmlRequestLocation = {\n /** The output file path name to use relative to the static folder. */\n filePath: string;\n /** The pathname to make requests to in order to fetch the HTML. */\n pathname: string;\n /** The runtime route node object, used to associate async modules with the static HTML. */\n route: RouteNode;\n};\n\nexport function injectScriptTags(html: string, scriptTags: ExtraScriptTag[]): string {\n const scriptTagsHtml = scriptTags\n .map((tag) =>\n tag.platform === 'web'\n ? `<script src=\"${tag.src}\"></script>`\n : `<script type=\"type/expo\" src=\"${tag.src}\" data-platform=\"${tag.platform}\"></script>`\n )\n .join('\\n');\n html = html.replace('</head>', `${scriptTagsHtml}\\n</head>`);\n return html;\n}\n\n/** Match `(page)` -> `page` */\nfunction matchGroupName(name: string): string | undefined {\n return name.match(/^\\(([^/]+?)\\)$/)?.[1];\n}\n\nexport async function getFilesToExportFromServerAsync(\n projectRoot: string,\n {\n manifest,\n serverManifest,\n renderAsync,\n // Servers can handle group routes automatically and therefore\n // don't require the build-time generation of every possible group\n // variation.\n exportServer,\n // name : contents\n files = new Map(),\n }: {\n manifest: ExpoRouterRuntimeManifest;\n serverManifest: ExpoRouterServerManifestV1;\n renderAsync: (requestLocation: HtmlRequestLocation) => Promise<string>;\n exportServer?: boolean;\n files?: ExportAssetMap;\n }\n): Promise<ExportAssetMap> {\n if (!exportServer && serverManifest) {\n // When we're not exporting a `server` output, we provide a `_expo/.routes.json` for\n // EAS Hosting to recognize the `headers` and `redirects` configs\n const subsetServerManifest = {\n headers: serverManifest.headers,\n redirects: serverManifest.redirects,\n };\n files.set('_expo/.routes.json', {\n contents: JSON.stringify(subsetServerManifest, null, 2),\n targetDomain: 'client',\n });\n }\n\n await Promise.all(\n getHtmlFiles({ manifest, includeGroupVariations: !exportServer }).map(\n async ({ route, filePath, pathname }) => {\n // Rewrite routes should not be statically generated\n if (route.type === 'rewrite') {\n return;\n }\n\n try {\n const targetDomain = exportServer ? 'server' : 'client';\n files.set(filePath, { contents: '', targetDomain });\n const data = await renderAsync({ route, filePath, pathname });\n files.set(filePath, {\n contents: data,\n routeId: pathname,\n targetDomain,\n });\n } catch (e: any) {\n await logMetroErrorAsync({ error: e, projectRoot });\n throw new Error('Failed to statically export route: ' + pathname);\n }\n }\n )\n );\n\n return files;\n}\n\nfunction modifyRouteNodeInRuntimeManifest(\n manifest: ExpoRouterRuntimeManifest,\n callback: (route: RouteNode) => any\n) {\n const iterateScreens = (screens: ExpoRouterRuntimeManifest['screens']) => {\n Object.values(screens).map((value) => {\n if (typeof value !== 'string') {\n if (value._route) callback(value._route);\n iterateScreens(value.screens);\n }\n });\n };\n\n iterateScreens(manifest.screens);\n}\n\n// TODO: Do this earlier in the process.\nfunction makeRuntimeEntryPointsAbsolute(manifest: ExpoRouterRuntimeManifest, appDir: string) {\n modifyRouteNodeInRuntimeManifest(manifest, (route) => {\n if (Array.isArray(route.entryPoints)) {\n route.entryPoints = route.entryPoints.map((entryPoint) => {\n // TODO(@hassankhan): ENG-16577\n if (shouldLinkExternally(entryPoint)) {\n return entryPoint;\n }\n\n if (entryPoint.startsWith('.')) {\n return path.resolve(appDir, entryPoint);\n } else if (!path.isAbsolute(entryPoint)) {\n return resolveFrom(appDir, entryPoint);\n }\n return entryPoint;\n });\n }\n });\n}\n\n/** Perform all fs commits */\nexport async function exportFromServerAsync(\n projectRoot: string,\n devServer: MetroBundlerDevServer,\n {\n outputDir,\n baseUrl,\n exportServer,\n includeSourceMaps,\n routerRoot,\n files = new Map(),\n exp,\n scriptTags,\n }: Options\n): Promise<ExportAssetMap> {\n Log.log(\n `Static rendering is enabled. ` +\n learnMore('https://docs.expo.dev/router/reference/static-rendering/')\n );\n\n const platform = 'web';\n const isExporting = true;\n const appDir = path.join(projectRoot, routerRoot);\n const injectFaviconTag = await getVirtualFaviconAssetsAsync(projectRoot, {\n outputDir,\n baseUrl,\n files,\n exp,\n });\n\n const [resources, { manifest, serverManifest, renderAsync }] = await Promise.all([\n devServer.getStaticResourcesAsync({\n includeSourceMaps,\n }),\n devServer.getStaticRenderFunctionAsync(),\n ]);\n\n makeRuntimeEntryPointsAbsolute(manifest, appDir);\n\n debug('Routes:\\n', inspect(manifest, { colors: true, depth: null }));\n\n await getFilesToExportFromServerAsync(projectRoot, {\n files,\n manifest,\n serverManifest,\n exportServer,\n async renderAsync({ pathname, route }) {\n const template = await renderAsync(pathname);\n let html = await serializeHtmlWithAssets({\n isExporting,\n resources: resources.artifacts,\n template,\n baseUrl,\n route,\n hydrate: true,\n });\n\n if (injectFaviconTag) {\n html = injectFaviconTag(html);\n }\n\n if (scriptTags) {\n // Inject script tags into the HTML.\n // <script type=\"type/expo\" data-platform=\"ios\" src=\"...\" />\n html = injectScriptTags(html, scriptTags);\n }\n\n return html;\n },\n });\n\n getFilesFromSerialAssets(resources.artifacts, {\n platform,\n includeSourceMaps,\n files,\n isServerHosted: true,\n });\n\n if (resources.assets) {\n // TODO: Collect files without writing to disk.\n // NOTE(kitten): Re. above, this is now using `files` except for iOS catalog output, which isn't used here\n await persistMetroAssetsAsync(projectRoot, resources.assets, {\n files,\n platform,\n outputDirectory: outputDir,\n baseUrl,\n });\n }\n\n if (exportServer) {\n const apiRoutes = await exportApiRoutesAsync({\n platform: 'web',\n server: devServer,\n manifest: serverManifest,\n // NOTE(kitten): For now, we always output source maps for API route exports\n includeSourceMaps: true,\n });\n\n // Add the api routes to the files to export.\n for (const [route, contents] of apiRoutes) {\n files.set(route, contents);\n }\n } else {\n warnPossibleInvalidExportType(appDir);\n }\n\n return files;\n}\n\nexport function getHtmlFiles({\n manifest,\n includeGroupVariations,\n}: {\n manifest: ExpoRouterRuntimeManifest;\n includeGroupVariations?: boolean;\n}): HtmlRequestLocation[] {\n const htmlFiles = new Set<Omit<HtmlRequestLocation, 'pathname'>>();\n\n function traverseScreens(\n screens: ExpoRouterRuntimeManifest['screens'],\n route: RouteNode | null,\n baseUrl = ''\n ) {\n for (const [key, value] of Object.entries(screens)) {\n let leaf: string | null = null;\n if (typeof value === 'string') {\n leaf = value;\n } else if (value.screens && Object.keys(value.screens).length === 0) {\n // Ensure the trailing index is accounted for.\n if (key === value.path + '/index') {\n leaf = key;\n } else {\n leaf = value.path;\n }\n\n route = value._route ?? null;\n }\n\n if (leaf != null) {\n let filePath = baseUrl + leaf;\n\n if (leaf === '') {\n filePath =\n baseUrl === ''\n ? 'index'\n : baseUrl.endsWith('/')\n ? baseUrl + 'index'\n : baseUrl.slice(0, -1);\n } else if (\n // If the path is a collection of group segments leading to an index route, append `/index`.\n stripGroupSegmentsFromPath(filePath) === ''\n ) {\n filePath += '/index';\n }\n\n // This should never happen, the type of `string | object` originally comes from React Navigation.\n if (!route) {\n throw new Error(\n `Internal error: Route not found for \"${filePath}\" while collecting static export paths.`\n );\n }\n\n if (includeGroupVariations) {\n // TODO: Dedupe requests for alias routes.\n addOptionalGroups(filePath, route);\n } else {\n htmlFiles.add({\n filePath,\n route,\n });\n }\n } else if (typeof value === 'object' && value?.screens) {\n // The __root slot has no path.\n const newPath = value.path ? baseUrl + value.path + '/' : baseUrl;\n traverseScreens(value.screens, value._route ?? null, newPath);\n }\n }\n }\n\n function addOptionalGroups(path: string, route: RouteNode) {\n const variations = getPathVariations(path);\n for (const variation of variations) {\n htmlFiles.add({ filePath: variation, route });\n }\n }\n\n traverseScreens(manifest.screens, null);\n\n return uniqueBy(Array.from(htmlFiles), (value) => value.filePath).map((value) => {\n const parts = value.filePath.split('/');\n // Replace `:foo` with `[foo]` and `*foo` with `[...foo]`\n const partsWithGroups = parts.map((part) => {\n if (part === '*not-found') {\n return `+not-found`;\n } else if (part.startsWith(':')) {\n return `[${part.slice(1)}]`;\n } else if (part.startsWith('*')) {\n return `[...${part.slice(1)}]`;\n }\n return part;\n });\n const filePathLocation = partsWithGroups.join('/');\n const filePath = filePathLocation + '.html';\n return {\n ...value,\n filePath,\n pathname: filePathLocation.replace(/(\\/?index)?$/, ''),\n };\n });\n}\n\nfunction uniqueBy<T>(array: T[], key: (value: T) => string): T[] {\n const seen = new Set<string>();\n const result: T[] = [];\n for (const value of array) {\n const id = key(value);\n if (!seen.has(id)) {\n seen.add(id);\n result.push(value);\n }\n }\n return result;\n}\n\n// Given a route like `(foo)/bar/(baz)`, return all possible variations of the route.\n// e.g. `(foo)/bar/(baz)`, `(foo)/bar/baz`, `foo/bar/(baz)`, `foo/bar/baz`,\nexport function getPathVariations(routePath: string): string[] {\n const variations = new Set<string>();\n const segments = routePath.split('/');\n\n function generateVariations(segments: string[], current = ''): void {\n if (segments.length === 0) {\n if (current) variations.add(current);\n return;\n }\n\n const [head, ...rest] = segments;\n\n if (matchGroupName(head)) {\n const groups = head.slice(1, -1).split(',');\n\n if (groups.length > 1) {\n for (const group of groups) {\n // If there are multiple groups, recurse on each group.\n generateVariations([`(${group.trim()})`, ...rest], current);\n }\n return;\n } else {\n // Start a fork where this group is included\n generateVariations(rest, current ? `${current}/(${groups[0]})` : `(${groups[0]})`);\n // This code will continue and add paths without this group included`\n }\n } else if (current) {\n current = `${current}/${head}`;\n } else {\n current = head;\n }\n\n generateVariations(rest, current);\n }\n\n generateVariations(segments);\n\n return Array.from(variations);\n}\n\nexport async function exportApiRoutesStandaloneAsync(\n devServer: MetroBundlerDevServer,\n {\n files = new Map(),\n platform,\n apiRoutesOnly,\n templateHtml,\n }: {\n files?: ExportAssetMap;\n platform: string;\n apiRoutesOnly: boolean;\n templateHtml?: string;\n }\n) {\n const { serverManifest, htmlManifest } = await devServer.getServerManifestAsync();\n\n const apiRoutes = await exportApiRoutesAsync({\n server: devServer,\n manifest: serverManifest,\n // NOTE(kitten): For now, we always output source maps for API route exports\n includeSourceMaps: true,\n platform,\n apiRoutesOnly,\n });\n\n // Add the api routes to the files to export.\n for (const [route, contents] of apiRoutes) {\n files.set(route, contents);\n }\n\n if (templateHtml && devServer.isReactServerComponentsEnabled) {\n // TODO: Export an HTML entry for each file. This is a temporary solution until we have SSR/SSG for RSC.\n await getFilesToExportFromServerAsync(devServer.projectRoot, {\n manifest: htmlManifest,\n serverManifest,\n exportServer: true,\n files,\n renderAsync: async ({ pathname, filePath }) => {\n files.set(filePath, {\n contents: templateHtml!,\n routeId: pathname,\n targetDomain: 'server',\n });\n return templateHtml!;\n },\n });\n }\n\n return files;\n}\n\nasync function exportApiRoutesAsync({\n includeSourceMaps,\n server,\n platform,\n apiRoutesOnly,\n ...props\n}: Pick<Options, 'includeSourceMaps'> & {\n server: MetroBundlerDevServer;\n manifest: ExpoRouterServerManifestV1;\n platform: string;\n apiRoutesOnly?: boolean;\n}): Promise<ExportAssetMap> {\n const { manifest, files } = await server.exportExpoRouterApiRoutesAsync({\n outputDir: '_expo/functions',\n prerenderManifest: props.manifest,\n includeSourceMaps,\n platform,\n });\n\n // HACK: Clear out the HTML and 404 routes if we're only exporting API routes. This is used for native apps that are using API routes but haven't implemented web support yet.\n if (apiRoutesOnly) {\n manifest.htmlRoutes = [];\n manifest.notFoundRoutes = [];\n }\n\n files.set('_expo/routes.json', {\n contents: JSON.stringify(manifest, null, 2),\n targetDomain: 'server',\n });\n\n return files;\n}\n\nfunction warnPossibleInvalidExportType(appDir: string) {\n const apiRoutes = getApiRoutesForDirectory(appDir);\n if (apiRoutes.length) {\n // TODO: Allow API Routes for native-only.\n Log.warn(\n chalk.yellow`Skipping export for API routes because \\`web.output\\` is not \"server\". You may want to remove the routes: ${apiRoutes\n .map((v) => path.relative(appDir, v))\n .join(', ')}`\n );\n }\n\n const middlewareFile = getMiddlewareForDirectory(appDir);\n if (middlewareFile) {\n Log.warn(\n chalk.yellow`Skipping export for middleware because \\`web.output\\` is not \"server\". You may want to remove ${path.relative(appDir, middlewareFile)}`\n );\n }\n}\n"],"names":["exportApiRoutesStandaloneAsync","exportFromServerAsync","getFilesToExportFromServerAsync","getHtmlFiles","getPathVariations","injectScriptTags","debug","require","html","scriptTags","scriptTagsHtml","map","tag","platform","src","join","replace","matchGroupName","name","match","projectRoot","manifest","serverManifest","renderAsync","exportServer","files","Map","subsetServerManifest","headers","redirects","set","contents","JSON","stringify","targetDomain","Promise","all","includeGroupVariations","route","filePath","pathname","type","data","routeId","e","logMetroErrorAsync","error","Error","modifyRouteNodeInRuntimeManifest","callback","iterateScreens","screens","Object","values","value","_route","makeRuntimeEntryPointsAbsolute","appDir","Array","isArray","entryPoints","entryPoint","shouldLinkExternally","startsWith","path","resolve","isAbsolute","resolveFrom","devServer","outputDir","baseUrl","includeSourceMaps","routerRoot","exp","Log","log","learnMore","isExporting","injectFaviconTag","getVirtualFaviconAssetsAsync","resources","getStaticResourcesAsync","getStaticRenderFunctionAsync","inspect","colors","depth","template","serializeHtmlWithAssets","artifacts","hydrate","getFilesFromSerialAssets","isServerHosted","assets","persistMetroAssetsAsync","outputDirectory","apiRoutes","exportApiRoutesAsync","server","warnPossibleInvalidExportType","htmlFiles","Set","traverseScreens","key","entries","leaf","keys","length","endsWith","slice","stripGroupSegmentsFromPath","addOptionalGroups","add","newPath","variations","variation","uniqueBy","from","parts","split","partsWithGroups","part","filePathLocation","array","seen","result","id","has","push","routePath","segments","generateVariations","current","head","rest","groups","group","trim","apiRoutesOnly","templateHtml","htmlManifest","getServerManifestAsync","isReactServerComponentsEnabled","props","exportExpoRouterApiRoutesAsync","prerenderManifest","htmlRoutes","notFoundRoutes","getApiRoutesForDirectory","warn","chalk","yellow","v","relative","middlewareFile","getMiddlewareForDirectory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/export/exportStaticAsync.ts"],"sourcesContent":["/**\n * Copyright © 2022 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 { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport { RouteNode } from 'expo-router/build/Route';\nimport { stripGroupSegmentsFromPath } from 'expo-router/build/matchers';\nimport { shouldLinkExternally } from 'expo-router/build/utils/url';\nimport { type RoutesManifest } from 'expo-server/private';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport { inspect } from 'util';\n\nimport { getVirtualFaviconAssetsAsync } from './favicon';\nimport { persistMetroAssetsAsync } from './persistMetroAssets';\nimport { ExportAssetMap, getFilesFromSerialAssets } from './saveAssets';\nimport { Log } from '../log';\nimport {\n ExpoRouterRuntimeManifest,\n MetroBundlerDevServer,\n} from '../start/server/metro/MetroBundlerDevServer';\nimport { logMetroErrorAsync } from '../start/server/metro/metroErrorInterface';\nimport { getApiRoutesForDirectory, getMiddlewareForDirectory } from '../start/server/metro/router';\nimport { serializeHtmlWithAssets } from '../start/server/metro/serializeHtml';\nimport { learnMore } from '../utils/link';\n\nconst debug = require('debug')('expo:export:generateStaticRoutes') as typeof console.log;\n\ntype ExtraScriptTag = {\n platform: string;\n src: string;\n};\n\ntype Options = {\n mode: 'production' | 'development';\n files?: ExportAssetMap;\n outputDir: string;\n minify: boolean;\n exportServer: boolean;\n baseUrl: string;\n includeSourceMaps: boolean;\n entryPoint?: string;\n clear: boolean;\n routerRoot: string;\n reactCompiler: boolean;\n maxWorkers?: number;\n isExporting: boolean;\n exp?: ExpoConfig;\n // <script type=\"type/expo\" data-platform=\"ios\" src=\"...\" />\n scriptTags?: ExtraScriptTag[];\n};\n\ntype HtmlRequestLocation = {\n /** The output file path name to use relative to the static folder. */\n filePath: string;\n /** The pathname to make requests to in order to fetch the HTML. */\n pathname: string;\n /** The runtime route node object, used to associate async modules with the static HTML. */\n route: RouteNode;\n};\n\nexport function injectScriptTags(html: string, scriptTags: ExtraScriptTag[]): string {\n const scriptTagsHtml = scriptTags\n .map((tag) =>\n tag.platform === 'web'\n ? `<script src=\"${tag.src}\"></script>`\n : `<script type=\"type/expo\" src=\"${tag.src}\" data-platform=\"${tag.platform}\"></script>`\n )\n .join('\\n');\n html = html.replace('</head>', `${scriptTagsHtml}\\n</head>`);\n return html;\n}\n\n/** Match `(page)` -> `page` */\nfunction matchGroupName(name: string): string | undefined {\n return name.match(/^\\(([^/]+?)\\)$/)?.[1];\n}\n\nexport async function getFilesToExportFromServerAsync(\n projectRoot: string,\n {\n manifest,\n serverManifest,\n renderAsync,\n // Servers can handle group routes automatically and therefore\n // don't require the build-time generation of every possible group\n // variation.\n exportServer,\n // name : contents\n files = new Map(),\n }: {\n manifest: ExpoRouterRuntimeManifest;\n serverManifest: RoutesManifest;\n renderAsync: (requestLocation: HtmlRequestLocation) => Promise<string>;\n exportServer?: boolean;\n files?: ExportAssetMap;\n }\n): Promise<ExportAssetMap> {\n if (!exportServer && serverManifest) {\n // When we're not exporting a `server` output, we provide a `_expo/.routes.json` for\n // EAS Hosting to recognize the `headers` and `redirects` configs\n const subsetServerManifest = {\n headers: serverManifest.headers,\n redirects: serverManifest.redirects,\n };\n files.set('_expo/.routes.json', {\n contents: JSON.stringify(subsetServerManifest, null, 2),\n targetDomain: 'client',\n });\n }\n\n await Promise.all(\n getHtmlFiles({ manifest, includeGroupVariations: !exportServer }).map(\n async ({ route, filePath, pathname }) => {\n // Rewrite routes should not be statically generated\n if (route.type === 'rewrite') {\n return;\n }\n\n try {\n const targetDomain = exportServer ? 'server' : 'client';\n files.set(filePath, { contents: '', targetDomain });\n const data = await renderAsync({ route, filePath, pathname });\n files.set(filePath, {\n contents: data,\n routeId: pathname,\n targetDomain,\n });\n } catch (e: any) {\n await logMetroErrorAsync({ error: e, projectRoot });\n throw new Error('Failed to statically export route: ' + pathname);\n }\n }\n )\n );\n\n return files;\n}\n\nfunction modifyRouteNodeInRuntimeManifest(\n manifest: ExpoRouterRuntimeManifest,\n callback: (route: RouteNode) => any\n) {\n const iterateScreens = (screens: ExpoRouterRuntimeManifest['screens']) => {\n Object.values(screens).map((value) => {\n if (typeof value !== 'string') {\n if (value._route) callback(value._route);\n iterateScreens(value.screens);\n }\n });\n };\n\n iterateScreens(manifest.screens);\n}\n\n// TODO: Do this earlier in the process.\nfunction makeRuntimeEntryPointsAbsolute(manifest: ExpoRouterRuntimeManifest, appDir: string) {\n modifyRouteNodeInRuntimeManifest(manifest, (route) => {\n if (Array.isArray(route.entryPoints)) {\n route.entryPoints = route.entryPoints.map((entryPoint) => {\n // TODO(@hassankhan): ENG-16577\n if (shouldLinkExternally(entryPoint)) {\n return entryPoint;\n }\n\n if (entryPoint.startsWith('.')) {\n return path.resolve(appDir, entryPoint);\n } else if (!path.isAbsolute(entryPoint)) {\n return resolveFrom(appDir, entryPoint);\n }\n return entryPoint;\n });\n }\n });\n}\n\n/** Perform all fs commits */\nexport async function exportFromServerAsync(\n projectRoot: string,\n devServer: MetroBundlerDevServer,\n {\n outputDir,\n baseUrl,\n exportServer,\n includeSourceMaps,\n routerRoot,\n files = new Map(),\n exp,\n scriptTags,\n }: Options\n): Promise<ExportAssetMap> {\n Log.log(\n `Static rendering is enabled. ` +\n learnMore('https://docs.expo.dev/router/reference/static-rendering/')\n );\n\n const platform = 'web';\n const isExporting = true;\n const appDir = path.join(projectRoot, routerRoot);\n const injectFaviconTag = await getVirtualFaviconAssetsAsync(projectRoot, {\n outputDir,\n baseUrl,\n files,\n exp,\n });\n\n const [resources, { manifest, serverManifest, renderAsync }] = await Promise.all([\n devServer.getStaticResourcesAsync({\n includeSourceMaps,\n }),\n devServer.getStaticRenderFunctionAsync(),\n ]);\n\n makeRuntimeEntryPointsAbsolute(manifest, appDir);\n\n debug('Routes:\\n', inspect(manifest, { colors: true, depth: null }));\n\n await getFilesToExportFromServerAsync(projectRoot, {\n files,\n manifest,\n serverManifest,\n exportServer,\n async renderAsync({ pathname, route }) {\n const template = await renderAsync(pathname);\n let html = await serializeHtmlWithAssets({\n isExporting,\n resources: resources.artifacts,\n template,\n baseUrl,\n route,\n hydrate: true,\n });\n\n if (injectFaviconTag) {\n html = injectFaviconTag(html);\n }\n\n if (scriptTags) {\n // Inject script tags into the HTML.\n // <script type=\"type/expo\" data-platform=\"ios\" src=\"...\" />\n html = injectScriptTags(html, scriptTags);\n }\n\n return html;\n },\n });\n\n getFilesFromSerialAssets(resources.artifacts, {\n platform,\n includeSourceMaps,\n files,\n isServerHosted: true,\n });\n\n if (resources.assets) {\n // TODO: Collect files without writing to disk.\n // NOTE(kitten): Re. above, this is now using `files` except for iOS catalog output, which isn't used here\n await persistMetroAssetsAsync(projectRoot, resources.assets, {\n files,\n platform,\n outputDirectory: outputDir,\n baseUrl,\n });\n }\n\n if (exportServer) {\n const apiRoutes = await exportApiRoutesAsync({\n platform: 'web',\n server: devServer,\n manifest: serverManifest,\n // NOTE(kitten): For now, we always output source maps for API route exports\n includeSourceMaps: true,\n });\n\n // Add the api routes to the files to export.\n for (const [route, contents] of apiRoutes) {\n files.set(route, contents);\n }\n } else {\n warnPossibleInvalidExportType(appDir);\n }\n\n return files;\n}\n\nexport function getHtmlFiles({\n manifest,\n includeGroupVariations,\n}: {\n manifest: ExpoRouterRuntimeManifest;\n includeGroupVariations?: boolean;\n}): HtmlRequestLocation[] {\n const htmlFiles = new Set<Omit<HtmlRequestLocation, 'pathname'>>();\n\n function traverseScreens(\n screens: ExpoRouterRuntimeManifest['screens'],\n route: RouteNode | null,\n baseUrl = ''\n ) {\n for (const [key, value] of Object.entries(screens)) {\n let leaf: string | null = null;\n if (typeof value === 'string') {\n leaf = value;\n } else if (value.screens && Object.keys(value.screens).length === 0) {\n // Ensure the trailing index is accounted for.\n if (key === value.path + '/index') {\n leaf = key;\n } else {\n leaf = value.path;\n }\n\n route = value._route ?? null;\n }\n\n if (leaf != null) {\n let filePath = baseUrl + leaf;\n\n if (leaf === '') {\n filePath =\n baseUrl === ''\n ? 'index'\n : baseUrl.endsWith('/')\n ? baseUrl + 'index'\n : baseUrl.slice(0, -1);\n } else if (\n // If the path is a collection of group segments leading to an index route, append `/index`.\n stripGroupSegmentsFromPath(filePath) === ''\n ) {\n filePath += '/index';\n }\n\n // This should never happen, the type of `string | object` originally comes from React Navigation.\n if (!route) {\n throw new Error(\n `Internal error: Route not found for \"${filePath}\" while collecting static export paths.`\n );\n }\n\n if (includeGroupVariations) {\n // TODO: Dedupe requests for alias routes.\n addOptionalGroups(filePath, route);\n } else {\n htmlFiles.add({\n filePath,\n route,\n });\n }\n } else if (typeof value === 'object' && value?.screens) {\n // The __root slot has no path.\n const newPath = value.path ? baseUrl + value.path + '/' : baseUrl;\n traverseScreens(value.screens, value._route ?? null, newPath);\n }\n }\n }\n\n function addOptionalGroups(path: string, route: RouteNode) {\n const variations = getPathVariations(path);\n for (const variation of variations) {\n htmlFiles.add({ filePath: variation, route });\n }\n }\n\n traverseScreens(manifest.screens, null);\n\n return uniqueBy(Array.from(htmlFiles), (value) => value.filePath).map((value) => {\n const parts = value.filePath.split('/');\n // Replace `:foo` with `[foo]` and `*foo` with `[...foo]`\n const partsWithGroups = parts.map((part) => {\n if (part === '*not-found') {\n return `+not-found`;\n } else if (part.startsWith(':')) {\n return `[${part.slice(1)}]`;\n } else if (part.startsWith('*')) {\n return `[...${part.slice(1)}]`;\n }\n return part;\n });\n const filePathLocation = partsWithGroups.join('/');\n const filePath = filePathLocation + '.html';\n return {\n ...value,\n filePath,\n pathname: filePathLocation.replace(/(\\/?index)?$/, ''),\n };\n });\n}\n\nfunction uniqueBy<T>(array: T[], key: (value: T) => string): T[] {\n const seen = new Set<string>();\n const result: T[] = [];\n for (const value of array) {\n const id = key(value);\n if (!seen.has(id)) {\n seen.add(id);\n result.push(value);\n }\n }\n return result;\n}\n\n// Given a route like `(foo)/bar/(baz)`, return all possible variations of the route.\n// e.g. `(foo)/bar/(baz)`, `(foo)/bar/baz`, `foo/bar/(baz)`, `foo/bar/baz`,\nexport function getPathVariations(routePath: string): string[] {\n const variations = new Set<string>();\n const segments = routePath.split('/');\n\n function generateVariations(segments: string[], current = ''): void {\n if (segments.length === 0) {\n if (current) variations.add(current);\n return;\n }\n\n const [head, ...rest] = segments;\n\n if (matchGroupName(head)) {\n const groups = head.slice(1, -1).split(',');\n\n if (groups.length > 1) {\n for (const group of groups) {\n // If there are multiple groups, recurse on each group.\n generateVariations([`(${group.trim()})`, ...rest], current);\n }\n return;\n } else {\n // Start a fork where this group is included\n generateVariations(rest, current ? `${current}/(${groups[0]})` : `(${groups[0]})`);\n // This code will continue and add paths without this group included`\n }\n } else if (current) {\n current = `${current}/${head}`;\n } else {\n current = head;\n }\n\n generateVariations(rest, current);\n }\n\n generateVariations(segments);\n\n return Array.from(variations);\n}\n\nexport async function exportApiRoutesStandaloneAsync(\n devServer: MetroBundlerDevServer,\n {\n files = new Map(),\n platform,\n apiRoutesOnly,\n templateHtml,\n }: {\n files?: ExportAssetMap;\n platform: string;\n apiRoutesOnly: boolean;\n templateHtml?: string;\n }\n) {\n const { serverManifest, htmlManifest } = await devServer.getServerManifestAsync();\n\n const apiRoutes = await exportApiRoutesAsync({\n server: devServer,\n manifest: serverManifest,\n // NOTE(kitten): For now, we always output source maps for API route exports\n includeSourceMaps: true,\n platform,\n apiRoutesOnly,\n });\n\n // Add the api routes to the files to export.\n for (const [route, contents] of apiRoutes) {\n files.set(route, contents);\n }\n\n if (templateHtml && devServer.isReactServerComponentsEnabled) {\n // TODO: Export an HTML entry for each file. This is a temporary solution until we have SSR/SSG for RSC.\n await getFilesToExportFromServerAsync(devServer.projectRoot, {\n manifest: htmlManifest,\n serverManifest,\n exportServer: true,\n files,\n renderAsync: async ({ pathname, filePath }) => {\n files.set(filePath, {\n contents: templateHtml!,\n routeId: pathname,\n targetDomain: 'server',\n });\n return templateHtml!;\n },\n });\n }\n\n return files;\n}\n\nasync function exportApiRoutesAsync({\n includeSourceMaps,\n server,\n platform,\n apiRoutesOnly,\n ...props\n}: Pick<Options, 'includeSourceMaps'> & {\n server: MetroBundlerDevServer;\n manifest: RoutesManifest<string>;\n platform: string;\n apiRoutesOnly?: boolean;\n}): Promise<ExportAssetMap> {\n const { manifest, files } = await server.exportExpoRouterApiRoutesAsync({\n outputDir: '_expo/functions',\n prerenderManifest: props.manifest,\n includeSourceMaps,\n platform,\n });\n\n // HACK: Clear out the HTML and 404 routes if we're only exporting API routes. This is used for native apps that are using API routes but haven't implemented web support yet.\n if (apiRoutesOnly) {\n manifest.htmlRoutes = [];\n manifest.notFoundRoutes = [];\n }\n\n files.set('_expo/routes.json', {\n contents: JSON.stringify(manifest, null, 2),\n targetDomain: 'server',\n });\n\n return files;\n}\n\nfunction warnPossibleInvalidExportType(appDir: string) {\n const apiRoutes = getApiRoutesForDirectory(appDir);\n if (apiRoutes.length) {\n // TODO: Allow API Routes for native-only.\n Log.warn(\n chalk.yellow`Skipping export for API routes because \\`web.output\\` is not \"server\". You may want to remove the routes: ${apiRoutes\n .map((v) => path.relative(appDir, v))\n .join(', ')}`\n );\n }\n\n const middlewareFile = getMiddlewareForDirectory(appDir);\n if (middlewareFile) {\n Log.warn(\n chalk.yellow`Skipping export for middleware because \\`web.output\\` is not \"server\". You may want to remove ${path.relative(appDir, middlewareFile)}`\n );\n }\n}\n"],"names":["exportApiRoutesStandaloneAsync","exportFromServerAsync","getFilesToExportFromServerAsync","getHtmlFiles","getPathVariations","injectScriptTags","debug","require","html","scriptTags","scriptTagsHtml","map","tag","platform","src","join","replace","matchGroupName","name","match","projectRoot","manifest","serverManifest","renderAsync","exportServer","files","Map","subsetServerManifest","headers","redirects","set","contents","JSON","stringify","targetDomain","Promise","all","includeGroupVariations","route","filePath","pathname","type","data","routeId","e","logMetroErrorAsync","error","Error","modifyRouteNodeInRuntimeManifest","callback","iterateScreens","screens","Object","values","value","_route","makeRuntimeEntryPointsAbsolute","appDir","Array","isArray","entryPoints","entryPoint","shouldLinkExternally","startsWith","path","resolve","isAbsolute","resolveFrom","devServer","outputDir","baseUrl","includeSourceMaps","routerRoot","exp","Log","log","learnMore","isExporting","injectFaviconTag","getVirtualFaviconAssetsAsync","resources","getStaticResourcesAsync","getStaticRenderFunctionAsync","inspect","colors","depth","template","serializeHtmlWithAssets","artifacts","hydrate","getFilesFromSerialAssets","isServerHosted","assets","persistMetroAssetsAsync","outputDirectory","apiRoutes","exportApiRoutesAsync","server","warnPossibleInvalidExportType","htmlFiles","Set","traverseScreens","key","entries","leaf","keys","length","endsWith","slice","stripGroupSegmentsFromPath","addOptionalGroups","add","newPath","variations","variation","uniqueBy","from","parts","split","partsWithGroups","part","filePathLocation","array","seen","result","id","has","push","routePath","segments","generateVariations","current","head","rest","groups","group","trim","apiRoutesOnly","templateHtml","htmlManifest","getServerManifestAsync","isReactServerComponentsEnabled","props","exportExpoRouterApiRoutesAsync","prerenderManifest","htmlRoutes","notFoundRoutes","getApiRoutesForDirectory","warn","chalk","yellow","v","relative","middlewareFile","getMiddlewareForDirectory"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/interface/commandsTable.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport qrcode from 'qrcode-terminal';\nimport wrapAnsi from 'wrap-ansi';\n\nimport * as Log from '../../log';\n\nexport const BLT = '\\u203A';\n\nexport type StartOptions = {\n isWebSocketsEnabled?: boolean;\n devClient?: boolean;\n reset?: boolean;\n nonPersistent?: boolean;\n maxWorkers?: number;\n platforms?: ExpoConfig['platforms'];\n};\n\nexport const printHelp = (): void => {\n logCommandsTable([{ key: '?', msg: 'show all commands' }]);\n};\n\n/** Print the world famous 'Expo QR Code'. */\nexport function printQRCode(url: string) {\n qrcode.generate(url, { small: true }, (code) => Log.log(code));\n}\n\nexport const getTerminalColumns = () => process.stdout.columns || 80;\nexport const printItem = (text: string): string =>\n `${BLT} ` + wrapAnsi(text, getTerminalColumns()).trimStart();\n\nexport function printUsage(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>,\n { verbose }: { verbose: boolean }\n) {\n const isMac = process.platform === 'darwin';\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n const isAndroidDisabled = !platforms.includes('android');\n const isIosDisabled = !platforms.includes('ios');\n const isWebDisable = !platforms.includes('web');\n\n const switchMsg = `switch to ${options.devClient === false ? 'development build' : 'Expo Go'}`;\n const target = options.devClient === false ? `Expo Go` : 'development build';\n\n Log.log();\n Log.log(printItem(chalk`Using {cyan ${target}}`));\n\n if (verbose) {\n logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n { key: 'shift+a', msg: 'select an Android device or emulator', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n isMac && { key: 'shift+i', msg: 'select an iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'j', msg: 'open debugger' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n { key: 'c', msg: 'show project QR' },\n {},\n ]);\n } else {\n logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'j', msg: 'open debugger' },\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n {},\n ]);\n }\n}\n\nfunction logCommandsTable(\n ui: (false | { key?: string; msg?: string; status?: string; disabled?: boolean })[]\n) {\n Log.log(\n ui\n .filter(Boolean)\n // @ts-ignore: filter doesn't work\n .map(({ key, msg, status, disabled }) => {\n if (!key) return '';\n let view = `${BLT} `;\n if (key.length === 1) view += 'Press ';\n view += chalk`{bold ${key}} {dim │} `;\n view += msg;\n if (status) {\n view += ` ${chalk.dim(`(${chalk.italic(status)})`)}`;\n }\n if (disabled) {\n view = chalk.dim(view);\n }\n return view;\n })\n .join('\\n')\n );\n}\n"],"names":["BLT","getTerminalColumns","printHelp","printItem","printQRCode","printUsage","logCommandsTable","key","msg","url","qrcode","generate","small","code","Log","log","process","stdout","columns","text","wrapAnsi","trimStart","options","verbose","isMac","platform","platforms","isAndroidDisabled","includes","isIosDisabled","isWebDisable","switchMsg","devClient","target","chalk","disabled","isWebSocketsEnabled","ui","filter","Boolean","map","status","view","length","dim","italic","join"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/interface/commandsTable.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport chalk from 'chalk';\nimport qrcode from 'qrcode-terminal';\nimport wrapAnsi from 'wrap-ansi';\n\nimport * as Log from '../../log';\nimport type { McpServer } from '../server/MCP';\n\nexport const BLT = '\\u203A';\n\nexport type StartOptions = {\n isWebSocketsEnabled?: boolean;\n devClient?: boolean;\n reset?: boolean;\n nonPersistent?: boolean;\n maxWorkers?: number;\n platforms?: ExpoConfig['platforms'];\n mcpServer?: McpServer;\n};\n\nexport const printHelp = (): void => {\n logCommandsTable([{ key: '?', msg: 'show all commands' }]);\n};\n\n/** Print the world famous 'Expo QR Code'. */\nexport function printQRCode(url: string) {\n qrcode.generate(url, { small: true }, (code) => Log.log(code));\n}\n\nexport const getTerminalColumns = () => process.stdout.columns || 80;\nexport const printItem = (text: string): string =>\n `${BLT} ` + wrapAnsi(text, getTerminalColumns()).trimStart();\n\nexport function printUsage(\n options: Pick<StartOptions, 'devClient' | 'isWebSocketsEnabled' | 'platforms'>,\n { verbose }: { verbose: boolean }\n) {\n const isMac = process.platform === 'darwin';\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n const isAndroidDisabled = !platforms.includes('android');\n const isIosDisabled = !platforms.includes('ios');\n const isWebDisable = !platforms.includes('web');\n\n const switchMsg = `switch to ${options.devClient === false ? 'development build' : 'Expo Go'}`;\n const target = options.devClient === false ? `Expo Go` : 'development build';\n\n Log.log();\n Log.log(printItem(chalk`Using {cyan ${target}}`));\n\n if (verbose) {\n logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n { key: 'shift+a', msg: 'select an Android device or emulator', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n isMac && { key: 'shift+i', msg: 'select an iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'j', msg: 'open debugger' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n { key: 'c', msg: 'show project QR' },\n {},\n ]);\n } else {\n logCommandsTable([\n { key: 's', msg: switchMsg },\n {},\n { key: 'a', msg: 'open Android', disabled: isAndroidDisabled },\n isMac && { key: 'i', msg: 'open iOS simulator', disabled: isIosDisabled },\n { key: 'w', msg: 'open web', disabled: isWebDisable },\n {},\n { key: 'j', msg: 'open debugger' },\n { key: 'r', msg: 'reload app' },\n !!options.isWebSocketsEnabled && { key: 'm', msg: 'toggle menu' },\n !!options.isWebSocketsEnabled && { key: 'shift+m', msg: 'more tools' },\n { key: 'o', msg: 'open project code in your editor' },\n {},\n ]);\n }\n}\n\nfunction logCommandsTable(\n ui: (false | { key?: string; msg?: string; status?: string; disabled?: boolean })[]\n) {\n Log.log(\n ui\n .filter(Boolean)\n // @ts-ignore: filter doesn't work\n .map(({ key, msg, status, disabled }) => {\n if (!key) return '';\n let view = `${BLT} `;\n if (key.length === 1) view += 'Press ';\n view += chalk`{bold ${key}} {dim │} `;\n view += msg;\n if (status) {\n view += ` ${chalk.dim(`(${chalk.italic(status)})`)}`;\n }\n if (disabled) {\n view = chalk.dim(view);\n }\n return view;\n })\n .join('\\n')\n );\n}\n"],"names":["BLT","getTerminalColumns","printHelp","printItem","printQRCode","printUsage","logCommandsTable","key","msg","url","qrcode","generate","small","code","Log","log","process","stdout","columns","text","wrapAnsi","trimStart","options","verbose","isMac","platform","platforms","isAndroidDisabled","includes","isIosDisabled","isWebDisable","switchMsg","devClient","target","chalk","disabled","isWebSocketsEnabled","ui","filter","Boolean","map","status","view","length","dim","italic","join"],"mappings":"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"}
|
|
@@ -122,6 +122,9 @@ async function startInterfaceAsync(devServerManager, options) {
|
|
|
122
122
|
}).start();
|
|
123
123
|
try {
|
|
124
124
|
await devServerManager.stopAsync();
|
|
125
|
+
if (options.mcpServer) {
|
|
126
|
+
await options.mcpServer.closeAsync();
|
|
127
|
+
}
|
|
125
128
|
spinner.stopAndPersist({
|
|
126
129
|
text: 'Stopped server',
|
|
127
130
|
symbol: `\u203A`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/interface/startInterface.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { KeyPressHandler } from './KeyPressHandler';\nimport { BLT, printHelp, printUsage, StartOptions } from './commandsTable';\nimport { DevServerManagerActions } from './interactiveActions';\nimport * as Log from '../../log';\nimport { openInEditorAsync } from '../../utils/editor';\nimport { AbortCommandError } from '../../utils/errors';\nimport { getAllSpinners, ora } from '../../utils/ora';\nimport { getProgressBar, setProgressBar } from '../../utils/progress';\nimport { addInteractionListener, pauseInteractions } from '../../utils/prompts';\nimport { WebSupportProjectPrerequisite } from '../doctor/web/WebSupportProjectPrerequisite';\nimport { DevServerManager } from '../server/DevServerManager';\n\nconst debug = require('debug')('expo:start:interface:startInterface') as typeof console.log;\n\nconst CTRL_C = '\\u0003';\nconst CTRL_D = '\\u0004';\nconst CTRL_L = '\\u000C';\n\nconst PLATFORM_SETTINGS: Record<\n string,\n { name: string; key: 'android' | 'ios'; launchTarget: 'emulator' | 'simulator' }\n> = {\n android: {\n name: 'Android',\n key: 'android',\n launchTarget: 'emulator',\n },\n ios: {\n name: 'iOS',\n key: 'ios',\n launchTarget: 'simulator',\n },\n};\n\nexport async function startInterfaceAsync(\n devServerManager: DevServerManager,\n options: Pick<StartOptions, 'devClient' | 'platforms'>\n) {\n const actions = new DevServerManagerActions(devServerManager, options);\n\n const isWebSocketsEnabled = devServerManager.getDefaultDevServer()?.isTargetingNative();\n\n const usageOptions = {\n isWebSocketsEnabled,\n devClient: devServerManager.options.devClient,\n ...options,\n };\n\n actions.printDevServerInfo(usageOptions);\n\n const onPressAsync = async (key: string) => {\n // Auxillary commands all escape.\n switch (key) {\n case CTRL_C:\n case CTRL_D: {\n // Prevent terminal UI from accepting commands while the process is closing.\n // Without this, fast typers will close the server then start typing their\n // next command and have a bunch of unrelated things pop up.\n pauseInteractions();\n\n const spinners = getAllSpinners();\n spinners.forEach((spinner) => {\n spinner.fail();\n });\n\n const currentProgress = getProgressBar();\n if (currentProgress) {\n currentProgress.terminate();\n setProgressBar(null);\n }\n const spinner = ora({ text: 'Stopping server', color: 'white' }).start();\n try {\n await devServerManager.stopAsync();\n spinner.stopAndPersist({ text: 'Stopped server', symbol: `\\u203A` });\n // @ts-ignore: Argument of type '\"SIGINT\"' is not assignable to parameter of type '\"disconnect\"'.\n process.emit('SIGINT');\n\n // TODO: Is this the right place to do this?\n process.exit();\n } catch (error) {\n spinner.fail('Failed to stop server');\n throw error;\n }\n break;\n }\n case CTRL_L:\n return Log.clear();\n case '?':\n return printUsage(usageOptions, { verbose: true });\n }\n\n // Optionally enabled\n\n if (isWebSocketsEnabled) {\n switch (key) {\n case 'm':\n return actions.toggleDevMenu();\n case 'M':\n return actions.openMoreToolsAsync();\n }\n }\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n if (['i', 'a'].includes(key.toLowerCase())) {\n const platform = key.toLowerCase() === 'i' ? 'ios' : 'android';\n\n const shouldPrompt = ['I', 'A'].includes(key);\n if (shouldPrompt) {\n Log.clear();\n }\n\n const server = devServerManager.getDefaultDevServer();\n const settings = PLATFORM_SETTINGS[platform];\n\n Log.log(`${BLT} Opening on ${settings.name}...`);\n\n if (server.isTargetingNative() && !platforms.includes(settings.key)) {\n Log.warn(\n chalk`${settings.name} is disabled, enable it by adding {bold ${settings.key}} to the platforms array in your app.json or app.config.js`\n );\n } else {\n try {\n await server.openPlatformAsync(settings.launchTarget, { shouldPrompt });\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n }\n // Break out early.\n return;\n }\n\n switch (key) {\n case 's': {\n Log.clear();\n if (await devServerManager.toggleRuntimeMode()) {\n usageOptions.devClient = devServerManager.options.devClient;\n return actions.printDevServerInfo(usageOptions);\n }\n break;\n }\n case 'w': {\n try {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n if (!platforms.includes('web')) {\n platforms.push('web');\n options.platforms?.push('web');\n }\n } catch (e: any) {\n Log.warn(e.message);\n break;\n }\n\n const isDisabled = !platforms.includes('web');\n if (isDisabled) {\n debug('Web is disabled');\n // Use warnings from the web support setup.\n break;\n }\n\n // Ensure the Webpack dev server is running first\n if (!devServerManager.getWebDevServer()) {\n debug('Starting up webpack dev server');\n await devServerManager.ensureWebDevServerRunningAsync();\n // When this is the first time webpack is started, reprint the connection info.\n actions.printDevServerInfo(usageOptions);\n }\n\n Log.log(`${BLT} Open in the web browser...`);\n try {\n await devServerManager.getWebDevServer()?.openPlatformAsync('desktop');\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n break;\n }\n case 'c':\n Log.clear();\n return actions.printDevServerInfo(usageOptions);\n case 'j':\n return actions.openJsInspectorAsync();\n case 'r':\n return actions.reloadApp();\n case 'o':\n Log.log(`${BLT} Opening the editor...`);\n return openInEditorAsync(devServerManager.projectRoot);\n }\n };\n\n const keyPressHandler = new KeyPressHandler(onPressAsync);\n\n const listener = keyPressHandler.createInteractionListener();\n\n addInteractionListener(listener);\n\n // Start observing...\n keyPressHandler.startInterceptingKeyStrokes();\n}\n"],"names":["startInterfaceAsync","debug","require","CTRL_C","CTRL_D","CTRL_L","PLATFORM_SETTINGS","android","name","key","launchTarget","ios","devServerManager","options","actions","DevServerManagerActions","isWebSocketsEnabled","getDefaultDevServer","isTargetingNative","usageOptions","devClient","printDevServerInfo","onPressAsync","pauseInteractions","spinners","getAllSpinners","forEach","spinner","fail","currentProgress","getProgressBar","terminate","setProgressBar","ora","text","color","start","stopAsync","stopAndPersist","symbol","process","emit","exit","error","Log","clear","printUsage","verbose","toggleDevMenu","openMoreToolsAsync","platforms","includes","toLowerCase","platform","shouldPrompt","server","settings","log","BLT","warn","chalk","openPlatformAsync","printHelp","AbortCommandError","exception","toggleRuntimeMode","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","push","e","message","isDisabled","getWebDevServer","ensureWebDevServerRunningAsync","openJsInspectorAsync","reloadApp","openInEditorAsync","projectRoot","keyPressHandler","KeyPressHandler","listener","createInteractionListener","addInteractionListener","startInterceptingKeyStrokes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/interface/startInterface.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { KeyPressHandler } from './KeyPressHandler';\nimport { BLT, printHelp, printUsage, StartOptions } from './commandsTable';\nimport { DevServerManagerActions } from './interactiveActions';\nimport * as Log from '../../log';\nimport { openInEditorAsync } from '../../utils/editor';\nimport { AbortCommandError } from '../../utils/errors';\nimport { getAllSpinners, ora } from '../../utils/ora';\nimport { getProgressBar, setProgressBar } from '../../utils/progress';\nimport { addInteractionListener, pauseInteractions } from '../../utils/prompts';\nimport { WebSupportProjectPrerequisite } from '../doctor/web/WebSupportProjectPrerequisite';\nimport { DevServerManager } from '../server/DevServerManager';\n\nconst debug = require('debug')('expo:start:interface:startInterface') as typeof console.log;\n\nconst CTRL_C = '\\u0003';\nconst CTRL_D = '\\u0004';\nconst CTRL_L = '\\u000C';\n\nconst PLATFORM_SETTINGS: Record<\n string,\n { name: string; key: 'android' | 'ios'; launchTarget: 'emulator' | 'simulator' }\n> = {\n android: {\n name: 'Android',\n key: 'android',\n launchTarget: 'emulator',\n },\n ios: {\n name: 'iOS',\n key: 'ios',\n launchTarget: 'simulator',\n },\n};\n\nexport async function startInterfaceAsync(\n devServerManager: DevServerManager,\n options: Pick<StartOptions, 'devClient' | 'platforms' | 'mcpServer'>\n) {\n const actions = new DevServerManagerActions(devServerManager, options);\n\n const isWebSocketsEnabled = devServerManager.getDefaultDevServer()?.isTargetingNative();\n\n const usageOptions = {\n isWebSocketsEnabled,\n devClient: devServerManager.options.devClient,\n ...options,\n };\n\n actions.printDevServerInfo(usageOptions);\n\n const onPressAsync = async (key: string) => {\n // Auxillary commands all escape.\n switch (key) {\n case CTRL_C:\n case CTRL_D: {\n // Prevent terminal UI from accepting commands while the process is closing.\n // Without this, fast typers will close the server then start typing their\n // next command and have a bunch of unrelated things pop up.\n pauseInteractions();\n\n const spinners = getAllSpinners();\n spinners.forEach((spinner) => {\n spinner.fail();\n });\n\n const currentProgress = getProgressBar();\n if (currentProgress) {\n currentProgress.terminate();\n setProgressBar(null);\n }\n const spinner = ora({ text: 'Stopping server', color: 'white' }).start();\n try {\n await devServerManager.stopAsync();\n if (options.mcpServer) {\n await options.mcpServer.closeAsync();\n }\n spinner.stopAndPersist({ text: 'Stopped server', symbol: `\\u203A` });\n // @ts-ignore: Argument of type '\"SIGINT\"' is not assignable to parameter of type '\"disconnect\"'.\n process.emit('SIGINT');\n\n // TODO: Is this the right place to do this?\n process.exit();\n } catch (error) {\n spinner.fail('Failed to stop server');\n throw error;\n }\n break;\n }\n case CTRL_L:\n return Log.clear();\n case '?':\n return printUsage(usageOptions, { verbose: true });\n }\n\n // Optionally enabled\n\n if (isWebSocketsEnabled) {\n switch (key) {\n case 'm':\n return actions.toggleDevMenu();\n case 'M':\n return actions.openMoreToolsAsync();\n }\n }\n\n const { platforms = ['ios', 'android', 'web'] } = options;\n\n if (['i', 'a'].includes(key.toLowerCase())) {\n const platform = key.toLowerCase() === 'i' ? 'ios' : 'android';\n\n const shouldPrompt = ['I', 'A'].includes(key);\n if (shouldPrompt) {\n Log.clear();\n }\n\n const server = devServerManager.getDefaultDevServer();\n const settings = PLATFORM_SETTINGS[platform];\n\n Log.log(`${BLT} Opening on ${settings.name}...`);\n\n if (server.isTargetingNative() && !platforms.includes(settings.key)) {\n Log.warn(\n chalk`${settings.name} is disabled, enable it by adding {bold ${settings.key}} to the platforms array in your app.json or app.config.js`\n );\n } else {\n try {\n await server.openPlatformAsync(settings.launchTarget, { shouldPrompt });\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n }\n // Break out early.\n return;\n }\n\n switch (key) {\n case 's': {\n Log.clear();\n if (await devServerManager.toggleRuntimeMode()) {\n usageOptions.devClient = devServerManager.options.devClient;\n return actions.printDevServerInfo(usageOptions);\n }\n break;\n }\n case 'w': {\n try {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n if (!platforms.includes('web')) {\n platforms.push('web');\n options.platforms?.push('web');\n }\n } catch (e: any) {\n Log.warn(e.message);\n break;\n }\n\n const isDisabled = !platforms.includes('web');\n if (isDisabled) {\n debug('Web is disabled');\n // Use warnings from the web support setup.\n break;\n }\n\n // Ensure the Webpack dev server is running first\n if (!devServerManager.getWebDevServer()) {\n debug('Starting up webpack dev server');\n await devServerManager.ensureWebDevServerRunningAsync();\n // When this is the first time webpack is started, reprint the connection info.\n actions.printDevServerInfo(usageOptions);\n }\n\n Log.log(`${BLT} Open in the web browser...`);\n try {\n await devServerManager.getWebDevServer()?.openPlatformAsync('desktop');\n printHelp();\n } catch (error: any) {\n if (!(error instanceof AbortCommandError)) {\n Log.exception(error);\n }\n }\n break;\n }\n case 'c':\n Log.clear();\n return actions.printDevServerInfo(usageOptions);\n case 'j':\n return actions.openJsInspectorAsync();\n case 'r':\n return actions.reloadApp();\n case 'o':\n Log.log(`${BLT} Opening the editor...`);\n return openInEditorAsync(devServerManager.projectRoot);\n }\n };\n\n const keyPressHandler = new KeyPressHandler(onPressAsync);\n\n const listener = keyPressHandler.createInteractionListener();\n\n addInteractionListener(listener);\n\n // Start observing...\n keyPressHandler.startInterceptingKeyStrokes();\n}\n"],"names":["startInterfaceAsync","debug","require","CTRL_C","CTRL_D","CTRL_L","PLATFORM_SETTINGS","android","name","key","launchTarget","ios","devServerManager","options","actions","DevServerManagerActions","isWebSocketsEnabled","getDefaultDevServer","isTargetingNative","usageOptions","devClient","printDevServerInfo","onPressAsync","pauseInteractions","spinners","getAllSpinners","forEach","spinner","fail","currentProgress","getProgressBar","terminate","setProgressBar","ora","text","color","start","stopAsync","mcpServer","closeAsync","stopAndPersist","symbol","process","emit","exit","error","Log","clear","printUsage","verbose","toggleDevMenu","openMoreToolsAsync","platforms","includes","toLowerCase","platform","shouldPrompt","server","settings","log","BLT","warn","chalk","openPlatformAsync","printHelp","AbortCommandError","exception","toggleRuntimeMode","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","push","e","message","isDisabled","getWebDevServer","ensureWebDevServerRunningAsync","openJsInspectorAsync","reloadApp","openInEditorAsync","projectRoot","keyPressHandler","KeyPressHandler","listener","createInteractionListener","addInteractionListener","startInterceptingKeyStrokes"],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ function _resolvefrom() {
|
|
|
18
18
|
const _UserSettings = require("../../api/user/UserSettings");
|
|
19
19
|
const _log = require("../../log");
|
|
20
20
|
const _env = require("../../utils/env");
|
|
21
|
+
const _exit = require("../../utils/exit");
|
|
21
22
|
function _interop_require_default(obj) {
|
|
22
23
|
return obj && obj.__esModule ? obj : {
|
|
23
24
|
default: obj
|
|
@@ -25,7 +26,7 @@ function _interop_require_default(obj) {
|
|
|
25
26
|
}
|
|
26
27
|
const importESM = require('@expo/cli/add-module');
|
|
27
28
|
const debug = require('debug')('expo:start:server:mcp');
|
|
28
|
-
async function maybeCreateMCPServerAsync(projectRoot) {
|
|
29
|
+
async function maybeCreateMCPServerAsync({ projectRoot, devServerUrl }) {
|
|
29
30
|
const mcpServer = _env.env.EXPO_UNSTABLE_MCP_SERVER;
|
|
30
31
|
if (!mcpServer) {
|
|
31
32
|
return null;
|
|
@@ -52,11 +53,21 @@ async function maybeCreateMCPServerAsync(projectRoot) {
|
|
|
52
53
|
_log.Log.log(...message);
|
|
53
54
|
}
|
|
54
55
|
};
|
|
55
|
-
const
|
|
56
|
+
const serverProxy = new TunnelMcpServerProxy(mcpServerUrl, {
|
|
56
57
|
logger,
|
|
57
|
-
wsHeaders: createAuthHeaders()
|
|
58
|
+
wsHeaders: createAuthHeaders(),
|
|
59
|
+
projectRoot,
|
|
60
|
+
devServerUrl
|
|
58
61
|
});
|
|
59
|
-
addMcpCapabilities(
|
|
62
|
+
addMcpCapabilities(serverProxy, projectRoot);
|
|
63
|
+
const removeExitHook = (0, _exit.installExitHooks)(async ()=>{
|
|
64
|
+
await serverProxy.close();
|
|
65
|
+
});
|
|
66
|
+
const server = serverProxy;
|
|
67
|
+
server.closeAsync = async ()=>{
|
|
68
|
+
removeExitHook();
|
|
69
|
+
await serverProxy.close();
|
|
70
|
+
};
|
|
60
71
|
return server;
|
|
61
72
|
} catch (error) {
|
|
62
73
|
debug(`Error creating MCP tunnel: ${error}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/server/MCP.ts"],"sourcesContent":["import type {\n McpServerProxy,\n TunnelMcpServerProxy as TunnelMcpServerProxyType,\n} from '@expo/mcp-tunnel' with { 'resolution-mode': 'import' };\nimport resolveFrom from 'resolve-from';\n\nimport { getAccessToken, getSession } from '../../api/user/UserSettings';\nimport { Log } from '../../log';\nimport { env } from '../../utils/env';\n\nconst importESM = require('@expo/cli/add-module') as <T>(moduleName: string) => Promise<T>;\n\nconst debug = require('debug')('expo:start:server:mcp') as typeof console.log;\n\n/**\n * Create the MCP server\n */\nexport async function maybeCreateMCPServerAsync(\n projectRoot:
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/MCP.ts"],"sourcesContent":["import type {\n McpServerProxy,\n TunnelMcpServerProxy as TunnelMcpServerProxyType,\n} from '@expo/mcp-tunnel' with { 'resolution-mode': 'import' };\nimport resolveFrom from 'resolve-from';\n\nimport { getAccessToken, getSession } from '../../api/user/UserSettings';\nimport { Log } from '../../log';\nimport { env } from '../../utils/env';\nimport { installExitHooks } from '../../utils/exit';\n\nconst importESM = require('@expo/cli/add-module') as <T>(moduleName: string) => Promise<T>;\n\nconst debug = require('debug')('expo:start:server:mcp') as typeof console.log;\n\n/**\n * The MCP server\n */\nexport type McpServer = Omit<McpServerProxy, 'close'> & {\n /**\n * Close the server\n */\n closeAsync: () => Promise<void>;\n};\n\n/**\n * Create the MCP server\n */\nexport async function maybeCreateMCPServerAsync({\n projectRoot,\n devServerUrl,\n}: {\n projectRoot: string;\n devServerUrl: string;\n}): Promise<McpServer | null> {\n const mcpServer = env.EXPO_UNSTABLE_MCP_SERVER;\n if (!mcpServer) {\n return null;\n }\n const mcpPackagePath = resolveFrom.silent(projectRoot, 'expo-mcp');\n if (!mcpPackagePath) {\n Log.error(\n 'Missing the `expo-mcp` package in the project. To enable the MCP integration, add the `expo-mcp` package to your project.'\n );\n return null;\n }\n\n const normalizedServer = /^([a-zA-Z][a-zA-Z\\d+\\-.]*):\\/\\//.test(mcpServer)\n ? mcpServer\n : `wss://${mcpServer}`;\n const mcpServerUrlObject = new URL(normalizedServer);\n const scheme = mcpServerUrlObject.protocol ?? 'wss:';\n const mcpServerUrl = `${scheme}//${mcpServerUrlObject.host}`;\n debug(`Creating MCP tunnel - server URL: ${mcpServerUrl}`);\n\n try {\n const { addMcpCapabilities } = await importESM<{\n addMcpCapabilities: (server: McpServerProxy, projectRoot: string) => void;\n }>(mcpPackagePath);\n const { TunnelMcpServerProxy } = await importESM<{\n TunnelMcpServerProxy: typeof TunnelMcpServerProxyType;\n }>('@expo/mcp-tunnel');\n\n const logger = {\n ...Log,\n debug(...message: any[]): void {\n debug(...message);\n },\n info(...message: any[]): void {\n Log.log(...message);\n },\n };\n const serverProxy: McpServerProxy = new TunnelMcpServerProxy(mcpServerUrl, {\n logger,\n wsHeaders: createAuthHeaders(),\n projectRoot,\n devServerUrl,\n });\n addMcpCapabilities(serverProxy, projectRoot);\n\n const removeExitHook = installExitHooks(async () => {\n await serverProxy.close();\n });\n const server = serverProxy as unknown as McpServer;\n server.closeAsync = async () => {\n removeExitHook();\n await serverProxy.close();\n };\n\n return server;\n } catch (error: unknown) {\n debug(`Error creating MCP tunnel: ${error}`);\n }\n return null;\n}\n\nfunction createAuthHeaders(): Record<string, string> {\n const token = getAccessToken();\n if (token) {\n return {\n authorization: `Bearer ${token}`,\n };\n }\n const sessionSecret = getSession()?.sessionSecret;\n if (sessionSecret) {\n return {\n 'expo-session': sessionSecret,\n };\n }\n return {};\n}\n"],"names":["maybeCreateMCPServerAsync","importESM","require","debug","projectRoot","devServerUrl","mcpServer","env","EXPO_UNSTABLE_MCP_SERVER","mcpPackagePath","resolveFrom","silent","Log","error","normalizedServer","test","mcpServerUrlObject","URL","scheme","protocol","mcpServerUrl","host","addMcpCapabilities","TunnelMcpServerProxy","logger","message","info","log","serverProxy","wsHeaders","createAuthHeaders","removeExitHook","installExitHooks","close","server","closeAsync","getSession","token","getAccessToken","authorization","sessionSecret"],"mappings":";;;;+BA4BsBA;;;eAAAA;;;;gEAxBE;;;;;;8BAEmB;qBACvB;qBACA;sBACa;;;;;;AAEjC,MAAMC,YAAYC,QAAQ;AAE1B,MAAMC,QAAQD,QAAQ,SAAS;AAexB,eAAeF,0BAA0B,EAC9CI,WAAW,EACXC,YAAY,EAIb;IACC,MAAMC,YAAYC,QAAG,CAACC,wBAAwB;IAC9C,IAAI,CAACF,WAAW;QACd,OAAO;IACT;IACA,MAAMG,iBAAiBC,sBAAW,CAACC,MAAM,CAACP,aAAa;IACvD,IAAI,CAACK,gBAAgB;QACnBG,QAAG,CAACC,KAAK,CACP;QAEF,OAAO;IACT;IAEA,MAAMC,mBAAmB,kCAAkCC,IAAI,CAACT,aAC5DA,YACA,CAAC,MAAM,EAAEA,WAAW;IACxB,MAAMU,qBAAqB,IAAIC,IAAIH;IACnC,MAAMI,SAASF,mBAAmBG,QAAQ,IAAI;IAC9C,MAAMC,eAAe,GAAGF,OAAO,EAAE,EAAEF,mBAAmBK,IAAI,EAAE;IAC5DlB,MAAM,CAAC,kCAAkC,EAAEiB,cAAc;IAEzD,IAAI;QACF,MAAM,EAAEE,kBAAkB,EAAE,GAAG,MAAMrB,UAElCQ;QACH,MAAM,EAAEc,oBAAoB,EAAE,GAAG,MAAMtB,UAEpC;QAEH,MAAMuB,SAAS;YACb,GAAGZ,QAAG;YACNT,OAAM,GAAGsB,OAAc;gBACrBtB,SAASsB;YACX;YACAC,MAAK,GAAGD,OAAc;gBACpBb,QAAG,CAACe,GAAG,IAAIF;YACb;QACF;QACA,MAAMG,cAA8B,IAAIL,qBAAqBH,cAAc;YACzEI;YACAK,WAAWC;YACX1B;YACAC;QACF;QACAiB,mBAAmBM,aAAaxB;QAEhC,MAAM2B,iBAAiBC,IAAAA,sBAAgB,EAAC;YACtC,MAAMJ,YAAYK,KAAK;QACzB;QACA,MAAMC,SAASN;QACfM,OAAOC,UAAU,GAAG;YAClBJ;YACA,MAAMH,YAAYK,KAAK;QACzB;QAEA,OAAOC;IACT,EAAE,OAAOrB,OAAgB;QACvBV,MAAM,CAAC,2BAA2B,EAAEU,OAAO;IAC7C;IACA,OAAO;AACT;AAEA,SAASiB;QAOeM;IANtB,MAAMC,QAAQC,IAAAA,4BAAc;IAC5B,IAAID,OAAO;QACT,OAAO;YACLE,eAAe,CAAC,OAAO,EAAEF,OAAO;QAClC;IACF;IACA,MAAMG,iBAAgBJ,cAAAA,IAAAA,wBAAU,wBAAVA,YAAcI,aAAa;IACjD,IAAIA,eAAe;QACjB,OAAO;YACL,gBAAgBA;QAClB;IACF;IACA,OAAO,CAAC;AACV"}
|