@expo/cli 0.22.4 → 0.23.0-canary-20241211-61c49bd
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/rest/client.js +1 -8
- package/build/src/api/rest/client.js.map +1 -1
- package/build/src/api/user/UserSettings.js +75 -9
- package/build/src/api/user/UserSettings.js.map +1 -1
- package/build/src/customize/customizeAsync.js +4 -1
- package/build/src/customize/customizeAsync.js.map +1 -1
- package/build/src/customize/templates.js +12 -0
- package/build/src/customize/templates.js.map +1 -1
- package/build/src/prebuild/resolveOptions.js +5 -0
- package/build/src/prebuild/resolveOptions.js.map +1 -1
- package/build/src/run/ios/XcodeBuild.js +35 -12
- package/build/src/run/ios/XcodeBuild.js.map +1 -1
- package/build/src/run/ios/runIosAsync.js +14 -0
- package/build/src/run/ios/runIosAsync.js.map +1 -1
- package/build/src/start/platforms/ios/devicectl.js +2 -8
- package/build/src/start/platforms/ios/devicectl.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +1 -2
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js +13 -3
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/utils/codesigning.js +2 -8
- package/build/src/utils/codesigning.js.map +1 -1
- package/build/src/utils/downloadExpoGoAsync.js +4 -10
- package/build/src/utils/downloadExpoGoAsync.js.map +1 -1
- package/build/src/utils/getAccountUsername.js +22 -0
- package/build/src/utils/getAccountUsername.js.map +1 -0
- package/build/src/utils/getOrPromptApplicationId.js +2 -1
- package/build/src/utils/getOrPromptApplicationId.js.map +1 -1
- package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
- package/build/src/utils/telemetry/utils/context.js +1 -1
- package/package.json +16 -17
- package/static/template/+html.tsx +28 -0
- package/static/template/+native-intent.ts +9 -0
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("0.
|
|
124
|
+
console.log("0.23.0-canary-20241211-61c49bd");
|
|
125
125
|
process.exit(0);
|
|
126
126
|
}
|
|
127
127
|
if (args["--non-interactive"]) {
|
|
@@ -17,13 +17,6 @@ _export(exports, {
|
|
|
17
17
|
createCachedFetch: ()=>createCachedFetch,
|
|
18
18
|
fetchAsync: ()=>fetchAsync
|
|
19
19
|
});
|
|
20
|
-
function _getUserState() {
|
|
21
|
-
const data = require("@expo/config/build/getUserState");
|
|
22
|
-
_getUserState = function() {
|
|
23
|
-
return data;
|
|
24
|
-
};
|
|
25
|
-
return data;
|
|
26
|
-
}
|
|
27
20
|
function _path() {
|
|
28
21
|
const data = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
29
22
|
_path = function() {
|
|
@@ -146,7 +139,7 @@ function createCachedFetch({ fetch =fetchWithCredentials , cacheDirectory , ttl
|
|
|
146
139
|
}
|
|
147
140
|
const { FileSystemResponseCache } = require("./cache/FileSystemResponseCache");
|
|
148
141
|
return (0, _wrapFetchWithCache.wrapFetchWithCache)(fetch, new FileSystemResponseCache({
|
|
149
|
-
cacheDirectory: _path().default.join((0,
|
|
142
|
+
cacheDirectory: _path().default.join((0, _userSettings.getExpoHomeDirectory)(), cacheDirectory),
|
|
150
143
|
ttl
|
|
151
144
|
}));
|
|
152
145
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/api/rest/client.ts"],"sourcesContent":["import { getExpoHomeDirectory } from '@expo/config/build/getUserState';\nimport type { JSONValue } from '@expo/json-file';\nimport path from 'path';\n\nimport { wrapFetchWithCache } from './cache/wrapFetchWithCache';\nimport type { FetchLike } from './client.types';\nimport { wrapFetchWithBaseUrl } from './wrapFetchWithBaseUrl';\nimport { wrapFetchWithOffline } from './wrapFetchWithOffline';\nimport { wrapFetchWithProgress } from './wrapFetchWithProgress';\nimport { wrapFetchWithProxy } from './wrapFetchWithProxy';\nimport { wrapFetchWithUserAgent } from './wrapFetchWithUserAgent';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { fetch } from '../../utils/fetch';\nimport { getExpoApiBaseUrl } from '../endpoint';\nimport { disableNetwork } from '../settings';\nimport { getAccessToken, getSession } from '../user/UserSettings';\n\nexport class ApiV2Error extends Error {\n readonly name = 'ApiV2Error';\n readonly code: string;\n readonly expoApiV2ErrorCode: string;\n readonly expoApiV2ErrorDetails?: JSONValue;\n readonly expoApiV2ErrorServerStack?: string;\n readonly expoApiV2ErrorMetadata?: object;\n\n constructor(response: {\n message: string;\n code: string;\n stack?: string;\n details?: JSONValue;\n metadata?: object;\n }) {\n super(response.message);\n this.code = response.code;\n this.expoApiV2ErrorCode = response.code;\n this.expoApiV2ErrorDetails = response.details;\n this.expoApiV2ErrorServerStack = response.stack;\n this.expoApiV2ErrorMetadata = response.metadata;\n }\n}\n\n/**\n * An Expo server error that didn't return the expected error JSON information.\n * The only 'expected' place for this is in testing, all other cases are bugs with the server.\n */\nexport class UnexpectedServerError extends Error {\n readonly name = 'UnexpectedServerError';\n}\n\n/**\n * An error defining that the server didn't return the expected error JSON information.\n * The only 'expected' place for this is in testing, all other cases are bugs with the client.\n */\nexport class UnexpectedServerData extends Error {\n readonly name = 'UnexpectedServerData';\n}\n\n/** Validate the response json contains `.data` property, or throw an unexpected server data error */\nexport function getResponseDataOrThrow<T = any>(json: unknown): T {\n if (!!json && typeof json === 'object' && 'data' in json) {\n return json.data as T;\n }\n\n throw new UnexpectedServerData(\n !!json && typeof json === 'object' ? JSON.stringify(json) : 'Unknown data received from server.'\n );\n}\n\n/**\n * @returns a `fetch` function that will inject user authentication information and handle errors from the Expo API.\n */\nexport function wrapFetchWithCredentials(fetchFunction: FetchLike): FetchLike {\n return async function fetchWithCredentials(url, options = {}) {\n if (Array.isArray(options.headers)) {\n throw new Error('request headers must be in object form');\n }\n\n const resolvedHeaders = options.headers ?? ({} as any);\n\n const token = getAccessToken();\n if (token) {\n resolvedHeaders.authorization = `Bearer ${token}`;\n } else {\n const sessionSecret = getSession()?.sessionSecret;\n if (sessionSecret) {\n resolvedHeaders['expo-session'] = sessionSecret;\n }\n }\n\n try {\n const response = await fetchFunction(url, {\n ...options,\n headers: resolvedHeaders,\n });\n\n // Handle expected API errors (4xx)\n if (response.status >= 400 && response.status < 500) {\n const body = await response.text();\n try {\n const data = JSON.parse(body);\n if (data?.errors?.length) {\n throw new ApiV2Error(data.errors[0]);\n }\n } catch (error: any) {\n // Server returned non-json response.\n if (error.message.includes('in JSON at position')) {\n throw new UnexpectedServerError(body);\n }\n throw error;\n }\n }\n\n return response;\n } catch (error: any) {\n // When running `expo start`, but wifi or internet has issues\n if (\n isNetworkError(error) || // node-fetch error handling\n ('cause' in error && isNetworkError(error.cause)) // undici error handling\n ) {\n disableNetwork();\n\n throw new CommandError(\n 'OFFLINE',\n 'Network connection is unreliable. Try again with the environment variable `EXPO_OFFLINE=1` to skip network requests.'\n );\n }\n\n throw error;\n }\n };\n}\n\n/**\n * Determine if the provided error is related to a network issue.\n * When this returns true, offline mode should be enabled.\n * - `ENOTFOUND` is thrown when the DNS lookup failed\n * - `UND_ERR_CONNECT_TIMEOUT` is thrown after DNS is resolved, but server can't be reached\n *\n * @see https://nodejs.org/api/errors.html\n * @see https://github.com/nodejs/undici#network-address-family-autoselection\n */\nfunction isNetworkError(error: Error & { code?: string }) {\n return (\n 'code' in error && error.code && ['ENOTFOUND', 'UND_ERR_CONNECT_TIMEOUT'].includes(error.code)\n );\n}\n\nconst fetchWithOffline = wrapFetchWithOffline(wrapFetchWithUserAgent(fetch));\n\nconst fetchWithBaseUrl = wrapFetchWithBaseUrl(fetchWithOffline, getExpoApiBaseUrl() + '/v2/');\n\nconst fetchWithProxy = wrapFetchWithProxy(fetchWithBaseUrl);\n\nconst fetchWithCredentials = wrapFetchWithProgress(wrapFetchWithCredentials(fetchWithProxy));\n\n/**\n * Create an instance of the fully qualified fetch command (auto authentication and api) but with caching in the '~/.expo' directory.\n * Caching is disabled automatically if the EXPO_NO_CACHE or EXPO_BETA environment variables are enabled.\n */\nexport function createCachedFetch({\n fetch = fetchWithCredentials,\n cacheDirectory,\n ttl,\n skipCache,\n}: {\n fetch?: FetchLike;\n cacheDirectory: string;\n ttl?: number;\n skipCache?: boolean;\n}): FetchLike {\n // Disable all caching in EXPO_BETA.\n if (skipCache || env.EXPO_BETA || env.EXPO_NO_CACHE) {\n return fetch;\n }\n\n const { FileSystemResponseCache } =\n require('./cache/FileSystemResponseCache') as typeof import('./cache/FileSystemResponseCache');\n\n return wrapFetchWithCache(\n fetch,\n new FileSystemResponseCache({\n cacheDirectory: path.join(getExpoHomeDirectory(), cacheDirectory),\n ttl,\n })\n );\n}\n\n/** Instance of fetch with automatic base URL pointing to the Expo API, user credential injection, and API error handling. Caching not included. */\nexport const fetchAsync = wrapFetchWithProgress(wrapFetchWithCredentials(fetchWithProxy));\n"],"names":["ApiV2Error","UnexpectedServerError","UnexpectedServerData","getResponseDataOrThrow","wrapFetchWithCredentials","createCachedFetch","fetchAsync","Error","name","constructor","response","message","code","expoApiV2ErrorCode","expoApiV2ErrorDetails","details","expoApiV2ErrorServerStack","stack","expoApiV2ErrorMetadata","metadata","json","data","JSON","stringify","fetchFunction","fetchWithCredentials","url","options","Array","isArray","headers","resolvedHeaders","token","getAccessToken","authorization","getSession","sessionSecret","status","body","text","parse","errors","length","error","includes","isNetworkError","cause","disableNetwork","CommandError","fetchWithOffline","wrapFetchWithOffline","wrapFetchWithUserAgent","fetch","fetchWithBaseUrl","wrapFetchWithBaseUrl","getExpoApiBaseUrl","fetchWithProxy","wrapFetchWithProxy","wrapFetchWithProgress","cacheDirectory","ttl","skipCache","env","EXPO_BETA","EXPO_NO_CACHE","FileSystemResponseCache","require","wrapFetchWithCache","path","join","getExpoHomeDirectory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/api/rest/client.ts"],"sourcesContent":["import type { JSONValue } from '@expo/json-file';\nimport path from 'path';\n\nimport { wrapFetchWithCache } from './cache/wrapFetchWithCache';\nimport type { FetchLike } from './client.types';\nimport { wrapFetchWithBaseUrl } from './wrapFetchWithBaseUrl';\nimport { wrapFetchWithOffline } from './wrapFetchWithOffline';\nimport { wrapFetchWithProgress } from './wrapFetchWithProgress';\nimport { wrapFetchWithProxy } from './wrapFetchWithProxy';\nimport { wrapFetchWithUserAgent } from './wrapFetchWithUserAgent';\nimport { env } from '../../utils/env';\nimport { CommandError } from '../../utils/errors';\nimport { fetch } from '../../utils/fetch';\nimport { getExpoApiBaseUrl } from '../endpoint';\nimport { disableNetwork } from '../settings';\nimport { getAccessToken, getExpoHomeDirectory, getSession } from '../user/UserSettings';\n\nexport class ApiV2Error extends Error {\n readonly name = 'ApiV2Error';\n readonly code: string;\n readonly expoApiV2ErrorCode: string;\n readonly expoApiV2ErrorDetails?: JSONValue;\n readonly expoApiV2ErrorServerStack?: string;\n readonly expoApiV2ErrorMetadata?: object;\n\n constructor(response: {\n message: string;\n code: string;\n stack?: string;\n details?: JSONValue;\n metadata?: object;\n }) {\n super(response.message);\n this.code = response.code;\n this.expoApiV2ErrorCode = response.code;\n this.expoApiV2ErrorDetails = response.details;\n this.expoApiV2ErrorServerStack = response.stack;\n this.expoApiV2ErrorMetadata = response.metadata;\n }\n}\n\n/**\n * An Expo server error that didn't return the expected error JSON information.\n * The only 'expected' place for this is in testing, all other cases are bugs with the server.\n */\nexport class UnexpectedServerError extends Error {\n readonly name = 'UnexpectedServerError';\n}\n\n/**\n * An error defining that the server didn't return the expected error JSON information.\n * The only 'expected' place for this is in testing, all other cases are bugs with the client.\n */\nexport class UnexpectedServerData extends Error {\n readonly name = 'UnexpectedServerData';\n}\n\n/** Validate the response json contains `.data` property, or throw an unexpected server data error */\nexport function getResponseDataOrThrow<T = any>(json: unknown): T {\n if (!!json && typeof json === 'object' && 'data' in json) {\n return json.data as T;\n }\n\n throw new UnexpectedServerData(\n !!json && typeof json === 'object' ? JSON.stringify(json) : 'Unknown data received from server.'\n );\n}\n\n/**\n * @returns a `fetch` function that will inject user authentication information and handle errors from the Expo API.\n */\nexport function wrapFetchWithCredentials(fetchFunction: FetchLike): FetchLike {\n return async function fetchWithCredentials(url, options = {}) {\n if (Array.isArray(options.headers)) {\n throw new Error('request headers must be in object form');\n }\n\n const resolvedHeaders = options.headers ?? ({} as any);\n\n const token = getAccessToken();\n if (token) {\n resolvedHeaders.authorization = `Bearer ${token}`;\n } else {\n const sessionSecret = getSession()?.sessionSecret;\n if (sessionSecret) {\n resolvedHeaders['expo-session'] = sessionSecret;\n }\n }\n\n try {\n const response = await fetchFunction(url, {\n ...options,\n headers: resolvedHeaders,\n });\n\n // Handle expected API errors (4xx)\n if (response.status >= 400 && response.status < 500) {\n const body = await response.text();\n try {\n const data = JSON.parse(body);\n if (data?.errors?.length) {\n throw new ApiV2Error(data.errors[0]);\n }\n } catch (error: any) {\n // Server returned non-json response.\n if (error.message.includes('in JSON at position')) {\n throw new UnexpectedServerError(body);\n }\n throw error;\n }\n }\n\n return response;\n } catch (error: any) {\n // When running `expo start`, but wifi or internet has issues\n if (\n isNetworkError(error) || // node-fetch error handling\n ('cause' in error && isNetworkError(error.cause)) // undici error handling\n ) {\n disableNetwork();\n\n throw new CommandError(\n 'OFFLINE',\n 'Network connection is unreliable. Try again with the environment variable `EXPO_OFFLINE=1` to skip network requests.'\n );\n }\n\n throw error;\n }\n };\n}\n\n/**\n * Determine if the provided error is related to a network issue.\n * When this returns true, offline mode should be enabled.\n * - `ENOTFOUND` is thrown when the DNS lookup failed\n * - `UND_ERR_CONNECT_TIMEOUT` is thrown after DNS is resolved, but server can't be reached\n *\n * @see https://nodejs.org/api/errors.html\n * @see https://github.com/nodejs/undici#network-address-family-autoselection\n */\nfunction isNetworkError(error: Error & { code?: string }) {\n return (\n 'code' in error && error.code && ['ENOTFOUND', 'UND_ERR_CONNECT_TIMEOUT'].includes(error.code)\n );\n}\n\nconst fetchWithOffline = wrapFetchWithOffline(wrapFetchWithUserAgent(fetch));\n\nconst fetchWithBaseUrl = wrapFetchWithBaseUrl(fetchWithOffline, getExpoApiBaseUrl() + '/v2/');\n\nconst fetchWithProxy = wrapFetchWithProxy(fetchWithBaseUrl);\n\nconst fetchWithCredentials = wrapFetchWithProgress(wrapFetchWithCredentials(fetchWithProxy));\n\n/**\n * Create an instance of the fully qualified fetch command (auto authentication and api) but with caching in the '~/.expo' directory.\n * Caching is disabled automatically if the EXPO_NO_CACHE or EXPO_BETA environment variables are enabled.\n */\nexport function createCachedFetch({\n fetch = fetchWithCredentials,\n cacheDirectory,\n ttl,\n skipCache,\n}: {\n fetch?: FetchLike;\n cacheDirectory: string;\n ttl?: number;\n skipCache?: boolean;\n}): FetchLike {\n // Disable all caching in EXPO_BETA.\n if (skipCache || env.EXPO_BETA || env.EXPO_NO_CACHE) {\n return fetch;\n }\n\n const { FileSystemResponseCache } =\n require('./cache/FileSystemResponseCache') as typeof import('./cache/FileSystemResponseCache');\n\n return wrapFetchWithCache(\n fetch,\n new FileSystemResponseCache({\n cacheDirectory: path.join(getExpoHomeDirectory(), cacheDirectory),\n ttl,\n })\n );\n}\n\n/** Instance of fetch with automatic base URL pointing to the Expo API, user credential injection, and API error handling. Caching not included. */\nexport const fetchAsync = wrapFetchWithProgress(wrapFetchWithCredentials(fetchWithProxy));\n"],"names":["ApiV2Error","UnexpectedServerError","UnexpectedServerData","getResponseDataOrThrow","wrapFetchWithCredentials","createCachedFetch","fetchAsync","Error","name","constructor","response","message","code","expoApiV2ErrorCode","expoApiV2ErrorDetails","details","expoApiV2ErrorServerStack","stack","expoApiV2ErrorMetadata","metadata","json","data","JSON","stringify","fetchFunction","fetchWithCredentials","url","options","Array","isArray","headers","resolvedHeaders","token","getAccessToken","authorization","getSession","sessionSecret","status","body","text","parse","errors","length","error","includes","isNetworkError","cause","disableNetwork","CommandError","fetchWithOffline","wrapFetchWithOffline","wrapFetchWithUserAgent","fetch","fetchWithBaseUrl","wrapFetchWithBaseUrl","getExpoApiBaseUrl","fetchWithProxy","wrapFetchWithProxy","wrapFetchWithProgress","cacheDirectory","ttl","skipCache","env","EXPO_BETA","EXPO_NO_CACHE","FileSystemResponseCache","require","wrapFetchWithCache","path","join","getExpoHomeDirectory"],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
+
getExpoHomeDirectory: ()=>getExpoHomeDirectory,
|
|
12
13
|
getSettingsDirectory: ()=>getSettingsDirectory,
|
|
13
14
|
getSettingsFilePath: ()=>getSettingsFilePath,
|
|
14
15
|
getSettings: ()=>getSettings,
|
|
@@ -19,13 +20,6 @@ _export(exports, {
|
|
|
19
20
|
getAnonymousIdAsync: ()=>getAnonymousIdAsync,
|
|
20
21
|
getAnonymousId: ()=>getAnonymousId
|
|
21
22
|
});
|
|
22
|
-
function _getUserState() {
|
|
23
|
-
const data = require("@expo/config/build/getUserState");
|
|
24
|
-
_getUserState = function() {
|
|
25
|
-
return data;
|
|
26
|
-
};
|
|
27
|
-
return data;
|
|
28
|
-
}
|
|
29
23
|
function _jsonFile() {
|
|
30
24
|
const data = /*#__PURE__*/ _interopRequireDefault(require("@expo/json-file"));
|
|
31
25
|
_jsonFile = function() {
|
|
@@ -40,21 +34,93 @@ function _crypto() {
|
|
|
40
34
|
};
|
|
41
35
|
return data;
|
|
42
36
|
}
|
|
37
|
+
function _getenv() {
|
|
38
|
+
const data = require("getenv");
|
|
39
|
+
_getenv = function() {
|
|
40
|
+
return data;
|
|
41
|
+
};
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
function _os() {
|
|
45
|
+
const data = require("os");
|
|
46
|
+
_os = function() {
|
|
47
|
+
return data;
|
|
48
|
+
};
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
function _path() {
|
|
52
|
+
const data = /*#__PURE__*/ _interopRequireWildcard(require("path"));
|
|
53
|
+
_path = function() {
|
|
54
|
+
return data;
|
|
55
|
+
};
|
|
56
|
+
return data;
|
|
57
|
+
}
|
|
43
58
|
function _interopRequireDefault(obj) {
|
|
44
59
|
return obj && obj.__esModule ? obj : {
|
|
45
60
|
default: obj
|
|
46
61
|
};
|
|
47
62
|
}
|
|
63
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
64
|
+
if (typeof WeakMap !== "function") return null;
|
|
65
|
+
var cacheBabelInterop = new WeakMap();
|
|
66
|
+
var cacheNodeInterop = new WeakMap();
|
|
67
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
68
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
69
|
+
})(nodeInterop);
|
|
70
|
+
}
|
|
71
|
+
function _interopRequireWildcard(obj, nodeInterop) {
|
|
72
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
73
|
+
return obj;
|
|
74
|
+
}
|
|
75
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
76
|
+
return {
|
|
77
|
+
default: obj
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
81
|
+
if (cache && cache.has(obj)) {
|
|
82
|
+
return cache.get(obj);
|
|
83
|
+
}
|
|
84
|
+
var newObj = {};
|
|
85
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
86
|
+
for(var key in obj){
|
|
87
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
88
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
89
|
+
if (desc && (desc.get || desc.set)) {
|
|
90
|
+
Object.defineProperty(newObj, key, desc);
|
|
91
|
+
} else {
|
|
92
|
+
newObj[key] = obj[key];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
newObj.default = obj;
|
|
97
|
+
if (cache) {
|
|
98
|
+
cache.set(obj, newObj);
|
|
99
|
+
}
|
|
100
|
+
return newObj;
|
|
101
|
+
}
|
|
102
|
+
function getExpoHomeDirectory() {
|
|
103
|
+
const home = (0, _os().homedir)();
|
|
104
|
+
if (process.env.__UNSAFE_EXPO_HOME_DIRECTORY) {
|
|
105
|
+
return process.env.__UNSAFE_EXPO_HOME_DIRECTORY;
|
|
106
|
+
} else if ((0, _getenv().boolish)("EXPO_STAGING", false)) {
|
|
107
|
+
return _path().join(home, ".expo-staging");
|
|
108
|
+
} else if ((0, _getenv().boolish)("EXPO_LOCAL", false)) {
|
|
109
|
+
return _path().join(home, ".expo-local");
|
|
110
|
+
}
|
|
111
|
+
return _path().join(home, ".expo");
|
|
112
|
+
}
|
|
48
113
|
function getSettingsDirectory() {
|
|
49
|
-
return
|
|
114
|
+
return getExpoHomeDirectory();
|
|
50
115
|
}
|
|
51
116
|
function getSettingsFilePath() {
|
|
52
|
-
return (
|
|
117
|
+
return _path().join(getExpoHomeDirectory(), "state.json");
|
|
53
118
|
}
|
|
54
119
|
function getSettings() {
|
|
55
120
|
return new (_jsonFile()).default(getSettingsFilePath(), {
|
|
56
121
|
ensureDir: true,
|
|
57
122
|
jsonParseErrorDefault: {},
|
|
123
|
+
// This will ensure that an error isn't thrown if the file doesn't exist.
|
|
58
124
|
cantReadFileDefault: {}
|
|
59
125
|
});
|
|
60
126
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/api/user/UserSettings.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../../../../src/api/user/UserSettings.ts"],"sourcesContent":["import JsonFile from '@expo/json-file';\nimport crypto from 'crypto';\nimport { boolish } from 'getenv';\nimport { homedir } from 'os';\nimport * as path from 'path';\n\ntype SessionData = {\n sessionSecret?: string;\n userId?: string;\n username?: string;\n currentConnection?: 'Username-Password-Authentication' | 'Browser-Flow-Authentication';\n};\n\nexport type UserSettingsData = {\n auth?: SessionData | null;\n ignoreBundledBinaries?: string[];\n PATH?: string;\n /** Last development code signing ID used for `npx expo run:ios`. */\n developmentCodeSigningId?: string;\n /** Unique user ID which is generated anonymously and can be cleared locally. */\n uuid?: string;\n};\n\n// The ~/.expo directory is used to store authentication sessions,\n// which are shared between EAS CLI and Expo CLI.\nexport function getExpoHomeDirectory() {\n const home = homedir();\n\n if (process.env.__UNSAFE_EXPO_HOME_DIRECTORY) {\n return process.env.__UNSAFE_EXPO_HOME_DIRECTORY;\n } else if (boolish('EXPO_STAGING', false)) {\n return path.join(home, '.expo-staging');\n } else if (boolish('EXPO_LOCAL', false)) {\n return path.join(home, '.expo-local');\n }\n return path.join(home, '.expo');\n}\n\n/** Return the user cache directory. */\nexport function getSettingsDirectory() {\n return getExpoHomeDirectory();\n}\n\n/** Return the file path of the settings file */\nexport function getSettingsFilePath(): string {\n return path.join(getExpoHomeDirectory(), 'state.json');\n}\n\n/** Get a new JsonFile instance pointed towards the settings file */\nexport function getSettings(): JsonFile<UserSettingsData> {\n return new JsonFile<UserSettingsData>(getSettingsFilePath(), {\n ensureDir: true,\n jsonParseErrorDefault: {},\n // This will ensure that an error isn't thrown if the file doesn't exist.\n cantReadFileDefault: {},\n });\n}\n\nexport function getAccessToken(): string | null {\n return process.env.EXPO_TOKEN ?? null;\n}\n\nexport function getSession() {\n return getSettings().get('auth', null);\n}\n\nexport async function setSessionAsync(sessionData?: SessionData) {\n await getSettings().setAsync('auth', sessionData, {\n default: {},\n ensureDir: true,\n });\n}\n\n/**\n * Check if there are credentials available, without fetching the user information.\n * This can be used as a faster check to see if users are authenticated.\n * Note, this isn't checking the validity of the credentials.\n */\nexport function hasCredentials() {\n return !!getAccessToken() || !!getSession();\n}\n\n/**\n * Get an anonymous and randomly generated identifier.\n * This is used to group telemetry event by unknown actor,\n * and cannot be used to identify a single user.\n */\nexport async function getAnonymousIdAsync(): Promise<string> {\n const settings = getSettings();\n let id = await settings.getAsync('uuid', null);\n\n if (!id) {\n id = crypto.randomUUID();\n await settings.setAsync('uuid', id);\n }\n\n return id;\n}\n\n/**\n * Get an anonymous and randomly generated identifier.\n * This is used to group telemetry event by unknown actor,\n * and cannot be used to identify a single user.\n */\nexport function getAnonymousId(): string {\n const settings = getSettings();\n let id = settings.get('uuid', null);\n\n if (!id) {\n id = crypto.randomUUID();\n settings.set('uuid', id);\n }\n\n return id;\n}\n"],"names":["getExpoHomeDirectory","getSettingsDirectory","getSettingsFilePath","getSettings","getAccessToken","getSession","setSessionAsync","hasCredentials","getAnonymousIdAsync","getAnonymousId","home","homedir","process","env","__UNSAFE_EXPO_HOME_DIRECTORY","boolish","path","join","JsonFile","ensureDir","jsonParseErrorDefault","cantReadFileDefault","EXPO_TOKEN","get","sessionData","setAsync","default","settings","id","getAsync","crypto","randomUUID","set"],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ function _config() {
|
|
|
14
14
|
return data;
|
|
15
15
|
}
|
|
16
16
|
const _generate = require("./generate");
|
|
17
|
+
const _router = require("../start/server/metro/router");
|
|
17
18
|
const _platformBundlers = require("../start/server/platformBundlers");
|
|
18
19
|
const _findUp = require("../utils/findUp");
|
|
19
20
|
const _nodeEnv = require("../utils/nodeEnv");
|
|
@@ -29,10 +30,12 @@ async function customizeAsync(files, options, extras) {
|
|
|
29
30
|
const { exp } = (0, _config().getConfig)(projectRoot, {
|
|
30
31
|
skipSDKVersionRequirement: true
|
|
31
32
|
});
|
|
33
|
+
const routerRoot = (0, _router.getRouterDirectoryModuleIdWithManifest)(projectRoot, exp);
|
|
32
34
|
// Create the destination resolution props which are used in both
|
|
33
35
|
// the query and select functions.
|
|
34
36
|
const props = {
|
|
35
|
-
webStaticPath: ((ref = exp.web) == null ? void 0 : ref.staticPath) ?? (0, _platformBundlers.getPlatformBundlers)(projectRoot, exp).web === "webpack" ? "web" : "public"
|
|
37
|
+
webStaticPath: ((ref = exp.web) == null ? void 0 : ref.staticPath) ?? (0, _platformBundlers.getPlatformBundlers)(projectRoot, exp).web === "webpack" ? "web" : "public",
|
|
38
|
+
appDirPath: routerRoot
|
|
36
39
|
};
|
|
37
40
|
// If the user provided files, we'll generate them without prompting.
|
|
38
41
|
if (files.length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/customize/customizeAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\n\nimport { queryAndGenerateAsync, selectAndGenerateAsync } from './generate';\nimport { Options } from './resolveOptions';\nimport { DestinationResolutionProps } from './templates';\nimport { getPlatformBundlers } from '../start/server/platformBundlers';\nimport { findUpProjectRootOrAssert } from '../utils/findUp';\nimport { setNodeEnv } from '../utils/nodeEnv';\n\nexport async function customizeAsync(files: string[], options: Options, extras: any[]) {\n setNodeEnv('development');\n // Locate the project root based on the process current working directory.\n // This enables users to run `npx expo customize` from a subdirectory of the project.\n const projectRoot = findUpProjectRootOrAssert(process.cwd());\n\n require('@expo/env').load(projectRoot);\n\n // Get the static path (defaults to 'web/')\n // Doesn't matter if expo is installed or which mode is used.\n const { exp } = getConfig(projectRoot, {\n skipSDKVersionRequirement: true,\n });\n\n // Create the destination resolution props which are used in both\n // the query and select functions.\n const props: DestinationResolutionProps = {\n webStaticPath:\n (exp.web?.staticPath ?? getPlatformBundlers(projectRoot, exp).web === 'webpack')\n ? 'web'\n : 'public',\n };\n\n // If the user provided files, we'll generate them without prompting.\n if (files.length) {\n return queryAndGenerateAsync(projectRoot, {\n files,\n props,\n extras,\n });\n }\n\n // Otherwise, we'll prompt the user to select which files to generate.\n await selectAndGenerateAsync(projectRoot, {\n props,\n extras,\n });\n}\n"],"names":["customizeAsync","files","options","extras","exp","setNodeEnv","projectRoot","findUpProjectRootOrAssert","process","cwd","require","load","getConfig","skipSDKVersionRequirement","props","webStaticPath","web","staticPath","getPlatformBundlers","length","queryAndGenerateAsync","selectAndGenerateAsync"],"mappings":"AAAA;;;;+
|
|
1
|
+
{"version":3,"sources":["../../../src/customize/customizeAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\n\nimport { queryAndGenerateAsync, selectAndGenerateAsync } from './generate';\nimport { Options } from './resolveOptions';\nimport { DestinationResolutionProps } from './templates';\nimport { getRouterDirectoryModuleIdWithManifest } from '../start/server/metro/router';\nimport { getPlatformBundlers } from '../start/server/platformBundlers';\nimport { findUpProjectRootOrAssert } from '../utils/findUp';\nimport { setNodeEnv } from '../utils/nodeEnv';\n\nexport async function customizeAsync(files: string[], options: Options, extras: any[]) {\n setNodeEnv('development');\n // Locate the project root based on the process current working directory.\n // This enables users to run `npx expo customize` from a subdirectory of the project.\n const projectRoot = findUpProjectRootOrAssert(process.cwd());\n\n require('@expo/env').load(projectRoot);\n\n // Get the static path (defaults to 'web/')\n // Doesn't matter if expo is installed or which mode is used.\n const { exp } = getConfig(projectRoot, {\n skipSDKVersionRequirement: true,\n });\n\n const routerRoot = getRouterDirectoryModuleIdWithManifest(projectRoot, exp);\n\n // Create the destination resolution props which are used in both\n // the query and select functions.\n const props: DestinationResolutionProps = {\n webStaticPath:\n (exp.web?.staticPath ?? getPlatformBundlers(projectRoot, exp).web === 'webpack')\n ? 'web'\n : 'public',\n appDirPath: routerRoot,\n };\n\n // If the user provided files, we'll generate them without prompting.\n if (files.length) {\n return queryAndGenerateAsync(projectRoot, {\n files,\n props,\n extras,\n });\n }\n\n // Otherwise, we'll prompt the user to select which files to generate.\n await selectAndGenerateAsync(projectRoot, {\n props,\n extras,\n });\n}\n"],"names":["customizeAsync","files","options","extras","exp","setNodeEnv","projectRoot","findUpProjectRootOrAssert","process","cwd","require","load","getConfig","skipSDKVersionRequirement","routerRoot","getRouterDirectoryModuleIdWithManifest","props","webStaticPath","web","staticPath","getPlatformBundlers","appDirPath","length","queryAndGenerateAsync","selectAndGenerateAsync"],"mappings":"AAAA;;;;+BAUsBA,gBAAc;;aAAdA,cAAc;;;yBAVV,cAAc;;;;;;0BAEsB,YAAY;wBAGnB,8BAA8B;kCACjD,kCAAkC;wBAC5B,iBAAiB;yBAChC,kBAAkB;AAEtC,eAAeA,cAAc,CAACC,KAAe,EAAEC,OAAgB,EAAEC,MAAa,EAAE;QAoBhFC,GAAO;IAnBZC,IAAAA,QAAU,WAAA,EAAC,aAAa,CAAC,CAAC;IAC1B,0EAA0E;IAC1E,qFAAqF;IACrF,MAAMC,WAAW,GAAGC,IAAAA,OAAyB,0BAAA,EAACC,OAAO,CAACC,GAAG,EAAE,CAAC,AAAC;IAE7DC,OAAO,CAAC,WAAW,CAAC,CAACC,IAAI,CAACL,WAAW,CAAC,CAAC;IAEvC,2CAA2C;IAC3C,6DAA6D;IAC7D,MAAM,EAAEF,GAAG,CAAA,EAAE,GAAGQ,IAAAA,OAAS,EAAA,UAAA,EAACN,WAAW,EAAE;QACrCO,yBAAyB,EAAE,IAAI;KAChC,CAAC,AAAC;IAEH,MAAMC,UAAU,GAAGC,IAAAA,OAAsC,uCAAA,EAACT,WAAW,EAAEF,GAAG,CAAC,AAAC;IAE5E,iEAAiE;IACjE,kCAAkC;IAClC,MAAMY,KAAK,GAA+B;QACxCC,aAAa,EACX,AAACb,CAAAA,CAAAA,GAAO,GAAPA,GAAG,CAACc,GAAG,SAAY,GAAnBd,KAAAA,CAAmB,GAAnBA,GAAO,CAAEe,UAAU,CAAA,IAAIC,IAAAA,iBAAmB,oBAAA,EAACd,WAAW,EAAEF,GAAG,CAAC,CAACc,GAAG,KAAK,SAAS,GAC3E,KAAK,GACL,QAAQ;QACdG,UAAU,EAAEP,UAAU;KACvB,AAAC;IAEF,qEAAqE;IACrE,IAAIb,KAAK,CAACqB,MAAM,EAAE;QAChB,OAAOC,IAAAA,SAAqB,sBAAA,EAACjB,WAAW,EAAE;YACxCL,KAAK;YACLe,KAAK;YACLb,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,sEAAsE;IACtE,MAAMqB,IAAAA,SAAsB,uBAAA,EAAClB,WAAW,EAAE;QACxCU,KAAK;QACLb,MAAM;KACP,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -127,6 +127,18 @@ const TEMPLATES = [
|
|
|
127
127
|
dependencies: [
|
|
128
128
|
"@expo/webpack-config"
|
|
129
129
|
]
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: "+html.tsx",
|
|
133
|
+
file: (projectRoot)=>importFromVendor(projectRoot, "+html.tsx"),
|
|
134
|
+
destination: ({ appDirPath })=>_path().default.join(appDirPath, "+html.tsx"),
|
|
135
|
+
dependencies: []
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
id: "+native-intent.ts",
|
|
139
|
+
file: (projectRoot)=>importFromVendor(projectRoot, "+native-intent.ts"),
|
|
140
|
+
destination: ({ appDirPath })=>_path().default.join(appDirPath, "+native-intent.ts"),
|
|
141
|
+
dependencies: []
|
|
130
142
|
},
|
|
131
143
|
];
|
|
132
144
|
/** Generate the prompt choices. */ function createChoices(projectRoot, props) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/customize/templates.ts"],"sourcesContent":["import chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport prompt, { ExpoChoice } from '../utils/prompts';\n\nconst debug = require('debug')('expo:customize:templates');\n\nexport type DestinationResolutionProps = {\n /** Web 'public' folder path (defaults to `/web`). This technically can be changed but shouldn't be. */\n webStaticPath: string;\n};\n\nfunction importFromExpoWebpackConfig(projectRoot: string, folder: string, moduleId: string) {\n try {\n const filePath = resolveFrom(projectRoot, `@expo/webpack-config/${folder}/${moduleId}`);\n debug(`Using @expo/webpack-config template for \"${moduleId}\": ${filePath}`);\n return filePath;\n } catch {\n debug(`@expo/webpack-config template for \"${moduleId}\" not found, falling back on @expo/cli`);\n }\n return importFromVendor(projectRoot, moduleId);\n}\n\nfunction importFromVendor(projectRoot: string, moduleId: string) {\n try {\n const filePath = resolveFrom(projectRoot, '@expo/cli/static/template/' + moduleId);\n debug(`Using @expo/cli template for \"${moduleId}\": ${filePath}`);\n return filePath;\n } catch {\n // For dev mode, testing and other cases where @expo/cli is not installed\n const filePath = require.resolve(`@expo/cli/static/template/${moduleId}`);\n debug(\n `Local @expo/cli template for \"${moduleId}\" not found, falling back on template relative to @expo/cli: ${filePath}`\n );\n\n return filePath;\n }\n}\n\nexport const TEMPLATES: {\n /** Unique ID for easily indexing. */\n id: string;\n /** Template file path to copy into the project. */\n file: (projectRoot: string) => string;\n /** Output location for the file in the user project. */\n destination: (props: DestinationResolutionProps) => string;\n /** List of dependencies to install in the project. These are used inside of the template file. */\n dependencies: string[];\n\n /** Custom step for configuring the file. Return true to exit early. */\n configureAsync?: (projectRoot: string) => Promise<boolean>;\n}[] = [\n {\n id: 'babel.config.js',\n file: (projectRoot) => importFromVendor(projectRoot, 'babel.config.js'),\n destination: () => 'babel.config.js',\n dependencies: [\n // Even though this is installed in `expo`, we should add it for now.\n 'babel-preset-expo',\n ],\n },\n {\n id: 'metro.config.js',\n dependencies: ['@expo/metro-config'],\n destination: () => 'metro.config.js',\n file: (projectRoot) => importFromVendor(projectRoot, 'metro.config.js'),\n },\n {\n // `tsconfig.json` is special-cased and doesn't follow the template.\n id: 'tsconfig.json',\n dependencies: [],\n destination: () => 'tsconfig.json',\n file: () => '',\n configureAsync: async (projectRoot) => {\n const { typescript } = require('./typescript') as typeof import('./typescript');\n await typescript(projectRoot);\n return true;\n },\n },\n {\n id: '.eslintrc.js',\n dependencies: [],\n destination: () => '.eslintrc.js',\n file: (projectRoot) => importFromVendor(projectRoot, '.eslintrc.js'),\n configureAsync: async (projectRoot) => {\n const { ESLintProjectPrerequisite } =\n require('../lint/ESlintPrerequisite') as typeof import('../lint/ESlintPrerequisite.js');\n const prerequisite = new ESLintProjectPrerequisite(projectRoot);\n if (!(await prerequisite.assertAsync())) {\n await prerequisite.bootstrapAsync();\n }\n return false;\n },\n },\n {\n id: 'index.html',\n file: (projectRoot) => importFromExpoWebpackConfig(projectRoot, 'web-default', 'index.html'),\n // web/index.html\n destination: ({ webStaticPath }) => webStaticPath + '/index.html',\n dependencies: [],\n },\n {\n id: 'webpack.config.js',\n file: (projectRoot) =>\n importFromExpoWebpackConfig(projectRoot, 'template', 'webpack.config.js'),\n destination: () => 'webpack.config.js',\n dependencies: ['@expo/webpack-config'],\n },\n];\n\n/** Generate the prompt choices. */\nfunction createChoices(\n projectRoot: string,\n props: DestinationResolutionProps\n): ExpoChoice<number>[] {\n return TEMPLATES.map((template, index) => {\n const destination = template.destination(props);\n const localProjectFile = path.resolve(projectRoot, destination);\n const exists = fs.existsSync(localProjectFile);\n\n return {\n title: destination,\n value: index,\n description: exists ? chalk.red('This will overwrite the existing file') : undefined,\n };\n });\n}\n\n/** Prompt to select templates to add. */\nexport async function selectTemplatesAsync(projectRoot: string, props: DestinationResolutionProps) {\n const options = createChoices(projectRoot, props);\n\n const { answer } = await prompt({\n type: 'multiselect',\n name: 'answer',\n message: 'Which files would you like to generate?',\n hint: '- Space to select. Return to submit',\n warn: 'File already exists.',\n limit: options.length,\n instructions: '',\n choices: options,\n });\n return answer;\n}\n"],"names":["TEMPLATES","selectTemplatesAsync","debug","require","importFromExpoWebpackConfig","projectRoot","folder","moduleId","filePath","resolveFrom","importFromVendor","resolve","id","file","destination","dependencies","configureAsync","typescript","ESLintProjectPrerequisite","prerequisite","assertAsync","bootstrapAsync","webStaticPath","createChoices","props","map","template","index","localProjectFile","path","exists","fs","existsSync","title","value","description","chalk","red","undefined","options","answer","prompt","type","name","message","hint","warn","limit","length","instructions","choices"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/customize/templates.ts"],"sourcesContent":["import chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\nimport resolveFrom from 'resolve-from';\n\nimport prompt, { ExpoChoice } from '../utils/prompts';\n\nconst debug = require('debug')('expo:customize:templates');\n\nexport type DestinationResolutionProps = {\n /** Web 'public' folder path (defaults to `/web`). This technically can be changed but shouldn't be. */\n webStaticPath: string;\n /** The Expo Router app directory. */\n appDirPath: string;\n};\n\nfunction importFromExpoWebpackConfig(projectRoot: string, folder: string, moduleId: string) {\n try {\n const filePath = resolveFrom(projectRoot, `@expo/webpack-config/${folder}/${moduleId}`);\n debug(`Using @expo/webpack-config template for \"${moduleId}\": ${filePath}`);\n return filePath;\n } catch {\n debug(`@expo/webpack-config template for \"${moduleId}\" not found, falling back on @expo/cli`);\n }\n return importFromVendor(projectRoot, moduleId);\n}\n\nfunction importFromVendor(projectRoot: string, moduleId: string) {\n try {\n const filePath = resolveFrom(projectRoot, '@expo/cli/static/template/' + moduleId);\n debug(`Using @expo/cli template for \"${moduleId}\": ${filePath}`);\n return filePath;\n } catch {\n // For dev mode, testing and other cases where @expo/cli is not installed\n const filePath = require.resolve(`@expo/cli/static/template/${moduleId}`);\n debug(\n `Local @expo/cli template for \"${moduleId}\" not found, falling back on template relative to @expo/cli: ${filePath}`\n );\n\n return filePath;\n }\n}\n\nexport const TEMPLATES: {\n /** Unique ID for easily indexing. */\n id: string;\n /** Template file path to copy into the project. */\n file: (projectRoot: string) => string;\n /** Output location for the file in the user project. */\n destination: (props: DestinationResolutionProps) => string;\n /** List of dependencies to install in the project. These are used inside of the template file. */\n dependencies: string[];\n\n /** Custom step for configuring the file. Return true to exit early. */\n configureAsync?: (projectRoot: string) => Promise<boolean>;\n}[] = [\n {\n id: 'babel.config.js',\n file: (projectRoot) => importFromVendor(projectRoot, 'babel.config.js'),\n destination: () => 'babel.config.js',\n dependencies: [\n // Even though this is installed in `expo`, we should add it for now.\n 'babel-preset-expo',\n ],\n },\n {\n id: 'metro.config.js',\n dependencies: ['@expo/metro-config'],\n destination: () => 'metro.config.js',\n file: (projectRoot) => importFromVendor(projectRoot, 'metro.config.js'),\n },\n {\n // `tsconfig.json` is special-cased and doesn't follow the template.\n id: 'tsconfig.json',\n dependencies: [],\n destination: () => 'tsconfig.json',\n file: () => '',\n configureAsync: async (projectRoot) => {\n const { typescript } = require('./typescript') as typeof import('./typescript');\n await typescript(projectRoot);\n return true;\n },\n },\n {\n id: '.eslintrc.js',\n dependencies: [],\n destination: () => '.eslintrc.js',\n file: (projectRoot) => importFromVendor(projectRoot, '.eslintrc.js'),\n configureAsync: async (projectRoot) => {\n const { ESLintProjectPrerequisite } =\n require('../lint/ESlintPrerequisite') as typeof import('../lint/ESlintPrerequisite.js');\n const prerequisite = new ESLintProjectPrerequisite(projectRoot);\n if (!(await prerequisite.assertAsync())) {\n await prerequisite.bootstrapAsync();\n }\n return false;\n },\n },\n {\n id: 'index.html',\n file: (projectRoot) => importFromExpoWebpackConfig(projectRoot, 'web-default', 'index.html'),\n // web/index.html\n destination: ({ webStaticPath }) => webStaticPath + '/index.html',\n dependencies: [],\n },\n {\n id: 'webpack.config.js',\n file: (projectRoot) =>\n importFromExpoWebpackConfig(projectRoot, 'template', 'webpack.config.js'),\n destination: () => 'webpack.config.js',\n dependencies: ['@expo/webpack-config'],\n },\n {\n id: '+html.tsx',\n file: (projectRoot) => importFromVendor(projectRoot, '+html.tsx'),\n destination: ({ appDirPath }) => path.join(appDirPath, '+html.tsx'),\n dependencies: [],\n },\n {\n id: '+native-intent.ts',\n file: (projectRoot) => importFromVendor(projectRoot, '+native-intent.ts'),\n destination: ({ appDirPath }) => path.join(appDirPath, '+native-intent.ts'),\n dependencies: [],\n },\n];\n\n/** Generate the prompt choices. */\nfunction createChoices(\n projectRoot: string,\n props: DestinationResolutionProps\n): ExpoChoice<number>[] {\n return TEMPLATES.map((template, index) => {\n const destination = template.destination(props);\n const localProjectFile = path.resolve(projectRoot, destination);\n const exists = fs.existsSync(localProjectFile);\n\n return {\n title: destination,\n value: index,\n description: exists ? chalk.red('This will overwrite the existing file') : undefined,\n };\n });\n}\n\n/** Prompt to select templates to add. */\nexport async function selectTemplatesAsync(projectRoot: string, props: DestinationResolutionProps) {\n const options = createChoices(projectRoot, props);\n\n const { answer } = await prompt({\n type: 'multiselect',\n name: 'answer',\n message: 'Which files would you like to generate?',\n hint: '- Space to select. Return to submit',\n warn: 'File already exists.',\n limit: options.length,\n instructions: '',\n choices: options,\n });\n return answer;\n}\n"],"names":["TEMPLATES","selectTemplatesAsync","debug","require","importFromExpoWebpackConfig","projectRoot","folder","moduleId","filePath","resolveFrom","importFromVendor","resolve","id","file","destination","dependencies","configureAsync","typescript","ESLintProjectPrerequisite","prerequisite","assertAsync","bootstrapAsync","webStaticPath","appDirPath","path","join","createChoices","props","map","template","index","localProjectFile","exists","fs","existsSync","title","value","description","chalk","red","undefined","options","answer","prompt","type","name","message","hint","warn","limit","length","instructions","choices"],"mappings":"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"}
|
|
@@ -112,6 +112,11 @@ function resolvePackageManagerOptions(args) {
|
|
|
112
112
|
}
|
|
113
113
|
function resolveTemplateOption(template) {
|
|
114
114
|
(0, _assert().default)(template, "template is required");
|
|
115
|
+
if (// Expands github shorthand (owner/repo) to full URLs
|
|
116
|
+
template.includes("/") && !(template.startsWith("@") || template.startsWith(".") || template.startsWith(_path().default.sep) || // Contains a protocol
|
|
117
|
+
/^[a-z][-a-z0-9\\.\\+]*:/.test(template))) {
|
|
118
|
+
template = `https://github.com/${template}`;
|
|
119
|
+
}
|
|
115
120
|
if (template.startsWith("https://") || template.startsWith("http://")) {
|
|
116
121
|
if (!(0, _url.validateUrl)(template)) {
|
|
117
122
|
throw new _errors.CommandError("BAD_ARGS", "Invalid URL provided as a template");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/prebuild/resolveOptions.ts"],"sourcesContent":["import { ModPlatform } from '@expo/config-plugins';\nimport assert from 'assert';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport * as Log from '../log';\nimport { CommandError } from '../utils/errors';\nimport { validateUrl } from '../utils/url';\n\nconst debug = require('debug')('expo:prebuild:resolveOptions') as typeof console.log;\n\nexport interface ResolvedTemplateOption {\n type: 'file' | 'npm' | 'repository';\n uri: string;\n}\n\nexport function resolvePackageManagerOptions(args: any) {\n const managers: Record<string, boolean> = {\n npm: args['--npm'],\n yarn: args['--yarn'],\n pnpm: args['--pnpm'],\n bun: args['--bun'],\n };\n\n if (\n [managers.npm, managers.pnpm, managers.yarn, managers.bun, !!args['--no-install']].filter(\n Boolean\n ).length > 1\n ) {\n throw new CommandError(\n 'BAD_ARGS',\n 'Specify at most one of: --no-install, --npm, --pnpm, --yarn, --bun'\n );\n }\n\n return managers;\n}\n\n/** Resolves a template option as a URL or file path pointing to a tar file. */\nexport function resolveTemplateOption(template: string): ResolvedTemplateOption {\n assert(template, 'template is required');\n\n if (template.startsWith('https://') || template.startsWith('http://')) {\n if (!validateUrl(template)) {\n throw new CommandError('BAD_ARGS', 'Invalid URL provided as a template');\n }\n debug('Resolved template to repository path:', template);\n return { type: 'repository', uri: template };\n }\n\n if (\n // Supports `file:./path/to/template.tgz`\n template.startsWith('file:') ||\n // Supports `../path/to/template.tgz`\n template.startsWith('.') ||\n // Supports `\\\\path\\\\to\\\\template.tgz`\n template.startsWith(path.sep)\n ) {\n let resolvedUri = template;\n if (resolvedUri.startsWith('file:')) {\n resolvedUri = resolvedUri.substring(5);\n }\n const templatePath = path.resolve(resolvedUri);\n assert(fs.existsSync(templatePath), 'template file does not exist: ' + templatePath);\n assert(\n fs.statSync(templatePath).isFile(),\n 'template must be a tar file created by running `npm pack` in a project: ' + templatePath\n );\n\n debug(`Resolved template to file path:`, templatePath);\n return { type: 'file', uri: templatePath };\n }\n\n if (fs.existsSync(template)) {\n // Backward compatible with the old local template argument, e.g. `--template dir/template.tgz`\n const templatePath = path.resolve(template);\n debug(`Resolved template to file path:`, templatePath);\n return { type: 'file', uri: templatePath };\n }\n\n debug(`Resolved template to NPM package:`, template);\n return { type: 'npm', uri: template };\n}\n\n/** Resolves dependencies to skip from a string joined by `,`. Example: `react-native,expo,lodash` */\nexport function resolveSkipDependencyUpdate(value: any) {\n if (!value || typeof value !== 'string') {\n return [];\n }\n return value.split(',');\n}\n\n/** Returns an array of platforms based on the input platform identifier and runtime constraints. */\nexport function resolvePlatformOption(\n platform: string = 'all',\n { loose }: { loose?: boolean } = {}\n): ModPlatform[] {\n switch (platform) {\n case 'ios':\n return ['ios'];\n case 'android':\n return ['android'];\n case 'all':\n return loose || process.platform !== 'win32' ? ['android', 'ios'] : ['android'];\n default:\n return [platform as ModPlatform];\n }\n}\n\n/** Warns and filters out unsupported platforms based on the runtime constraints. Essentially this means no iOS on Windows devices. */\nexport function ensureValidPlatforms(platforms: ModPlatform[]): ModPlatform[] {\n // Skip prebuild for iOS on Windows\n if (process.platform === 'win32' && platforms.includes('ios')) {\n Log.warn(\n chalk`⚠️ Skipping generating the iOS native project files. Run {bold npx expo prebuild} again from macOS or Linux to generate the iOS project.\\n`\n );\n return platforms.filter((platform) => platform !== 'ios');\n }\n return platforms;\n}\n\n/** Asserts platform length must be greater than zero. */\nexport function assertPlatforms(platforms: ModPlatform[]) {\n if (!platforms?.length) {\n throw new CommandError('At least one platform must be enabled when syncing');\n }\n}\n"],"names":["resolvePackageManagerOptions","resolveTemplateOption","resolveSkipDependencyUpdate","resolvePlatformOption","ensureValidPlatforms","assertPlatforms","debug","require","args","managers","npm","yarn","pnpm","bun","filter","Boolean","length","CommandError","template","assert","startsWith","
|
|
1
|
+
{"version":3,"sources":["../../../src/prebuild/resolveOptions.ts"],"sourcesContent":["import { ModPlatform } from '@expo/config-plugins';\nimport assert from 'assert';\nimport chalk from 'chalk';\nimport fs from 'fs';\nimport path from 'path';\n\nimport * as Log from '../log';\nimport { CommandError } from '../utils/errors';\nimport { validateUrl } from '../utils/url';\n\nconst debug = require('debug')('expo:prebuild:resolveOptions') as typeof console.log;\n\nexport interface ResolvedTemplateOption {\n type: 'file' | 'npm' | 'repository';\n uri: string;\n}\n\nexport function resolvePackageManagerOptions(args: any) {\n const managers: Record<string, boolean> = {\n npm: args['--npm'],\n yarn: args['--yarn'],\n pnpm: args['--pnpm'],\n bun: args['--bun'],\n };\n\n if (\n [managers.npm, managers.pnpm, managers.yarn, managers.bun, !!args['--no-install']].filter(\n Boolean\n ).length > 1\n ) {\n throw new CommandError(\n 'BAD_ARGS',\n 'Specify at most one of: --no-install, --npm, --pnpm, --yarn, --bun'\n );\n }\n\n return managers;\n}\n\n/** Resolves a template option as a URL or file path pointing to a tar file. */\nexport function resolveTemplateOption(template: string): ResolvedTemplateOption {\n assert(template, 'template is required');\n\n if (\n // Expands github shorthand (owner/repo) to full URLs\n template.includes('/') &&\n !(\n template.startsWith('@') || // Scoped package\n template.startsWith('.') || // Relative path\n template.startsWith(path.sep) || // Absolute path\n // Contains a protocol\n /^[a-z][-a-z0-9\\\\.\\\\+]*:/.test(template)\n )\n ) {\n template = `https://github.com/${template}`;\n }\n\n if (template.startsWith('https://') || template.startsWith('http://')) {\n if (!validateUrl(template)) {\n throw new CommandError('BAD_ARGS', 'Invalid URL provided as a template');\n }\n debug('Resolved template to repository path:', template);\n return { type: 'repository', uri: template };\n }\n\n if (\n // Supports `file:./path/to/template.tgz`\n template.startsWith('file:') ||\n // Supports `../path/to/template.tgz`\n template.startsWith('.') ||\n // Supports `\\\\path\\\\to\\\\template.tgz`\n template.startsWith(path.sep)\n ) {\n let resolvedUri = template;\n if (resolvedUri.startsWith('file:')) {\n resolvedUri = resolvedUri.substring(5);\n }\n const templatePath = path.resolve(resolvedUri);\n assert(fs.existsSync(templatePath), 'template file does not exist: ' + templatePath);\n assert(\n fs.statSync(templatePath).isFile(),\n 'template must be a tar file created by running `npm pack` in a project: ' + templatePath\n );\n\n debug(`Resolved template to file path:`, templatePath);\n return { type: 'file', uri: templatePath };\n }\n\n if (fs.existsSync(template)) {\n // Backward compatible with the old local template argument, e.g. `--template dir/template.tgz`\n const templatePath = path.resolve(template);\n debug(`Resolved template to file path:`, templatePath);\n return { type: 'file', uri: templatePath };\n }\n\n debug(`Resolved template to NPM package:`, template);\n return { type: 'npm', uri: template };\n}\n\n/** Resolves dependencies to skip from a string joined by `,`. Example: `react-native,expo,lodash` */\nexport function resolveSkipDependencyUpdate(value: any) {\n if (!value || typeof value !== 'string') {\n return [];\n }\n return value.split(',');\n}\n\n/** Returns an array of platforms based on the input platform identifier and runtime constraints. */\nexport function resolvePlatformOption(\n platform: string = 'all',\n { loose }: { loose?: boolean } = {}\n): ModPlatform[] {\n switch (platform) {\n case 'ios':\n return ['ios'];\n case 'android':\n return ['android'];\n case 'all':\n return loose || process.platform !== 'win32' ? ['android', 'ios'] : ['android'];\n default:\n return [platform as ModPlatform];\n }\n}\n\n/** Warns and filters out unsupported platforms based on the runtime constraints. Essentially this means no iOS on Windows devices. */\nexport function ensureValidPlatforms(platforms: ModPlatform[]): ModPlatform[] {\n // Skip prebuild for iOS on Windows\n if (process.platform === 'win32' && platforms.includes('ios')) {\n Log.warn(\n chalk`⚠️ Skipping generating the iOS native project files. Run {bold npx expo prebuild} again from macOS or Linux to generate the iOS project.\\n`\n );\n return platforms.filter((platform) => platform !== 'ios');\n }\n return platforms;\n}\n\n/** Asserts platform length must be greater than zero. */\nexport function assertPlatforms(platforms: ModPlatform[]) {\n if (!platforms?.length) {\n throw new CommandError('At least one platform must be enabled when syncing');\n }\n}\n"],"names":["resolvePackageManagerOptions","resolveTemplateOption","resolveSkipDependencyUpdate","resolvePlatformOption","ensureValidPlatforms","assertPlatforms","debug","require","args","managers","npm","yarn","pnpm","bun","filter","Boolean","length","CommandError","template","assert","includes","startsWith","path","sep","test","validateUrl","type","uri","resolvedUri","substring","templatePath","resolve","fs","existsSync","statSync","isFile","value","split","platform","loose","process","platforms","Log","warn","chalk"],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ function _export(target, all) {
|
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
12
|
logPrettyItem: ()=>logPrettyItem,
|
|
13
|
+
matchEstimatedBinaryPath: ()=>matchEstimatedBinaryPath,
|
|
13
14
|
getAppBinaryPath: ()=>getAppBinaryPath,
|
|
14
15
|
getEscapedPath: ()=>getEscapedPath,
|
|
15
16
|
extractEnvVariableFromBuild: ()=>extractEnvVariableFromBuild,
|
|
@@ -114,21 +115,43 @@ function _interopRequireWildcard(obj, nodeInterop) {
|
|
|
114
115
|
function logPrettyItem(message) {
|
|
115
116
|
_log.log((0, _chalk().default)`{whiteBright \u203A} ${message}`);
|
|
116
117
|
}
|
|
118
|
+
function matchEstimatedBinaryPath(buildOutput) {
|
|
119
|
+
// Match the full path that contains `/(.*)/Developer/Xcode/DerivedData/(.*)/Build/Products/(.*)/(.*).app`
|
|
120
|
+
const appBinaryPathMatch = buildOutput.match(/(\/(?:\\\s|[^ ])+\/Developer\/Xcode\/DerivedData\/(?:\\\s|[^ ])+\/Build\/Products\/(?:Debug|Release)-(?:[^\s/]+)\/(?:\\\s|[^ ])+\.app)/);
|
|
121
|
+
if (!(appBinaryPathMatch == null ? void 0 : appBinaryPathMatch.length)) {
|
|
122
|
+
throw new _errors.CommandError("XCODE_BUILD", `Malformed xcodebuild results: app binary path was not generated in build output. Please report this issue and run your project with Xcode instead.`);
|
|
123
|
+
} else {
|
|
124
|
+
// Sort for the shortest
|
|
125
|
+
const shortestPath = appBinaryPathMatch.filter((a)=>typeof a === "string" && a).sort((a, b)=>a.length - b.length)[0].trim();
|
|
126
|
+
_log.debug(`Found app binary path: ${shortestPath}`);
|
|
127
|
+
return shortestPath;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
117
130
|
function getAppBinaryPath(buildOutput) {
|
|
118
131
|
// Matches what's used in "Bundle React Native code and images" script.
|
|
119
132
|
// Requires that `-hideShellScriptEnvironment` is not included in the build command (extra logs).
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
try {
|
|
134
|
+
// Like `\=/Users/evanbacon/Library/Developer/Xcode/DerivedData/Exponent-anpuosnglkxokahjhfszejloqfvo/Build/Products/Debug-iphonesimulator`
|
|
135
|
+
const CONFIGURATION_BUILD_DIR = extractEnvVariableFromBuild(buildOutput, "CONFIGURATION_BUILD_DIR").sort(// Longer name means more suffixes, we want the shortest possible one to be first.
|
|
136
|
+
// Massive projects (like Expo Go) can sometimes print multiple different sets of environment variables.
|
|
137
|
+
// This can become an issue with some
|
|
138
|
+
(a, b)=>a.length - b.length);
|
|
139
|
+
// Like `Exponent.app`
|
|
140
|
+
const UNLOCALIZED_RESOURCES_FOLDER_PATH = extractEnvVariableFromBuild(buildOutput, "UNLOCALIZED_RESOURCES_FOLDER_PATH");
|
|
141
|
+
const binaryPath = _path().default.join(// Use the shortest defined env variable (usually there's just one).
|
|
142
|
+
CONFIGURATION_BUILD_DIR[0], // Use the last defined env variable.
|
|
143
|
+
UNLOCALIZED_RESOURCES_FOLDER_PATH[UNLOCALIZED_RESOURCES_FOLDER_PATH.length - 1]);
|
|
144
|
+
// If the app has a space in the name it'll fail because it isn't escaped properly by Xcode.
|
|
145
|
+
return getEscapedPath(binaryPath);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (error instanceof _errors.CommandError && error.code === "XCODE_BUILD") {
|
|
148
|
+
const possiblePath = matchEstimatedBinaryPath(buildOutput);
|
|
149
|
+
if (possiblePath) {
|
|
150
|
+
return possiblePath;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
132
155
|
}
|
|
133
156
|
function getEscapedPath(filePath) {
|
|
134
157
|
if (_fs().default.existsSync(filePath)) {
|