@expo/cli 1.0.0-canary-20250729-d8899ae → 54.0.0
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/metro-require/require.js +24 -13
- package/build/src/api/getExpoSchema.js +8 -7
- package/build/src/api/getExpoSchema.js.map +1 -1
- package/build/src/expoUpdatesExports.js +28 -0
- package/build/src/expoUpdatesExports.js.map +1 -0
- package/build/src/export/embed/exportEmbedAsync.js +4 -2
- package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
- package/build/src/export/exportApp.js +7 -4
- package/build/src/export/exportApp.js.map +1 -1
- package/build/src/export/exportAssets.js +20 -4
- package/build/src/export/exportAssets.js.map +1 -1
- package/build/src/export/exportHermes.js +34 -9
- package/build/src/export/exportHermes.js.map +1 -1
- package/build/src/export/exportStaticAsync.js +19 -2
- package/build/src/export/exportStaticAsync.js.map +1 -1
- package/build/src/export/index.js +1 -0
- package/build/src/export/index.js.map +1 -1
- package/build/src/export/resolveOptions.js +1 -0
- package/build/src/export/resolveOptions.js.map +1 -1
- package/build/src/export/saveAssets.js +12 -0
- package/build/src/export/saveAssets.js.map +1 -1
- package/build/src/install/checkPackages.js +9 -1
- package/build/src/install/checkPackages.js.map +1 -1
- package/build/src/lint/lintAsync.js +2 -0
- package/build/src/lint/lintAsync.js.map +1 -1
- package/build/src/prebuild/prebuildAsync.js +18 -0
- package/build/src/prebuild/prebuildAsync.js.map +1 -1
- package/build/src/prebuild/resolveLocalTemplate.js +42 -0
- package/build/src/prebuild/resolveLocalTemplate.js.map +1 -0
- package/build/src/prebuild/resolveTemplate.js +17 -7
- package/build/src/prebuild/resolveTemplate.js.map +1 -1
- package/build/src/prebuild/updateFromTemplate.js +1 -0
- package/build/src/prebuild/updateFromTemplate.js.map +1 -1
- package/build/src/prebuild/updatePackageJson.js +5 -3
- package/build/src/prebuild/updatePackageJson.js.map +1 -1
- package/build/src/run/android/resolveOptions.js +2 -2
- package/build/src/run/android/resolveOptions.js.map +1 -1
- package/build/src/run/ios/options/resolveOptions.js +2 -2
- package/build/src/run/ios/options/resolveOptions.js.map +1 -1
- package/build/src/run/ios/runIosAsync.js +3 -0
- package/build/src/run/ios/runIosAsync.js.map +1 -1
- package/build/src/serve/serveAsync.js +5 -2
- package/build/src/serve/serveAsync.js.map +1 -1
- package/build/src/start/platforms/ExpoGoInstaller.js +1 -1
- package/build/src/start/platforms/ExpoGoInstaller.js.map +1 -1
- package/build/src/start/server/DevToolsPluginManager.js +7 -35
- package/build/src/start/server/DevToolsPluginManager.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +68 -29
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/MetroTerminalReporter.js +63 -18
- package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
- package/build/src/start/server/metro/createExpoAutolinkingResolver.js +121 -0
- package/build/src/start/server/metro/createExpoAutolinkingResolver.js.map +1 -0
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +4 -4
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js +54 -8
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +1 -1
- package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js +1 -0
- package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +20 -18
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/metroErrorInterface.js +20 -13
- package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
- package/build/src/start/server/metro/router.js +75 -0
- package/build/src/start/server/metro/router.js.map +1 -1
- package/build/src/start/server/metro/serializeHtml.js +45 -5
- package/build/src/start/server/metro/serializeHtml.js.map +1 -1
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js +267 -0
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js.map +1 -0
- package/build/src/start/server/metro/withMetroMultiPlatform.js +50 -35
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/metro/withMetroResolvers.js +0 -176
- package/build/src/start/server/metro/withMetroResolvers.js.map +1 -1
- package/build/src/start/server/metro/withMetroSupervisingTransformWorker.js +63 -0
- package/build/src/start/server/metro/withMetroSupervisingTransformWorker.js.map +1 -0
- package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js +1 -1
- package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +7 -2
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/start/server/serverLogLikeMetro.js +13 -11
- package/build/src/start/server/serverLogLikeMetro.js.map +1 -1
- package/build/src/utils/build-cache-providers/index.js.map +1 -1
- package/build/src/utils/dir.js +7 -0
- package/build/src/utils/dir.js.map +1 -1
- package/build/src/utils/env.js +3 -1
- package/build/src/utils/env.js.map +1 -1
- package/build/src/utils/errors.js +1 -1
- package/build/src/utils/errors.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/internal/unstable-expo-updates-exports.d.ts +31 -0
- package/internal/unstable-expo-updates-exports.js +3 -0
- package/package.json +33 -18
- package/static/template/[...rsc]+api.ts +1 -1
- package/build/src/start/server/metro/createExpoStickyResolver.js +0 -137
- package/build/src/start/server/metro/createExpoStickyResolver.js.map +0 -1
- package/build/src/utils/jsonSchemaDeref.js +0 -150
- package/build/src/utils/jsonSchemaDeref.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/exportAssets.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport fs from 'fs';\nimport { minimatch } from 'minimatch';\nimport path from 'path';\n\nimport { getAssetIdForLogGrouping, persistMetroAssetsAsync } from './persistMetroAssets';\nimport type { Asset, BundleAssetWithFileHashes, BundleOutput, ExportAssetMap } from './saveAssets';\nimport * as Log from '../log';\nimport { resolveGoogleServicesFile } from '../start/server/middleware/resolveAssets';\nimport { uniqBy } from '../utils/array';\n\nconst debug = require('debug')('expo:export:exportAssets') as typeof console.log;\n\nfunction mapAssetHashToAssetString(asset: Asset, hash: string) {\n return 'asset_' + hash + ('type' in asset && asset.type ? '.' + asset.type : '');\n}\n\nexport function assetPatternsToBeBundled(\n exp: ExpoConfig & { extra?: { updates?: { assetPatternsToBeBundled?: string[] } } }\n): string[] | undefined {\n // new location for this key\n if (exp.updates?.assetPatternsToBeBundled?.length) {\n return exp.updates.assetPatternsToBeBundled;\n }\n\n // old, untyped location for this key. we may want to change this to throw in a few SDK versions (deprecated as of SDK 52).\n if (exp.extra?.updates?.assetPatternsToBeBundled?.length) {\n return exp.extra.updates.assetPatternsToBeBundled;\n }\n\n return undefined;\n}\n\n/**\n * Given an asset and a set of strings representing the assets to be bundled, returns true if\n * the asset is part of the set to be bundled.\n * @param asset Asset object\n * @param bundledAssetsSet Set of strings\n * @returns true if the asset should be bundled\n */\nfunction assetShouldBeIncludedInExport(asset: Asset, bundledAssetsSet: Set<string> | undefined) {\n if (!bundledAssetsSet) {\n return true;\n }\n return (\n asset.fileHashes.filter((hash) => bundledAssetsSet.has(mapAssetHashToAssetString(asset, hash)))\n .length > 0\n );\n}\n\n/**\n * Computes a set of strings representing the assets to be bundled with an export, given an array of assets,\n * and a set of patterns to match\n * @param assets The asset array\n * @param assetPatternsToBeBundled An array of strings with glob patterns to match\n * @param projectRoot The project root\n * @returns A set of asset strings\n */\nfunction setOfAssetsToBeBundled(\n assets: Asset[],\n assetPatternsToBeBundled: string[],\n projectRoot: string\n): Set<string> | undefined {\n // Convert asset patterns to a list of asset strings that match them.\n // Assets strings are formatted as `asset_<hash>.<type>` and represent\n // the name that the file will have in the app bundle. The `asset_` prefix is\n // needed because android doesn't support assets that start with numbers.\n\n const fullPatterns: string[] = assetPatternsToBeBundled.map((p: string) =>\n path.join(projectRoot, p)\n );\n\n logPatterns(fullPatterns);\n\n const allBundledAssets = assets\n .map((asset) => {\n const shouldBundle = shouldBundleAsset(asset, fullPatterns);\n if (shouldBundle) {\n debug(`${shouldBundle ? 'Include' : 'Exclude'} asset ${asset.files?.[0]}`);\n return asset.fileHashes.map((hash) => mapAssetHashToAssetString(asset, hash));\n }\n return [];\n })\n .flat();\n\n // The assets returned by the RN packager has duplicates so make sure we\n // only bundle each once.\n return new Set(allBundledAssets);\n}\n\n/**\n * Resolves the assetBundlePatterns from the manifest and returns the set of assets to bundle.\n *\n * @modifies {exp}\n */\nexport function resolveAssetPatternsToBeBundled<T extends ExpoConfig>(\n projectRoot: string,\n exp: T,\n assets: Asset[]\n): Set<string> | undefined {\n const assetPatternsToBeBundledForConfig = assetPatternsToBeBundled(exp);\n if (!assetPatternsToBeBundledForConfig) {\n return undefined;\n }\n const bundledAssets = setOfAssetsToBeBundled(\n assets,\n assetPatternsToBeBundledForConfig,\n projectRoot\n );\n return bundledAssets;\n}\n\nfunction logPatterns(patterns: string[]) {\n // Only log the patterns in debug mode, if they aren't already defined in the app.json, then all files will be targeted.\n Log.log('\\nProcessing asset bundle patterns:');\n patterns.forEach((p) => Log.log('- ' + p));\n}\n\nfunction shouldBundleAsset(asset: Asset, patterns: string[]) {\n const file = asset.files?.[0];\n return !!(\n '__packager_asset' in asset &&\n asset.__packager_asset &&\n file &&\n patterns.some((pattern) => minimatch(file, pattern))\n );\n}\n\nexport async function exportAssetsAsync(\n projectRoot: string,\n {\n exp,\n outputDir,\n bundles: { web, ...bundles },\n baseUrl,\n files = new Map(),\n }: {\n exp: ExpoConfig;\n bundles: Partial<Record<string, BundleOutput>>;\n outputDir: string;\n baseUrl: string;\n files?: ExportAssetMap;\n }\n) {\n // NOTE: We use a different system for static web\n if (web) {\n // Save assets like a typical bundler, preserving the file paths on web.\n // TODO: Update React Native Web to support loading files from asset hashes.\n await persistMetroAssetsAsync(projectRoot, web.assets, {\n files,\n platform: 'web',\n outputDirectory: outputDir,\n baseUrl,\n });\n }\n\n const assets: BundleAssetWithFileHashes[] = uniqBy(\n Object.values(bundles).flatMap((bundle) => bundle!.assets),\n (asset) => asset.hash\n );\n\n let bundledAssetsSet: Set<string> | undefined = undefined;\n let filteredAssets = assets;\n const embeddedHashSet: Set<string> = new Set();\n\n if (assets[0]?.fileHashes) {\n debug(`Assets = ${JSON.stringify(assets, null, 2)}`);\n // Updates the manifest to reflect additional asset bundling + configs\n // Get only asset strings for assets we will save\n bundledAssetsSet = resolveAssetPatternsToBeBundled(projectRoot, exp, assets);\n if (bundledAssetsSet) {\n debug(`Bundled assets = ${JSON.stringify([...bundledAssetsSet], null, 2)}`);\n // Filter asset objects to only ones that include assetPatternsToBeBundled matches\n filteredAssets = assets.filter((asset) => {\n const shouldInclude = assetShouldBeIncludedInExport(asset, bundledAssetsSet);\n if (!shouldInclude) {\n embeddedHashSet.add(asset.hash);\n }\n return shouldInclude;\n });\n debug(`Filtered assets count = ${filteredAssets.length}`);\n }\n\n const hashes = new Set<string>();\n\n // Add assets to copy.\n filteredAssets.forEach((asset) => {\n const assetId = getAssetIdForLogGrouping(projectRoot, asset);\n\n asset.files.forEach((fp: string, index: number) => {\n const hash = asset.fileHashes[index];\n if (hashes.has(hash)) return;\n hashes.add(hash);\n files.set(path.join('assets', hash), {\n originFilename: path.relative(projectRoot, fp),\n contents: fs.readFileSync(fp),\n assetId,\n });\n });\n });\n }\n\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n\n return { exp, assets, embeddedHashSet, files };\n}\n"],"names":["assetPatternsToBeBundled","exportAssetsAsync","resolveAssetPatternsToBeBundled","debug","require","mapAssetHashToAssetString","asset","hash","type","exp","updates","length","extra","undefined","assetShouldBeIncludedInExport","bundledAssetsSet","fileHashes","filter","has","setOfAssetsToBeBundled","assets","projectRoot","fullPatterns","map","p","path","join","logPatterns","allBundledAssets","shouldBundle","shouldBundleAsset","files","flat","Set","assetPatternsToBeBundledForConfig","bundledAssets","patterns","Log","log","forEach","file","__packager_asset","some","pattern","minimatch","outputDir","bundles","web","baseUrl","Map","persistMetroAssetsAsync","platform","outputDirectory","uniqBy","Object","values","flatMap","bundle","filteredAssets","embeddedHashSet","JSON","stringify","shouldInclude","add","hashes","assetId","getAssetIdForLogGrouping","fp","index","set","originFilename","relative","contents","fs","readFileSync","resolveGoogleServicesFile"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/export/exportAssets.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config';\nimport fs from 'fs';\nimport { minimatch } from 'minimatch';\nimport path from 'path';\n\nimport { getAssetIdForLogGrouping, persistMetroAssetsAsync } from './persistMetroAssets';\nimport type { Asset, BundleAssetWithFileHashes, BundleOutput, ExportAssetMap } from './saveAssets';\nimport * as Log from '../log';\nimport { resolveGoogleServicesFile } from '../start/server/middleware/resolveAssets';\nimport { uniqBy } from '../utils/array';\n\nconst debug = require('debug')('expo:export:exportAssets') as typeof console.log;\n\nfunction mapAssetHashToAssetString(asset: Asset, hash: string) {\n return 'asset_' + hash + ('type' in asset && asset.type ? '.' + asset.type : '');\n}\n\nexport function assetPatternsToBeBundled(\n exp: ExpoConfig & { extra?: { updates?: { assetPatternsToBeBundled?: string[] } } }\n): string[] | undefined {\n // new location for this key\n if (exp.updates?.assetPatternsToBeBundled?.length) {\n return exp.updates.assetPatternsToBeBundled;\n }\n\n // old, untyped location for this key. we may want to change this to throw in a few SDK versions (deprecated as of SDK 52).\n if (exp.extra?.updates?.assetPatternsToBeBundled?.length) {\n return exp.extra.updates.assetPatternsToBeBundled;\n }\n\n return undefined;\n}\n\n/**\n * Given an asset and a set of strings representing the assets to be bundled, returns true if\n * the asset is part of the set to be bundled.\n * @param asset Asset object\n * @param bundledAssetsSet Set of strings\n * @returns true if the asset should be bundled\n */\nfunction assetShouldBeIncludedInExport(asset: Asset, bundledAssetsSet: Set<string> | undefined) {\n if (!bundledAssetsSet) {\n return true;\n }\n return (\n asset.fileHashes.filter((hash) => bundledAssetsSet.has(mapAssetHashToAssetString(asset, hash)))\n .length > 0\n );\n}\n\n/**\n * Computes a set of strings representing the assets to be bundled with an export, given an array of assets,\n * and a set of patterns to match\n * @param assets The asset array\n * @param assetPatternsToBeBundled An array of strings with glob patterns to match\n * @param projectRoot The project root\n * @returns A set of asset strings\n */\nfunction setOfAssetsToBeBundled(\n assets: Asset[],\n assetPatternsToBeBundled: string[],\n projectRoot: string\n): Set<string> | undefined {\n // Convert asset patterns to a list of asset strings that match them.\n // Assets strings are formatted as `asset_<hash>.<type>` and represent\n // the name that the file will have in the app bundle. The `asset_` prefix is\n // needed because android doesn't support assets that start with numbers.\n\n const fullPatterns: string[] = assetPatternsToBeBundled.map((p: string) =>\n path.join(projectRoot, p)\n );\n\n logPatterns(fullPatterns);\n\n const allBundledAssets = assets\n .map((asset) => {\n const shouldBundle = shouldBundleAsset(asset, fullPatterns);\n if (shouldBundle) {\n debug(`${shouldBundle ? 'Include' : 'Exclude'} asset ${asset.files?.[0]}`);\n return asset.fileHashes.map((hash) => mapAssetHashToAssetString(asset, hash));\n }\n return [];\n })\n .flat();\n\n // The assets returned by the RN packager has duplicates so make sure we\n // only bundle each once.\n return new Set(allBundledAssets);\n}\n\n/**\n * Resolves the assetBundlePatterns from the manifest and returns the set of assets to bundle.\n *\n * @modifies {exp}\n */\nexport function resolveAssetPatternsToBeBundled<T extends ExpoConfig>(\n projectRoot: string,\n exp: T,\n assets: Asset[]\n): Set<string> | undefined {\n const assetPatternsToBeBundledForConfig = assetPatternsToBeBundled(exp);\n if (!assetPatternsToBeBundledForConfig) {\n return undefined;\n }\n const bundledAssets = setOfAssetsToBeBundled(\n assets,\n assetPatternsToBeBundledForConfig,\n projectRoot\n );\n return bundledAssets;\n}\n\nfunction logPatterns(patterns: string[]) {\n // Only log the patterns in debug mode, if they aren't already defined in the app.json, then all files will be targeted.\n Log.log('\\nProcessing asset bundle patterns:');\n patterns.forEach((p) => Log.log('- ' + p));\n}\n\nfunction shouldBundleAsset(asset: Asset, patterns: string[]) {\n const file = asset.files?.[0];\n return !!(\n '__packager_asset' in asset &&\n asset.__packager_asset &&\n file &&\n patterns.some((pattern) => minimatch(file, pattern))\n );\n}\n\nexport async function exportAssetsAsync(\n projectRoot: string,\n {\n exp,\n outputDir,\n bundles: { web, ...bundles },\n baseUrl,\n files = new Map(),\n hostedNative,\n }: {\n exp: ExpoConfig;\n bundles: Partial<Record<string, BundleOutput>>;\n outputDir: string;\n baseUrl: string;\n files?: ExportAssetMap;\n hostedNative?: boolean;\n }\n): Promise<{\n exp: ExpoConfig;\n assets: BundleAssetWithFileHashes[];\n embeddedHashSet: Set<string>;\n files: ExportAssetMap;\n}> {\n const hostedAssets: BundleAssetWithFileHashes[] = web ? [...web.assets] : [];\n\n // If the native assets should be hosted like web, then we can add them to the hosted assets to export.\n if (hostedNative) {\n hostedAssets.push(...Object.values(bundles).flatMap((bundle) => bundle!.assets ?? []));\n }\n\n if (hostedAssets.length) {\n // Save assets like a typical bundler, preserving the file paths on web.\n // TODO: Update React Native Web to support loading files from asset hashes.\n await persistMetroAssetsAsync(projectRoot, hostedAssets, {\n files,\n platform: 'web',\n outputDirectory: outputDir,\n baseUrl,\n });\n }\n\n if (hostedNative) {\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n return { exp, assets: [], embeddedHashSet: new Set(), files };\n }\n\n const assets: BundleAssetWithFileHashes[] = uniqBy(\n Object.values(bundles).flatMap((bundle) => bundle!.assets),\n (asset) => asset.hash\n );\n\n let bundledAssetsSet: Set<string> | undefined = undefined;\n let filteredAssets = assets;\n const embeddedHashSet: Set<string> = new Set();\n\n if (assets[0]?.fileHashes) {\n debug(`Assets = ${JSON.stringify(assets, null, 2)}`);\n // Updates the manifest to reflect additional asset bundling + configs\n // Get only asset strings for assets we will save\n bundledAssetsSet = resolveAssetPatternsToBeBundled(projectRoot, exp, assets);\n if (bundledAssetsSet) {\n debug(`Bundled assets = ${JSON.stringify([...bundledAssetsSet], null, 2)}`);\n // Filter asset objects to only ones that include assetPatternsToBeBundled matches\n filteredAssets = assets.filter((asset) => {\n const shouldInclude = assetShouldBeIncludedInExport(asset, bundledAssetsSet);\n if (!shouldInclude) {\n embeddedHashSet.add(asset.hash);\n }\n return shouldInclude;\n });\n debug(`Filtered assets count = ${filteredAssets.length}`);\n }\n\n const hashes = new Set<string>();\n\n // Add assets to copy.\n filteredAssets.forEach((asset) => {\n const assetId = getAssetIdForLogGrouping(projectRoot, asset);\n\n asset.files.forEach((fp: string, index: number) => {\n const hash = asset.fileHashes[index];\n if (hashes.has(hash)) return;\n hashes.add(hash);\n files.set(path.join('assets', hash), {\n originFilename: path.relative(projectRoot, fp),\n contents: fs.readFileSync(fp),\n assetId,\n });\n });\n });\n }\n\n // Add google services file if it exists\n await resolveGoogleServicesFile(projectRoot, exp);\n\n return { exp, assets, embeddedHashSet, files };\n}\n"],"names":["assetPatternsToBeBundled","exportAssetsAsync","resolveAssetPatternsToBeBundled","debug","require","mapAssetHashToAssetString","asset","hash","type","exp","updates","length","extra","undefined","assetShouldBeIncludedInExport","bundledAssetsSet","fileHashes","filter","has","setOfAssetsToBeBundled","assets","projectRoot","fullPatterns","map","p","path","join","logPatterns","allBundledAssets","shouldBundle","shouldBundleAsset","files","flat","Set","assetPatternsToBeBundledForConfig","bundledAssets","patterns","Log","log","forEach","file","__packager_asset","some","pattern","minimatch","outputDir","bundles","web","baseUrl","Map","hostedNative","hostedAssets","push","Object","values","flatMap","bundle","persistMetroAssetsAsync","platform","outputDirectory","resolveGoogleServicesFile","embeddedHashSet","uniqBy","filteredAssets","JSON","stringify","shouldInclude","add","hashes","assetId","getAssetIdForLogGrouping","fp","index","set","originFilename","relative","contents","fs","readFileSync"],"mappings":"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"}
|
|
@@ -76,6 +76,23 @@ function _interop_require_default(obj) {
|
|
|
76
76
|
default: obj
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
+
const PODFILE_HERMES_LHS = /(?::hermes_enabled\s*=>|hermes_enabled\s*:)/;
|
|
80
|
+
const PODFILE_HERMES_PROPS_REFERENCE_RE = new RegExp(String.raw`^\s*${PODFILE_HERMES_LHS.source}\s*podfile_properties\['expo\.jsEngine'\]\s*==\s*nil\s*\|\|\s*podfile_properties\['expo\.jsEngine'\]\s*==\s*'hermes'\s*,?\s*(?:#.*)?$`, 'm');
|
|
81
|
+
const PODFILE_HERMES_TRUE_RE = new RegExp(String.raw`^\s*${PODFILE_HERMES_LHS.source}\s*true\s*(?:,\s*)?(?:[^\n]*)?$`, 'm');
|
|
82
|
+
const PODFILE_HERMES_FALSE_RE = new RegExp(String.raw`^\s*${PODFILE_HERMES_LHS.source}\s*false\s*(?:,\s*)?(?:[^\n]*)?$`, 'm');
|
|
83
|
+
function getLiteralHermesSettingFromPodfile(content) {
|
|
84
|
+
const isPropsReference = content.search(PODFILE_HERMES_PROPS_REFERENCE_RE) >= 0;
|
|
85
|
+
if (isPropsReference) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
if (PODFILE_HERMES_TRUE_RE.test(content)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
if (PODFILE_HERMES_FALSE_RE.test(content)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
79
96
|
async function assertEngineMismatchAsync(projectRoot, exp, platform) {
|
|
80
97
|
const isHermesManaged = isEnableHermesManaged(exp, platform);
|
|
81
98
|
const paths = (0, _config().getConfigFilePaths)(projectRoot);
|
|
@@ -136,13 +153,15 @@ async function maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged)
|
|
|
136
153
|
}
|
|
137
154
|
function isHermesPossiblyEnabled(projectRoot) {
|
|
138
155
|
// Trying best to check ios native project if by chance to be consistent between app config
|
|
139
|
-
// Check ios/Podfile for
|
|
156
|
+
// Check ios/Podfile for a literal :hermes_enabled => (true|false) or hermes_enabled: (true|false)
|
|
140
157
|
const podfilePath = _path().default.join(projectRoot, 'ios', 'Podfile');
|
|
141
158
|
if (_fs().default.existsSync(podfilePath)) {
|
|
142
159
|
const content = _fs().default.readFileSync(podfilePath, 'utf8');
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
160
|
+
const literal = getLiteralHermesSettingFromPodfile(content);
|
|
161
|
+
if (literal != null) return literal;
|
|
162
|
+
// If there is no props reference and no literal, assume Hermes is enabled by default
|
|
163
|
+
const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);
|
|
164
|
+
if (!hasPropsReference) {
|
|
146
165
|
return true;
|
|
147
166
|
}
|
|
148
167
|
}
|
|
@@ -160,14 +179,20 @@ function isHermesPossiblyEnabled(projectRoot) {
|
|
|
160
179
|
}
|
|
161
180
|
async function maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged) {
|
|
162
181
|
// Trying best to check ios native project if by chance to be consistent between app config
|
|
163
|
-
// Check ios/Podfile for
|
|
182
|
+
// Check ios/Podfile for a literal :hermes_enabled => (true|false)
|
|
164
183
|
const podfilePath = _path().default.join(projectRoot, 'ios', 'Podfile');
|
|
165
184
|
if (_fs().default.existsSync(podfilePath)) {
|
|
166
185
|
const content = await _fs().default.promises.readFile(podfilePath, 'utf8');
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
186
|
+
const literal = getLiteralHermesSettingFromPodfile(content);
|
|
187
|
+
if (literal != null) {
|
|
188
|
+
if (isHermesManaged !== literal) return true;
|
|
189
|
+
} else {
|
|
190
|
+
// If there is no props reference and no literal, assume Hermes is enabled by default
|
|
191
|
+
const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);
|
|
192
|
+
if (!hasPropsReference) {
|
|
193
|
+
const assumedEnabled = true;
|
|
194
|
+
if (isHermesManaged !== assumedEnabled) return true;
|
|
195
|
+
}
|
|
171
196
|
}
|
|
172
197
|
}
|
|
173
198
|
// Check Podfile.properties.json from prebuild template
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/exportHermes.ts"],"sourcesContent":["import { ExpoConfig, getConfigFilePaths, Platform } from '@expo/config';\nimport JsonFile from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nexport async function assertEngineMismatchAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>,\n platform: Platform\n) {\n const isHermesManaged = isEnableHermesManaged(exp, platform);\n const paths = getConfigFilePaths(projectRoot);\n const configFilePath = paths.dynamicConfigPath ?? paths.staticConfigPath ?? 'app.json';\n await maybeThrowFromInconsistentEngineAsync(\n projectRoot,\n configFilePath,\n platform,\n isHermesManaged\n );\n}\n\nexport function isEnableHermesManaged(\n expoConfig: Partial<Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>>,\n platform: string\n): boolean {\n switch (platform) {\n case 'android': {\n return (expoConfig.android?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n case 'ios': {\n return (expoConfig.ios?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n default:\n return false;\n }\n}\n\nexport function parseGradleProperties(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (let line of content.split('\\n')) {\n line = line.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const sepIndex = line.indexOf('=');\n const key = line.slice(0, sepIndex);\n const value = line.slice(sepIndex + 1);\n result[key] = value;\n }\n return result;\n}\n\nexport async function maybeThrowFromInconsistentEngineAsync(\n projectRoot: string,\n configFilePath: string,\n platform: string,\n isHermesManaged: boolean\n): Promise<void> {\n const configFileName = path.basename(configFilePath);\n if (\n platform === 'android' &&\n (await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged))\n ) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'android', 'gradle.properties')}\\n` +\n ` - ${path.join(projectRoot, 'android', 'app', 'build.gradle')}\\n` +\n 'Learn more: https://expo.fyi/hermes-android-config'\n );\n }\n\n if (platform === 'ios' && (await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged))) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile')}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile.properties.json')}\\n` +\n 'Learn more: https://expo.fyi/hermes-ios-config'\n );\n }\n}\n\nexport async function maybeInconsistentEngineAndroidAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check android native project if by chance to be consistent between app config\n\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(await fs.promises.readFile(gradlePropertiesPath, 'utf8'));\n const isHermesBare = props['hermesEnabled'] === 'true';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isHermesPossiblyEnabled(projectRoot: string): boolean | null {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = fs.readFileSync(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n try {\n const props = JsonFile.read(podfilePropertiesPath);\n return props['expo.jsEngine'] === 'hermes';\n } catch {\n // ignore\n }\n }\n\n return null;\n}\n\nexport async function maybeInconsistentEngineIosAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = await fs.promises.readFile(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);\n const isHermesBare = props['expo.jsEngine'] === 'hermes';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\n// https://github.com/facebook/hermes/blob/release-v0.5/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25\nconst HERMES_MAGIC_HEADER = 'c61fbc03c103191f';\n\nexport async function isHermesBytecodeBundleAsync(file: string): Promise<boolean> {\n const header = await readHermesHeaderAsync(file);\n return header.subarray(0, 8).toString('hex') === HERMES_MAGIC_HEADER;\n}\n\nexport async function getHermesBytecodeBundleVersionAsync(file: string): Promise<number> {\n const header = await readHermesHeaderAsync(file);\n if (header.subarray(0, 8).toString('hex') !== HERMES_MAGIC_HEADER) {\n throw new Error('Invalid hermes bundle file');\n }\n return header.readUInt32LE(8);\n}\n\nasync function readHermesHeaderAsync(file: string): Promise<Buffer> {\n const fd = await fs.promises.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fd.read(buffer, 0, 12, null);\n await fd.close();\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.promises.readFile(podfilePropertiesPath, 'utf8'));\n } catch {\n return {};\n }\n}\n\nexport function isAndroidUsingHermes(projectRoot: string) {\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(fs.readFileSync(gradlePropertiesPath, 'utf8'));\n return props['hermesEnabled'] === 'true';\n }\n\n // Assume Hermes is used by default.\n return true;\n}\n\nexport function isIosUsingHermes(projectRoot: string) {\n // If nullish, then assume Hermes is used.\n return isHermesPossiblyEnabled(projectRoot) !== false;\n}\n"],"names":["assertEngineMismatchAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isEnableHermesManaged","isHermesBytecodeBundleAsync","isHermesPossiblyEnabled","isIosUsingHermes","maybeInconsistentEngineAndroidAsync","maybeInconsistentEngineIosAsync","maybeThrowFromInconsistentEngineAsync","parseGradleProperties","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","content","result","line","split","trim","startsWith","sepIndex","indexOf","key","slice","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","promises","readFile","isHermesBare","podfilePath","readFileSync","isPropsReference","search","podfilePropertiesPath","JsonFile","read","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","subarray","toString","readUInt32LE","fd","open","buffer","Buffer","alloc","close","JSON","parse"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/export/exportHermes.ts"],"sourcesContent":["import { ExpoConfig, getConfigFilePaths, Platform } from '@expo/config';\nimport JsonFile from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nconst PODFILE_HERMES_LHS = /(?::hermes_enabled\\s*=>|hermes_enabled\\s*:)/;\nconst PODFILE_HERMES_PROPS_REFERENCE_RE = new RegExp(\n String.raw`^\\s*${PODFILE_HERMES_LHS.source}\\s*podfile_properties\\['expo\\.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo\\.jsEngine'\\]\\s*==\\s*'hermes'\\s*,?\\s*(?:#.*)?$`,\n 'm'\n);\nconst PODFILE_HERMES_TRUE_RE = new RegExp(\n String.raw`^\\s*${PODFILE_HERMES_LHS.source}\\s*true\\s*(?:,\\s*)?(?:[^\\n]*)?$`,\n 'm'\n);\nconst PODFILE_HERMES_FALSE_RE = new RegExp(\n String.raw`^\\s*${PODFILE_HERMES_LHS.source}\\s*false\\s*(?:,\\s*)?(?:[^\\n]*)?$`,\n 'm'\n);\n\nfunction getLiteralHermesSettingFromPodfile(content: string): boolean | null {\n const isPropsReference = content.search(PODFILE_HERMES_PROPS_REFERENCE_RE) >= 0;\n if (isPropsReference) {\n return null;\n }\n if (PODFILE_HERMES_TRUE_RE.test(content)) {\n return true;\n }\n if (PODFILE_HERMES_FALSE_RE.test(content)) {\n return false;\n }\n return null;\n}\n\nexport async function assertEngineMismatchAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>,\n platform: Platform\n) {\n const isHermesManaged = isEnableHermesManaged(exp, platform);\n const paths = getConfigFilePaths(projectRoot);\n const configFilePath = paths.dynamicConfigPath ?? paths.staticConfigPath ?? 'app.json';\n await maybeThrowFromInconsistentEngineAsync(\n projectRoot,\n configFilePath,\n platform,\n isHermesManaged\n );\n}\n\nexport function isEnableHermesManaged(\n expoConfig: Partial<Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>>,\n platform: string\n): boolean {\n switch (platform) {\n case 'android': {\n return (expoConfig.android?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n case 'ios': {\n return (expoConfig.ios?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n default:\n return false;\n }\n}\n\nexport function parseGradleProperties(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (let line of content.split('\\n')) {\n line = line.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const sepIndex = line.indexOf('=');\n const key = line.slice(0, sepIndex);\n const value = line.slice(sepIndex + 1);\n result[key] = value;\n }\n return result;\n}\n\nexport async function maybeThrowFromInconsistentEngineAsync(\n projectRoot: string,\n configFilePath: string,\n platform: string,\n isHermesManaged: boolean\n): Promise<void> {\n const configFileName = path.basename(configFilePath);\n if (\n platform === 'android' &&\n (await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged))\n ) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'android', 'gradle.properties')}\\n` +\n ` - ${path.join(projectRoot, 'android', 'app', 'build.gradle')}\\n` +\n 'Learn more: https://expo.fyi/hermes-android-config'\n );\n }\n\n if (platform === 'ios' && (await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged))) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile')}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile.properties.json')}\\n` +\n 'Learn more: https://expo.fyi/hermes-ios-config'\n );\n }\n}\n\nexport async function maybeInconsistentEngineAndroidAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check android native project if by chance to be consistent between app config\n\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(await fs.promises.readFile(gradlePropertiesPath, 'utf8'));\n const isHermesBare = props['hermesEnabled'] === 'true';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isHermesPossiblyEnabled(projectRoot: string): boolean | null {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for a literal :hermes_enabled => (true|false) or hermes_enabled: (true|false)\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = fs.readFileSync(podfilePath, 'utf8');\n const literal = getLiteralHermesSettingFromPodfile(content);\n if (literal != null) return literal;\n\n // If there is no props reference and no literal, assume Hermes is enabled by default\n const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);\n if (!hasPropsReference) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n try {\n const props = JsonFile.read(podfilePropertiesPath);\n return props['expo.jsEngine'] === 'hermes';\n } catch {\n // ignore\n }\n }\n\n return null;\n}\n\nexport async function maybeInconsistentEngineIosAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for a literal :hermes_enabled => (true|false)\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = await fs.promises.readFile(podfilePath, 'utf8');\n const literal = getLiteralHermesSettingFromPodfile(content);\n if (literal != null) {\n if (isHermesManaged !== literal) return true;\n } else {\n // If there is no props reference and no literal, assume Hermes is enabled by default\n const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);\n if (!hasPropsReference) {\n const assumedEnabled = true;\n if (isHermesManaged !== assumedEnabled) return true;\n }\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);\n const isHermesBare = props['expo.jsEngine'] === 'hermes';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\n// https://github.com/facebook/hermes/blob/release-v0.5/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25\nconst HERMES_MAGIC_HEADER = 'c61fbc03c103191f';\n\nexport async function isHermesBytecodeBundleAsync(file: string): Promise<boolean> {\n const header = await readHermesHeaderAsync(file);\n return header.subarray(0, 8).toString('hex') === HERMES_MAGIC_HEADER;\n}\n\nexport async function getHermesBytecodeBundleVersionAsync(file: string): Promise<number> {\n const header = await readHermesHeaderAsync(file);\n if (header.subarray(0, 8).toString('hex') !== HERMES_MAGIC_HEADER) {\n throw new Error('Invalid hermes bundle file');\n }\n return header.readUInt32LE(8);\n}\n\nasync function readHermesHeaderAsync(file: string): Promise<Buffer> {\n const fd = await fs.promises.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fd.read(buffer, 0, 12, null);\n await fd.close();\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.promises.readFile(podfilePropertiesPath, 'utf8'));\n } catch {\n return {};\n }\n}\n\nexport function isAndroidUsingHermes(projectRoot: string) {\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(fs.readFileSync(gradlePropertiesPath, 'utf8'));\n return props['hermesEnabled'] === 'true';\n }\n\n // Assume Hermes is used by default.\n return true;\n}\n\nexport function isIosUsingHermes(projectRoot: string) {\n // If nullish, then assume Hermes is used.\n return isHermesPossiblyEnabled(projectRoot) !== false;\n}\n"],"names":["assertEngineMismatchAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isEnableHermesManaged","isHermesBytecodeBundleAsync","isHermesPossiblyEnabled","isIosUsingHermes","maybeInconsistentEngineAndroidAsync","maybeInconsistentEngineIosAsync","maybeThrowFromInconsistentEngineAsync","parseGradleProperties","PODFILE_HERMES_LHS","PODFILE_HERMES_PROPS_REFERENCE_RE","RegExp","String","raw","source","PODFILE_HERMES_TRUE_RE","PODFILE_HERMES_FALSE_RE","getLiteralHermesSettingFromPodfile","content","isPropsReference","search","test","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","result","line","split","trim","startsWith","sepIndex","indexOf","key","slice","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","promises","readFile","isHermesBare","podfilePath","readFileSync","literal","hasPropsReference","podfilePropertiesPath","JsonFile","read","assumedEnabled","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","subarray","toString","readUInt32LE","fd","open","buffer","Buffer","alloc","close","JSON","parse"],"mappings":"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"}
|
|
@@ -28,6 +28,9 @@ _export(exports, {
|
|
|
28
28
|
},
|
|
29
29
|
getPathVariations: function() {
|
|
30
30
|
return getPathVariations;
|
|
31
|
+
},
|
|
32
|
+
injectScriptTags: function() {
|
|
33
|
+
return injectScriptTags;
|
|
31
34
|
}
|
|
32
35
|
});
|
|
33
36
|
function _chalk() {
|
|
@@ -86,6 +89,11 @@ function _interop_require_default(obj) {
|
|
|
86
89
|
};
|
|
87
90
|
}
|
|
88
91
|
const debug = require('debug')('expo:export:generateStaticRoutes');
|
|
92
|
+
function injectScriptTags(html, scriptTags) {
|
|
93
|
+
const scriptTagsHtml = scriptTags.map((tag)=>tag.platform === 'web' ? `<script src="${tag.src}"></script>` : `<script type="type/expo" src="${tag.src}" data-platform="${tag.platform}"></script>`).join('\n');
|
|
94
|
+
html = html.replace('</head>', `${scriptTagsHtml}\n</head>`);
|
|
95
|
+
return html;
|
|
96
|
+
}
|
|
89
97
|
/** Match `(page)` -> `page` */ function matchGroupName(name) {
|
|
90
98
|
var _name_match;
|
|
91
99
|
return (_name_match = name.match(/^\(([^/]+?)\)$/)) == null ? void 0 : _name_match[1];
|
|
@@ -159,7 +167,7 @@ function makeRuntimeEntryPointsAbsolute(manifest, appDir) {
|
|
|
159
167
|
}
|
|
160
168
|
});
|
|
161
169
|
}
|
|
162
|
-
async function exportFromServerAsync(projectRoot, devServer, { outputDir, baseUrl, exportServer, includeSourceMaps, routerRoot, files = new Map(), exp }) {
|
|
170
|
+
async function exportFromServerAsync(projectRoot, devServer, { outputDir, baseUrl, exportServer, includeSourceMaps, routerRoot, files = new Map(), exp, scriptTags }) {
|
|
163
171
|
_log.Log.log(`Static rendering is enabled. ` + (0, _link.learnMore)('https://docs.expo.dev/router/reference/static-rendering/'));
|
|
164
172
|
const platform = 'web';
|
|
165
173
|
const isExporting = true;
|
|
@@ -198,6 +206,11 @@ async function exportFromServerAsync(projectRoot, devServer, { outputDir, baseUr
|
|
|
198
206
|
if (injectFaviconTag) {
|
|
199
207
|
html = injectFaviconTag(html);
|
|
200
208
|
}
|
|
209
|
+
if (scriptTags) {
|
|
210
|
+
// Inject script tags into the HTML.
|
|
211
|
+
// <script type="type/expo" data-platform="ios" src="..." />
|
|
212
|
+
html = injectScriptTags(html, scriptTags);
|
|
213
|
+
}
|
|
201
214
|
return html;
|
|
202
215
|
}
|
|
203
216
|
});
|
|
@@ -241,7 +254,7 @@ function getHtmlFiles({ manifest, includeGroupVariations }) {
|
|
|
241
254
|
let leaf = null;
|
|
242
255
|
if (typeof value === 'string') {
|
|
243
256
|
leaf = value;
|
|
244
|
-
} else if (Object.keys(value.screens).length === 0) {
|
|
257
|
+
} else if (value.screens && Object.keys(value.screens).length === 0) {
|
|
245
258
|
// Ensure the trailing index is accounted for.
|
|
246
259
|
if (key === value.path + '/index') {
|
|
247
260
|
leaf = key;
|
|
@@ -413,6 +426,10 @@ function warnPossibleInvalidExportType(appDir) {
|
|
|
413
426
|
// TODO: Allow API Routes for native-only.
|
|
414
427
|
_log.Log.warn(_chalk().default.yellow`Skipping export for API routes because \`web.output\` is not "server". You may want to remove the routes: ${apiRoutes.map((v)=>_path().default.relative(appDir, v)).join(', ')}`);
|
|
415
428
|
}
|
|
429
|
+
const middlewareFile = (0, _router.getMiddlewareForDirectory)(appDir);
|
|
430
|
+
if (middlewareFile) {
|
|
431
|
+
_log.Log.warn(_chalk().default.yellow`Skipping export for middleware because \`web.output\` is not "server". You may want to remove ${_path().default.relative(appDir, middlewareFile)}`);
|
|
432
|
+
}
|
|
416
433
|
}
|
|
417
434
|
|
|
418
435
|
//# sourceMappingURL=exportStaticAsync.js.map
|
|
@@ -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 } 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 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};\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\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 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 renderAsync: (requestLocation: HtmlRequestLocation) => Promise<string>;\n exportServer?: boolean;\n files?: ExportAssetMap;\n }\n): Promise<ExportAssetMap> {\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 }: 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 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 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 (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 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"],"names":["exportApiRoutesStandaloneAsync","exportFromServerAsync","getFilesToExportFromServerAsync","getHtmlFiles","getPathVariations","debug","require","matchGroupName","name","match","projectRoot","manifest","renderAsync","exportServer","files","Map","Promise","all","includeGroupVariations","map","route","filePath","pathname","type","targetDomain","set","contents","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","platform","isExporting","join","injectFaviconTag","getVirtualFaviconAssetsAsync","resources","serverManifest","getStaticResourcesAsync","getStaticRenderFunctionAsync","inspect","colors","depth","template","html","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","replace","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","JSON","stringify","getApiRoutesForDirectory","warn","chalk","yellow","v","relative"],"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 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 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 renderAsync: (requestLocation: HtmlRequestLocation) => Promise<string>;\n exportServer?: boolean;\n files?: ExportAssetMap;\n }\n): Promise<ExportAssetMap> {\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 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 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","renderAsync","exportServer","files","Map","Promise","all","includeGroupVariations","route","filePath","pathname","type","targetDomain","set","contents","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","serverManifest","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","JSON","stringify","getApiRoutesForDirectory","warn","chalk","yellow","v","relative","middlewareFile","getMiddlewareForDirectory"],"mappings":"AAAA;;;;;CAKC;;;;;;;;;;;IAwaqBA,8BAA8B;eAA9BA;;IAxQAC,qBAAqB;eAArBA;;IApFAC,+BAA+B;eAA/BA;;IA+LNC,YAAY;eAAZA;;IAqHAC,iBAAiB;eAAjBA;;IArUAC,gBAAgB;eAAhBA;;;;gEAzDE;;;;;;;yBAEyB;;;;;;;yBACN;;;;;;;gEACpB;;;;;;;gEACO;;;;;;;yBACA;;;;;;yBAEqB;oCACL;4BACiB;qBACrC;qCAMe;wBACiC;+BAC5B;sBACd;;;;;;AAE1B,MAAMC,QAAQC,QAAQ,SAAS;AAmCxB,SAASF,iBAAiBG,IAAY,EAAEC,UAA4B;IACzE,MAAMC,iBAAiBD,WACpBE,GAAG,CAAC,CAACC,MACJA,IAAIC,QAAQ,KAAK,QACb,CAAC,aAAa,EAAED,IAAIE,GAAG,CAAC,WAAW,CAAC,GACpC,CAAC,8BAA8B,EAAEF,IAAIE,GAAG,CAAC,iBAAiB,EAAEF,IAAIC,QAAQ,CAAC,WAAW,CAAC,EAE1FE,IAAI,CAAC;IACRP,OAAOA,KAAKQ,OAAO,CAAC,WAAW,GAAGN,eAAe,SAAS,CAAC;IAC3D,OAAOF;AACT;AAEA,6BAA6B,GAC7B,SAASS,eAAeC,IAAY;QAC3BA;IAAP,QAAOA,cAAAA,KAAKC,KAAK,CAAC,sCAAXD,WAA8B,CAAC,EAAE;AAC1C;AAEO,eAAehB,gCACpBkB,WAAmB,EACnB,EACEC,QAAQ,EACRC,WAAW,EACX,8DAA8D;AAC9D,kEAAkE;AAClE,aAAa;AACbC,YAAY,EACZ,kBAAkB;AAClBC,QAAQ,IAAIC,KAAK,EAMlB;IAED,MAAMC,QAAQC,GAAG,CACfxB,aAAa;QAAEkB;QAAUO,wBAAwB,CAACL;IAAa,GAAGZ,GAAG,CACnE,OAAO,EAAEkB,KAAK,EAAEC,QAAQ,EAAEC,QAAQ,EAAE;QAClC,oDAAoD;QACpD,IAAIF,MAAMG,IAAI,KAAK,WAAW;YAC5B;QACF;QAEA,IAAI;YACF,MAAMC,eAAeV,eAAe,WAAW;YAC/CC,MAAMU,GAAG,CAACJ,UAAU;gBAAEK,UAAU;gBAAIF;YAAa;YACjD,MAAMG,OAAO,MAAMd,YAAY;gBAAEO;gBAAOC;gBAAUC;YAAS;YAC3DP,MAAMU,GAAG,CAACJ,UAAU;gBAClBK,UAAUC;gBACVC,SAASN;gBACTE;YACF;QACF,EAAE,OAAOK,GAAQ;YACf,MAAMC,IAAAA,uCAAkB,EAAC;gBAAEC,OAAOF;gBAAGlB;YAAY;YACjD,MAAM,IAAIqB,MAAM,wCAAwCV;QAC1D;IACF;IAIJ,OAAOP;AACT;AAEA,SAASkB,iCACPrB,QAAmC,EACnCsB,QAAmC;IAEnC,MAAMC,iBAAiB,CAACC;QACtBC,OAAOC,MAAM,CAACF,SAASlC,GAAG,CAAC,CAACqC;YAC1B,IAAI,OAAOA,UAAU,UAAU;gBAC7B,IAAIA,MAAMC,MAAM,EAAEN,SAASK,MAAMC,MAAM;gBACvCL,eAAeI,MAAMH,OAAO;YAC9B;QACF;IACF;IAEAD,eAAevB,SAASwB,OAAO;AACjC;AAEA,wCAAwC;AACxC,SAASK,+BAA+B7B,QAAmC,EAAE8B,MAAc;IACzFT,iCAAiCrB,UAAU,CAACQ;QAC1C,IAAIuB,MAAMC,OAAO,CAACxB,MAAMyB,WAAW,GAAG;YACpCzB,MAAMyB,WAAW,GAAGzB,MAAMyB,WAAW,CAAC3C,GAAG,CAAC,CAAC4C;gBACzC,+BAA+B;gBAC/B,IAAIC,IAAAA,2BAAoB,EAACD,aAAa;oBACpC,OAAOA;gBACT;gBAEA,IAAIA,WAAWE,UAAU,CAAC,MAAM;oBAC9B,OAAOC,eAAI,CAACC,OAAO,CAACR,QAAQI;gBAC9B,OAAO,IAAI,CAACG,eAAI,CAACE,UAAU,CAACL,aAAa;oBACvC,OAAOM,IAAAA,sBAAW,EAACV,QAAQI;gBAC7B;gBACA,OAAOA;YACT;QACF;IACF;AACF;AAGO,eAAetD,sBACpBmB,WAAmB,EACnB0C,SAAgC,EAChC,EACEC,SAAS,EACTC,OAAO,EACPzC,YAAY,EACZ0C,iBAAiB,EACjBC,UAAU,EACV1C,QAAQ,IAAIC,KAAK,EACjB0C,GAAG,EACH1D,UAAU,EACF;IAEV2D,QAAG,CAACC,GAAG,CACL,CAAC,6BAA6B,CAAC,GAC7BC,IAAAA,eAAS,EAAC;IAGd,MAAMzD,WAAW;IACjB,MAAM0D,cAAc;IACpB,MAAMpB,SAASO,eAAI,CAAC3C,IAAI,CAACK,aAAa8C;IACtC,MAAMM,mBAAmB,MAAMC,IAAAA,qCAA4B,EAACrD,aAAa;QACvE2C;QACAC;QACAxC;QACA2C;IACF;IAEA,MAAM,CAACO,WAAW,EAAErD,QAAQ,EAAEsD,cAAc,EAAErD,WAAW,EAAE,CAAC,GAAG,MAAMI,QAAQC,GAAG,CAAC;QAC/EmC,UAAUc,uBAAuB,CAAC;YAChCX;QACF;QACAH,UAAUe,4BAA4B;KACvC;IAED3B,+BAA+B7B,UAAU8B;IAEzC7C,MAAM,aAAawE,IAAAA,eAAO,EAACzD,UAAU;QAAE0D,QAAQ;QAAMC,OAAO;IAAK;IAEjE,MAAM9E,gCAAgCkB,aAAa;QACjDI;QACAH;QACAE;QACA,MAAMD,aAAY,EAAES,QAAQ,EAAEF,KAAK,EAAE;YACnC,MAAMoD,WAAW,MAAM3D,YAAYS;YACnC,IAAIvB,OAAO,MAAM0E,IAAAA,sCAAuB,EAAC;gBACvCX;gBACAG,WAAWA,UAAUS,SAAS;gBAC9BF;gBACAjB;gBACAnC;gBACAuD,SAAS;YACX;YAEA,IAAIZ,kBAAkB;gBACpBhE,OAAOgE,iBAAiBhE;YAC1B;YAEA,IAAIC,YAAY;gBACd,oCAAoC;gBACpC,4DAA4D;gBAC5DD,OAAOH,iBAAiBG,MAAMC;YAChC;YAEA,OAAOD;QACT;IACF;IAEA6E,IAAAA,oCAAwB,EAACX,UAAUS,SAAS,EAAE;QAC5CtE;QACAoD;QACAzC;QACA8D,gBAAgB;IAClB;IAEA,IAAIZ,UAAUa,MAAM,EAAE;QACpB,+CAA+C;QAC/C,0GAA0G;QAC1G,MAAMC,IAAAA,2CAAuB,EAACpE,aAAasD,UAAUa,MAAM,EAAE;YAC3D/D;YACAX;YACA4E,iBAAiB1B;YACjBC;QACF;IACF;IAEA,IAAIzC,cAAc;QAChB,MAAMmE,YAAY,MAAMC,qBAAqB;YAC3C9E,UAAU;YACV+E,QAAQ9B;YACRzC,UAAUsD;YACV,4EAA4E;YAC5EV,mBAAmB;QACrB;QAEA,6CAA6C;QAC7C,KAAK,MAAM,CAACpC,OAAOM,SAAS,IAAIuD,UAAW;YACzClE,MAAMU,GAAG,CAACL,OAAOM;QACnB;IACF,OAAO;QACL0D,8BAA8B1C;IAChC;IAEA,OAAO3B;AACT;AAEO,SAASrB,aAAa,EAC3BkB,QAAQ,EACRO,sBAAsB,EAIvB;IACC,MAAMkE,YAAY,IAAIC;IAEtB,SAASC,gBACPnD,OAA6C,EAC7ChB,KAAuB,EACvBmC,UAAU,EAAE;QAEZ,KAAK,MAAM,CAACiC,KAAKjD,MAAM,IAAIF,OAAOoD,OAAO,CAACrD,SAAU;YAClD,IAAIsD,OAAsB;YAC1B,IAAI,OAAOnD,UAAU,UAAU;gBAC7BmD,OAAOnD;YACT,OAAO,IAAIA,MAAMH,OAAO,IAAIC,OAAOsD,IAAI,CAACpD,MAAMH,OAAO,EAAEwD,MAAM,KAAK,GAAG;gBACnE,8CAA8C;gBAC9C,IAAIJ,QAAQjD,MAAMU,IAAI,GAAG,UAAU;oBACjCyC,OAAOF;gBACT,OAAO;oBACLE,OAAOnD,MAAMU,IAAI;gBACnB;gBAEA7B,QAAQmB,MAAMC,MAAM,IAAI;YAC1B;YAEA,IAAIkD,QAAQ,MAAM;gBAChB,IAAIrE,WAAWkC,UAAUmC;gBAEzB,IAAIA,SAAS,IAAI;oBACfrE,WACEkC,YAAY,KACR,UACAA,QAAQsC,QAAQ,CAAC,OACftC,UAAU,UACVA,QAAQuC,KAAK,CAAC,GAAG,CAAC;gBAC5B,OAAO,IACL,4FAA4F;gBAC5FC,IAAAA,sCAA0B,EAAC1E,cAAc,IACzC;oBACAA,YAAY;gBACd;gBAEA,kGAAkG;gBAClG,IAAI,CAACD,OAAO;oBACV,MAAM,IAAIY,MACR,CAAC,qCAAqC,EAAEX,SAAS,uCAAuC,CAAC;gBAE7F;gBAEA,IAAIF,wBAAwB;oBAC1B,0CAA0C;oBAC1C6E,kBAAkB3E,UAAUD;gBAC9B,OAAO;oBACLiE,UAAUY,GAAG,CAAC;wBACZ5E;wBACAD;oBACF;gBACF;YACF,OAAO,IAAI,OAAOmB,UAAU,aAAYA,yBAAAA,MAAOH,OAAO,GAAE;gBACtD,+BAA+B;gBAC/B,MAAM8D,UAAU3D,MAAMU,IAAI,GAAGM,UAAUhB,MAAMU,IAAI,GAAG,MAAMM;gBAC1DgC,gBAAgBhD,MAAMH,OAAO,EAAEG,MAAMC,MAAM,IAAI,MAAM0D;YACvD;QACF;IACF;IAEA,SAASF,kBAAkB/C,IAAY,EAAE7B,KAAgB;QACvD,MAAM+E,aAAaxG,kBAAkBsD;QACrC,KAAK,MAAMmD,aAAaD,WAAY;YAClCd,UAAUY,GAAG,CAAC;gBAAE5E,UAAU+E;gBAAWhF;YAAM;QAC7C;IACF;IAEAmE,gBAAgB3E,SAASwB,OAAO,EAAE;IAElC,OAAOiE,SAAS1D,MAAM2D,IAAI,CAACjB,YAAY,CAAC9C,QAAUA,MAAMlB,QAAQ,EAAEnB,GAAG,CAAC,CAACqC;QACrE,MAAMgE,QAAQhE,MAAMlB,QAAQ,CAACmF,KAAK,CAAC;QACnC,yDAAyD;QACzD,MAAMC,kBAAkBF,MAAMrG,GAAG,CAAC,CAACwG;YACjC,IAAIA,SAAS,cAAc;gBACzB,OAAO,CAAC,UAAU,CAAC;YACrB,OAAO,IAAIA,KAAK1D,UAAU,CAAC,MAAM;gBAC/B,OAAO,CAAC,CAAC,EAAE0D,KAAKZ,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO,IAAIY,KAAK1D,UAAU,CAAC,MAAM;gBAC/B,OAAO,CAAC,IAAI,EAAE0D,KAAKZ,KAAK,CAAC,GAAG,CAAC,CAAC;YAChC;YACA,OAAOY;QACT;QACA,MAAMC,mBAAmBF,gBAAgBnG,IAAI,CAAC;QAC9C,MAAMe,WAAWsF,mBAAmB;QACpC,OAAO;YACL,GAAGpE,KAAK;YACRlB;YACAC,UAAUqF,iBAAiBpG,OAAO,CAAC,gBAAgB;QACrD;IACF;AACF;AAEA,SAAS8F,SAAYO,KAAU,EAAEpB,GAAyB;IACxD,MAAMqB,OAAO,IAAIvB;IACjB,MAAMwB,SAAc,EAAE;IACtB,KAAK,MAAMvE,SAASqE,MAAO;QACzB,MAAMG,KAAKvB,IAAIjD;QACf,IAAI,CAACsE,KAAKG,GAAG,CAACD,KAAK;YACjBF,KAAKZ,GAAG,CAACc;YACTD,OAAOG,IAAI,CAAC1E;QACd;IACF;IACA,OAAOuE;AACT;AAIO,SAASnH,kBAAkBuH,SAAiB;IACjD,MAAMf,aAAa,IAAIb;IACvB,MAAM6B,WAAWD,UAAUV,KAAK,CAAC;IAEjC,SAASY,mBAAmBD,QAAkB,EAAEE,UAAU,EAAE;QAC1D,IAAIF,SAASvB,MAAM,KAAK,GAAG;YACzB,IAAIyB,SAASlB,WAAWF,GAAG,CAACoB;YAC5B;QACF;QAEA,MAAM,CAACC,MAAM,GAAGC,KAAK,GAAGJ;QAExB,IAAI3G,eAAe8G,OAAO;YACxB,MAAME,SAASF,KAAKxB,KAAK,CAAC,GAAG,CAAC,GAAGU,KAAK,CAAC;YAEvC,IAAIgB,OAAO5B,MAAM,GAAG,GAAG;gBACrB,KAAK,MAAM6B,SAASD,OAAQ;oBAC1B,uDAAuD;oBACvDJ,mBAAmB;wBAAC,CAAC,CAAC,EAAEK,MAAMC,IAAI,GAAG,CAAC,CAAC;2BAAKH;qBAAK,EAAEF;gBACrD;gBACA;YACF,OAAO;gBACL,4CAA4C;gBAC5CD,mBAAmBG,MAAMF,UAAU,GAAGA,QAAQ,EAAE,EAAEG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAEA,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YACjF,qEAAqE;YACvE;QACF,OAAO,IAAIH,SAAS;YAClBA,UAAU,GAAGA,QAAQ,CAAC,EAAEC,MAAM;QAChC,OAAO;YACLD,UAAUC;QACZ;QAEAF,mBAAmBG,MAAMF;IAC3B;IAEAD,mBAAmBD;IAEnB,OAAOxE,MAAM2D,IAAI,CAACH;AACpB;AAEO,eAAe5G,+BACpB8D,SAAgC,EAChC,EACEtC,QAAQ,IAAIC,KAAK,EACjBZ,QAAQ,EACRuH,aAAa,EACbC,YAAY,EAMb;IAED,MAAM,EAAE1D,cAAc,EAAE2D,YAAY,EAAE,GAAG,MAAMxE,UAAUyE,sBAAsB;IAE/E,MAAM7C,YAAY,MAAMC,qBAAqB;QAC3CC,QAAQ9B;QACRzC,UAAUsD;QACV,4EAA4E;QAC5EV,mBAAmB;QACnBpD;QACAuH;IACF;IAEA,6CAA6C;IAC7C,KAAK,MAAM,CAACvG,OAAOM,SAAS,IAAIuD,UAAW;QACzClE,MAAMU,GAAG,CAACL,OAAOM;IACnB;IAEA,IAAIkG,gBAAgBvE,UAAU0E,8BAA8B,EAAE;QAC5D,wGAAwG;QACxG,MAAMtI,gCAAgC4D,UAAU1C,WAAW,EAAE;YAC3DC,UAAUiH;YACV/G,cAAc;YACdC;YACAF,aAAa,OAAO,EAAES,QAAQ,EAAED,QAAQ,EAAE;gBACxCN,MAAMU,GAAG,CAACJ,UAAU;oBAClBK,UAAUkG;oBACVhG,SAASN;oBACTE,cAAc;gBAChB;gBACA,OAAOoG;YACT;QACF;IACF;IAEA,OAAO7G;AACT;AAEA,eAAemE,qBAAqB,EAClC1B,iBAAiB,EACjB2B,MAAM,EACN/E,QAAQ,EACRuH,aAAa,EACb,GAAGK,OAMJ;IACC,MAAM,EAAEpH,QAAQ,EAAEG,KAAK,EAAE,GAAG,MAAMoE,OAAO8C,8BAA8B,CAAC;QACtE3E,WAAW;QACX4E,mBAAmBF,MAAMpH,QAAQ;QACjC4C;QACApD;IACF;IAEA,8KAA8K;IAC9K,IAAIuH,eAAe;QACjB/G,SAASuH,UAAU,GAAG,EAAE;QACxBvH,SAASwH,cAAc,GAAG,EAAE;IAC9B;IAEArH,MAAMU,GAAG,CAAC,qBAAqB;QAC7BC,UAAU2G,KAAKC,SAAS,CAAC1H,UAAU,MAAM;QACzCY,cAAc;IAChB;IAEA,OAAOT;AACT;AAEA,SAASqE,8BAA8B1C,MAAc;IACnD,MAAMuC,YAAYsD,IAAAA,gCAAwB,EAAC7F;IAC3C,IAAIuC,UAAUW,MAAM,EAAE;QACpB,0CAA0C;QAC1CjC,QAAG,CAAC6E,IAAI,CACNC,gBAAK,CAACC,MAAM,CAAC,0GAA0G,EAAEzD,UACtH/E,GAAG,CAAC,CAACyI,IAAM1F,eAAI,CAAC2F,QAAQ,CAAClG,QAAQiG,IACjCrI,IAAI,CAAC,MAAM,CAAC;IAEnB;IAEA,MAAMuI,iBAAiBC,IAAAA,iCAAyB,EAACpG;IACjD,IAAImG,gBAAgB;QAClBlF,QAAG,CAAC6E,IAAI,CACNC,gBAAK,CAACC,MAAM,CAAC,8FAA8F,EAAEzF,eAAI,CAAC2F,QAAQ,CAAClG,QAAQmG,gBAAgB,CAAC;IAExJ;AACF"}
|
|
@@ -80,6 +80,7 @@ const expoExport = async (argv)=>{
|
|
|
80
80
|
'--no-minify': Boolean,
|
|
81
81
|
'--no-bytecode': Boolean,
|
|
82
82
|
'--no-ssg': Boolean,
|
|
83
|
+
'--unstable-hosted-native': Boolean,
|
|
83
84
|
// Hack: This is added because EAS CLI always includes the flag.
|
|
84
85
|
// If supplied, we'll do nothing with the value, but at least the process won't crash.
|
|
85
86
|
// Note that we also don't show this value in the `--help` prompt since we don't want people to use it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport chalk from 'chalk';\n\nimport { Command } from '../../bin/cli';\nimport { assertArgs, getProjectRoot, printHelp } from '../utils/args';\nimport { logCmdError } from '../utils/errors';\n\nexport const expoExport: Command = async (argv) => {\n const args = assertArgs(\n {\n // Types\n '--help': Boolean,\n '--clear': Boolean,\n '--dump-assetmap': Boolean,\n '--dev': Boolean,\n '--source-maps': Boolean,\n '--max-workers': Number,\n '--output-dir': String,\n '--platform': [String],\n '--no-minify': Boolean,\n '--no-bytecode': Boolean,\n '--no-ssg': Boolean,\n\n // Hack: This is added because EAS CLI always includes the flag.\n // If supplied, we'll do nothing with the value, but at least the process won't crash.\n // Note that we also don't show this value in the `--help` prompt since we don't want people to use it.\n '--experimental-bundle': Boolean,\n\n // Aliases\n '-h': '--help',\n '-s': '--source-maps',\n // '-d': '--dump-assetmap',\n '-c': '--clear',\n '-p': '--platform',\n // Interop with Metro docs and RedBox errors.\n '--reset-cache': '--clear',\n\n // Deprecated\n '--dump-sourcemap': '--source-maps',\n },\n argv\n );\n\n if (args['--help']) {\n printHelp(\n `Export the static files of the app for hosting it on a web server`,\n chalk`npx expo export {dim <dir>}`,\n [\n chalk`<dir> Directory of the Expo project. {dim Default: Current working directory}`,\n chalk`--output-dir <dir> The directory to export the static files to. {dim Default: dist}`,\n `--dev Configure static files for developing locally using a non-https server`,\n `--no-minify Prevent minifying source`,\n `--no-bytecode Prevent generating Hermes bytecode`,\n `--max-workers <number> Maximum number of tasks to allow the bundler to spawn`,\n `--dump-assetmap Emit an asset map for further processing`,\n `--no-ssg Skip exporting static HTML files for web routes`,\n chalk`-p, --platform <platform> Options: android, ios, web, all. {dim Default: all}`,\n `-s, --source-maps Emit JavaScript source maps`,\n `-c, --clear Clear the bundler cache`,\n `-h, --help Usage info`,\n ].join('\\n')\n );\n }\n\n const projectRoot = getProjectRoot(args);\n const { resolveOptionsAsync } = await import('./resolveOptions.js');\n const options = await resolveOptionsAsync(projectRoot, args).catch(logCmdError);\n\n const { exportAsync } = await import('./exportAsync.js');\n return exportAsync(projectRoot, options).catch(logCmdError);\n};\n"],"names":["expoExport","argv","args","assertArgs","Boolean","Number","String","printHelp","chalk","join","projectRoot","getProjectRoot","resolveOptionsAsync","options","catch","logCmdError","exportAsync"],"mappings":";;;;;+BAOaA;;;eAAAA;;;;gEANK;;;;;;sBAGoC;wBAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMA,aAAsB,OAAOC;IACxC,MAAMC,OAAOC,IAAAA,gBAAU,EACrB;QACE,QAAQ;QACR,UAAUC;QACV,WAAWA;QACX,mBAAmBA;QACnB,SAASA;QACT,iBAAiBA;QACjB,iBAAiBC;QACjB,gBAAgBC;QAChB,cAAc;YAACA;SAAO;QACtB,eAAeF;QACf,iBAAiBA;QACjB,YAAYA;
|
|
1
|
+
{"version":3,"sources":["../../../src/export/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport chalk from 'chalk';\n\nimport { Command } from '../../bin/cli';\nimport { assertArgs, getProjectRoot, printHelp } from '../utils/args';\nimport { logCmdError } from '../utils/errors';\n\nexport const expoExport: Command = async (argv) => {\n const args = assertArgs(\n {\n // Types\n '--help': Boolean,\n '--clear': Boolean,\n '--dump-assetmap': Boolean,\n '--dev': Boolean,\n '--source-maps': Boolean,\n '--max-workers': Number,\n '--output-dir': String,\n '--platform': [String],\n '--no-minify': Boolean,\n '--no-bytecode': Boolean,\n '--no-ssg': Boolean,\n '--unstable-hosted-native': Boolean,\n\n // Hack: This is added because EAS CLI always includes the flag.\n // If supplied, we'll do nothing with the value, but at least the process won't crash.\n // Note that we also don't show this value in the `--help` prompt since we don't want people to use it.\n '--experimental-bundle': Boolean,\n\n // Aliases\n '-h': '--help',\n '-s': '--source-maps',\n // '-d': '--dump-assetmap',\n '-c': '--clear',\n '-p': '--platform',\n // Interop with Metro docs and RedBox errors.\n '--reset-cache': '--clear',\n\n // Deprecated\n '--dump-sourcemap': '--source-maps',\n },\n argv\n );\n\n if (args['--help']) {\n printHelp(\n `Export the static files of the app for hosting it on a web server`,\n chalk`npx expo export {dim <dir>}`,\n [\n chalk`<dir> Directory of the Expo project. {dim Default: Current working directory}`,\n chalk`--output-dir <dir> The directory to export the static files to. {dim Default: dist}`,\n `--dev Configure static files for developing locally using a non-https server`,\n `--no-minify Prevent minifying source`,\n `--no-bytecode Prevent generating Hermes bytecode`,\n `--max-workers <number> Maximum number of tasks to allow the bundler to spawn`,\n `--dump-assetmap Emit an asset map for further processing`,\n `--no-ssg Skip exporting static HTML files for web routes`,\n chalk`-p, --platform <platform> Options: android, ios, web, all. {dim Default: all}`,\n `-s, --source-maps Emit JavaScript source maps`,\n `-c, --clear Clear the bundler cache`,\n `-h, --help Usage info`,\n ].join('\\n')\n );\n }\n\n const projectRoot = getProjectRoot(args);\n const { resolveOptionsAsync } = await import('./resolveOptions.js');\n const options = await resolveOptionsAsync(projectRoot, args).catch(logCmdError);\n\n const { exportAsync } = await import('./exportAsync.js');\n return exportAsync(projectRoot, options).catch(logCmdError);\n};\n"],"names":["expoExport","argv","args","assertArgs","Boolean","Number","String","printHelp","chalk","join","projectRoot","getProjectRoot","resolveOptionsAsync","options","catch","logCmdError","exportAsync"],"mappings":";;;;;+BAOaA;;;eAAAA;;;;gEANK;;;;;;sBAGoC;wBAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAErB,MAAMA,aAAsB,OAAOC;IACxC,MAAMC,OAAOC,IAAAA,gBAAU,EACrB;QACE,QAAQ;QACR,UAAUC;QACV,WAAWA;QACX,mBAAmBA;QACnB,SAASA;QACT,iBAAiBA;QACjB,iBAAiBC;QACjB,gBAAgBC;QAChB,cAAc;YAACA;SAAO;QACtB,eAAeF;QACf,iBAAiBA;QACjB,YAAYA;QACZ,4BAA4BA;QAE5B,gEAAgE;QAChE,sFAAsF;QACtF,uGAAuG;QACvG,yBAAyBA;QAEzB,UAAU;QACV,MAAM;QACN,MAAM;QACN,2BAA2B;QAC3B,MAAM;QACN,MAAM;QACN,6CAA6C;QAC7C,iBAAiB;QAEjB,aAAa;QACb,oBAAoB;IACtB,GACAH;IAGF,IAAIC,IAAI,CAAC,SAAS,EAAE;QAClBK,IAAAA,eAAS,EACP,CAAC,iEAAiE,CAAC,EACnEC,IAAAA,gBAAK,CAAA,CAAC,2BAA2B,CAAC,EAClC;YACEA,IAAAA,gBAAK,CAAA,CAAC,kGAAkG,CAAC;YACzGA,IAAAA,gBAAK,CAAA,CAAC,2FAA2F,CAAC;YAClG,CAAC,iGAAiG,CAAC;YACnG,CAAC,mDAAmD,CAAC;YACrD,CAAC,6DAA6D,CAAC;YAC/D,CAAC,gFAAgF,CAAC;YAClF,CAAC,mEAAmE,CAAC;YACrE,CAAC,0EAA0E,CAAC;YAC5EA,IAAAA,gBAAK,CAAA,CAAC,8EAA8E,CAAC;YACrF,CAAC,sDAAsD,CAAC;YACxD,CAAC,kDAAkD,CAAC;YACpD,CAAC,qCAAqC,CAAC;SACxC,CAACC,IAAI,CAAC;IAEX;IAEA,MAAMC,cAAcC,IAAAA,oBAAc,EAACT;IACnC,MAAM,EAAEU,mBAAmB,EAAE,GAAG,MAAM,mEAAA,QAAO;IAC7C,MAAMC,UAAU,MAAMD,oBAAoBF,aAAaR,MAAMY,KAAK,CAACC,mBAAW;IAE9E,MAAM,EAAEC,WAAW,EAAE,GAAG,MAAM,mEAAA,QAAO;IACrC,OAAOA,YAAYN,aAAaG,SAASC,KAAK,CAACC,mBAAW;AAC5D"}
|
|
@@ -71,6 +71,7 @@ async function resolveOptionsAsync(projectRoot, args) {
|
|
|
71
71
|
const platforms = resolvePlatformOption(exp, platformBundlers, args['--platform']);
|
|
72
72
|
return {
|
|
73
73
|
platforms,
|
|
74
|
+
hostedNative: !!args['--unstable-hosted-native'],
|
|
74
75
|
outputDir: args['--output-dir'] ?? 'dist',
|
|
75
76
|
minify: !args['--no-minify'],
|
|
76
77
|
bytecode: !args['--no-bytecode'],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/resolveOptions.ts"],"sourcesContent":["import { ExpoConfig, getConfig, Platform } from '@expo/config';\n\nimport { getPlatformBundlers, PlatformBundlers } from '../start/server/platformBundlers';\nimport { CommandError } from '../utils/errors';\n\nexport type Options = {\n outputDir: string;\n platforms: Platform[];\n maxWorkers?: number;\n dev: boolean;\n clear: boolean;\n minify: boolean;\n bytecode: boolean;\n dumpAssetmap: boolean;\n sourceMaps: boolean;\n skipSSG: boolean;\n};\n\n/** Returns an array of platforms based on the input platform identifier and runtime constraints. */\nexport function resolvePlatformOption(\n exp: ExpoConfig,\n platformBundlers: PlatformBundlers,\n platform: string[] = ['all']\n): Platform[] {\n const platformsAvailable: Partial<PlatformBundlers> = Object.fromEntries(\n Object.entries(platformBundlers).filter(\n ([platform, bundler]) => bundler === 'metro' && exp.platforms?.includes(platform as Platform)\n )\n );\n\n if (!Object.keys(platformsAvailable).length) {\n throw new CommandError(\n `No platforms are configured to use the Metro bundler in the project Expo config.`\n );\n }\n\n const assertPlatformBundler = (platform: Platform): Platform => {\n if (!platformsAvailable[platform]) {\n if (!exp.platforms?.includes(platform) && platform === 'web') {\n // Pass through so the more robust error message is shown.\n return platform;\n }\n throw new CommandError(\n 'BAD_ARGS',\n `Platform \"${platform}\" is not configured to use the Metro bundler in the project Expo config, or is missing from the supported platforms in the platforms array: [${exp.platforms?.join(\n ', '\n )}].`\n );\n }\n\n return platform;\n };\n\n const knownPlatforms = ['android', 'ios', 'web'] as Platform[];\n const assertPlatformIsKnown = (platform: string): Platform => {\n if (!knownPlatforms.includes(platform as Platform)) {\n throw new CommandError(\n `Unsupported platform \"${platform}\". Options are: ${knownPlatforms.join(',')},all`\n );\n }\n\n return platform as Platform;\n };\n\n return (\n platform\n // Expand `all` to all available platforms.\n .map((platform) => (platform === 'all' ? Object.keys(platformsAvailable) : platform))\n .flat()\n // Remove duplicated platforms\n .filter((platform, index, list) => list.indexOf(platform) === index)\n // Assert platforms are valid\n .map((platform) => assertPlatformIsKnown(platform))\n .map((platform) => assertPlatformBundler(platform))\n );\n}\n\nexport async function resolveOptionsAsync(projectRoot: string, args: any): Promise<Options> {\n const { exp } = getConfig(projectRoot, { skipPlugins: true, skipSDKVersionRequirement: true });\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const platforms = resolvePlatformOption(exp, platformBundlers, args['--platform']);\n return {\n platforms,\n outputDir: args['--output-dir'] ?? 'dist',\n minify: !args['--no-minify'],\n bytecode: !args['--no-bytecode'],\n clear: !!args['--clear'],\n dev: !!args['--dev'],\n maxWorkers: args['--max-workers'],\n dumpAssetmap: !!args['--dump-assetmap'],\n sourceMaps: !!args['--source-maps'],\n skipSSG: !!args['--no-ssg'],\n };\n}\n"],"names":["resolveOptionsAsync","resolvePlatformOption","exp","platformBundlers","platform","platformsAvailable","Object","fromEntries","entries","filter","bundler","platforms","includes","keys","length","CommandError","assertPlatformBundler","join","knownPlatforms","assertPlatformIsKnown","map","flat","index","list","indexOf","projectRoot","args","getConfig","skipPlugins","skipSDKVersionRequirement","getPlatformBundlers","outputDir","minify","bytecode","clear","dev","maxWorkers","dumpAssetmap","sourceMaps","skipSSG"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../src/export/resolveOptions.ts"],"sourcesContent":["import { ExpoConfig, getConfig, Platform } from '@expo/config';\n\nimport { getPlatformBundlers, PlatformBundlers } from '../start/server/platformBundlers';\nimport { CommandError } from '../utils/errors';\n\nexport type Options = {\n outputDir: string;\n platforms: Platform[];\n maxWorkers?: number;\n dev: boolean;\n clear: boolean;\n minify: boolean;\n bytecode: boolean;\n dumpAssetmap: boolean;\n sourceMaps: boolean;\n skipSSG: boolean;\n hostedNative: boolean;\n};\n\n/** Returns an array of platforms based on the input platform identifier and runtime constraints. */\nexport function resolvePlatformOption(\n exp: ExpoConfig,\n platformBundlers: PlatformBundlers,\n platform: string[] = ['all']\n): Platform[] {\n const platformsAvailable: Partial<PlatformBundlers> = Object.fromEntries(\n Object.entries(platformBundlers).filter(\n ([platform, bundler]) => bundler === 'metro' && exp.platforms?.includes(platform as Platform)\n )\n );\n\n if (!Object.keys(platformsAvailable).length) {\n throw new CommandError(\n `No platforms are configured to use the Metro bundler in the project Expo config.`\n );\n }\n\n const assertPlatformBundler = (platform: Platform): Platform => {\n if (!platformsAvailable[platform]) {\n if (!exp.platforms?.includes(platform) && platform === 'web') {\n // Pass through so the more robust error message is shown.\n return platform;\n }\n throw new CommandError(\n 'BAD_ARGS',\n `Platform \"${platform}\" is not configured to use the Metro bundler in the project Expo config, or is missing from the supported platforms in the platforms array: [${exp.platforms?.join(\n ', '\n )}].`\n );\n }\n\n return platform;\n };\n\n const knownPlatforms = ['android', 'ios', 'web'] as Platform[];\n const assertPlatformIsKnown = (platform: string): Platform => {\n if (!knownPlatforms.includes(platform as Platform)) {\n throw new CommandError(\n `Unsupported platform \"${platform}\". Options are: ${knownPlatforms.join(',')},all`\n );\n }\n\n return platform as Platform;\n };\n\n return (\n platform\n // Expand `all` to all available platforms.\n .map((platform) => (platform === 'all' ? Object.keys(platformsAvailable) : platform))\n .flat()\n // Remove duplicated platforms\n .filter((platform, index, list) => list.indexOf(platform) === index)\n // Assert platforms are valid\n .map((platform) => assertPlatformIsKnown(platform))\n .map((platform) => assertPlatformBundler(platform))\n );\n}\n\nexport async function resolveOptionsAsync(projectRoot: string, args: any): Promise<Options> {\n const { exp } = getConfig(projectRoot, { skipPlugins: true, skipSDKVersionRequirement: true });\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const platforms = resolvePlatformOption(exp, platformBundlers, args['--platform']);\n return {\n platforms,\n hostedNative: !!args['--unstable-hosted-native'],\n outputDir: args['--output-dir'] ?? 'dist',\n minify: !args['--no-minify'],\n bytecode: !args['--no-bytecode'],\n clear: !!args['--clear'],\n dev: !!args['--dev'],\n maxWorkers: args['--max-workers'],\n dumpAssetmap: !!args['--dump-assetmap'],\n sourceMaps: !!args['--source-maps'],\n skipSSG: !!args['--no-ssg'],\n };\n}\n"],"names":["resolveOptionsAsync","resolvePlatformOption","exp","platformBundlers","platform","platformsAvailable","Object","fromEntries","entries","filter","bundler","platforms","includes","keys","length","CommandError","assertPlatformBundler","join","knownPlatforms","assertPlatformIsKnown","map","flat","index","list","indexOf","projectRoot","args","getConfig","skipPlugins","skipSDKVersionRequirement","getPlatformBundlers","hostedNative","outputDir","minify","bytecode","clear","dev","maxWorkers","dumpAssetmap","sourceMaps","skipSSG"],"mappings":";;;;;;;;;;;IA8EsBA,mBAAmB;eAAnBA;;IA1DNC,qBAAqB;eAArBA;;;;yBApBgC;;;;;;kCAEM;wBACzB;AAiBtB,SAASA,sBACdC,GAAe,EACfC,gBAAkC,EAClCC,WAAqB;IAAC;CAAM;IAE5B,MAAMC,qBAAgDC,OAAOC,WAAW,CACtED,OAAOE,OAAO,CAACL,kBAAkBM,MAAM,CACrC,CAAC,CAACL,UAAUM,QAAQ;YAA4BR;eAAvBQ,YAAY,aAAWR,iBAAAA,IAAIS,SAAS,qBAAbT,eAAeU,QAAQ,CAACR;;IAI5E,IAAI,CAACE,OAAOO,IAAI,CAACR,oBAAoBS,MAAM,EAAE;QAC3C,MAAM,IAAIC,oBAAY,CACpB,CAAC,gFAAgF,CAAC;IAEtF;IAEA,MAAMC,wBAAwB,CAACZ;QAC7B,IAAI,CAACC,kBAAkB,CAACD,SAAS,EAAE;gBAC5BF,gBAMkKA;YANvK,IAAI,GAACA,iBAAAA,IAAIS,SAAS,qBAAbT,eAAeU,QAAQ,CAACR,cAAaA,aAAa,OAAO;gBAC5D,0DAA0D;gBAC1D,OAAOA;YACT;YACA,MAAM,IAAIW,oBAAY,CACpB,YACA,CAAC,UAAU,EAAEX,SAAS,6IAA6I,GAAEF,kBAAAA,IAAIS,SAAS,qBAAbT,gBAAee,IAAI,CACtL,MACA,EAAE,CAAC;QAET;QAEA,OAAOb;IACT;IAEA,MAAMc,iBAAiB;QAAC;QAAW;QAAO;KAAM;IAChD,MAAMC,wBAAwB,CAACf;QAC7B,IAAI,CAACc,eAAeN,QAAQ,CAACR,WAAuB;YAClD,MAAM,IAAIW,oBAAY,CACpB,CAAC,sBAAsB,EAAEX,SAAS,gBAAgB,EAAEc,eAAeD,IAAI,CAAC,KAAK,IAAI,CAAC;QAEtF;QAEA,OAAOb;IACT;IAEA,OACEA,QACE,2CAA2C;KAC1CgB,GAAG,CAAC,CAAChB,WAAcA,aAAa,QAAQE,OAAOO,IAAI,CAACR,sBAAsBD,UAC1EiB,IAAI,EACL,8BAA8B;KAC7BZ,MAAM,CAAC,CAACL,UAAUkB,OAAOC,OAASA,KAAKC,OAAO,CAACpB,cAAckB,MAC9D,6BAA6B;KAC5BF,GAAG,CAAC,CAAChB,WAAae,sBAAsBf,WACxCgB,GAAG,CAAC,CAAChB,WAAaY,sBAAsBZ;AAE/C;AAEO,eAAeJ,oBAAoByB,WAAmB,EAAEC,IAAS;IACtE,MAAM,EAAExB,GAAG,EAAE,GAAGyB,IAAAA,mBAAS,EAACF,aAAa;QAAEG,aAAa;QAAMC,2BAA2B;IAAK;IAC5F,MAAM1B,mBAAmB2B,IAAAA,qCAAmB,EAACL,aAAavB;IAE1D,MAAMS,YAAYV,sBAAsBC,KAAKC,kBAAkBuB,IAAI,CAAC,aAAa;IACjF,OAAO;QACLf;QACAoB,cAAc,CAAC,CAACL,IAAI,CAAC,2BAA2B;QAChDM,WAAWN,IAAI,CAAC,eAAe,IAAI;QACnCO,QAAQ,CAACP,IAAI,CAAC,cAAc;QAC5BQ,UAAU,CAACR,IAAI,CAAC,gBAAgB;QAChCS,OAAO,CAAC,CAACT,IAAI,CAAC,UAAU;QACxBU,KAAK,CAAC,CAACV,IAAI,CAAC,QAAQ;QACpBW,YAAYX,IAAI,CAAC,gBAAgB;QACjCY,cAAc,CAAC,CAACZ,IAAI,CAAC,kBAAkB;QACvCa,YAAY,CAAC,CAACb,IAAI,CAAC,gBAAgB;QACnCc,SAAS,CAAC,CAACd,IAAI,CAAC,WAAW;IAC7B;AACF"}
|
|
@@ -72,6 +72,7 @@ async function persistMetroFilesAsync(files, outputDir) {
|
|
|
72
72
|
// );
|
|
73
73
|
const assetEntries = [];
|
|
74
74
|
const apiRouteEntries = [];
|
|
75
|
+
const middlewareEntries = [];
|
|
75
76
|
const routeEntries = [];
|
|
76
77
|
const rscEntries = [];
|
|
77
78
|
const remainingEntries = [];
|
|
@@ -80,6 +81,7 @@ async function persistMetroFilesAsync(files, outputDir) {
|
|
|
80
81
|
hasServerOutput = hasServerOutput || asset[1].targetDomain === 'server';
|
|
81
82
|
if (asset[1].assetId) assetEntries.push(asset);
|
|
82
83
|
else if (asset[1].routeId != null) routeEntries.push(asset);
|
|
84
|
+
else if (asset[1].middlewareId != null) middlewareEntries.push(asset);
|
|
83
85
|
else if (asset[1].apiRouteId != null) apiRouteEntries.push(asset);
|
|
84
86
|
else if (asset[1].rscId != null) rscEntries.push(asset);
|
|
85
87
|
else remainingEntries.push(asset);
|
|
@@ -189,6 +191,16 @@ async function persistMetroFilesAsync(files, outputDir) {
|
|
|
189
191
|
_log.Log.log(id === '' ? _chalk().default.gray(' (index)') : id, sizeStr(assets.contents), hasSourceMap ? _chalk().default.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : '');
|
|
190
192
|
}
|
|
191
193
|
}
|
|
194
|
+
if (middlewareEntries.length) {
|
|
195
|
+
const middlewareWithoutSourcemaps = middlewareEntries.filter((route)=>!route[0].endsWith('.map'));
|
|
196
|
+
_log.Log.log('');
|
|
197
|
+
_log.Log.log(_chalk().default.bold`${BLT} Middleware:`);
|
|
198
|
+
for (const [middlewareFilename, assets] of middlewareWithoutSourcemaps.sort((a, b)=>a[0].length - b[0].length)){
|
|
199
|
+
const id = assets.middlewareId;
|
|
200
|
+
const hasSourceMap = middlewareEntries.find(([filename, route])=>filename !== middlewareFilename && route.middlewareId === assets.middlewareId && filename.endsWith('.map'));
|
|
201
|
+
_log.Log.log(id, sizeStr(assets.contents), hasSourceMap ? _chalk().default.gray(`(source map ${sizeStr(hasSourceMap[1].contents)})`) : '');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
192
204
|
// Decouple logging from writing for better performance.
|
|
193
205
|
await Promise.all([
|
|
194
206
|
...files.entries()
|