@expo/cli 1.0.0-canary-20250207-8bc5146 → 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/api/getNativeModuleVersions.js +1 -1
- package/build/src/api/getNativeModuleVersions.js.map +1 -1
- package/build/src/api/rest/cache/FileSystemResponseCache.js +129 -50
- package/build/src/api/rest/cache/FileSystemResponseCache.js.map +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/AsyncWsTunnel.js +47 -12
- package/build/src/start/server/AsyncWsTunnel.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/metro/withMetroMultiPlatform.js +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/DomComponentsMiddleware.js +1 -1
- package/build/src/start/server/middleware/DomComponentsMiddleware.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/middleware/metroOptions.js +1 -1
- package/build/src/start/server/middleware/metroOptions.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/getOrPromptApplicationId.js +18 -19
- package/build/src/utils/getOrPromptApplicationId.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 -25
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"]) {
|
|
@@ -12,7 +12,7 @@ async function getNativeModuleVersionsAsync(sdkVersion) {
|
|
|
12
12
|
const fetchAsync = (0, _client.createCachedFetch)({
|
|
13
13
|
cacheDirectory: "native-modules-cache",
|
|
14
14
|
// 1 minute cache
|
|
15
|
-
ttl: 1000 * 60
|
|
15
|
+
ttl: 1000 * 60
|
|
16
16
|
});
|
|
17
17
|
const response = await fetchAsync(`sdks/${sdkVersion}/native-modules`);
|
|
18
18
|
if (!response.ok) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/api/getNativeModuleVersions.ts"],"sourcesContent":["import { createCachedFetch, getResponseDataOrThrow } from './rest/client';\nimport { CommandError } from '../utils/errors';\n\ninterface NativeModule {\n npmPackage: string;\n versionRange: string;\n}\ntype BundledNativeModuleList = NativeModule[];\n\nexport type BundledNativeModules = Record<string, string>;\n\n/**\n * The endpoint returns the list of bundled native modules for a given SDK version.\n * The data is populated by the `et sync-bundled-native-modules` script from expo/expo repo.\n * See the code for more details:\n * https://github.com/expo/expo/blob/main/tools/src/commands/SyncBundledNativeModules.ts\n *\n * Example result:\n * [\n * {\n * id: \"79285187-e5c4-47f7-b6a9-664f5d16f0db\",\n * sdkVersion: \"41.0.0\",\n * npmPackage: \"expo-camera\",\n * versionRange: \"~10.1.0\",\n * createdAt: \"2021-04-29T09:34:32.825Z\",\n * updatedAt: \"2021-04-29T09:34:32.825Z\"\n * },\n * ...\n * ]\n */\nexport async function getNativeModuleVersionsAsync(\n sdkVersion: string\n): Promise<BundledNativeModules> {\n const fetchAsync = createCachedFetch({\n cacheDirectory: 'native-modules-cache',\n // 1 minute cache\n ttl: 1000 * 60
|
|
1
|
+
{"version":3,"sources":["../../../src/api/getNativeModuleVersions.ts"],"sourcesContent":["import { createCachedFetch, getResponseDataOrThrow } from './rest/client';\nimport { CommandError } from '../utils/errors';\n\ninterface NativeModule {\n npmPackage: string;\n versionRange: string;\n}\ntype BundledNativeModuleList = NativeModule[];\n\nexport type BundledNativeModules = Record<string, string>;\n\n/**\n * The endpoint returns the list of bundled native modules for a given SDK version.\n * The data is populated by the `et sync-bundled-native-modules` script from expo/expo repo.\n * See the code for more details:\n * https://github.com/expo/expo/blob/main/tools/src/commands/SyncBundledNativeModules.ts\n *\n * Example result:\n * [\n * {\n * id: \"79285187-e5c4-47f7-b6a9-664f5d16f0db\",\n * sdkVersion: \"41.0.0\",\n * npmPackage: \"expo-camera\",\n * versionRange: \"~10.1.0\",\n * createdAt: \"2021-04-29T09:34:32.825Z\",\n * updatedAt: \"2021-04-29T09:34:32.825Z\"\n * },\n * ...\n * ]\n */\nexport async function getNativeModuleVersionsAsync(\n sdkVersion: string\n): Promise<BundledNativeModules> {\n const fetchAsync = createCachedFetch({\n cacheDirectory: 'native-modules-cache',\n // 1 minute cache\n ttl: 1000 * 60,\n });\n const response = await fetchAsync(`sdks/${sdkVersion}/native-modules`);\n if (!response.ok) {\n throw new CommandError(\n 'API',\n `Unexpected response when fetching version info from Expo servers: ${response.statusText}.`\n );\n }\n\n const json = await response.json();\n const data = getResponseDataOrThrow<BundledNativeModuleList>(json);\n if (!data.length) {\n throw new CommandError('VERSIONS', 'The bundled native module list from the Expo API is empty');\n }\n return fromBundledNativeModuleList(data);\n}\n\nfunction fromBundledNativeModuleList(list: BundledNativeModuleList): BundledNativeModules {\n return list.reduce((acc, i) => {\n acc[i.npmPackage] = i.versionRange;\n return acc;\n }, {} as BundledNativeModules);\n}\n"],"names":["getNativeModuleVersionsAsync","sdkVersion","fetchAsync","createCachedFetch","cacheDirectory","ttl","response","ok","CommandError","statusText","json","data","getResponseDataOrThrow","length","fromBundledNativeModuleList","list","reduce","acc","i","npmPackage","versionRange"],"mappings":"AAAA;;;;+BA8BsBA,8BAA4B;;aAA5BA,4BAA4B;;wBA9BQ,eAAe;wBAC5C,iBAAiB;AA6BvC,eAAeA,4BAA4B,CAChDC,UAAkB,EACa;IAC/B,MAAMC,UAAU,GAAGC,IAAAA,OAAiB,kBAAA,EAAC;QACnCC,cAAc,EAAE,sBAAsB;QACtC,iBAAiB;QACjBC,GAAG,EAAE,IAAI,GAAG,EAAE;KACf,CAAC,AAAC;IACH,MAAMC,QAAQ,GAAG,MAAMJ,UAAU,CAAC,CAAC,KAAK,EAAED,UAAU,CAAC,eAAe,CAAC,CAAC,AAAC;IACvE,IAAI,CAACK,QAAQ,CAACC,EAAE,EAAE;QAChB,MAAM,IAAIC,OAAY,aAAA,CACpB,KAAK,EACL,CAAC,kEAAkE,EAAEF,QAAQ,CAACG,UAAU,CAAC,CAAC,CAAC,CAC5F,CAAC;IACJ,CAAC;IAED,MAAMC,IAAI,GAAG,MAAMJ,QAAQ,CAACI,IAAI,EAAE,AAAC;IACnC,MAAMC,IAAI,GAAGC,IAAAA,OAAsB,uBAAA,EAA0BF,IAAI,CAAC,AAAC;IACnE,IAAI,CAACC,IAAI,CAACE,MAAM,EAAE;QAChB,MAAM,IAAIL,OAAY,aAAA,CAAC,UAAU,EAAE,2DAA2D,CAAC,CAAC;IAClG,CAAC;IACD,OAAOM,2BAA2B,CAACH,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,SAASG,2BAA2B,CAACC,IAA6B,EAAwB;IACxF,OAAOA,IAAI,CAACC,MAAM,CAAC,CAACC,GAAG,EAAEC,CAAC,GAAK;QAC7BD,GAAG,CAACC,CAAC,CAACC,UAAU,CAAC,GAAGD,CAAC,CAACE,YAAY,CAAC;QACnC,OAAOH,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAyB,CAAC;AACjC,CAAC"}
|
|
@@ -6,58 +6,130 @@ Object.defineProperty(exports, "FileSystemResponseCache", {
|
|
|
6
6
|
enumerable: true,
|
|
7
7
|
get: ()=>FileSystemResponseCache
|
|
8
8
|
});
|
|
9
|
-
function
|
|
10
|
-
const data = /*#__PURE__*/ _interopRequireDefault(require("
|
|
11
|
-
|
|
9
|
+
function _nodeCrypto() {
|
|
10
|
+
const data = /*#__PURE__*/ _interopRequireDefault(require("node:crypto"));
|
|
11
|
+
_nodeCrypto = function() {
|
|
12
12
|
return data;
|
|
13
13
|
};
|
|
14
14
|
return data;
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
const data = require("
|
|
18
|
-
|
|
16
|
+
function _nodeFs() {
|
|
17
|
+
const data = /*#__PURE__*/ _interopRequireDefault(require("node:fs"));
|
|
18
|
+
_nodeFs = function() {
|
|
19
19
|
return data;
|
|
20
20
|
};
|
|
21
21
|
return data;
|
|
22
22
|
}
|
|
23
|
+
function _nodePath() {
|
|
24
|
+
const data = /*#__PURE__*/ _interopRequireDefault(require("node:path"));
|
|
25
|
+
_nodePath = function() {
|
|
26
|
+
return data;
|
|
27
|
+
};
|
|
28
|
+
return data;
|
|
29
|
+
}
|
|
30
|
+
function _nodeStream() {
|
|
31
|
+
const data = /*#__PURE__*/ _interopRequireWildcard(require("node:stream"));
|
|
32
|
+
_nodeStream = function() {
|
|
33
|
+
return data;
|
|
34
|
+
};
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
const _dir = require("../../../utils/dir");
|
|
23
38
|
function _interopRequireDefault(obj) {
|
|
24
39
|
return obj && obj.__esModule ? obj : {
|
|
25
40
|
default: obj
|
|
26
41
|
};
|
|
27
42
|
}
|
|
43
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
44
|
+
if (typeof WeakMap !== "function") return null;
|
|
45
|
+
var cacheBabelInterop = new WeakMap();
|
|
46
|
+
var cacheNodeInterop = new WeakMap();
|
|
47
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
48
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
49
|
+
})(nodeInterop);
|
|
50
|
+
}
|
|
51
|
+
function _interopRequireWildcard(obj, nodeInterop) {
|
|
52
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
53
|
+
return obj;
|
|
54
|
+
}
|
|
55
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
56
|
+
return {
|
|
57
|
+
default: obj
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
61
|
+
if (cache && cache.has(obj)) {
|
|
62
|
+
return cache.get(obj);
|
|
63
|
+
}
|
|
64
|
+
var newObj = {};
|
|
65
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
66
|
+
for(var key in obj){
|
|
67
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
68
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
69
|
+
if (desc && (desc.get || desc.set)) {
|
|
70
|
+
Object.defineProperty(newObj, key, desc);
|
|
71
|
+
} else {
|
|
72
|
+
newObj[key] = obj[key];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
newObj.default = obj;
|
|
77
|
+
if (cache) {
|
|
78
|
+
cache.set(obj, newObj);
|
|
79
|
+
}
|
|
80
|
+
return newObj;
|
|
81
|
+
}
|
|
28
82
|
class FileSystemResponseCache {
|
|
29
83
|
constructor(options){
|
|
30
84
|
this.cacheDirectory = options.cacheDirectory;
|
|
31
85
|
this.timeToLive = options.ttl;
|
|
32
86
|
}
|
|
87
|
+
getFilePaths(cacheKey) {
|
|
88
|
+
// Create a hash of the cache key to use as filename
|
|
89
|
+
const hash = _nodeCrypto().default.createHash("sha256").update(cacheKey).digest("hex");
|
|
90
|
+
return {
|
|
91
|
+
info: _nodePath().default.join(this.cacheDirectory, `${hash}-info.json`),
|
|
92
|
+
body: _nodePath().default.join(this.cacheDirectory, `${hash}-body.bin`)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
33
95
|
/** Retrieve the cache response, if any */ async get(cacheKey) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
// Abort if the response info is not found
|
|
37
|
-
if (!responseInfoMeta) {
|
|
96
|
+
const paths = this.getFilePaths(cacheKey);
|
|
97
|
+
if (!await (0, _dir.fileExistsAsync)(paths.info)) {
|
|
38
98
|
return undefined;
|
|
39
99
|
}
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
100
|
+
// Read and parse the info file
|
|
101
|
+
const infoBuffer = await _nodeFs().default.promises.readFile(paths.info);
|
|
102
|
+
try {
|
|
103
|
+
const responseInfo = JSON.parse(infoBuffer.toString());
|
|
104
|
+
// Check if the response has expired
|
|
105
|
+
if (responseInfo.expiration && responseInfo.expiration < Date.now()) {
|
|
106
|
+
await this.remove(cacheKey);
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
// Remove cache-specific data from the response info
|
|
110
|
+
const { empty , expiration , bodyPath , ...cleanInfo } = responseInfo;
|
|
111
|
+
// Create response body stream
|
|
112
|
+
let responseBody;
|
|
113
|
+
if (empty) {
|
|
114
|
+
responseBody = _nodeStream().Readable.toWeb(_nodeStream().Readable.from(Buffer.alloc(0)));
|
|
115
|
+
} else {
|
|
116
|
+
const bodyBuffer = await _nodeFs().default.promises.readFile(paths.body);
|
|
117
|
+
responseBody = _nodeStream().Readable.toWeb(_nodeStream().Readable.from(bodyBuffer));
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
body: responseBody,
|
|
121
|
+
info: cleanInfo
|
|
122
|
+
};
|
|
123
|
+
} catch {
|
|
124
|
+
// If file doesn't exist or other errors, return undefined
|
|
49
125
|
return undefined;
|
|
50
126
|
}
|
|
51
|
-
// Create a read-stream for the response body
|
|
52
|
-
const responseBody = empty ? _stream().Readable.from(Buffer.alloc(0)) : _stream().Readable.from(_cacache().default.get.stream.byDigest(this.cacheDirectory, bodyIntegrity));
|
|
53
|
-
return {
|
|
54
|
-
body: _stream().Readable.toWeb(responseBody),
|
|
55
|
-
info: responseInfo
|
|
56
|
-
};
|
|
57
127
|
}
|
|
58
128
|
/** Store the response for caching */ async set(cacheKey, response) {
|
|
59
|
-
|
|
60
|
-
|
|
129
|
+
await _nodeFs().default.promises.mkdir(this.cacheDirectory, {
|
|
130
|
+
recursive: true
|
|
131
|
+
});
|
|
132
|
+
const paths = this.getFilePaths(cacheKey);
|
|
61
133
|
// Create a copy of the response info, to add cache-specific data
|
|
62
134
|
const responseInfo = {
|
|
63
135
|
...response.info
|
|
@@ -67,35 +139,42 @@ class FileSystemResponseCache {
|
|
|
67
139
|
responseInfo.expiration = Date.now() + this.timeToLive;
|
|
68
140
|
}
|
|
69
141
|
try {
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
142
|
+
// Clone the response body stream since we need to read it twice
|
|
143
|
+
const [forSize, forWrite] = response.body.tee();
|
|
144
|
+
// Check if the body is empty by reading the first stream
|
|
145
|
+
const reader = forSize.getReader();
|
|
146
|
+
const { value } = await reader.read();
|
|
147
|
+
reader.releaseLock();
|
|
148
|
+
if (!value || value.length === 0) {
|
|
149
|
+
responseInfo.empty = true;
|
|
150
|
+
} else {
|
|
151
|
+
// Create write stream and pipe response body to file
|
|
152
|
+
const writeStream = _nodeFs().default.createWriteStream(paths.body);
|
|
153
|
+
const nodeStream = _nodeStream().Readable.fromWeb(forWrite);
|
|
154
|
+
nodeStream.pipe(writeStream);
|
|
155
|
+
// Wait for the stream to finish
|
|
156
|
+
await _nodeStream().default.promises.finished(writeStream);
|
|
157
|
+
responseInfo.bodyPath = paths.body;
|
|
77
158
|
}
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
159
|
+
// Write info to file
|
|
160
|
+
await _nodeFs().default.promises.writeFile(paths.info, JSON.stringify(responseInfo));
|
|
161
|
+
return await this.get(cacheKey);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
// Clean up any partially written files
|
|
164
|
+
await this.remove(cacheKey);
|
|
165
|
+
throw error;
|
|
81
166
|
}
|
|
82
|
-
// Store the response info
|
|
83
|
-
const responseInfoBuffer = Buffer.from(JSON.stringify(responseInfo));
|
|
84
|
-
await _cacache().default.put(this.cacheDirectory, responseInfoKey, responseInfoBuffer);
|
|
85
|
-
return await this.get(cacheKey);
|
|
86
167
|
}
|
|
87
168
|
/** Remove the response from caching */ async remove(cacheKey) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
_cacache().default.rm.entry(this.cacheDirectory, getResponseBodyKey(cacheKey)),
|
|
91
|
-
]);
|
|
169
|
+
const paths = this.getFilePaths(cacheKey);
|
|
170
|
+
await removeAllAsync(paths.info, paths.body);
|
|
92
171
|
}
|
|
93
172
|
}
|
|
94
|
-
function
|
|
95
|
-
return
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
173
|
+
function removeAllAsync(...paths) {
|
|
174
|
+
return Promise.all(paths.map((path)=>_nodeFs().default.promises.rm(path, {
|
|
175
|
+
recursive: true,
|
|
176
|
+
force: true
|
|
177
|
+
}).catch(()=>{})));
|
|
99
178
|
}
|
|
100
179
|
|
|
101
180
|
//# sourceMappingURL=FileSystemResponseCache.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/api/rest/cache/FileSystemResponseCache.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../../../src/api/rest/cache/FileSystemResponseCache.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport stream, { Readable } from 'node:stream';\nimport { ReadableStream } from 'node:stream/web';\n\nimport type { ResponseCache, ResponseCacheEntry } from './ResponseCache';\nimport { fileExistsAsync } from '../../../utils/dir';\n\ntype FileSystemResponseCacheInfo = ResponseCacheEntry['info'] & {\n /** The path to the cached body file */\n bodyPath?: string;\n /** If there is no response body */\n empty?: boolean;\n /** The expiration time, in milliseconds, when the response should be invalidated */\n expiration?: number;\n};\n\nexport class FileSystemResponseCache implements ResponseCache {\n /** The absolute path to the directory used to store responses */\n private cacheDirectory: string;\n /** Optional auto-expiration for all stored responses */\n private timeToLive?: number;\n\n constructor(options: { cacheDirectory: string; ttl?: number }) {\n this.cacheDirectory = options.cacheDirectory;\n this.timeToLive = options.ttl;\n }\n\n private getFilePaths(cacheKey: string) {\n // Create a hash of the cache key to use as filename\n const hash = crypto.createHash('sha256').update(cacheKey).digest('hex');\n return {\n info: path.join(this.cacheDirectory, `${hash}-info.json`),\n body: path.join(this.cacheDirectory, `${hash}-body.bin`),\n };\n }\n\n /** Retrieve the cache response, if any */\n async get(cacheKey: string): Promise<ResponseCacheEntry | undefined> {\n const paths = this.getFilePaths(cacheKey);\n\n if (!(await fileExistsAsync(paths.info))) {\n return undefined;\n }\n\n // Read and parse the info file\n const infoBuffer = await fs.promises.readFile(paths.info);\n\n try {\n const responseInfo: FileSystemResponseCacheInfo = JSON.parse(infoBuffer.toString());\n\n // Check if the response has expired\n if (responseInfo.expiration && responseInfo.expiration < Date.now()) {\n await this.remove(cacheKey);\n return undefined;\n }\n\n // Remove cache-specific data from the response info\n const { empty, expiration, bodyPath, ...cleanInfo } = responseInfo;\n\n // Create response body stream\n let responseBody: ReadableStream;\n if (empty) {\n responseBody = Readable.toWeb(Readable.from(Buffer.alloc(0)));\n } else {\n const bodyBuffer = await fs.promises.readFile(paths.body);\n responseBody = Readable.toWeb(Readable.from(bodyBuffer));\n }\n\n return {\n body: responseBody,\n info: cleanInfo,\n };\n } catch {\n // If file doesn't exist or other errors, return undefined\n return undefined;\n }\n }\n\n /** Store the response for caching */\n async set(\n cacheKey: string,\n response: ResponseCacheEntry\n ): Promise<ResponseCacheEntry | undefined> {\n await fs.promises.mkdir(this.cacheDirectory, { recursive: true });\n const paths = this.getFilePaths(cacheKey);\n\n // Create a copy of the response info, to add cache-specific data\n const responseInfo: FileSystemResponseCacheInfo = { ...response.info };\n\n // Add expiration time if the \"time to live\" is set\n if (typeof this.timeToLive === 'number') {\n responseInfo.expiration = Date.now() + this.timeToLive;\n }\n\n try {\n // Clone the response body stream since we need to read it twice\n const [forSize, forWrite] = response.body.tee();\n\n // Check if the body is empty by reading the first stream\n const reader = forSize.getReader();\n const { value } = await reader.read();\n reader.releaseLock();\n\n if (!value || value.length === 0) {\n responseInfo.empty = true;\n } else {\n // Create write stream and pipe response body to file\n const writeStream = fs.createWriteStream(paths.body);\n const nodeStream = Readable.fromWeb(forWrite);\n nodeStream.pipe(writeStream);\n\n // Wait for the stream to finish\n await stream.promises.finished(writeStream);\n\n responseInfo.bodyPath = paths.body;\n }\n\n // Write info to file\n await fs.promises.writeFile(paths.info, JSON.stringify(responseInfo));\n\n return await this.get(cacheKey);\n } catch (error) {\n // Clean up any partially written files\n await this.remove(cacheKey);\n throw error;\n }\n }\n\n /** Remove the response from caching */\n async remove(cacheKey: string): Promise<void> {\n const paths = this.getFilePaths(cacheKey);\n await removeAllAsync(paths.info, paths.body);\n }\n}\n\nfunction removeAllAsync(...paths: string[]) {\n return Promise.all(\n paths.map((path) => fs.promises.rm(path, { recursive: true, force: true }).catch(() => {}))\n );\n}\n"],"names":["FileSystemResponseCache","constructor","options","cacheDirectory","timeToLive","ttl","getFilePaths","cacheKey","hash","crypto","createHash","update","digest","info","path","join","body","get","paths","fileExistsAsync","undefined","infoBuffer","fs","promises","readFile","responseInfo","JSON","parse","toString","expiration","Date","now","remove","empty","bodyPath","cleanInfo","responseBody","Readable","toWeb","from","Buffer","alloc","bodyBuffer","set","response","mkdir","recursive","forSize","forWrite","tee","reader","getReader","value","read","releaseLock","length","writeStream","createWriteStream","nodeStream","fromWeb","pipe","stream","finished","writeFile","stringify","error","removeAllAsync","Promise","all","map","rm","force","catch"],"mappings":"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"}
|
|
@@ -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.
|