@expo/cli 1.0.0-canary-20250219-4a5dade → 1.0.0-canary-20250221-ef26fed
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/cli +1 -1
- package/build/src/customize/generate.js +1 -4
- package/build/src/customize/generate.js.map +1 -1
- package/build/src/export/exportDomComponents.js +17 -4
- package/build/src/export/exportDomComponents.js.map +1 -1
- package/build/src/export/exportHermes.js +21 -21
- package/build/src/export/exportHermes.js.map +1 -1
- package/build/src/export/publicFolder.js +1 -3
- package/build/src/export/publicFolder.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js +17 -20
- package/build/src/start/server/middleware/ExpoGoManifestHandlerMiddleware.js.map +1 -1
- package/build/src/start/server/type-generation/routes.js +8 -8
- package/build/src/start/server/type-generation/routes.js.map +1 -1
- package/build/src/utils/dir.js +32 -7
- package/build/src/utils/dir.js.map +1 -1
- package/build/src/utils/multipartMixed.js +54 -0
- package/build/src/utils/multipartMixed.js.map +1 -0
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +15 -23
package/build/bin/cli
CHANGED
|
@@ -121,7 +121,7 @@ const args = (0, _arg().default)({
|
|
|
121
121
|
});
|
|
122
122
|
if (args["--version"]) {
|
|
123
123
|
// Version is added in the build script.
|
|
124
|
-
console.log("1.0.0-canary-
|
|
124
|
+
console.log("1.0.0-canary-20250221-ef26fed");
|
|
125
125
|
process.exit(0);
|
|
126
126
|
}
|
|
127
127
|
if (args["--non-interactive"]) {
|
|
@@ -74,10 +74,7 @@ async function generateAsync(projectRoot, { answer , props , extras }) {
|
|
|
74
74
|
}
|
|
75
75
|
const projectFilePath = _path().default.resolve(projectRoot, template.destination(props));
|
|
76
76
|
// copy the file from template
|
|
77
|
-
return (0, _dir.copyAsync)(template.file(projectRoot), projectFilePath
|
|
78
|
-
overwrite: true,
|
|
79
|
-
recursive: true
|
|
80
|
-
});
|
|
77
|
+
return (0, _dir.copyAsync)(template.file(projectRoot), projectFilePath);
|
|
81
78
|
}));
|
|
82
79
|
// Install dependencies
|
|
83
80
|
const packages = answer.map((file)=>_templates.TEMPLATES[file].dependencies).flat().filter((pkg)=>!_resolveFrom().default.silent(projectRoot, pkg));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/customize/generate.ts"],"sourcesContent":["import path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { DestinationResolutionProps, selectTemplatesAsync, TEMPLATES } from './templates';\nimport { installAsync } from '../install/installAsync';\nimport { Log } from '../log';\nimport { copyAsync } from '../utils/dir';\nimport { CommandError } from '../utils/errors';\n\nexport async function queryAndGenerateAsync(\n projectRoot: string,\n {\n files,\n props,\n extras,\n }: {\n files: string[];\n props: DestinationResolutionProps;\n /** Any extra props to pass to the install command. */\n extras: any[];\n }\n) {\n const valid = files.filter(\n (file) => !!TEMPLATES.find((template) => template.destination(props) === file)\n );\n\n if (valid.length !== files.length) {\n const diff = files.filter(\n (file) => !TEMPLATES.find((template) => template.destination(props) === file)\n );\n throw new CommandError(\n `Invalid files: ${diff.join(', ')}. Allowed: ${TEMPLATES.map((template) =>\n template.destination(props)\n ).join(', ')}`\n );\n }\n\n if (!valid.length) {\n return;\n }\n Log.log(`Generating: ${valid.join(', ')}`);\n return generateAsync(projectRoot, {\n answer: files.map((file) =>\n TEMPLATES.findIndex((template) => template.destination(props) === file)\n ),\n props,\n extras,\n });\n}\n\n/** Select templates to generate then generate and install. */\nexport async function selectAndGenerateAsync(\n projectRoot: string,\n {\n props,\n extras,\n }: {\n props: DestinationResolutionProps;\n /** Any extra props to pass to the install command. */\n extras: any[];\n }\n) {\n const answer = await selectTemplatesAsync(projectRoot, props);\n\n if (!answer?.length) {\n Log.exit('\\n\\u203A Exiting with no change...', 0);\n }\n\n await generateAsync(projectRoot, {\n answer,\n props,\n extras,\n });\n}\n\nasync function generateAsync(\n projectRoot: string,\n {\n answer,\n props,\n extras,\n }: {\n answer: number[];\n props: DestinationResolutionProps;\n /** Any extra props to pass to the install command. */\n extras: any[];\n }\n) {\n // Copy files\n await Promise.all(\n answer.map(async (file) => {\n const template = TEMPLATES[file];\n\n if (template.configureAsync) {\n if (await template.configureAsync(projectRoot)) {\n return;\n }\n }\n\n const projectFilePath = path.resolve(projectRoot, template.destination(props));\n // copy the file from template\n return copyAsync(template.file(projectRoot), projectFilePath
|
|
1
|
+
{"version":3,"sources":["../../../src/customize/generate.ts"],"sourcesContent":["import path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { DestinationResolutionProps, selectTemplatesAsync, TEMPLATES } from './templates';\nimport { installAsync } from '../install/installAsync';\nimport { Log } from '../log';\nimport { copyAsync } from '../utils/dir';\nimport { CommandError } from '../utils/errors';\n\nexport async function queryAndGenerateAsync(\n projectRoot: string,\n {\n files,\n props,\n extras,\n }: {\n files: string[];\n props: DestinationResolutionProps;\n /** Any extra props to pass to the install command. */\n extras: any[];\n }\n) {\n const valid = files.filter(\n (file) => !!TEMPLATES.find((template) => template.destination(props) === file)\n );\n\n if (valid.length !== files.length) {\n const diff = files.filter(\n (file) => !TEMPLATES.find((template) => template.destination(props) === file)\n );\n throw new CommandError(\n `Invalid files: ${diff.join(', ')}. Allowed: ${TEMPLATES.map((template) =>\n template.destination(props)\n ).join(', ')}`\n );\n }\n\n if (!valid.length) {\n return;\n }\n Log.log(`Generating: ${valid.join(', ')}`);\n return generateAsync(projectRoot, {\n answer: files.map((file) =>\n TEMPLATES.findIndex((template) => template.destination(props) === file)\n ),\n props,\n extras,\n });\n}\n\n/** Select templates to generate then generate and install. */\nexport async function selectAndGenerateAsync(\n projectRoot: string,\n {\n props,\n extras,\n }: {\n props: DestinationResolutionProps;\n /** Any extra props to pass to the install command. */\n extras: any[];\n }\n) {\n const answer = await selectTemplatesAsync(projectRoot, props);\n\n if (!answer?.length) {\n Log.exit('\\n\\u203A Exiting with no change...', 0);\n }\n\n await generateAsync(projectRoot, {\n answer,\n props,\n extras,\n });\n}\n\nasync function generateAsync(\n projectRoot: string,\n {\n answer,\n props,\n extras,\n }: {\n answer: number[];\n props: DestinationResolutionProps;\n /** Any extra props to pass to the install command. */\n extras: any[];\n }\n) {\n // Copy files\n await Promise.all(\n answer.map(async (file) => {\n const template = TEMPLATES[file];\n\n if (template.configureAsync) {\n if (await template.configureAsync(projectRoot)) {\n return;\n }\n }\n\n const projectFilePath = path.resolve(projectRoot, template.destination(props));\n // copy the file from template\n return copyAsync(template.file(projectRoot), projectFilePath);\n })\n );\n\n // Install dependencies\n const packages = answer\n .map((file) => TEMPLATES[file].dependencies)\n .flat()\n .filter((pkg) => !resolveFrom.silent(projectRoot, pkg));\n if (packages.length) {\n Log.debug('Installing ' + packages.join(', '));\n await installAsync(packages, {}, ['--dev', ...extras]);\n }\n}\n"],"names":["queryAndGenerateAsync","selectAndGenerateAsync","projectRoot","files","props","extras","valid","filter","file","TEMPLATES","find","template","destination","length","diff","CommandError","join","map","Log","log","generateAsync","answer","findIndex","selectTemplatesAsync","exit","Promise","all","configureAsync","projectFilePath","path","resolve","copyAsync","packages","dependencies","flat","pkg","resolveFrom","silent","debug","installAsync"],"mappings":"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"}
|
|
@@ -63,7 +63,7 @@ async function exportDomComponentAsync({ filePath , projectRoot , dev , devServe
|
|
|
63
63
|
const virtualEntry = (0, _filePath.toPosixPath)((0, _resolveFrom().default)(projectRoot, "expo/dom/entry.js"));
|
|
64
64
|
debug("Bundle DOM Component:", filePath);
|
|
65
65
|
// MUST MATCH THE BABEL PLUGIN!
|
|
66
|
-
const hash = _crypto().default.createHash("
|
|
66
|
+
const hash = _crypto().default.createHash("md5").update(filePath).digest("hex");
|
|
67
67
|
const outputName = `${_domComponentsMiddleware.DOM_COMPONENTS_BUNDLE_DIR}/${hash}.html`;
|
|
68
68
|
const generatedEntryPath = (0, _filePath.toPosixPath)(filePath.startsWith("file://") ? _url().default.fileURLToPath(filePath) : filePath);
|
|
69
69
|
const baseUrl = `/${_domComponentsMiddleware.DOM_COMPONENTS_BUNDLE_DIR}`;
|
|
@@ -144,15 +144,28 @@ function updateDomComponentAssetsForMD5Naming({ domComponentReference , nativeBu
|
|
|
144
144
|
const htmlContent = files.get(htmlOutputName);
|
|
145
145
|
(0, _assert().default)(htmlContent);
|
|
146
146
|
const htmlMd5 = _crypto().default.createHash("md5").update(htmlContent.contents.toString()).digest("hex");
|
|
147
|
-
const hash = _crypto().default.createHash("
|
|
147
|
+
const hash = _crypto().default.createHash("md5").update(domComponentReference).digest("hex");
|
|
148
148
|
for (const artifact1 of nativeBundle.artifacts){
|
|
149
149
|
if (artifact1.type !== "js") {
|
|
150
150
|
continue;
|
|
151
151
|
}
|
|
152
152
|
const assetEntity = files.get(artifact1.filename);
|
|
153
153
|
(0, _assert().default)(assetEntity);
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
if (Buffer.isBuffer(assetEntity.contents)) {
|
|
155
|
+
const searchBuffer = Buffer.from(`${hash}.html`, "utf8");
|
|
156
|
+
const replaceBuffer = Buffer.from(`${htmlMd5}.html`, "utf8");
|
|
157
|
+
(0, _assert().default)(searchBuffer.length === replaceBuffer.length);
|
|
158
|
+
let index1 = assetEntity.contents.indexOf(searchBuffer, 0);
|
|
159
|
+
while(index1 !== -1){
|
|
160
|
+
replaceBuffer.copy(assetEntity.contents, index1);
|
|
161
|
+
index1 = assetEntity.contents.indexOf(searchBuffer, index1 + searchBuffer.length);
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
const search = `${hash}.html`;
|
|
165
|
+
const replace = `${htmlMd5}.html`;
|
|
166
|
+
(0, _assert().default)(search.length === replace.length);
|
|
167
|
+
assetEntity.contents = assetEntity.contents.toString().replaceAll(search, replace);
|
|
168
|
+
}
|
|
156
169
|
}
|
|
157
170
|
assetsMetadata.push({
|
|
158
171
|
path: htmlOutputName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/exportDomComponents.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config';\nimport assert from 'assert';\nimport crypto from 'crypto';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport url from 'url';\n\nimport { type PlatformMetadata } from './createMetadataJson';\nimport { type BundleOutput, type ExportAssetMap, getFilesFromSerialAssets } from './saveAssets';\nimport { type MetroBundlerDevServer } from '../start/server/metro/MetroBundlerDevServer';\nimport { serializeHtmlWithAssets } from '../start/server/metro/serializeHtml';\nimport {\n getDomComponentHtml,\n DOM_COMPONENTS_BUNDLE_DIR,\n} from '../start/server/middleware/DomComponentsMiddleware';\nimport { env } from '../utils/env';\nimport { resolveRealEntryFilePath, toPosixPath } from '../utils/filePath';\n\nconst debug = require('debug')('expo:export:exportDomComponents') as typeof console.log;\n\n// TODO(EvanBacon): determine how to support DOM Components with hosting.\nexport async function exportDomComponentAsync({\n filePath,\n projectRoot,\n dev,\n devServer,\n isHermes,\n includeSourceMaps,\n exp,\n files,\n}: {\n filePath: string;\n projectRoot: string;\n dev: boolean;\n devServer: MetroBundlerDevServer;\n isHermes: boolean;\n includeSourceMaps: boolean;\n exp: ExpoConfig;\n files: ExportAssetMap;\n}): Promise<{\n bundle: BundleOutput;\n htmlOutputName: string;\n}> {\n const virtualEntry = toPosixPath(resolveFrom(projectRoot, 'expo/dom/entry.js'));\n debug('Bundle DOM Component:', filePath);\n // MUST MATCH THE BABEL PLUGIN!\n const hash = crypto.createHash('sha1').update(filePath).digest('hex');\n const outputName = `${DOM_COMPONENTS_BUNDLE_DIR}/${hash}.html`;\n const generatedEntryPath = toPosixPath(\n filePath.startsWith('file://') ? url.fileURLToPath(filePath) : filePath\n );\n const baseUrl = `/${DOM_COMPONENTS_BUNDLE_DIR}`;\n // The relative import path will be used like URI so it must be POSIX.\n const relativeImport = './' + path.posix.relative(path.dirname(virtualEntry), generatedEntryPath);\n // Run metro bundler and create the JS bundles/source maps.\n const bundle = await devServer.legacySinglePageExportBundleAsync({\n platform: 'web',\n domRoot: encodeURI(relativeImport),\n splitChunks: !env.EXPO_NO_BUNDLE_SPLITTING,\n mainModuleName: resolveRealEntryFilePath(projectRoot, virtualEntry),\n mode: dev ? 'development' : 'production',\n engine: isHermes ? 'hermes' : undefined,\n serializerIncludeMaps: includeSourceMaps,\n bytecode: false,\n reactCompiler: !!exp.experiments?.reactCompiler,\n baseUrl: './',\n // Minify may be false because it's skipped on native when Hermes is enabled, default to true.\n minify: true,\n });\n\n const html = await serializeHtmlWithAssets({\n isExporting: true,\n resources: bundle.artifacts,\n template: getDomComponentHtml(),\n baseUrl: './',\n });\n\n const serialAssets = bundle.artifacts.map((a) => {\n return {\n ...a,\n filename: path.join(baseUrl, a.filename),\n };\n });\n\n getFilesFromSerialAssets(serialAssets, {\n includeSourceMaps,\n files,\n platform: 'web',\n });\n\n files.set(outputName, {\n contents: html,\n });\n\n return {\n bundle,\n htmlOutputName: outputName,\n };\n}\n\n/**\n * For EAS Updates exports,\n * post-processes the DOM component bundle and updates the asset paths to use flattened MD5 naming.\n */\nexport function updateDomComponentAssetsForMD5Naming({\n domComponentReference,\n nativeBundle,\n domComponentBundle,\n files,\n htmlOutputName,\n}: {\n domComponentReference: string;\n nativeBundle: BundleOutput;\n domComponentBundle: BundleOutput;\n files: ExportAssetMap;\n htmlOutputName: string;\n}): PlatformMetadata['assets'] {\n const assetsMetadata: PlatformMetadata['assets'] = [];\n\n for (const artifact of domComponentBundle.artifacts) {\n if (artifact.type !== 'js') {\n continue;\n }\n const artifactAssetName = `/${DOM_COMPONENTS_BUNDLE_DIR}/${artifact.filename}`;\n let source = artifact.source;\n\n // [0] Updates asset paths in the DOM component JS bundle (which is a web bundle)\n for (const asset of domComponentBundle.assets) {\n const prefix = asset.httpServerLocation.startsWith('./')\n ? asset.httpServerLocation.slice(2)\n : asset.httpServerLocation;\n const uri = `${prefix}/${asset.name}.${asset.type}`;\n const regexp = new RegExp(`(uri:\")(${uri})(\")`, 'g');\n const index = asset.scales.findIndex((s) => s === 1) ?? 0; // DOM components (web) uses 1x assets\n const md5 = asset.fileHashes[index];\n source = source.replace(regexp, `$1${md5}.${asset.type}$3`);\n\n const domJsAssetEntity = files.get(artifactAssetName);\n assert(domJsAssetEntity);\n domJsAssetEntity.contents = source;\n }\n\n // [1] Updates JS artifacts in HTML\n const md5 = crypto.createHash('md5').update(source).digest('hex');\n const htmlAssetEntity = files.get(htmlOutputName);\n assert(htmlAssetEntity);\n const regexp = new RegExp(`(<script src=\")(.*${artifact.filename})(\" defer></script>)`, 'g');\n htmlAssetEntity.contents = htmlAssetEntity.contents.toString().replace(regexp, `$1${md5}.js$3`);\n\n assetsMetadata.push({\n path: artifactAssetName.slice(1),\n ext: 'js',\n });\n }\n\n // [2] Updates HTML names from native bundle\n const htmlContent = files.get(htmlOutputName);\n assert(htmlContent);\n const htmlMd5 = crypto.createHash('md5').update(htmlContent.contents.toString()).digest('hex');\n const hash = crypto.createHash('sha1').update(domComponentReference).digest('hex');\n for (const artifact of nativeBundle.artifacts) {\n if (artifact.type !== 'js') {\n continue;\n }\n const assetEntity = files.get(artifact.filename);\n assert(assetEntity);\n const regexp = new RegExp(`(['\"])${hash}\\\\.html(['\"])`, 'g');\n assetEntity.contents = assetEntity.contents.toString().replace(regexp, `$1${htmlMd5}.html$2`);\n }\n assetsMetadata.push({\n path: htmlOutputName,\n ext: 'html',\n });\n\n return assetsMetadata;\n}\n"],"names":["exportDomComponentAsync","updateDomComponentAssetsForMD5Naming","debug","require","filePath","projectRoot","dev","devServer","isHermes","includeSourceMaps","exp","files","virtualEntry","toPosixPath","resolveFrom","hash","crypto","createHash","update","digest","outputName","DOM_COMPONENTS_BUNDLE_DIR","generatedEntryPath","startsWith","url","fileURLToPath","baseUrl","relativeImport","path","posix","relative","dirname","bundle","legacySinglePageExportBundleAsync","platform","domRoot","encodeURI","splitChunks","env","EXPO_NO_BUNDLE_SPLITTING","mainModuleName","resolveRealEntryFilePath","mode","engine","undefined","serializerIncludeMaps","bytecode","reactCompiler","experiments","minify","html","serializeHtmlWithAssets","isExporting","resources","artifacts","template","getDomComponentHtml","serialAssets","map","a","filename","join","getFilesFromSerialAssets","set","contents","htmlOutputName","domComponentReference","nativeBundle","domComponentBundle","assetsMetadata","artifact","type","artifactAssetName","source","asset","assets","prefix","httpServerLocation","slice","uri","name","regexp","RegExp","index","scales","findIndex","s","md5","fileHashes","replace","domJsAssetEntity","get","assert","htmlAssetEntity","toString","push","ext","htmlContent","htmlMd5","assetEntity"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/export/exportDomComponents.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config';\nimport assert from 'assert';\nimport crypto from 'crypto';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\nimport url from 'url';\n\nimport { type PlatformMetadata } from './createMetadataJson';\nimport { type BundleOutput, type ExportAssetMap, getFilesFromSerialAssets } from './saveAssets';\nimport { type MetroBundlerDevServer } from '../start/server/metro/MetroBundlerDevServer';\nimport { serializeHtmlWithAssets } from '../start/server/metro/serializeHtml';\nimport {\n getDomComponentHtml,\n DOM_COMPONENTS_BUNDLE_DIR,\n} from '../start/server/middleware/DomComponentsMiddleware';\nimport { env } from '../utils/env';\nimport { resolveRealEntryFilePath, toPosixPath } from '../utils/filePath';\n\nconst debug = require('debug')('expo:export:exportDomComponents') as typeof console.log;\n\n// TODO(EvanBacon): determine how to support DOM Components with hosting.\nexport async function exportDomComponentAsync({\n filePath,\n projectRoot,\n dev,\n devServer,\n isHermes,\n includeSourceMaps,\n exp,\n files,\n}: {\n filePath: string;\n projectRoot: string;\n dev: boolean;\n devServer: MetroBundlerDevServer;\n isHermes: boolean;\n includeSourceMaps: boolean;\n exp: ExpoConfig;\n files: ExportAssetMap;\n}): Promise<{\n bundle: BundleOutput;\n htmlOutputName: string;\n}> {\n const virtualEntry = toPosixPath(resolveFrom(projectRoot, 'expo/dom/entry.js'));\n debug('Bundle DOM Component:', filePath);\n // MUST MATCH THE BABEL PLUGIN!\n const hash = crypto.createHash('md5').update(filePath).digest('hex');\n const outputName = `${DOM_COMPONENTS_BUNDLE_DIR}/${hash}.html`;\n const generatedEntryPath = toPosixPath(\n filePath.startsWith('file://') ? url.fileURLToPath(filePath) : filePath\n );\n const baseUrl = `/${DOM_COMPONENTS_BUNDLE_DIR}`;\n // The relative import path will be used like URI so it must be POSIX.\n const relativeImport = './' + path.posix.relative(path.dirname(virtualEntry), generatedEntryPath);\n // Run metro bundler and create the JS bundles/source maps.\n const bundle = await devServer.legacySinglePageExportBundleAsync({\n platform: 'web',\n domRoot: encodeURI(relativeImport),\n splitChunks: !env.EXPO_NO_BUNDLE_SPLITTING,\n mainModuleName: resolveRealEntryFilePath(projectRoot, virtualEntry),\n mode: dev ? 'development' : 'production',\n engine: isHermes ? 'hermes' : undefined,\n serializerIncludeMaps: includeSourceMaps,\n bytecode: false,\n reactCompiler: !!exp.experiments?.reactCompiler,\n baseUrl: './',\n // Minify may be false because it's skipped on native when Hermes is enabled, default to true.\n minify: true,\n });\n\n const html = await serializeHtmlWithAssets({\n isExporting: true,\n resources: bundle.artifacts,\n template: getDomComponentHtml(),\n baseUrl: './',\n });\n\n const serialAssets = bundle.artifacts.map((a) => {\n return {\n ...a,\n filename: path.join(baseUrl, a.filename),\n };\n });\n\n getFilesFromSerialAssets(serialAssets, {\n includeSourceMaps,\n files,\n platform: 'web',\n });\n\n files.set(outputName, {\n contents: html,\n });\n\n return {\n bundle,\n htmlOutputName: outputName,\n };\n}\n\n/**\n * For EAS Updates exports,\n * post-processes the DOM component bundle and updates the asset paths to use flattened MD5 naming.\n */\nexport function updateDomComponentAssetsForMD5Naming({\n domComponentReference,\n nativeBundle,\n domComponentBundle,\n files,\n htmlOutputName,\n}: {\n domComponentReference: string;\n nativeBundle: BundleOutput;\n domComponentBundle: BundleOutput;\n files: ExportAssetMap;\n htmlOutputName: string;\n}): PlatformMetadata['assets'] {\n const assetsMetadata: PlatformMetadata['assets'] = [];\n\n for (const artifact of domComponentBundle.artifacts) {\n if (artifact.type !== 'js') {\n continue;\n }\n const artifactAssetName = `/${DOM_COMPONENTS_BUNDLE_DIR}/${artifact.filename}`;\n let source = artifact.source;\n\n // [0] Updates asset paths in the DOM component JS bundle (which is a web bundle)\n for (const asset of domComponentBundle.assets) {\n const prefix = asset.httpServerLocation.startsWith('./')\n ? asset.httpServerLocation.slice(2)\n : asset.httpServerLocation;\n const uri = `${prefix}/${asset.name}.${asset.type}`;\n const regexp = new RegExp(`(uri:\")(${uri})(\")`, 'g');\n const index = asset.scales.findIndex((s) => s === 1) ?? 0; // DOM components (web) uses 1x assets\n const md5 = asset.fileHashes[index];\n source = source.replace(regexp, `$1${md5}.${asset.type}$3`);\n\n const domJsAssetEntity = files.get(artifactAssetName);\n assert(domJsAssetEntity);\n domJsAssetEntity.contents = source;\n }\n\n // [1] Updates JS artifacts in HTML\n const md5 = crypto.createHash('md5').update(source).digest('hex');\n const htmlAssetEntity = files.get(htmlOutputName);\n assert(htmlAssetEntity);\n const regexp = new RegExp(`(<script src=\")(.*${artifact.filename})(\" defer></script>)`, 'g');\n htmlAssetEntity.contents = htmlAssetEntity.contents.toString().replace(regexp, `$1${md5}.js$3`);\n\n assetsMetadata.push({\n path: artifactAssetName.slice(1),\n ext: 'js',\n });\n }\n\n // [2] Updates HTML names from native bundle\n const htmlContent = files.get(htmlOutputName);\n assert(htmlContent);\n const htmlMd5 = crypto.createHash('md5').update(htmlContent.contents.toString()).digest('hex');\n const hash = crypto.createHash('md5').update(domComponentReference).digest('hex');\n for (const artifact of nativeBundle.artifacts) {\n if (artifact.type !== 'js') {\n continue;\n }\n const assetEntity = files.get(artifact.filename);\n assert(assetEntity);\n if (Buffer.isBuffer(assetEntity.contents)) {\n const searchBuffer = Buffer.from(`${hash}.html`, 'utf8');\n const replaceBuffer = Buffer.from(`${htmlMd5}.html`, 'utf8');\n assert(searchBuffer.length === replaceBuffer.length);\n let index = assetEntity.contents.indexOf(searchBuffer, 0);\n while (index !== -1) {\n replaceBuffer.copy(assetEntity.contents, index);\n index = assetEntity.contents.indexOf(searchBuffer, index + searchBuffer.length);\n }\n } else {\n const search = `${hash}.html`;\n const replace = `${htmlMd5}.html`;\n assert(search.length === replace.length);\n assetEntity.contents = assetEntity.contents.toString().replaceAll(search, replace);\n }\n }\n assetsMetadata.push({\n path: htmlOutputName,\n ext: 'html',\n });\n\n return assetsMetadata;\n}\n"],"names":["exportDomComponentAsync","updateDomComponentAssetsForMD5Naming","debug","require","filePath","projectRoot","dev","devServer","isHermes","includeSourceMaps","exp","files","virtualEntry","toPosixPath","resolveFrom","hash","crypto","createHash","update","digest","outputName","DOM_COMPONENTS_BUNDLE_DIR","generatedEntryPath","startsWith","url","fileURLToPath","baseUrl","relativeImport","path","posix","relative","dirname","bundle","legacySinglePageExportBundleAsync","platform","domRoot","encodeURI","splitChunks","env","EXPO_NO_BUNDLE_SPLITTING","mainModuleName","resolveRealEntryFilePath","mode","engine","undefined","serializerIncludeMaps","bytecode","reactCompiler","experiments","minify","html","serializeHtmlWithAssets","isExporting","resources","artifacts","template","getDomComponentHtml","serialAssets","map","a","filename","join","getFilesFromSerialAssets","set","contents","htmlOutputName","domComponentReference","nativeBundle","domComponentBundle","assetsMetadata","artifact","type","artifactAssetName","source","asset","assets","prefix","httpServerLocation","slice","uri","name","regexp","RegExp","index","scales","findIndex","s","md5","fileHashes","replace","domJsAssetEntity","get","assert","htmlAssetEntity","toString","push","ext","htmlContent","htmlMd5","assetEntity","Buffer","isBuffer","searchBuffer","from","replaceBuffer","length","indexOf","copy","search","replaceAll"],"mappings":"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"}
|
|
@@ -35,9 +35,9 @@ function _jsonFile() {
|
|
|
35
35
|
};
|
|
36
36
|
return data;
|
|
37
37
|
}
|
|
38
|
-
function
|
|
39
|
-
const data = /*#__PURE__*/ _interopRequireDefault(require("fs
|
|
40
|
-
|
|
38
|
+
function _fs() {
|
|
39
|
+
const data = /*#__PURE__*/ _interopRequireDefault(require("fs"));
|
|
40
|
+
_fs = function() {
|
|
41
41
|
return data;
|
|
42
42
|
};
|
|
43
43
|
return data;
|
|
@@ -84,8 +84,8 @@ function parseGradleProperties(content) {
|
|
|
84
84
|
continue;
|
|
85
85
|
}
|
|
86
86
|
const sepIndex = line.indexOf("=");
|
|
87
|
-
const key = line.
|
|
88
|
-
const value = line.
|
|
87
|
+
const key = line.slice(0, sepIndex);
|
|
88
|
+
const value = line.slice(sepIndex + 1);
|
|
89
89
|
result[key] = value;
|
|
90
90
|
}
|
|
91
91
|
return result;
|
|
@@ -103,8 +103,8 @@ async function maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged)
|
|
|
103
103
|
// Trying best to check android native project if by chance to be consistent between app config
|
|
104
104
|
// Check gradle.properties from prebuild template
|
|
105
105
|
const gradlePropertiesPath = _path().default.join(projectRoot, "android", "gradle.properties");
|
|
106
|
-
if (
|
|
107
|
-
const props = parseGradleProperties(await
|
|
106
|
+
if (_fs().default.existsSync(gradlePropertiesPath)) {
|
|
107
|
+
const props = parseGradleProperties(await _fs().default.promises.readFile(gradlePropertiesPath, "utf8"));
|
|
108
108
|
const isHermesBare = props["hermesEnabled"] === "true";
|
|
109
109
|
if (isHermesManaged !== isHermesBare) {
|
|
110
110
|
return true;
|
|
@@ -116,8 +116,8 @@ function isHermesPossiblyEnabled(projectRoot) {
|
|
|
116
116
|
// Trying best to check ios native project if by chance to be consistent between app config
|
|
117
117
|
// Check ios/Podfile for ":hermes_enabled => true"
|
|
118
118
|
const podfilePath = _path().default.join(projectRoot, "ios", "Podfile");
|
|
119
|
-
if (
|
|
120
|
-
const content =
|
|
119
|
+
if (_fs().default.existsSync(podfilePath)) {
|
|
120
|
+
const content = _fs().default.readFileSync(podfilePath, "utf8");
|
|
121
121
|
const isPropsReference = content.search(/^\s*:hermes_enabled\s*=>\s*podfile_properties\['expo.jsEngine'\]\s*==\s*nil\s*\|\|\s*podfile_properties\['expo.jsEngine'\]\s*==\s*'hermes',?/m) >= 0;
|
|
122
122
|
const isHermesBare = content.search(/^\s*:hermes_enabled\s*=>\s*true,?\s+/m) >= 0;
|
|
123
123
|
if (!isPropsReference && isHermesBare) {
|
|
@@ -126,7 +126,7 @@ function isHermesPossiblyEnabled(projectRoot) {
|
|
|
126
126
|
}
|
|
127
127
|
// Check Podfile.properties.json from prebuild template
|
|
128
128
|
const podfilePropertiesPath = _path().default.join(projectRoot, "ios", "Podfile.properties.json");
|
|
129
|
-
if (
|
|
129
|
+
if (_fs().default.existsSync(podfilePropertiesPath)) {
|
|
130
130
|
try {
|
|
131
131
|
const props = _jsonFile().default.read(podfilePropertiesPath);
|
|
132
132
|
return props["expo.jsEngine"] === "hermes";
|
|
@@ -140,8 +140,8 @@ async function maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged) {
|
|
|
140
140
|
// Trying best to check ios native project if by chance to be consistent between app config
|
|
141
141
|
// Check ios/Podfile for ":hermes_enabled => true"
|
|
142
142
|
const podfilePath = _path().default.join(projectRoot, "ios", "Podfile");
|
|
143
|
-
if (
|
|
144
|
-
const content = await
|
|
143
|
+
if (_fs().default.existsSync(podfilePath)) {
|
|
144
|
+
const content = await _fs().default.promises.readFile(podfilePath, "utf8");
|
|
145
145
|
const isPropsReference = content.search(/^\s*:hermes_enabled\s*=>\s*podfile_properties\['expo.jsEngine'\]\s*==\s*nil\s*\|\|\s*podfile_properties\['expo.jsEngine'\]\s*==\s*'hermes',?/m) >= 0;
|
|
146
146
|
const isHermesBare = content.search(/^\s*:hermes_enabled\s*=>\s*true,?\s+/m) >= 0;
|
|
147
147
|
if (!isPropsReference && isHermesManaged !== isHermesBare) {
|
|
@@ -150,7 +150,7 @@ async function maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged) {
|
|
|
150
150
|
}
|
|
151
151
|
// Check Podfile.properties.json from prebuild template
|
|
152
152
|
const podfilePropertiesPath = _path().default.join(projectRoot, "ios", "Podfile.properties.json");
|
|
153
|
-
if (
|
|
153
|
+
if (_fs().default.existsSync(podfilePropertiesPath)) {
|
|
154
154
|
const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);
|
|
155
155
|
const isHermesBare1 = props["expo.jsEngine"] === "hermes";
|
|
156
156
|
if (isHermesManaged !== isHermesBare1) {
|
|
@@ -163,25 +163,25 @@ async function maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged) {
|
|
|
163
163
|
const HERMES_MAGIC_HEADER = "c61fbc03c103191f";
|
|
164
164
|
async function isHermesBytecodeBundleAsync(file) {
|
|
165
165
|
const header = await readHermesHeaderAsync(file);
|
|
166
|
-
return header.
|
|
166
|
+
return header.subarray(0, 8).toString("hex") === HERMES_MAGIC_HEADER;
|
|
167
167
|
}
|
|
168
168
|
async function getHermesBytecodeBundleVersionAsync(file) {
|
|
169
169
|
const header = await readHermesHeaderAsync(file);
|
|
170
|
-
if (header.
|
|
170
|
+
if (header.subarray(0, 8).toString("hex") !== HERMES_MAGIC_HEADER) {
|
|
171
171
|
throw new Error("Invalid hermes bundle file");
|
|
172
172
|
}
|
|
173
173
|
return header.readUInt32LE(8);
|
|
174
174
|
}
|
|
175
175
|
async function readHermesHeaderAsync(file) {
|
|
176
|
-
const fd = await
|
|
176
|
+
const fd = await _fs().default.promises.open(file, "r");
|
|
177
177
|
const buffer = Buffer.alloc(12);
|
|
178
|
-
await
|
|
179
|
-
await
|
|
178
|
+
await fd.read(buffer, 0, 12, null);
|
|
179
|
+
await fd.close();
|
|
180
180
|
return buffer;
|
|
181
181
|
}
|
|
182
182
|
async function parsePodfilePropertiesAsync(podfilePropertiesPath) {
|
|
183
183
|
try {
|
|
184
|
-
return JSON.parse(await
|
|
184
|
+
return JSON.parse(await _fs().default.promises.readFile(podfilePropertiesPath, "utf8"));
|
|
185
185
|
} catch {
|
|
186
186
|
return {};
|
|
187
187
|
}
|
|
@@ -189,8 +189,8 @@ async function parsePodfilePropertiesAsync(podfilePropertiesPath) {
|
|
|
189
189
|
function isAndroidUsingHermes(projectRoot) {
|
|
190
190
|
// Check gradle.properties from prebuild template
|
|
191
191
|
const gradlePropertiesPath = _path().default.join(projectRoot, "android", "gradle.properties");
|
|
192
|
-
if (
|
|
193
|
-
const props = parseGradleProperties(
|
|
192
|
+
if (_fs().default.existsSync(gradlePropertiesPath)) {
|
|
193
|
+
const props = parseGradleProperties(_fs().default.readFileSync(gradlePropertiesPath, "utf8"));
|
|
194
194
|
return props["hermesEnabled"] === "true";
|
|
195
195
|
}
|
|
196
196
|
// Assume Hermes is used by default.
|
|
@@ -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-extra';\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.substr(0, sepIndex);\n const value = line.substr(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 `Please 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 `Please 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.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.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.slice(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.slice(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.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fs.read(fd, buffer, 0, 12, null);\n await fs.close(fd);\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.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","isEnableHermesManaged","parseGradleProperties","maybeThrowFromInconsistentEngineAsync","maybeInconsistentEngineAndroidAsync","isHermesPossiblyEnabled","maybeInconsistentEngineIosAsync","isHermesBytecodeBundleAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isIosUsingHermes","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","content","result","line","split","trim","startsWith","sepIndex","indexOf","key","substr","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","readFile","isHermesBare","podfilePath","readFileSync","isPropsReference","search","podfilePropertiesPath","JsonFile","read","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","slice","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\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 `Please 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 `Please 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","isEnableHermesManaged","parseGradleProperties","maybeThrowFromInconsistentEngineAsync","maybeInconsistentEngineAndroidAsync","isHermesPossiblyEnabled","maybeInconsistentEngineIosAsync","isHermesBytecodeBundleAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isIosUsingHermes","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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"}
|
|
@@ -50,9 +50,7 @@ async function copyPublicFolderAsync(publicFolder, outputFolder) {
|
|
|
50
50
|
await _fs().default.promises.mkdir(outputFolder, {
|
|
51
51
|
recursive: true
|
|
52
52
|
});
|
|
53
|
-
await (0, _dir.copyAsync)(publicFolder, outputFolder
|
|
54
|
-
overwrite: true
|
|
55
|
-
});
|
|
53
|
+
await (0, _dir.copyAsync)(publicFolder, outputFolder);
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/export/publicFolder.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { copyAsync } from '../utils/dir';\nimport { env } from '../utils/env';\n\nconst debug = require('debug')('expo:public-folder') as typeof console.log;\n\n/** @returns the file system path for a user-defined file in the public folder. */\nexport function getUserDefinedFile(projectRoot: string, possiblePaths: string[]): string | null {\n const publicPath = path.join(projectRoot, env.EXPO_PUBLIC_FOLDER);\n\n for (const possiblePath of possiblePaths) {\n const fullPath = path.join(publicPath, possiblePath);\n if (fs.existsSync(fullPath)) {\n debug(`Found user-defined public file: ` + possiblePath);\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Copy the contents of the public folder into the output folder.\n * This enables users to add static files like `favicon.ico`.\n *\n * The contents of this folder are completely universal since they refer to\n * static network requests which fall outside the scope of React Native's magic\n * platform resolution patterns.\n */\nexport async function copyPublicFolderAsync(publicFolder: string, outputFolder: string) {\n if (fs.existsSync(publicFolder)) {\n await fs.promises.mkdir(outputFolder, { recursive: true });\n await copyAsync(publicFolder, outputFolder
|
|
1
|
+
{"version":3,"sources":["../../../src/export/publicFolder.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nimport { copyAsync } from '../utils/dir';\nimport { env } from '../utils/env';\n\nconst debug = require('debug')('expo:public-folder') as typeof console.log;\n\n/** @returns the file system path for a user-defined file in the public folder. */\nexport function getUserDefinedFile(projectRoot: string, possiblePaths: string[]): string | null {\n const publicPath = path.join(projectRoot, env.EXPO_PUBLIC_FOLDER);\n\n for (const possiblePath of possiblePaths) {\n const fullPath = path.join(publicPath, possiblePath);\n if (fs.existsSync(fullPath)) {\n debug(`Found user-defined public file: ` + possiblePath);\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Copy the contents of the public folder into the output folder.\n * This enables users to add static files like `favicon.ico`.\n *\n * The contents of this folder are completely universal since they refer to\n * static network requests which fall outside the scope of React Native's magic\n * platform resolution patterns.\n */\nexport async function copyPublicFolderAsync(publicFolder: string, outputFolder: string) {\n if (fs.existsSync(publicFolder)) {\n await fs.promises.mkdir(outputFolder, { recursive: true });\n await copyAsync(publicFolder, outputFolder);\n }\n}\n"],"names":["getUserDefinedFile","copyPublicFolderAsync","debug","require","projectRoot","possiblePaths","publicPath","path","join","env","EXPO_PUBLIC_FOLDER","possiblePath","fullPath","fs","existsSync","publicFolder","outputFolder","promises","mkdir","recursive","copyAsync"],"mappings":"AAAA;;;;;;;;;;;IASgBA,kBAAkB,MAAlBA,kBAAkB;IAsBZC,qBAAqB,MAArBA,qBAAqB;;;8DA/B5B,IAAI;;;;;;;8DACF,MAAM;;;;;;qBAEG,cAAc;qBACpB,cAAc;;;;;;AAElC,MAAMC,KAAK,GAAGC,OAAO,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,AAAsB,AAAC;AAGpE,SAASH,kBAAkB,CAACI,WAAmB,EAAEC,aAAuB,EAAiB;IAC9F,MAAMC,UAAU,GAAGC,KAAI,EAAA,QAAA,CAACC,IAAI,CAACJ,WAAW,EAAEK,IAAG,IAAA,CAACC,kBAAkB,CAAC,AAAC;IAElE,KAAK,MAAMC,YAAY,IAAIN,aAAa,CAAE;QACxC,MAAMO,QAAQ,GAAGL,KAAI,EAAA,QAAA,CAACC,IAAI,CAACF,UAAU,EAAEK,YAAY,CAAC,AAAC;QACrD,IAAIE,GAAE,EAAA,QAAA,CAACC,UAAU,CAACF,QAAQ,CAAC,EAAE;YAC3BV,KAAK,CAAC,CAAC,gCAAgC,CAAC,GAAGS,YAAY,CAAC,CAAC;YACzD,OAAOC,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAUM,eAAeX,qBAAqB,CAACc,YAAoB,EAAEC,YAAoB,EAAE;IACtF,IAAIH,GAAE,EAAA,QAAA,CAACC,UAAU,CAACC,YAAY,CAAC,EAAE;QAC/B,MAAMF,GAAE,EAAA,QAAA,CAACI,QAAQ,CAACC,KAAK,CAACF,YAAY,EAAE;YAAEG,SAAS,EAAE,IAAI;SAAE,CAAC,CAAC;QAC3D,MAAMC,IAAAA,IAAS,UAAA,EAACL,YAAY,EAAEC,YAAY,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
|
|
@@ -45,7 +45,7 @@ const debug = require("debug")("expo:start:server:metro");
|
|
|
45
45
|
const resolveAsync = (0, _util().promisify)(_resolve().default);
|
|
46
46
|
function createRouteHandlerMiddleware(projectRoot, options) {
|
|
47
47
|
if (!_resolveFrom().default.silent(projectRoot, "expo-router")) {
|
|
48
|
-
throw new _errors.CommandError(
|
|
48
|
+
throw new _errors.CommandError(`static and server rendering requires the expo-router package to be installed in your project. Either install the expo-router package or change 'web.output' to 'static' in your app.json.`);
|
|
49
49
|
}
|
|
50
50
|
const { createRequestHandler } = require("@expo/server/build/vendor/http");
|
|
51
51
|
return createRequestHandler({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/metro/createServerRouteMiddleware.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 */\n\nimport type { ProjectConfig } from '@expo/config';\nimport resolve from 'resolve';\nimport resolveFrom from 'resolve-from';\nimport { promisify } from 'util';\n\nimport { fetchManifest } from './fetchRouterManifest';\nimport { getErrorOverlayHtmlAsync, logMetroError } from './metroErrorInterface';\nimport { warnInvalidWebOutput } from './router';\nimport { CommandError } from '../../../utils/errors';\n\nconst debug = require('debug')('expo:start:server:metro') as typeof console.log;\n\nconst resolveAsync = promisify(resolve) as any as (\n id: string,\n opts: resolve.AsyncOpts\n) => Promise<string | null>;\n\nexport function createRouteHandlerMiddleware(\n projectRoot: string,\n options: {\n appDir: string;\n routerRoot: string;\n getStaticPageAsync: (pathname: string) => Promise<{ content: string }>;\n bundleApiRoute: (\n functionFilePath: string\n ) => Promise<null | Record<string, Function> | Response>;\n config: ProjectConfig;\n } & import('expo-router/build/routes-manifest').Options\n) {\n if (!resolveFrom.silent(projectRoot, 'expo-router')) {\n throw new CommandError(\n
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/metro/createServerRouteMiddleware.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 */\n\nimport type { ProjectConfig } from '@expo/config';\nimport resolve from 'resolve';\nimport resolveFrom from 'resolve-from';\nimport { promisify } from 'util';\n\nimport { fetchManifest } from './fetchRouterManifest';\nimport { getErrorOverlayHtmlAsync, logMetroError } from './metroErrorInterface';\nimport { warnInvalidWebOutput } from './router';\nimport { CommandError } from '../../../utils/errors';\n\nconst debug = require('debug')('expo:start:server:metro') as typeof console.log;\n\nconst resolveAsync = promisify(resolve) as any as (\n id: string,\n opts: resolve.AsyncOpts\n) => Promise<string | null>;\n\nexport function createRouteHandlerMiddleware(\n projectRoot: string,\n options: {\n appDir: string;\n routerRoot: string;\n getStaticPageAsync: (pathname: string) => Promise<{ content: string }>;\n bundleApiRoute: (\n functionFilePath: string\n ) => Promise<null | Record<string, Function> | Response>;\n config: ProjectConfig;\n } & import('expo-router/build/routes-manifest').Options\n) {\n if (!resolveFrom.silent(projectRoot, 'expo-router')) {\n throw new CommandError(\n `static and server rendering requires the expo-router package to be installed in your project. Either install the expo-router package or change 'web.output' to 'static' in your app.json.`\n );\n }\n\n const { createRequestHandler } =\n require('@expo/server/build/vendor/http') as typeof import('@expo/server/build/vendor/http');\n\n return createRequestHandler(\n { build: '' },\n {\n async getRoutesManifest() {\n const manifest = await fetchManifest<RegExp>(projectRoot, options);\n debug('manifest', manifest);\n // NOTE: no app dir if null\n // TODO: Redirect to 404 page\n return (\n manifest ?? {\n // Support the onboarding screen if there's no manifest\n htmlRoutes: [\n {\n file: 'index.js',\n page: '/index',\n routeKeys: {},\n namedRegex: /^\\/(?:index)?\\/?$/i,\n },\n ],\n apiRoutes: [],\n notFoundRoutes: [],\n }\n );\n },\n async getHtml(request) {\n try {\n const { content } = await options.getStaticPageAsync(request.url);\n return content;\n } catch (error: any) {\n // Forward the Metro server response as-is. It won't be pretty, but at least it will be accurate.\n\n try {\n return new Response(\n await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot,\n }),\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n } catch (staticError: any) {\n debug('Failed to render static error overlay:', staticError);\n // Fallback error for when Expo Router is misconfigured in the project.\n return new Response(\n '<span><h3>Internal Error:</h3><b>Project is not setup correctly for static rendering (check terminal for more info):</b><br/>' +\n error.message +\n '<br/><br/>' +\n staticError.message +\n '</span>',\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n }\n },\n logApiRouteExecutionError(error) {\n logMetroError(projectRoot, { error });\n },\n async handleApiRouteError(error) {\n const htmlServerError = await getErrorOverlayHtmlAsync({\n error,\n projectRoot,\n routerRoot: options.routerRoot!,\n });\n\n return new Response(htmlServerError, {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n });\n },\n async getApiRoute(route) {\n const { exp } = options.config;\n if (exp.web?.output !== 'server') {\n warnInvalidWebOutput();\n }\n\n const resolvedFunctionPath = await resolveAsync(route.file, {\n extensions: ['.js', '.jsx', '.ts', '.tsx'],\n basedir: options.appDir,\n })!;\n\n try {\n debug(`Bundling middleware at: ${resolvedFunctionPath}`);\n return await options.bundleApiRoute(resolvedFunctionPath!);\n } catch (error: any) {\n return new Response(\n 'Failed to load API Route: ' + resolvedFunctionPath + '\\n\\n' + error.message,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n }\n );\n }\n },\n }\n );\n}\n"],"names":["createRouteHandlerMiddleware","debug","require","resolveAsync","promisify","resolve","projectRoot","options","resolveFrom","silent","CommandError","createRequestHandler","build","getRoutesManifest","manifest","fetchManifest","htmlRoutes","file","page","routeKeys","namedRegex","apiRoutes","notFoundRoutes","getHtml","request","content","getStaticPageAsync","url","error","Response","getErrorOverlayHtmlAsync","routerRoot","status","headers","staticError","message","logApiRouteExecutionError","logMetroError","handleApiRouteError","htmlServerError","getApiRoute","route","exp","config","web","output","warnInvalidWebOutput","resolvedFunctionPath","extensions","basedir","appDir","bundleApiRoute"],"mappings":"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"}
|
|
@@ -33,13 +33,6 @@ function _crypto() {
|
|
|
33
33
|
};
|
|
34
34
|
return data;
|
|
35
35
|
}
|
|
36
|
-
function _formData() {
|
|
37
|
-
const data = /*#__PURE__*/ _interopRequireDefault(require("form-data"));
|
|
38
|
-
_formData = function() {
|
|
39
|
-
return data;
|
|
40
|
-
};
|
|
41
|
-
return data;
|
|
42
|
-
}
|
|
43
36
|
function _structuredHeaders() {
|
|
44
37
|
const data = require("structured-headers");
|
|
45
38
|
_structuredHeaders = function() {
|
|
@@ -54,6 +47,7 @@ const _userSettings = require("../../../api/user/UserSettings");
|
|
|
54
47
|
const _user = require("../../../api/user/user");
|
|
55
48
|
const _codesigning = require("../../../utils/codesigning");
|
|
56
49
|
const _errors = require("../../../utils/errors");
|
|
50
|
+
const _multipartMixed = require("../../../utils/multipartMixed");
|
|
57
51
|
const _url = require("../../../utils/url");
|
|
58
52
|
function _interopRequireDefault(obj) {
|
|
59
53
|
return obj && obj.__esModule ? obj : {
|
|
@@ -185,14 +179,14 @@ class ExpoGoManifestHandlerMiddleware extends _manifestMiddleware.ManifestMiddle
|
|
|
185
179
|
switch(requestOptions.responseContentType){
|
|
186
180
|
case 3:
|
|
187
181
|
{
|
|
188
|
-
const
|
|
182
|
+
const encoded = await this.encodeFormDataAsync({
|
|
189
183
|
stringifiedManifest,
|
|
190
184
|
manifestPartHeaders,
|
|
191
185
|
certificateChainBody
|
|
192
186
|
});
|
|
193
|
-
headers.set("content-type", `multipart/mixed; boundary=${
|
|
187
|
+
headers.set("content-type", `multipart/mixed; boundary=${encoded.boundary}`);
|
|
194
188
|
return {
|
|
195
|
-
body:
|
|
189
|
+
body: encoded.body,
|
|
196
190
|
version: runtimeVersion,
|
|
197
191
|
headers
|
|
198
192
|
};
|
|
@@ -227,20 +221,23 @@ class ExpoGoManifestHandlerMiddleware extends _manifestMiddleware.ManifestMiddle
|
|
|
227
221
|
return "text/plain";
|
|
228
222
|
}
|
|
229
223
|
}
|
|
230
|
-
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
224
|
+
encodeFormDataAsync({ stringifiedManifest , manifestPartHeaders , certificateChainBody }) {
|
|
225
|
+
const fields = [
|
|
226
|
+
{
|
|
227
|
+
name: "manifest",
|
|
228
|
+
value: stringifiedManifest,
|
|
229
|
+
contentType: "application/json",
|
|
230
|
+
partHeaders: manifestPartHeaders
|
|
231
|
+
},
|
|
232
|
+
];
|
|
238
233
|
if (certificateChainBody && certificateChainBody.length > 0) {
|
|
239
|
-
|
|
234
|
+
fields.push({
|
|
235
|
+
name: "certificate_chain",
|
|
236
|
+
value: certificateChainBody,
|
|
240
237
|
contentType: "application/x-pem-file"
|
|
241
238
|
});
|
|
242
239
|
}
|
|
243
|
-
return
|
|
240
|
+
return (0, _multipartMixed.encodeMultipartMixed)(fields);
|
|
244
241
|
}
|
|
245
242
|
static async getScopeKeyAsync({ slug , codeSigningInfo }) {
|
|
246
243
|
const scopeKeyFromCodeSigningInfo = codeSigningInfo == null ? void 0 : codeSigningInfo.scopeKey;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/middleware/ExpoGoManifestHandlerMiddleware.ts"],"sourcesContent":["import { ExpoUpdatesManifest } from '@expo/config';\nimport { Updates } from '@expo/config-plugins';\nimport accepts from 'accepts';\nimport crypto from 'crypto';\nimport FormData from 'form-data';\nimport { serializeDictionary, Dictionary } from 'structured-headers';\n\nimport { ManifestMiddleware, ManifestRequestInfo } from './ManifestMiddleware';\nimport { assertRuntimePlatform, parsePlatformHeader } from './resolvePlatform';\nimport { resolveRuntimeVersionWithExpoUpdatesAsync } from './resolveRuntimeVersionWithExpoUpdatesAsync';\nimport { ServerHeaders, ServerRequest } from './server.types';\nimport { getAnonymousIdAsync } from '../../../api/user/UserSettings';\nimport { ANONYMOUS_USERNAME } from '../../../api/user/user';\nimport {\n CodeSigningInfo,\n getCodeSigningInfoAsync,\n signManifestString,\n} from '../../../utils/codesigning';\nimport { CommandError } from '../../../utils/errors';\nimport { stripPort } from '../../../utils/url';\n\nconst debug = require('debug')('expo:start:server:middleware:ExpoGoManifestHandlerMiddleware');\n\nexport enum ResponseContentType {\n TEXT_PLAIN,\n APPLICATION_JSON,\n APPLICATION_EXPO_JSON,\n MULTIPART_MIXED,\n}\n\ninterface ExpoGoManifestRequestInfo extends ManifestRequestInfo {\n responseContentType: ResponseContentType;\n expectSignature: string | null;\n}\n\nexport class ExpoGoManifestHandlerMiddleware extends ManifestMiddleware<ExpoGoManifestRequestInfo> {\n public getParsedHeaders(req: ServerRequest): ExpoGoManifestRequestInfo {\n let platform = parsePlatformHeader(req);\n\n if (!platform) {\n debug(\n `No \"expo-platform\" header or \"platform\" query parameter specified. Falling back to \"ios\".`\n );\n platform = 'ios';\n }\n\n assertRuntimePlatform(platform);\n\n // Expo Updates clients explicitly accept \"multipart/mixed\" responses while browsers implicitly\n // accept them with \"accept: */*\". To make it easier to debug manifest responses by visiting their\n // URLs in a browser, we denote the response as \"text/plain\" if the user agent appears not to be\n // an Expo Updates client.\n const accept = accepts(req);\n const acceptedType = accept.types([\n 'unknown/unknown',\n 'multipart/mixed',\n 'application/json',\n 'application/expo+json',\n 'text/plain',\n ]);\n\n let responseContentType;\n switch (acceptedType) {\n case 'multipart/mixed':\n responseContentType = ResponseContentType.MULTIPART_MIXED;\n break;\n case 'application/json':\n responseContentType = ResponseContentType.APPLICATION_JSON;\n break;\n case 'application/expo+json':\n responseContentType = ResponseContentType.APPLICATION_EXPO_JSON;\n break;\n default:\n responseContentType = ResponseContentType.TEXT_PLAIN;\n break;\n }\n\n const expectSignature = req.headers['expo-expect-signature'];\n\n return {\n responseContentType,\n platform,\n expectSignature: expectSignature ? String(expectSignature) : null,\n hostname: stripPort(req.headers['host']),\n protocol: req.headers['x-forwarded-proto'] as 'http' | 'https' | undefined,\n };\n }\n\n private getDefaultResponseHeaders(): ServerHeaders {\n const headers = new Map<string, number | string | readonly string[]>();\n // set required headers for Expo Updates manifest specification\n headers.set('expo-protocol-version', 0);\n headers.set('expo-sfv-version', 0);\n headers.set('cache-control', 'private, max-age=0');\n return headers;\n }\n\n public async _getManifestResponseAsync(requestOptions: ExpoGoManifestRequestInfo): Promise<{\n body: string;\n version: string;\n headers: ServerHeaders;\n }> {\n const { exp, hostUri, expoGoConfig, bundleUrl } =\n await this._resolveProjectSettingsAsync(requestOptions);\n\n const runtimeVersion =\n (await resolveRuntimeVersionWithExpoUpdatesAsync({\n projectRoot: this.projectRoot,\n platform: requestOptions.platform,\n })) ??\n // if expo-updates can't determine runtime version, fall back to calculation from config-plugin.\n // this happens when expo-updates is installed but runtimeVersion hasn't yet been configured or when\n // expo-updates is not installed.\n (await Updates.getRuntimeVersionAsync(\n this.projectRoot,\n { ...exp, runtimeVersion: exp.runtimeVersion ?? { policy: 'sdkVersion' } },\n requestOptions.platform\n ));\n if (!runtimeVersion) {\n throw new CommandError(\n 'MANIFEST_MIDDLEWARE',\n `Unable to determine runtime version for platform '${requestOptions.platform}'`\n );\n }\n\n const codeSigningInfo = await getCodeSigningInfoAsync(\n exp,\n requestOptions.expectSignature,\n this.options.privateKeyPath\n );\n\n const easProjectId = exp.extra?.eas?.projectId as string | undefined | null;\n const scopeKey = await ExpoGoManifestHandlerMiddleware.getScopeKeyAsync({\n slug: exp.slug,\n codeSigningInfo,\n });\n\n const expoUpdatesManifest: ExpoUpdatesManifest = {\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n runtimeVersion,\n launchAsset: {\n key: 'bundle',\n contentType: 'application/javascript',\n url: bundleUrl,\n },\n assets: [], // assets are not used in development\n metadata: {}, // required for the client to detect that this is an expo-updates manifest\n extra: {\n eas: {\n projectId: easProjectId ?? undefined,\n },\n expoClient: {\n ...exp,\n hostUri,\n },\n expoGo: expoGoConfig,\n scopeKey,\n },\n };\n\n const stringifiedManifest = JSON.stringify(expoUpdatesManifest);\n\n let manifestPartHeaders: { 'expo-signature': string } | null = null;\n let certificateChainBody: string | null = null;\n if (codeSigningInfo) {\n const signature = signManifestString(stringifiedManifest, codeSigningInfo);\n manifestPartHeaders = {\n 'expo-signature': serializeDictionary(\n convertToDictionaryItemsRepresentation({\n keyid: codeSigningInfo.keyId,\n sig: signature,\n alg: 'rsa-v1_5-sha256',\n })\n ),\n };\n certificateChainBody = codeSigningInfo.certificateChainForResponse.join('\\n');\n }\n\n const headers = this.getDefaultResponseHeaders();\n\n switch (requestOptions.responseContentType) {\n case ResponseContentType.MULTIPART_MIXED: {\n const form = this.getFormData({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n });\n headers.set('content-type', `multipart/mixed; boundary=${form.getBoundary()}`);\n return {\n body: form.getBuffer().toString(),\n version: runtimeVersion,\n headers,\n };\n }\n case ResponseContentType.APPLICATION_EXPO_JSON:\n case ResponseContentType.APPLICATION_JSON:\n case ResponseContentType.TEXT_PLAIN: {\n headers.set(\n 'content-type',\n ExpoGoManifestHandlerMiddleware.getContentTypeForResponseContentType(\n requestOptions.responseContentType\n )\n );\n if (manifestPartHeaders) {\n Object.entries(manifestPartHeaders).forEach(([key, value]) => {\n headers.set(key, value);\n });\n }\n\n return {\n body: stringifiedManifest,\n version: runtimeVersion,\n headers,\n };\n }\n }\n }\n\n private static getContentTypeForResponseContentType(\n responseContentType: ResponseContentType\n ): string {\n switch (responseContentType) {\n case ResponseContentType.MULTIPART_MIXED:\n return 'multipart/mixed';\n case ResponseContentType.APPLICATION_EXPO_JSON:\n return 'application/expo+json';\n case ResponseContentType.APPLICATION_JSON:\n return 'application/json';\n case ResponseContentType.TEXT_PLAIN:\n return 'text/plain';\n }\n }\n\n private getFormData({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n }: {\n stringifiedManifest: string;\n manifestPartHeaders: { 'expo-signature': string } | null;\n certificateChainBody: string | null;\n }): FormData {\n const form = new FormData();\n form.append('manifest', stringifiedManifest, {\n contentType: 'application/json',\n header: {\n ...manifestPartHeaders,\n },\n });\n if (certificateChainBody && certificateChainBody.length > 0) {\n form.append('certificate_chain', certificateChainBody, {\n contentType: 'application/x-pem-file',\n });\n }\n return form;\n }\n\n private static async getScopeKeyAsync({\n slug,\n codeSigningInfo,\n }: {\n slug: string;\n codeSigningInfo: CodeSigningInfo | null;\n }): Promise<string> {\n const scopeKeyFromCodeSigningInfo = codeSigningInfo?.scopeKey;\n if (scopeKeyFromCodeSigningInfo) {\n return scopeKeyFromCodeSigningInfo;\n }\n\n // Log.warn(\n // env.EXPO_OFFLINE\n // ? 'Using anonymous scope key in manifest for offline mode.'\n // : 'Using anonymous scope key in manifest.'\n // );\n return await getAnonymousScopeKeyAsync(slug);\n }\n}\n\nasync function getAnonymousScopeKeyAsync(slug: string): Promise<string> {\n const userAnonymousIdentifier = await getAnonymousIdAsync();\n return `@${ANONYMOUS_USERNAME}/${slug}-${userAnonymousIdentifier}`;\n}\n\nfunction convertToDictionaryItemsRepresentation(obj: { [key: string]: string }): Dictionary {\n return new Map(\n Object.entries(obj).map(([k, v]) => {\n return [k, [v, new Map()]];\n })\n );\n}\n"],"names":["ExpoGoManifestHandlerMiddleware","debug","require","ResponseContentType","TEXT_PLAIN","APPLICATION_JSON","APPLICATION_EXPO_JSON","MULTIPART_MIXED","ManifestMiddleware","getParsedHeaders","req","platform","parsePlatformHeader","assertRuntimePlatform","accept","accepts","acceptedType","types","responseContentType","expectSignature","headers","String","hostname","stripPort","protocol","getDefaultResponseHeaders","Map","set","_getManifestResponseAsync","requestOptions","exp","hostUri","expoGoConfig","bundleUrl","_resolveProjectSettingsAsync","runtimeVersion","resolveRuntimeVersionWithExpoUpdatesAsync","projectRoot","Updates","getRuntimeVersionAsync","policy","CommandError","codeSigningInfo","getCodeSigningInfoAsync","options","privateKeyPath","easProjectId","extra","eas","projectId","scopeKey","getScopeKeyAsync","slug","expoUpdatesManifest","id","crypto","randomUUID","createdAt","Date","toISOString","launchAsset","key","contentType","url","assets","metadata","undefined","expoClient","expoGo","stringifiedManifest","JSON","stringify","manifestPartHeaders","certificateChainBody","signature","signManifestString","serializeDictionary","convertToDictionaryItemsRepresentation","keyid","keyId","sig","alg","certificateChainForResponse","join","form","getFormData","getBoundary","body","getBuffer","toString","version","getContentTypeForResponseContentType","Object","entries","forEach","value","FormData","append","header","length","scopeKeyFromCodeSigningInfo","getAnonymousScopeKeyAsync","userAnonymousIdentifier","getAnonymousIdAsync","ANONYMOUS_USERNAME","obj","map","k","v"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/middleware/ExpoGoManifestHandlerMiddleware.ts"],"sourcesContent":["import { ExpoUpdatesManifest } from '@expo/config';\nimport { Updates } from '@expo/config-plugins';\nimport accepts from 'accepts';\nimport crypto from 'crypto';\nimport { serializeDictionary, Dictionary } from 'structured-headers';\n\nimport { ManifestMiddleware, ManifestRequestInfo } from './ManifestMiddleware';\nimport { assertRuntimePlatform, parsePlatformHeader } from './resolvePlatform';\nimport { resolveRuntimeVersionWithExpoUpdatesAsync } from './resolveRuntimeVersionWithExpoUpdatesAsync';\nimport { ServerHeaders, ServerRequest } from './server.types';\nimport { getAnonymousIdAsync } from '../../../api/user/UserSettings';\nimport { ANONYMOUS_USERNAME } from '../../../api/user/user';\nimport {\n CodeSigningInfo,\n getCodeSigningInfoAsync,\n signManifestString,\n} from '../../../utils/codesigning';\nimport { CommandError } from '../../../utils/errors';\nimport {\n encodeMultipartMixed,\n FormDataField,\n EncodedFormData,\n} from '../../../utils/multipartMixed';\nimport { stripPort } from '../../../utils/url';\n\nconst debug = require('debug')('expo:start:server:middleware:ExpoGoManifestHandlerMiddleware');\n\nexport enum ResponseContentType {\n TEXT_PLAIN,\n APPLICATION_JSON,\n APPLICATION_EXPO_JSON,\n MULTIPART_MIXED,\n}\n\ninterface ExpoGoManifestRequestInfo extends ManifestRequestInfo {\n responseContentType: ResponseContentType;\n expectSignature: string | null;\n}\n\nexport class ExpoGoManifestHandlerMiddleware extends ManifestMiddleware<ExpoGoManifestRequestInfo> {\n public getParsedHeaders(req: ServerRequest): ExpoGoManifestRequestInfo {\n let platform = parsePlatformHeader(req);\n\n if (!platform) {\n debug(\n `No \"expo-platform\" header or \"platform\" query parameter specified. Falling back to \"ios\".`\n );\n platform = 'ios';\n }\n\n assertRuntimePlatform(platform);\n\n // Expo Updates clients explicitly accept \"multipart/mixed\" responses while browsers implicitly\n // accept them with \"accept: */*\". To make it easier to debug manifest responses by visiting their\n // URLs in a browser, we denote the response as \"text/plain\" if the user agent appears not to be\n // an Expo Updates client.\n const accept = accepts(req);\n const acceptedType = accept.types([\n 'unknown/unknown',\n 'multipart/mixed',\n 'application/json',\n 'application/expo+json',\n 'text/plain',\n ]);\n\n let responseContentType;\n switch (acceptedType) {\n case 'multipart/mixed':\n responseContentType = ResponseContentType.MULTIPART_MIXED;\n break;\n case 'application/json':\n responseContentType = ResponseContentType.APPLICATION_JSON;\n break;\n case 'application/expo+json':\n responseContentType = ResponseContentType.APPLICATION_EXPO_JSON;\n break;\n default:\n responseContentType = ResponseContentType.TEXT_PLAIN;\n break;\n }\n\n const expectSignature = req.headers['expo-expect-signature'];\n\n return {\n responseContentType,\n platform,\n expectSignature: expectSignature ? String(expectSignature) : null,\n hostname: stripPort(req.headers['host']),\n protocol: req.headers['x-forwarded-proto'] as 'http' | 'https' | undefined,\n };\n }\n\n private getDefaultResponseHeaders(): ServerHeaders {\n const headers = new Map<string, number | string | readonly string[]>();\n // set required headers for Expo Updates manifest specification\n headers.set('expo-protocol-version', 0);\n headers.set('expo-sfv-version', 0);\n headers.set('cache-control', 'private, max-age=0');\n return headers;\n }\n\n public async _getManifestResponseAsync(requestOptions: ExpoGoManifestRequestInfo): Promise<{\n body: string;\n version: string;\n headers: ServerHeaders;\n }> {\n const { exp, hostUri, expoGoConfig, bundleUrl } =\n await this._resolveProjectSettingsAsync(requestOptions);\n\n const runtimeVersion =\n (await resolveRuntimeVersionWithExpoUpdatesAsync({\n projectRoot: this.projectRoot,\n platform: requestOptions.platform,\n })) ??\n // if expo-updates can't determine runtime version, fall back to calculation from config-plugin.\n // this happens when expo-updates is installed but runtimeVersion hasn't yet been configured or when\n // expo-updates is not installed.\n (await Updates.getRuntimeVersionAsync(\n this.projectRoot,\n { ...exp, runtimeVersion: exp.runtimeVersion ?? { policy: 'sdkVersion' } },\n requestOptions.platform\n ));\n if (!runtimeVersion) {\n throw new CommandError(\n 'MANIFEST_MIDDLEWARE',\n `Unable to determine runtime version for platform '${requestOptions.platform}'`\n );\n }\n\n const codeSigningInfo = await getCodeSigningInfoAsync(\n exp,\n requestOptions.expectSignature,\n this.options.privateKeyPath\n );\n\n const easProjectId = exp.extra?.eas?.projectId as string | undefined | null;\n const scopeKey = await ExpoGoManifestHandlerMiddleware.getScopeKeyAsync({\n slug: exp.slug,\n codeSigningInfo,\n });\n\n const expoUpdatesManifest: ExpoUpdatesManifest = {\n id: crypto.randomUUID(),\n createdAt: new Date().toISOString(),\n runtimeVersion,\n launchAsset: {\n key: 'bundle',\n contentType: 'application/javascript',\n url: bundleUrl,\n },\n assets: [], // assets are not used in development\n metadata: {}, // required for the client to detect that this is an expo-updates manifest\n extra: {\n eas: {\n projectId: easProjectId ?? undefined,\n },\n expoClient: {\n ...exp,\n hostUri,\n },\n expoGo: expoGoConfig,\n scopeKey,\n },\n };\n\n const stringifiedManifest = JSON.stringify(expoUpdatesManifest);\n\n let manifestPartHeaders: { 'expo-signature': string } | null = null;\n let certificateChainBody: string | null = null;\n if (codeSigningInfo) {\n const signature = signManifestString(stringifiedManifest, codeSigningInfo);\n manifestPartHeaders = {\n 'expo-signature': serializeDictionary(\n convertToDictionaryItemsRepresentation({\n keyid: codeSigningInfo.keyId,\n sig: signature,\n alg: 'rsa-v1_5-sha256',\n })\n ),\n };\n certificateChainBody = codeSigningInfo.certificateChainForResponse.join('\\n');\n }\n\n const headers = this.getDefaultResponseHeaders();\n\n switch (requestOptions.responseContentType) {\n case ResponseContentType.MULTIPART_MIXED: {\n const encoded = await this.encodeFormDataAsync({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n });\n headers.set('content-type', `multipart/mixed; boundary=${encoded.boundary}`);\n return {\n body: encoded.body,\n version: runtimeVersion,\n headers,\n };\n }\n case ResponseContentType.APPLICATION_EXPO_JSON:\n case ResponseContentType.APPLICATION_JSON:\n case ResponseContentType.TEXT_PLAIN: {\n headers.set(\n 'content-type',\n ExpoGoManifestHandlerMiddleware.getContentTypeForResponseContentType(\n requestOptions.responseContentType\n )\n );\n if (manifestPartHeaders) {\n Object.entries(manifestPartHeaders).forEach(([key, value]) => {\n headers.set(key, value);\n });\n }\n\n return {\n body: stringifiedManifest,\n version: runtimeVersion,\n headers,\n };\n }\n }\n }\n\n private static getContentTypeForResponseContentType(\n responseContentType: ResponseContentType\n ): string {\n switch (responseContentType) {\n case ResponseContentType.MULTIPART_MIXED:\n return 'multipart/mixed';\n case ResponseContentType.APPLICATION_EXPO_JSON:\n return 'application/expo+json';\n case ResponseContentType.APPLICATION_JSON:\n return 'application/json';\n case ResponseContentType.TEXT_PLAIN:\n return 'text/plain';\n }\n }\n\n private encodeFormDataAsync({\n stringifiedManifest,\n manifestPartHeaders,\n certificateChainBody,\n }: {\n stringifiedManifest: string;\n manifestPartHeaders: { 'expo-signature': string } | null;\n certificateChainBody: string | null;\n }): Promise<EncodedFormData> {\n const fields: FormDataField[] = [\n {\n name: 'manifest',\n value: stringifiedManifest,\n contentType: 'application/json',\n partHeaders: manifestPartHeaders,\n },\n ];\n if (certificateChainBody && certificateChainBody.length > 0) {\n fields.push({\n name: 'certificate_chain',\n value: certificateChainBody,\n contentType: 'application/x-pem-file',\n });\n }\n return encodeMultipartMixed(fields);\n }\n\n private static async getScopeKeyAsync({\n slug,\n codeSigningInfo,\n }: {\n slug: string;\n codeSigningInfo: CodeSigningInfo | null;\n }): Promise<string> {\n const scopeKeyFromCodeSigningInfo = codeSigningInfo?.scopeKey;\n if (scopeKeyFromCodeSigningInfo) {\n return scopeKeyFromCodeSigningInfo;\n }\n\n // Log.warn(\n // env.EXPO_OFFLINE\n // ? 'Using anonymous scope key in manifest for offline mode.'\n // : 'Using anonymous scope key in manifest.'\n // );\n return await getAnonymousScopeKeyAsync(slug);\n }\n}\n\nasync function getAnonymousScopeKeyAsync(slug: string): Promise<string> {\n const userAnonymousIdentifier = await getAnonymousIdAsync();\n return `@${ANONYMOUS_USERNAME}/${slug}-${userAnonymousIdentifier}`;\n}\n\nfunction convertToDictionaryItemsRepresentation(obj: { [key: string]: string }): Dictionary {\n return new Map(\n Object.entries(obj).map(([k, v]) => {\n return [k, [v, new Map()]];\n })\n );\n}\n"],"names":["ExpoGoManifestHandlerMiddleware","debug","require","ResponseContentType","TEXT_PLAIN","APPLICATION_JSON","APPLICATION_EXPO_JSON","MULTIPART_MIXED","ManifestMiddleware","getParsedHeaders","req","platform","parsePlatformHeader","assertRuntimePlatform","accept","accepts","acceptedType","types","responseContentType","expectSignature","headers","String","hostname","stripPort","protocol","getDefaultResponseHeaders","Map","set","_getManifestResponseAsync","requestOptions","exp","hostUri","expoGoConfig","bundleUrl","_resolveProjectSettingsAsync","runtimeVersion","resolveRuntimeVersionWithExpoUpdatesAsync","projectRoot","Updates","getRuntimeVersionAsync","policy","CommandError","codeSigningInfo","getCodeSigningInfoAsync","options","privateKeyPath","easProjectId","extra","eas","projectId","scopeKey","getScopeKeyAsync","slug","expoUpdatesManifest","id","crypto","randomUUID","createdAt","Date","toISOString","launchAsset","key","contentType","url","assets","metadata","undefined","expoClient","expoGo","stringifiedManifest","JSON","stringify","manifestPartHeaders","certificateChainBody","signature","signManifestString","serializeDictionary","convertToDictionaryItemsRepresentation","keyid","keyId","sig","alg","certificateChainForResponse","join","encoded","encodeFormDataAsync","boundary","body","version","getContentTypeForResponseContentType","Object","entries","forEach","value","fields","name","partHeaders","length","push","encodeMultipartMixed","scopeKeyFromCodeSigningInfo","getAnonymousScopeKeyAsync","userAnonymousIdentifier","getAnonymousIdAsync","ANONYMOUS_USERNAME","obj","map","k","v"],"mappings":"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"}
|
|
@@ -28,13 +28,6 @@ function _promises() {
|
|
|
28
28
|
};
|
|
29
29
|
return data;
|
|
30
30
|
}
|
|
31
|
-
function _lodashDebounce() {
|
|
32
|
-
const data = /*#__PURE__*/ _interopRequireDefault(require("lodash.debounce"));
|
|
33
|
-
_lodashDebounce = function() {
|
|
34
|
-
return data;
|
|
35
|
-
};
|
|
36
|
-
return data;
|
|
37
|
-
}
|
|
38
31
|
function _path() {
|
|
39
32
|
const data = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
40
33
|
_path = function() {
|
|
@@ -154,10 +147,17 @@ async function legacyTypedRoutes({ server , metro , typesDirectory , projectRoot
|
|
|
154
147
|
...dynamicRoutes.values()
|
|
155
148
|
].flatMap((v)=>Array.from(v))), new Set(dynamicRoutes.keys()));
|
|
156
149
|
}
|
|
150
|
+
function debounce(fn, delay) {
|
|
151
|
+
let timeoutId;
|
|
152
|
+
return function(...args) {
|
|
153
|
+
clearTimeout(timeoutId);
|
|
154
|
+
timeoutId = setTimeout(()=>fn.apply(this, args), delay);
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
157
|
/**
|
|
158
158
|
* Generate a router.d.ts file that contains all of the routes in the project.
|
|
159
159
|
* Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)
|
|
160
|
-
*/ const regenerateRouterDotTS = (
|
|
160
|
+
*/ const regenerateRouterDotTS = debounce(async (typesDir, staticRoutes, dynamicRoutes, dynamicRouteTemplates)=>{
|
|
161
161
|
await _promises().default.mkdir(typesDir, {
|
|
162
162
|
recursive: true
|
|
163
163
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/type-generation/routes.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport debounce from 'lodash.debounce';\nimport { Server } from 'metro';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { directoryExistsAsync } from '../../../utils/dir';\nimport { unsafeTemplate } from '../../../utils/template';\nimport { ServerLike } from '../BundlerDevServer';\nimport { metroWatchTypeScriptFiles } from '../metro/metroWatchTypeScriptFiles';\n\n// /test/[...param1]/[param2]/[param3] - captures [\"param1\", \"param2\", \"param3\"]\nexport const CAPTURE_DYNAMIC_PARAMS = /\\[(?:\\.{3})?(\\w*?)[\\]$]/g;\n// /[...param1]/ - Match [...param1]\nexport const CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nexport const SLUG = /\\[.+?\\]/g;\n// /(group1,group2,group3)/test - match (group1,group2,group3)\nexport const ARRAY_GROUP_REGEX = /\\(\\s*\\w[\\w\\s]*?,.*?\\)/g;\n// /(group1,group2,group3)/test - captures [\"group1\", \"group2\", \"group3\"]\nexport const CAPTURE_GROUP_REGEX = /[\\\\(,]\\s*(\\w[\\w\\s]*?)\\s*(?=[,\\\\)])/g;\n/**\n * Match:\n * - _layout files, +html, +not-found, string+api, etc\n * - Routes can still use `+`, but it cannot be in the last segment.\n */\nexport const TYPED_ROUTES_EXCLUSION_REGEX = /(_layout|[^/]*?\\+[^/]*?)\\.[tj]sx?$/;\n\nexport interface SetupTypedRoutesOptions {\n server?: ServerLike;\n metro?: Server | null;\n typesDirectory: string;\n projectRoot: string;\n /** Absolute expo router routes directory. */\n routerDirectory: string;\n plugin?: Record<string, any>;\n}\n\nexport async function setupTypedRoutes(options: SetupTypedRoutesOptions) {\n /*\n * In SDK 51, TypedRoutes was moved out of cli and into expo-router. For now we need to support both\n * the legacy and new versions of TypedRoutes.\n *\n * TODO (@marklawlor): Remove this check in SDK 53, only support Expo Router v4 and above.\n */\n const typedRoutesModule = resolveFrom.silent(\n options.projectRoot,\n 'expo-router/build/typed-routes'\n );\n return typedRoutesModule ? typedRoutes(typedRoutesModule, options) : legacyTypedRoutes(options);\n}\n\nasync function typedRoutes(\n typedRoutesModulePath: any,\n { server, metro, typesDirectory, projectRoot, routerDirectory, plugin }: SetupTypedRoutesOptions\n) {\n /*\n * Expo Router uses EXPO_ROUTER_APP_ROOT in multiple places to determine the root of the project.\n * In apps compiled by Metro, this code is compiled away. But Typed Routes run in NodeJS with no compilation\n * so we need to explicitly set it.\n */\n process.env.EXPO_ROUTER_APP_ROOT = routerDirectory;\n\n const typedRoutesModule = require(typedRoutesModulePath);\n\n /*\n * Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n */\n if (metro && server) {\n // Setup out watcher first\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n callback: typedRoutesModule.getWatchHandler(typesDirectory),\n });\n }\n\n /*\n * In SDK 52, the `regenerateDeclarations` was changed to accept plugin options.\n * This function has an optional parameter that we cannot override, so we need to ensure the user\n * is using a compatible version of `expo-router`. Otherwise, we will fallback to the old method.\n *\n * TODO(@marklawlor): In SDK53+ we should remove this check and always use the new method.\n */\n if ('version' in typedRoutesModule && typedRoutesModule.version >= 52) {\n typedRoutesModule.regenerateDeclarations(typesDirectory, plugin);\n } else {\n typedRoutesModule.regenerateDeclarations(typesDirectory);\n }\n}\n\nasync function legacyTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n routerDirectory,\n}: SetupTypedRoutesOptions) {\n const { filePathToRoute, staticRoutes, dynamicRoutes, addFilePath, isRouteFile } =\n getTypedRoutesUtils(routerDirectory);\n\n // Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n if (metro && server) {\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n async callback({ filePath, type }) {\n if (!isRouteFile(filePath)) {\n return;\n }\n\n let shouldRegenerate = false;\n\n if (type === 'delete') {\n const route = filePathToRoute(filePath);\n staticRoutes.delete(route);\n dynamicRoutes.delete(route);\n shouldRegenerate = true;\n } else {\n shouldRegenerate = addFilePath(filePath);\n }\n\n if (shouldRegenerate) {\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n }\n },\n });\n }\n\n if (await directoryExistsAsync(routerDirectory)) {\n // Do we need to walk the entire tree on startup?\n // Idea: Store the list of files in the last write, then simply check Git for what files have changed\n await walk(routerDirectory, addFilePath);\n }\n\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n}\n\n/**\n * Generate a router.d.ts file that contains all of the routes in the project.\n * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)\n */\nconst regenerateRouterDotTS = debounce(\n async (\n typesDir: string,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n ) => {\n await fs.mkdir(typesDir, { recursive: true });\n await fs.writeFile(\n path.resolve(typesDir, './router.d.ts'),\n getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates)\n );\n },\n 100\n);\n\n/*\n * This is exported for testing purposes\n */\nexport function getTemplateString(\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n) {\n return routerDotTSTemplate({\n staticRoutes: setToUnionType(staticRoutes),\n dynamicRoutes: setToUnionType(dynamicRoutes),\n dynamicRouteParams: setToUnionType(dynamicRouteTemplates),\n });\n}\n\n/**\n * Utility functions for typed routes\n *\n * These are extracted for easier testing\n */\nexport function getTypedRoutesUtils(appRoot: string, filePathSeperator = path.sep) {\n /*\n * staticRoutes are a map where the key if the route without groups and the value\n * is another set of all group versions of the route. e.g,\n * Map([\n * [\"/\", [\"/(app)/(notes)\", \"/(app)/(profile)\"]\n * ])\n */\n const staticRoutes = new Map<string, Set<string>>([['/', new Set('/')]]);\n /*\n * dynamicRoutes are the same as staticRoutes (key if the resolved route,\n * and the value is a set of possible routes). e.g:\n *\n * /[...fruits] -> /${CatchAllRoutePart<T>}\n * /color/[color] -> /color/${SingleRoutePart<T>}\n *\n * The keys of this map are also important, as they can be used as \"static\" types\n * <Link href={{ pathname: \"/[...fruits]\",params: { fruits: [\"apple\"] } }} />\n */\n const dynamicRoutes = new Map<string, Set<string>>();\n\n function normalizedFilePath(filePath: string) {\n return filePath.replaceAll(filePathSeperator, '/');\n }\n\n const normalizedAppRoot = normalizedFilePath(appRoot);\n\n const filePathToRoute = (filePath: string) => {\n return normalizedFilePath(filePath)\n .replace(normalizedAppRoot, '')\n .replace(/index\\.[jt]sx?/, '')\n .replace(/\\.[jt]sx?$/, '');\n };\n\n const isRouteFile = (filePath: string) => {\n if (filePath.match(TYPED_ROUTES_EXCLUSION_REGEX)) {\n return false;\n }\n\n // Route files must be nested with in the appRoot\n const relative = path.relative(appRoot, filePath);\n return relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n };\n\n const addFilePath = (filePath: string): boolean => {\n if (!isRouteFile(filePath)) {\n return false;\n }\n\n const route = filePathToRoute(filePath);\n\n // We have already processed this file\n if (staticRoutes.has(route) || dynamicRoutes.has(route)) {\n return false;\n }\n\n const dynamicParams = new Set(\n [...route.matchAll(CAPTURE_DYNAMIC_PARAMS)].map((match) => match[1])\n );\n const isDynamic = dynamicParams.size > 0;\n\n const addRoute = (originalRoute: string, route: string) => {\n if (isDynamic) {\n let set = dynamicRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n dynamicRoutes.set(originalRoute, set);\n }\n\n set.add(\n route\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<T>}')\n );\n } else {\n let set = staticRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n staticRoutes.set(originalRoute, set);\n }\n\n set.add(route);\n }\n };\n\n if (!route.match(ARRAY_GROUP_REGEX)) {\n addRoute(route, route);\n }\n\n // Does this route have a group? eg /(group)\n if (route.includes('/(')) {\n const routeWithoutGroups = route.replace(/\\/\\(.+?\\)/g, '');\n addRoute(route, routeWithoutGroups);\n\n // If there are multiple groups, we need to expand them\n // eg /(test1,test2)/page => /test1/page & /test2/page\n for (const routeWithSingleGroup of extrapolateGroupRoutes(route)) {\n addRoute(route, routeWithSingleGroup);\n }\n }\n\n return true;\n };\n\n return {\n staticRoutes,\n dynamicRoutes,\n filePathToRoute,\n addFilePath,\n isRouteFile,\n };\n}\n\nexport const setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0 ? [...set].map((s) => `\\`${s}\\``).join(' | ') : 'never';\n};\n\n/**\n * Recursively walk a directory and call the callback with the file path.\n */\nasync function walk(directory: string, callback: (filePath: string) => void) {\n const files = await fs.readdir(directory);\n for (const file of files) {\n const p = path.join(directory, file);\n if ((await fs.stat(p)).isDirectory()) {\n await walk(p, callback);\n } else {\n // Normalise the paths so they are easier to convert to URLs\n const normalizedPath = p.replaceAll(path.sep, '/');\n callback(normalizedPath);\n }\n }\n}\n\n/**\n * Given a route, return all possible routes that could be generated from it.\n */\nexport function extrapolateGroupRoutes(\n route: string,\n routes: Set<string> = new Set()\n): Set<string> {\n // Create a version with no groups. We will then need to cleanup double and/or trailing slashes\n routes.add(route.replaceAll(ARRAY_GROUP_REGEX, '').replaceAll(/\\/+/g, '/').replace(/\\/$/, ''));\n\n const match = route.match(ARRAY_GROUP_REGEX);\n\n if (!match) {\n routes.add(route);\n return routes;\n }\n\n const groupsMatch = match[0];\n\n for (const group of groupsMatch.matchAll(CAPTURE_GROUP_REGEX)) {\n extrapolateGroupRoutes(route.replace(groupsMatch, `(${group[1].trim()})`), routes);\n }\n\n return routes;\n}\n\n/**\n * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to\n * mix with arbitrary versions.\n * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.\n */\nconst routerDotTSTemplate = unsafeTemplate`/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\ndeclare module \"expo-router\" {\n import type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\n import type { Router as OriginalRouter } from 'expo-router/build/types';\n export * from 'expo-router/build';\n\n // prettier-ignore\n type StaticRoutes = ${'staticRoutes'};\n // prettier-ignore\n type DynamicRoutes<T extends string> = ${'dynamicRoutes'};\n // prettier-ignore\n type DynamicRouteTemplate = ${'dynamicRouteParams'};\n\n type RelativePathString = \\`./\\${string}\\` | \\`../\\${string}\\` | '..';\n type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\n type ExternalPathString = \\`\\${string}:\\${string}\\`;\n\n type ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\n export type AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n /****************\n * Route Utils *\n ****************/\n\n type SearchOrHash = \\`?\\${string}\\` | \\`#\\${string}\\`;\n type UnknownInputParams = Record<string, string | number | (string | number)[]>;\n type UnknownOutputParams = Record<string, string | string[]>;\n\n /**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\n type SingleRoutePart<S extends string> = S extends \\`\\${string}/\\${string}\\`\n ? never\n : S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`(\\${string})\\`\n ? never\n : S extends \\`[\\${string}]\\`\n ? never\n : S;\n\n /**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\n type CatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`\\${string}(\\${string})\\${string}\\`\n ? never\n : S extends \\`\\${string}[\\${string}]\\${string}\\`\n ? never\n : S;\n\n // type OptionalCatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\` ? never : S\n\n /**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\n type IsParameter<Part> = Part extends \\`[\\${infer ParamName}]\\` ? ParamName : never;\n\n /**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\n type ParameterNames<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n /**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\n type RouteSegments<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n /**\n * Returns a Record of the routes parameters as strings and CatchAll parameters\n *\n * There are two versions, input and output, as you can input 'string | number' but\n * the output will always be 'string'\n *\n * /[id]/[...rest] -> { id: string, rest: string[] }\n * /no-params -> {}\n */\n type InputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? (string | number)[] : string | number;\n } & UnknownInputParams;\n\n type OutputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? string[] : string;\n } & UnknownOutputParams;\n\n /**\n * Returns the search parameters for a route.\n */\n export type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate\n ? OutputRouteParams<T>\n : T extends StaticRoutes\n ? never\n : UnknownOutputParams;\n\n /**\n * Route is mostly used as part of Href to ensure that a valid route is provided\n *\n * Given a dynamic route, this will return never. This is helpful for conditional logic\n *\n * /test -> /test, /test2, etc\n * /test/[abc] -> never\n * /test/resolve -> /test, /test2, etc\n *\n * Note that if we provide a value for [abc] then the route is allowed\n *\n * This is named Route to prevent confusion, as users they will often see it in tooltips\n */\n export type Route<T> = T extends string\n ? T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | ExternalPathString\n | (T extends \\`\\${infer P}\\${SearchOrHash}\\`\n ? P extends DynamicRoutes<infer _>\n ? T\n : never\n : T extends DynamicRoutes<infer _>\n ? T\n : never)\n : never;\n\n /*********\n * Href *\n *********/\n\n export type Href<T> = T extends Record<'pathname', string> ? HrefObject<T> : Route<T>;\n\n export type HrefObject<\n R extends Record<'pathname', string>,\n P = R['pathname'],\n > = P extends DynamicRouteTemplate\n ? { pathname: P; params: InputRouteParams<P> }\n : P extends Route<P>\n ? { pathname: Route<P> | DynamicRouteTemplate; params?: never | InputRouteParams<never> }\n : never;\n\n /***********************\n * Expo Router Exports *\n ***********************/\n\n export type Router = Omit<OriginalRouter, 'push' | 'replace' | 'setParams'> & {\n /** Navigate to the provided href. */\n push: <T>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T>(href: Href<T>) => void;\n /** Update the current route query params. */\n setParams: <T = ''>(params?: T extends '' ? Record<string, string> : InputRouteParams<T>) => void;\n };\n\n /** The imperative router. */\n export const router: Router;\n\n /************\n * <Link /> *\n ************/\n export interface LinkProps<T> extends OriginalLinkProps {\n href: Href<T>;\n }\n\n export interface LinkComponent {\n <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T>(href: Href<T>) => string;\n }\n\n /**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. \\`/feeds/hot\\`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n * @param props.className On web, this sets the HTML \\`class\\` directly. On native, this can be used with CSS interop tools like Nativewind.\n */\n export const Link: LinkComponent;\n\n /** Redirects to the href as soon as the component is mounted. */\n export const Redirect: <T>(\n props: React.PropsWithChildren<{ href: Href<T> }>\n ) => JSX.Element;\n\n /************\n * Hooks *\n ************/\n export function useRouter(): Router;\n\n export function useLocalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n /** @deprecated renamed to \\`useGlobalSearchParams\\` */\n export function useSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useGlobalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useSegments<\n T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString,\n >(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;\n}\n`;\n"],"names":["CAPTURE_DYNAMIC_PARAMS","CATCH_ALL","SLUG","ARRAY_GROUP_REGEX","CAPTURE_GROUP_REGEX","TYPED_ROUTES_EXCLUSION_REGEX","setupTypedRoutes","getTemplateString","getTypedRoutesUtils","setToUnionType","extrapolateGroupRoutes","options","typedRoutesModule","resolveFrom","silent","projectRoot","typedRoutes","legacyTypedRoutes","typedRoutesModulePath","server","metro","typesDirectory","routerDirectory","plugin","process","env","EXPO_ROUTER_APP_ROOT","require","metroWatchTypeScriptFiles","eventTypes","callback","getWatchHandler","version","regenerateDeclarations","filePathToRoute","staticRoutes","dynamicRoutes","addFilePath","isRouteFile","filePath","type","shouldRegenerate","route","delete","regenerateRouterDotTS","Set","values","flatMap","v","Array","from","keys","directoryExistsAsync","walk","debounce","typesDir","dynamicRouteTemplates","fs","mkdir","recursive","writeFile","path","resolve","routerDotTSTemplate","dynamicRouteParams","appRoot","filePathSeperator","sep","Map","normalizedFilePath","replaceAll","normalizedAppRoot","replace","match","relative","startsWith","isAbsolute","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","includes","routeWithoutGroups","routeWithSingleGroup","s","join","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","routes","groupsMatch","group","trim","unsafeTemplate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/type-generation/routes.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport { Server } from 'metro';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport { directoryExistsAsync } from '../../../utils/dir';\nimport { unsafeTemplate } from '../../../utils/template';\nimport { ServerLike } from '../BundlerDevServer';\nimport { metroWatchTypeScriptFiles } from '../metro/metroWatchTypeScriptFiles';\n\n// /test/[...param1]/[param2]/[param3] - captures [\"param1\", \"param2\", \"param3\"]\nexport const CAPTURE_DYNAMIC_PARAMS = /\\[(?:\\.{3})?(\\w*?)[\\]$]/g;\n// /[...param1]/ - Match [...param1]\nexport const CATCH_ALL = /\\[\\.\\.\\..+?\\]/g;\n// /[param1] - Match [param1]\nexport const SLUG = /\\[.+?\\]/g;\n// /(group1,group2,group3)/test - match (group1,group2,group3)\nexport const ARRAY_GROUP_REGEX = /\\(\\s*\\w[\\w\\s]*?,.*?\\)/g;\n// /(group1,group2,group3)/test - captures [\"group1\", \"group2\", \"group3\"]\nexport const CAPTURE_GROUP_REGEX = /[\\\\(,]\\s*(\\w[\\w\\s]*?)\\s*(?=[,\\\\)])/g;\n/**\n * Match:\n * - _layout files, +html, +not-found, string+api, etc\n * - Routes can still use `+`, but it cannot be in the last segment.\n */\nexport const TYPED_ROUTES_EXCLUSION_REGEX = /(_layout|[^/]*?\\+[^/]*?)\\.[tj]sx?$/;\n\nexport interface SetupTypedRoutesOptions {\n server?: ServerLike;\n metro?: Server | null;\n typesDirectory: string;\n projectRoot: string;\n /** Absolute expo router routes directory. */\n routerDirectory: string;\n plugin?: Record<string, any>;\n}\n\nexport async function setupTypedRoutes(options: SetupTypedRoutesOptions) {\n /*\n * In SDK 51, TypedRoutes was moved out of cli and into expo-router. For now we need to support both\n * the legacy and new versions of TypedRoutes.\n *\n * TODO (@marklawlor): Remove this check in SDK 53, only support Expo Router v4 and above.\n */\n const typedRoutesModule = resolveFrom.silent(\n options.projectRoot,\n 'expo-router/build/typed-routes'\n );\n return typedRoutesModule ? typedRoutes(typedRoutesModule, options) : legacyTypedRoutes(options);\n}\n\nasync function typedRoutes(\n typedRoutesModulePath: any,\n { server, metro, typesDirectory, projectRoot, routerDirectory, plugin }: SetupTypedRoutesOptions\n) {\n /*\n * Expo Router uses EXPO_ROUTER_APP_ROOT in multiple places to determine the root of the project.\n * In apps compiled by Metro, this code is compiled away. But Typed Routes run in NodeJS with no compilation\n * so we need to explicitly set it.\n */\n process.env.EXPO_ROUTER_APP_ROOT = routerDirectory;\n\n const typedRoutesModule = require(typedRoutesModulePath);\n\n /*\n * Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n */\n if (metro && server) {\n // Setup out watcher first\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n callback: typedRoutesModule.getWatchHandler(typesDirectory),\n });\n }\n\n /*\n * In SDK 52, the `regenerateDeclarations` was changed to accept plugin options.\n * This function has an optional parameter that we cannot override, so we need to ensure the user\n * is using a compatible version of `expo-router`. Otherwise, we will fallback to the old method.\n *\n * TODO(@marklawlor): In SDK53+ we should remove this check and always use the new method.\n */\n if ('version' in typedRoutesModule && typedRoutesModule.version >= 52) {\n typedRoutesModule.regenerateDeclarations(typesDirectory, plugin);\n } else {\n typedRoutesModule.regenerateDeclarations(typesDirectory);\n }\n}\n\nasync function legacyTypedRoutes({\n server,\n metro,\n typesDirectory,\n projectRoot,\n routerDirectory,\n}: SetupTypedRoutesOptions) {\n const { filePathToRoute, staticRoutes, dynamicRoutes, addFilePath, isRouteFile } =\n getTypedRoutesUtils(routerDirectory);\n\n // Typed Routes can be run with out Metro or a Server, e.g. `expo customize tsconfig.json`\n if (metro && server) {\n metroWatchTypeScriptFiles({\n projectRoot,\n server,\n metro,\n eventTypes: ['add', 'delete', 'change'],\n async callback({ filePath, type }) {\n if (!isRouteFile(filePath)) {\n return;\n }\n\n let shouldRegenerate = false;\n\n if (type === 'delete') {\n const route = filePathToRoute(filePath);\n staticRoutes.delete(route);\n dynamicRoutes.delete(route);\n shouldRegenerate = true;\n } else {\n shouldRegenerate = addFilePath(filePath);\n }\n\n if (shouldRegenerate) {\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n }\n },\n });\n }\n\n if (await directoryExistsAsync(routerDirectory)) {\n // Do we need to walk the entire tree on startup?\n // Idea: Store the list of files in the last write, then simply check Git for what files have changed\n await walk(routerDirectory, addFilePath);\n }\n\n regenerateRouterDotTS(\n typesDirectory,\n new Set([...staticRoutes.values()].flatMap((v) => Array.from(v))),\n new Set([...dynamicRoutes.values()].flatMap((v) => Array.from(v))),\n new Set(dynamicRoutes.keys())\n );\n}\n\nfunction debounce<U, T extends (this: U, ...args: any[]) => void>(fn: T, delay: number): T {\n let timeoutId: NodeJS.Timeout | undefined;\n return function (this: U, ...args: any[]) {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn.apply(this, args), delay);\n } as T;\n}\n\n/**\n * Generate a router.d.ts file that contains all of the routes in the project.\n * Should be debounced as its very common for developers to make changes to multiple files at once (eg Save All)\n */\nconst regenerateRouterDotTS = debounce(\n async (\n typesDir: string,\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n ) => {\n await fs.mkdir(typesDir, { recursive: true });\n await fs.writeFile(\n path.resolve(typesDir, './router.d.ts'),\n getTemplateString(staticRoutes, dynamicRoutes, dynamicRouteTemplates)\n );\n },\n 100\n);\n\n/*\n * This is exported for testing purposes\n */\nexport function getTemplateString(\n staticRoutes: Set<string>,\n dynamicRoutes: Set<string>,\n dynamicRouteTemplates: Set<string>\n) {\n return routerDotTSTemplate({\n staticRoutes: setToUnionType(staticRoutes),\n dynamicRoutes: setToUnionType(dynamicRoutes),\n dynamicRouteParams: setToUnionType(dynamicRouteTemplates),\n });\n}\n\n/**\n * Utility functions for typed routes\n *\n * These are extracted for easier testing\n */\nexport function getTypedRoutesUtils(appRoot: string, filePathSeperator = path.sep) {\n /*\n * staticRoutes are a map where the key if the route without groups and the value\n * is another set of all group versions of the route. e.g,\n * Map([\n * [\"/\", [\"/(app)/(notes)\", \"/(app)/(profile)\"]\n * ])\n */\n const staticRoutes = new Map<string, Set<string>>([['/', new Set('/')]]);\n /*\n * dynamicRoutes are the same as staticRoutes (key if the resolved route,\n * and the value is a set of possible routes). e.g:\n *\n * /[...fruits] -> /${CatchAllRoutePart<T>}\n * /color/[color] -> /color/${SingleRoutePart<T>}\n *\n * The keys of this map are also important, as they can be used as \"static\" types\n * <Link href={{ pathname: \"/[...fruits]\",params: { fruits: [\"apple\"] } }} />\n */\n const dynamicRoutes = new Map<string, Set<string>>();\n\n function normalizedFilePath(filePath: string) {\n return filePath.replaceAll(filePathSeperator, '/');\n }\n\n const normalizedAppRoot = normalizedFilePath(appRoot);\n\n const filePathToRoute = (filePath: string) => {\n return normalizedFilePath(filePath)\n .replace(normalizedAppRoot, '')\n .replace(/index\\.[jt]sx?/, '')\n .replace(/\\.[jt]sx?$/, '');\n };\n\n const isRouteFile = (filePath: string) => {\n if (filePath.match(TYPED_ROUTES_EXCLUSION_REGEX)) {\n return false;\n }\n\n // Route files must be nested with in the appRoot\n const relative = path.relative(appRoot, filePath);\n return relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n };\n\n const addFilePath = (filePath: string): boolean => {\n if (!isRouteFile(filePath)) {\n return false;\n }\n\n const route = filePathToRoute(filePath);\n\n // We have already processed this file\n if (staticRoutes.has(route) || dynamicRoutes.has(route)) {\n return false;\n }\n\n const dynamicParams = new Set(\n [...route.matchAll(CAPTURE_DYNAMIC_PARAMS)].map((match) => match[1])\n );\n const isDynamic = dynamicParams.size > 0;\n\n const addRoute = (originalRoute: string, route: string) => {\n if (isDynamic) {\n let set = dynamicRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n dynamicRoutes.set(originalRoute, set);\n }\n\n set.add(\n route\n .replaceAll(CATCH_ALL, '${CatchAllRoutePart<T>}')\n .replaceAll(SLUG, '${SingleRoutePart<T>}')\n );\n } else {\n let set = staticRoutes.get(originalRoute);\n\n if (!set) {\n set = new Set();\n staticRoutes.set(originalRoute, set);\n }\n\n set.add(route);\n }\n };\n\n if (!route.match(ARRAY_GROUP_REGEX)) {\n addRoute(route, route);\n }\n\n // Does this route have a group? eg /(group)\n if (route.includes('/(')) {\n const routeWithoutGroups = route.replace(/\\/\\(.+?\\)/g, '');\n addRoute(route, routeWithoutGroups);\n\n // If there are multiple groups, we need to expand them\n // eg /(test1,test2)/page => /test1/page & /test2/page\n for (const routeWithSingleGroup of extrapolateGroupRoutes(route)) {\n addRoute(route, routeWithSingleGroup);\n }\n }\n\n return true;\n };\n\n return {\n staticRoutes,\n dynamicRoutes,\n filePathToRoute,\n addFilePath,\n isRouteFile,\n };\n}\n\nexport const setToUnionType = <T>(set: Set<T>) => {\n return set.size > 0 ? [...set].map((s) => `\\`${s}\\``).join(' | ') : 'never';\n};\n\n/**\n * Recursively walk a directory and call the callback with the file path.\n */\nasync function walk(directory: string, callback: (filePath: string) => void) {\n const files = await fs.readdir(directory);\n for (const file of files) {\n const p = path.join(directory, file);\n if ((await fs.stat(p)).isDirectory()) {\n await walk(p, callback);\n } else {\n // Normalise the paths so they are easier to convert to URLs\n const normalizedPath = p.replaceAll(path.sep, '/');\n callback(normalizedPath);\n }\n }\n}\n\n/**\n * Given a route, return all possible routes that could be generated from it.\n */\nexport function extrapolateGroupRoutes(\n route: string,\n routes: Set<string> = new Set()\n): Set<string> {\n // Create a version with no groups. We will then need to cleanup double and/or trailing slashes\n routes.add(route.replaceAll(ARRAY_GROUP_REGEX, '').replaceAll(/\\/+/g, '/').replace(/\\/$/, ''));\n\n const match = route.match(ARRAY_GROUP_REGEX);\n\n if (!match) {\n routes.add(route);\n return routes;\n }\n\n const groupsMatch = match[0];\n\n for (const group of groupsMatch.matchAll(CAPTURE_GROUP_REGEX)) {\n extrapolateGroupRoutes(route.replace(groupsMatch, `(${group[1].trim()})`), routes);\n }\n\n return routes;\n}\n\n/**\n * NOTE: This code refers to a specific version of `expo-router` and is therefore unsafe to\n * mix with arbitrary versions.\n * TODO: Version this code with `expo-router` or version expo-router with `@expo/cli`.\n */\nconst routerDotTSTemplate = unsafeTemplate`/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable import/export */\n/* eslint-disable @typescript-eslint/ban-types */\ndeclare module \"expo-router\" {\n import type { LinkProps as OriginalLinkProps } from 'expo-router/build/link/Link';\n import type { Router as OriginalRouter } from 'expo-router/build/types';\n export * from 'expo-router/build';\n\n // prettier-ignore\n type StaticRoutes = ${'staticRoutes'};\n // prettier-ignore\n type DynamicRoutes<T extends string> = ${'dynamicRoutes'};\n // prettier-ignore\n type DynamicRouteTemplate = ${'dynamicRouteParams'};\n\n type RelativePathString = \\`./\\${string}\\` | \\`../\\${string}\\` | '..';\n type AbsoluteRoute = DynamicRouteTemplate | StaticRoutes;\n type ExternalPathString = \\`\\${string}:\\${string}\\`;\n\n type ExpoRouterRoutes = DynamicRouteTemplate | StaticRoutes | RelativePathString;\n export type AllRoutes = ExpoRouterRoutes | ExternalPathString;\n\n /****************\n * Route Utils *\n ****************/\n\n type SearchOrHash = \\`?\\${string}\\` | \\`#\\${string}\\`;\n type UnknownInputParams = Record<string, string | number | (string | number)[]>;\n type UnknownOutputParams = Record<string, string | string[]>;\n\n /**\n * Return only the RoutePart of a string. If the string has multiple parts return never\n *\n * string | type\n * ---------|------\n * 123 | 123\n * /123/abc | never\n * 123?abc | never\n * ./123 | never\n * /123 | never\n * 123/../ | never\n */\n type SingleRoutePart<S extends string> = S extends \\`\\${string}/\\${string}\\`\n ? never\n : S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`(\\${string})\\`\n ? never\n : S extends \\`[\\${string}]\\`\n ? never\n : S;\n\n /**\n * Return only the CatchAll router part. If the string has search parameters or a hash return never\n */\n type CatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\`\n ? never\n : S extends ''\n ? never\n : S extends \\`\\${string}(\\${string})\\${string}\\`\n ? never\n : S extends \\`\\${string}[\\${string}]\\${string}\\`\n ? never\n : S;\n\n // type OptionalCatchAllRoutePart<S extends string> = S extends \\`\\${string}\\${SearchOrHash}\\` ? never : S\n\n /**\n * Return the name of a route parameter\n * '[test]' -> 'test'\n * 'test' -> never\n * '[...test]' -> '...test'\n */\n type IsParameter<Part> = Part extends \\`[\\${infer ParamName}]\\` ? ParamName : never;\n\n /**\n * Return a union of all parameter names. If there are no names return never\n *\n * /[test] -> 'test'\n * /[abc]/[...def] -> 'abc'|'...def'\n */\n type ParameterNames<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? IsParameter<PartA> | ParameterNames<PartB>\n : IsParameter<Path>;\n\n /**\n * Returns all segements of a route.\n *\n * /(group)/123/abc/[id]/[...rest] -> ['(group)', '123', 'abc', '[id]', '[...rest]'\n */\n type RouteSegments<Path> = Path extends \\`\\${infer PartA}/\\${infer PartB}\\`\n ? PartA extends '' | '.'\n ? [...RouteSegments<PartB>]\n : [PartA, ...RouteSegments<PartB>]\n : Path extends ''\n ? []\n : [Path];\n\n /**\n * Returns a Record of the routes parameters as strings and CatchAll parameters\n *\n * There are two versions, input and output, as you can input 'string | number' but\n * the output will always be 'string'\n *\n * /[id]/[...rest] -> { id: string, rest: string[] }\n * /no-params -> {}\n */\n type InputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? (string | number)[] : string | number;\n } & UnknownInputParams;\n\n type OutputRouteParams<Path> = {\n [Key in ParameterNames<Path> as Key extends \\`...\\${infer Name}\\`\n ? Name\n : Key]: Key extends \\`...\\${string}\\` ? string[] : string;\n } & UnknownOutputParams;\n\n /**\n * Returns the search parameters for a route.\n */\n export type SearchParams<T extends AllRoutes> = T extends DynamicRouteTemplate\n ? OutputRouteParams<T>\n : T extends StaticRoutes\n ? never\n : UnknownOutputParams;\n\n /**\n * Route is mostly used as part of Href to ensure that a valid route is provided\n *\n * Given a dynamic route, this will return never. This is helpful for conditional logic\n *\n * /test -> /test, /test2, etc\n * /test/[abc] -> never\n * /test/resolve -> /test, /test2, etc\n *\n * Note that if we provide a value for [abc] then the route is allowed\n *\n * This is named Route to prevent confusion, as users they will often see it in tooltips\n */\n export type Route<T> = T extends string\n ? T extends DynamicRouteTemplate\n ? never\n :\n | StaticRoutes\n | RelativePathString\n | ExternalPathString\n | (T extends \\`\\${infer P}\\${SearchOrHash}\\`\n ? P extends DynamicRoutes<infer _>\n ? T\n : never\n : T extends DynamicRoutes<infer _>\n ? T\n : never)\n : never;\n\n /*********\n * Href *\n *********/\n\n export type Href<T> = T extends Record<'pathname', string> ? HrefObject<T> : Route<T>;\n\n export type HrefObject<\n R extends Record<'pathname', string>,\n P = R['pathname'],\n > = P extends DynamicRouteTemplate\n ? { pathname: P; params: InputRouteParams<P> }\n : P extends Route<P>\n ? { pathname: Route<P> | DynamicRouteTemplate; params?: never | InputRouteParams<never> }\n : never;\n\n /***********************\n * Expo Router Exports *\n ***********************/\n\n export type Router = Omit<OriginalRouter, 'push' | 'replace' | 'setParams'> & {\n /** Navigate to the provided href. */\n push: <T>(href: Href<T>) => void;\n /** Navigate to route without appending to the history. */\n replace: <T>(href: Href<T>) => void;\n /** Update the current route query params. */\n setParams: <T = ''>(params?: T extends '' ? Record<string, string> : InputRouteParams<T>) => void;\n };\n\n /** The imperative router. */\n export const router: Router;\n\n /************\n * <Link /> *\n ************/\n export interface LinkProps<T> extends OriginalLinkProps {\n href: Href<T>;\n }\n\n export interface LinkComponent {\n <T>(props: React.PropsWithChildren<LinkProps<T>>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: <T>(href: Href<T>) => string;\n }\n\n /**\n * Component to render link to another route using a path.\n * Uses an anchor tag on the web.\n *\n * @param props.href Absolute path to route (e.g. \\`/feeds/hot\\`).\n * @param props.replace Should replace the current route without adding to the history.\n * @param props.asChild Forward props to child component. Useful for custom buttons.\n * @param props.children Child elements to render the content.\n * @param props.className On web, this sets the HTML \\`class\\` directly. On native, this can be used with CSS interop tools like Nativewind.\n */\n export const Link: LinkComponent;\n\n /** Redirects to the href as soon as the component is mounted. */\n export const Redirect: <T>(\n props: React.PropsWithChildren<{ href: Href<T> }>\n ) => JSX.Element;\n\n /************\n * Hooks *\n ************/\n export function useRouter(): Router;\n\n export function useLocalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n /** @deprecated renamed to \\`useGlobalSearchParams\\` */\n export function useSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useGlobalSearchParams<\n T extends AllRoutes | UnknownOutputParams = UnknownOutputParams,\n >(): T extends AllRoutes ? SearchParams<T> : T;\n\n export function useSegments<\n T extends AbsoluteRoute | RouteSegments<AbsoluteRoute> | RelativePathString,\n >(): T extends AbsoluteRoute ? RouteSegments<T> : T extends string ? string[] : T;\n}\n`;\n"],"names":["CAPTURE_DYNAMIC_PARAMS","CATCH_ALL","SLUG","ARRAY_GROUP_REGEX","CAPTURE_GROUP_REGEX","TYPED_ROUTES_EXCLUSION_REGEX","setupTypedRoutes","getTemplateString","getTypedRoutesUtils","setToUnionType","extrapolateGroupRoutes","options","typedRoutesModule","resolveFrom","silent","projectRoot","typedRoutes","legacyTypedRoutes","typedRoutesModulePath","server","metro","typesDirectory","routerDirectory","plugin","process","env","EXPO_ROUTER_APP_ROOT","require","metroWatchTypeScriptFiles","eventTypes","callback","getWatchHandler","version","regenerateDeclarations","filePathToRoute","staticRoutes","dynamicRoutes","addFilePath","isRouteFile","filePath","type","shouldRegenerate","route","delete","regenerateRouterDotTS","Set","values","flatMap","v","Array","from","keys","directoryExistsAsync","walk","debounce","fn","delay","timeoutId","args","clearTimeout","setTimeout","apply","typesDir","dynamicRouteTemplates","fs","mkdir","recursive","writeFile","path","resolve","routerDotTSTemplate","dynamicRouteParams","appRoot","filePathSeperator","sep","Map","normalizedFilePath","replaceAll","normalizedAppRoot","replace","match","relative","startsWith","isAbsolute","has","dynamicParams","matchAll","map","isDynamic","size","addRoute","originalRoute","set","get","add","includes","routeWithoutGroups","routeWithSingleGroup","s","join","directory","files","readdir","file","p","stat","isDirectory","normalizedPath","routes","groupsMatch","group","trim","unsafeTemplate"],"mappings":"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"}
|
package/build/src/utils/dir.js
CHANGED
|
@@ -26,9 +26,9 @@ function _fs() {
|
|
|
26
26
|
};
|
|
27
27
|
return data;
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
const data = /*#__PURE__*/ _interopRequireDefault(require("
|
|
31
|
-
|
|
29
|
+
function _path() {
|
|
30
|
+
const data = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
31
|
+
_path = function() {
|
|
32
32
|
return data;
|
|
33
33
|
};
|
|
34
34
|
return data;
|
|
@@ -61,11 +61,36 @@ async function fileExistsAsync(file) {
|
|
|
61
61
|
const ensureDirectoryAsync = (path)=>_fs().default.promises.mkdir(path, {
|
|
62
62
|
recursive: true
|
|
63
63
|
});
|
|
64
|
-
const ensureDirectory = (path)=>
|
|
64
|
+
const ensureDirectory = (path)=>{
|
|
65
|
+
_fs().default.mkdirSync(path, {
|
|
65
66
|
recursive: true
|
|
66
67
|
});
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
const
|
|
68
|
+
};
|
|
69
|
+
const copySync = (src, dest)=>{
|
|
70
|
+
const destParent = _path().default.dirname(dest);
|
|
71
|
+
if (!_fs().default.existsSync(destParent)) ensureDirectory(destParent);
|
|
72
|
+
_fs().default.cpSync(src, dest, {
|
|
73
|
+
recursive: true,
|
|
74
|
+
force: true
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
const copyAsync = async (src, dest)=>{
|
|
78
|
+
const destParent = _path().default.dirname(dest);
|
|
79
|
+
if (!_fs().default.existsSync(destParent)) {
|
|
80
|
+
await _fs().default.promises.mkdir(destParent, {
|
|
81
|
+
recursive: true
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
await _fs().default.promises.cp(src, dest, {
|
|
85
|
+
recursive: true,
|
|
86
|
+
force: true
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
const removeAsync = (path)=>{
|
|
90
|
+
return _fs().default.promises.rm(path, {
|
|
91
|
+
recursive: true,
|
|
92
|
+
force: true
|
|
93
|
+
});
|
|
94
|
+
};
|
|
70
95
|
|
|
71
96
|
//# sourceMappingURL=dir.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/dir.ts"],"sourcesContent":["import fs from 'fs';\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/dir.ts"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\n\nexport function fileExistsSync(file: string): boolean {\n return !!fs\n .statSync(file, {\n throwIfNoEntry: false,\n })\n ?.isFile();\n}\n\nexport function directoryExistsSync(file: string): boolean {\n return !!fs\n .statSync(file, {\n throwIfNoEntry: false,\n })\n ?.isDirectory();\n}\n\nexport async function directoryExistsAsync(file: string): Promise<boolean> {\n return (await fs.promises.stat(file).catch(() => null))?.isDirectory() ?? false;\n}\n\nexport async function fileExistsAsync(file: string): Promise<boolean> {\n return (await fs.promises.stat(file).catch(() => null))?.isFile() ?? false;\n}\n\nexport const ensureDirectoryAsync = (path: string) => fs.promises.mkdir(path, { recursive: true });\n\nexport const ensureDirectory = (path: string): void => {\n fs.mkdirSync(path, {\n recursive: true,\n });\n};\n\nexport const copySync = (src: string, dest: string): void => {\n const destParent = path.dirname(dest);\n if (!fs.existsSync(destParent)) ensureDirectory(destParent);\n fs.cpSync(src, dest, {\n recursive: true,\n force: true,\n });\n};\n\nexport const copyAsync = async (src: string, dest: string): Promise<void> => {\n const destParent = path.dirname(dest);\n if (!fs.existsSync(destParent)) {\n await fs.promises.mkdir(destParent, { recursive: true });\n }\n await fs.promises.cp(src, dest, {\n recursive: true,\n force: true,\n });\n};\n\nexport const removeAsync = (path: string): Promise<void> => {\n return fs.promises.rm(path, {\n recursive: true,\n force: true,\n });\n};\n"],"names":["fileExistsSync","directoryExistsSync","directoryExistsAsync","fileExistsAsync","ensureDirectoryAsync","ensureDirectory","copySync","copyAsync","removeAsync","file","fs","statSync","throwIfNoEntry","isFile","isDirectory","promises","stat","catch","path","mkdir","recursive","mkdirSync","src","dest","destParent","dirname","existsSync","cpSync","force","cp","rm"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "encodeMultipartMixed", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: ()=>encodeMultipartMixed
|
|
8
|
+
});
|
|
9
|
+
function _nodeCrypto() {
|
|
10
|
+
const data = require("node:crypto");
|
|
11
|
+
_nodeCrypto = function() {
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
const CRLF = "\r\n";
|
|
17
|
+
const BOUNDARY_HYPHEN_CHARACTERS = "-".repeat(2);
|
|
18
|
+
const getFormHeader = (boundary, field)=>{
|
|
19
|
+
let header = `${BOUNDARY_HYPHEN_CHARACTERS}${boundary}${CRLF}`;
|
|
20
|
+
header += `Content-Disposition: form-data; name="${field.name}"`;
|
|
21
|
+
if (typeof field.value !== "string") {
|
|
22
|
+
header += `; filename="${field.value.name ?? "blob"}"${CRLF}`;
|
|
23
|
+
header += `Content-Type: ${field.value.type || "application/octet-stream"}`;
|
|
24
|
+
} else if (field.contentType) {
|
|
25
|
+
header += `${CRLF}Content-Type: ${field.contentType}`;
|
|
26
|
+
}
|
|
27
|
+
if (field.partHeaders) {
|
|
28
|
+
for(const headerName in field.partHeaders){
|
|
29
|
+
header += `${CRLF}${headerName}: ${field.partHeaders[headerName]}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return `${header}${CRLF}${CRLF}`;
|
|
33
|
+
};
|
|
34
|
+
const getFormFooter = (boundary)=>`${BOUNDARY_HYPHEN_CHARACTERS}${boundary}${BOUNDARY_HYPHEN_CHARACTERS}${CRLF}${CRLF}`;
|
|
35
|
+
async function encodeMultipartMixed(fields) {
|
|
36
|
+
const boundary = `formdata-${(0, _nodeCrypto().randomBytes)(8).toString("hex")}`;
|
|
37
|
+
let body = "";
|
|
38
|
+
for (const field of fields){
|
|
39
|
+
if (typeof field.value !== "string") {
|
|
40
|
+
body += getFormHeader(boundary, field);
|
|
41
|
+
body += await field.value.text();
|
|
42
|
+
body += CRLF;
|
|
43
|
+
} else {
|
|
44
|
+
body += getFormHeader(boundary, field) + field.value + CRLF;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
body += getFormFooter(boundary);
|
|
48
|
+
return {
|
|
49
|
+
boundary,
|
|
50
|
+
body
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=multipartMixed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/multipartMixed.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\n\nexport interface FormDataField {\n name: string;\n value: string | File | Blob;\n contentType?: string | null;\n partHeaders?: Record<string, string> | null;\n}\n\nexport interface EncodedFormData {\n boundary: string;\n body: string;\n}\n\nconst CRLF = '\\r\\n';\nconst BOUNDARY_HYPHEN_CHARACTERS = '-'.repeat(2);\n\nconst getFormHeader = (boundary: string, field: FormDataField): string => {\n let header = `${BOUNDARY_HYPHEN_CHARACTERS}${boundary}${CRLF}`;\n header += `Content-Disposition: form-data; name=\"${field.name}\"`;\n if (typeof field.value !== 'string') {\n header += `; filename=\"${(field.value as File).name ?? 'blob'}\"${CRLF}`;\n header += `Content-Type: ${field.value.type || 'application/octet-stream'}`;\n } else if (field.contentType) {\n header += `${CRLF}Content-Type: ${field.contentType}`;\n }\n if (field.partHeaders) {\n for (const headerName in field.partHeaders) {\n header += `${CRLF}${headerName}: ${field.partHeaders[headerName]}`;\n }\n }\n return `${header}${CRLF}${CRLF}`;\n};\n\nconst getFormFooter = (boundary: string) =>\n `${BOUNDARY_HYPHEN_CHARACTERS}${boundary}${BOUNDARY_HYPHEN_CHARACTERS}${CRLF}${CRLF}`;\n\nexport async function encodeMultipartMixed(fields: FormDataField[]): Promise<EncodedFormData> {\n const boundary = `formdata-${randomBytes(8).toString('hex')}`;\n let body = '';\n for (const field of fields) {\n if (typeof field.value !== 'string') {\n body += getFormHeader(boundary, field);\n body += await field.value.text();\n body += CRLF;\n } else {\n body += getFormHeader(boundary, field) + field.value + CRLF;\n }\n }\n body += getFormFooter(boundary);\n return { boundary, body };\n}\n"],"names":["encodeMultipartMixed","CRLF","BOUNDARY_HYPHEN_CHARACTERS","repeat","getFormHeader","boundary","field","header","name","value","type","contentType","partHeaders","headerName","getFormFooter","fields","randomBytes","toString","body","text"],"mappings":"AAAA;;;;+BAqCsBA,sBAAoB;;aAApBA,oBAAoB;;;yBArCd,aAAa;;;;;;AAczC,MAAMC,IAAI,GAAG,MAAM,AAAC;AACpB,MAAMC,0BAA0B,GAAG,GAAG,CAACC,MAAM,CAAC,CAAC,CAAC,AAAC;AAEjD,MAAMC,aAAa,GAAG,CAACC,QAAgB,EAAEC,KAAoB,GAAa;IACxE,IAAIC,MAAM,GAAG,CAAC,EAAEL,0BAA0B,CAAC,EAAEG,QAAQ,CAAC,EAAEJ,IAAI,CAAC,CAAC,AAAC;IAC/DM,MAAM,IAAI,CAAC,sCAAsC,EAAED,KAAK,CAACE,IAAI,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,OAAOF,KAAK,CAACG,KAAK,KAAK,QAAQ,EAAE;QACnCF,MAAM,IAAI,CAAC,YAAY,EAAE,AAACD,KAAK,CAACG,KAAK,CAAUD,IAAI,IAAI,MAAM,CAAC,CAAC,EAAEP,IAAI,CAAC,CAAC,CAAC;QACxEM,MAAM,IAAI,CAAC,cAAc,EAAED,KAAK,CAACG,KAAK,CAACC,IAAI,IAAI,0BAA0B,CAAC,CAAC,CAAC;IAC9E,OAAO,IAAIJ,KAAK,CAACK,WAAW,EAAE;QAC5BJ,MAAM,IAAI,CAAC,EAAEN,IAAI,CAAC,cAAc,EAAEK,KAAK,CAACK,WAAW,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,IAAIL,KAAK,CAACM,WAAW,EAAE;QACrB,IAAK,MAAMC,UAAU,IAAIP,KAAK,CAACM,WAAW,CAAE;YAC1CL,MAAM,IAAI,CAAC,EAAEN,IAAI,CAAC,EAAEY,UAAU,CAAC,EAAE,EAAEP,KAAK,CAACM,WAAW,CAACC,UAAU,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IACD,OAAO,CAAC,EAAEN,MAAM,CAAC,EAAEN,IAAI,CAAC,EAAEA,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC,AAAC;AAEF,MAAMa,aAAa,GAAG,CAACT,QAAgB,GACrC,CAAC,EAAEH,0BAA0B,CAAC,EAAEG,QAAQ,CAAC,EAAEH,0BAA0B,CAAC,EAAED,IAAI,CAAC,EAAEA,IAAI,CAAC,CAAC,AAAC;AAEjF,eAAeD,oBAAoB,CAACe,MAAuB,EAA4B;IAC5F,MAAMV,QAAQ,GAAG,CAAC,SAAS,EAAEW,IAAAA,WAAW,EAAA,YAAA,EAAC,CAAC,CAAC,CAACC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,AAAC;IAC9D,IAAIC,IAAI,GAAG,EAAE,AAAC;IACd,KAAK,MAAMZ,KAAK,IAAIS,MAAM,CAAE;QAC1B,IAAI,OAAOT,KAAK,CAACG,KAAK,KAAK,QAAQ,EAAE;YACnCS,IAAI,IAAId,aAAa,CAACC,QAAQ,EAAEC,KAAK,CAAC,CAAC;YACvCY,IAAI,IAAI,MAAMZ,KAAK,CAACG,KAAK,CAACU,IAAI,EAAE,CAAC;YACjCD,IAAI,IAAIjB,IAAI,CAAC;QACf,OAAO;YACLiB,IAAI,IAAId,aAAa,CAACC,QAAQ,EAAEC,KAAK,CAAC,GAAGA,KAAK,CAACG,KAAK,GAAGR,IAAI,CAAC;QAC9D,CAAC;IACH,CAAC;IACDiB,IAAI,IAAIJ,aAAa,CAACT,QAAQ,CAAC,CAAC;IAChC,OAAO;QAAEA,QAAQ;QAAEa,IAAI;KAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -31,7 +31,7 @@ class FetchClient {
|
|
|
31
31
|
this.headers = {
|
|
32
32
|
accept: "application/json",
|
|
33
33
|
"content-type": "application/json",
|
|
34
|
-
"user-agent": `expo-cli/${"1.0.0-canary-
|
|
34
|
+
"user-agent": `expo-cli/${"1.0.0-canary-20250221-ef26fed"}`,
|
|
35
35
|
authorization: "Basic " + _nodeBuffer().Buffer.from(`${target}:`).toString("base64")
|
|
36
36
|
};
|
|
37
37
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expo/cli",
|
|
3
|
-
"version": "1.0.0-canary-
|
|
3
|
+
"version": "1.0.0-canary-20250221-ef26fed",
|
|
4
4
|
"description": "The Expo CLI",
|
|
5
5
|
"main": "build/bin/cli",
|
|
6
6
|
"bin": {
|
|
@@ -42,17 +42,17 @@
|
|
|
42
42
|
"@0no-co/graphql.web": "^1.0.8",
|
|
43
43
|
"@babel/runtime": "^7.20.0",
|
|
44
44
|
"@expo/code-signing-certificates": "^0.0.5",
|
|
45
|
-
"@expo/config": "11.0.0-canary-
|
|
46
|
-
"@expo/config-plugins": "9.0.16-canary-
|
|
45
|
+
"@expo/config": "11.0.0-canary-20250221-ef26fed",
|
|
46
|
+
"@expo/config-plugins": "9.0.16-canary-20250221-ef26fed",
|
|
47
47
|
"@expo/devcert": "^1.1.2",
|
|
48
|
-
"@expo/env": "1.0.1-canary-
|
|
49
|
-
"@expo/image-utils": "0.6.6-canary-
|
|
50
|
-
"@expo/json-file": "9.0.3-canary-
|
|
51
|
-
"@expo/metro-config": "0.20.0-canary-
|
|
52
|
-
"@expo/osascript": "2.1.7-canary-
|
|
53
|
-
"@expo/package-manager": "1.8.0-canary-
|
|
54
|
-
"@expo/plist": "0.2.3-canary-
|
|
55
|
-
"@expo/prebuild-config": "8.0.
|
|
48
|
+
"@expo/env": "1.0.1-canary-20250221-ef26fed",
|
|
49
|
+
"@expo/image-utils": "0.6.6-canary-20250221-ef26fed",
|
|
50
|
+
"@expo/json-file": "9.0.3-canary-20250221-ef26fed",
|
|
51
|
+
"@expo/metro-config": "0.20.0-canary-20250221-ef26fed",
|
|
52
|
+
"@expo/osascript": "2.1.7-canary-20250221-ef26fed",
|
|
53
|
+
"@expo/package-manager": "1.8.0-canary-20250221-ef26fed",
|
|
54
|
+
"@expo/plist": "0.2.3-canary-20250221-ef26fed",
|
|
55
|
+
"@expo/prebuild-config": "8.0.29-canary-20250221-ef26fed",
|
|
56
56
|
"@expo/rudder-sdk-node": "^1.1.1",
|
|
57
57
|
"@expo/spawn-async": "^1.7.2",
|
|
58
58
|
"@expo/ws-tunnel": "^1.0.1",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"accepts": "^1.3.8",
|
|
64
64
|
"arg": "^5.0.2",
|
|
65
65
|
"better-opn": "~3.0.2",
|
|
66
|
-
"bplist-creator": "0.0
|
|
66
|
+
"bplist-creator": "0.1.0",
|
|
67
67
|
"bplist-parser": "^0.3.1",
|
|
68
68
|
"chalk": "^4.0.0",
|
|
69
69
|
"ci-info": "^3.3.0",
|
|
@@ -72,15 +72,10 @@
|
|
|
72
72
|
"debug": "^4.3.4",
|
|
73
73
|
"env-editor": "^0.4.1",
|
|
74
74
|
"fast-glob": "^3.3.2",
|
|
75
|
-
"form-data": "^3.0.1",
|
|
76
75
|
"freeport-async": "^2.0.0",
|
|
77
|
-
"fs-extra": "~8.1.0",
|
|
78
76
|
"getenv": "^1.0.0",
|
|
79
77
|
"glob": "^10.4.2",
|
|
80
78
|
"internal-ip": "6.1.0",
|
|
81
|
-
"is-docker": "^2.0.0",
|
|
82
|
-
"is-wsl": "^2.1.1",
|
|
83
|
-
"lodash.debounce": "^4.0.8",
|
|
84
79
|
"minimatch": "^3.0.4",
|
|
85
80
|
"node-forge": "^1.3.1",
|
|
86
81
|
"npm-package-arg": "^11.0.0",
|
|
@@ -119,7 +114,7 @@
|
|
|
119
114
|
"devDependencies": {
|
|
120
115
|
"@expo/multipart-body-parser": "^1.0.0",
|
|
121
116
|
"@expo/ngrok": "4.1.3",
|
|
122
|
-
"@expo/server": "0.5.2-canary-
|
|
117
|
+
"@expo/server": "0.5.2-canary-20250221-ef26fed",
|
|
123
118
|
"@graphql-codegen/cli": "^2.16.3",
|
|
124
119
|
"@graphql-codegen/typescript": "^2.8.7",
|
|
125
120
|
"@graphql-codegen/typescript-operations": "^2.5.12",
|
|
@@ -133,10 +128,8 @@
|
|
|
133
128
|
"@types/cross-spawn": "^6.0.6",
|
|
134
129
|
"@types/debug": "^4.1.7",
|
|
135
130
|
"@types/execa": "^0.9.0",
|
|
136
|
-
"@types/form-data": "^2.2.0",
|
|
137
131
|
"@types/getenv": "^1.0.0",
|
|
138
132
|
"@types/klaw-sync": "^6.0.0",
|
|
139
|
-
"@types/lodash.debounce": "^4.0.9",
|
|
140
133
|
"@types/minimatch": "^3.0.5",
|
|
141
134
|
"@types/node": "^18.19.34",
|
|
142
135
|
"@types/npm-package-arg": "^6.1.0",
|
|
@@ -153,7 +146,7 @@
|
|
|
153
146
|
"@types/ws": "^8.5.4",
|
|
154
147
|
"devtools-protocol": "^0.0.1113120",
|
|
155
148
|
"expo-atlas": "^0.4.0",
|
|
156
|
-
"expo-module-scripts": "4.0.5-canary-
|
|
149
|
+
"expo-module-scripts": "4.0.5-canary-20250221-ef26fed",
|
|
157
150
|
"find-process": "^1.4.7",
|
|
158
151
|
"jest-runner-tsd": "^6.0.0",
|
|
159
152
|
"klaw-sync": "^6.0.0",
|
|
@@ -165,6 +158,5 @@
|
|
|
165
158
|
"taskr": "^1.1.0",
|
|
166
159
|
"tree-kill": "^1.2.2",
|
|
167
160
|
"tsd": "^0.28.1"
|
|
168
|
-
}
|
|
169
|
-
"gitHead": "4a5daded61d3d8b9d501059039ac74c09c25675b"
|
|
161
|
+
}
|
|
170
162
|
}
|