@expo/cli 55.0.0-canary-20251127-587bc53 → 55.0.0-canary-20251205-a1dedc6
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/add-module.js +4 -1
- package/build/bin/cli +1 -1
- package/build/src/export/embed/exportEmbedAsync.js +17 -13
- package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
- package/build/src/export/exportApp.js +0 -1
- package/build/src/export/exportApp.js.map +1 -1
- package/build/src/prebuild/resolveLocalTemplate.js +34 -2
- package/build/src/prebuild/resolveLocalTemplate.js.map +1 -1
- package/build/src/run/ios/options/promptDevice.js.map +1 -1
- package/build/src/run/ios/options/resolveDevice.js +1 -3
- package/build/src/run/ios/options/resolveDevice.js.map +1 -1
- package/build/src/start/server/MCP.js +13 -1
- package/build/src/start/server/MCP.js.map +1 -1
- package/build/src/start/server/getStaticRenderFunctions.js +0 -2
- package/build/src/start/server/getStaticRenderFunctions.js.map +1 -1
- package/build/src/start/server/metro/MetroBundlerDevServer.js +10 -15
- package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
- package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
- package/build/src/start/server/metro/createServerRouteMiddleware.js.map +1 -1
- package/build/src/start/server/metro/debugging/MessageHandler.js +0 -2
- package/build/src/start/server/metro/debugging/MessageHandler.js.map +1 -1
- package/build/src/start/server/metro/debugging/pageIsSupported.js +0 -1
- package/build/src/start/server/metro/debugging/pageIsSupported.js.map +1 -1
- package/build/src/start/server/metro/externals.js +1 -2
- package/build/src/start/server/metro/externals.js.map +1 -1
- package/build/src/start/server/metro/fetchRouterManifest.js +2 -3
- package/build/src/start/server/metro/fetchRouterManifest.js.map +1 -1
- package/build/src/start/server/metro/instantiateMetro.js +9 -11
- package/build/src/start/server/metro/instantiateMetro.js.map +1 -1
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js +0 -1
- package/build/src/start/server/metro/withMetroErrorReportingResolver.js.map +1 -1
- package/build/src/start/server/metro/withMetroMultiPlatform.js +12 -16
- package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
- package/build/src/start/server/middleware/DataLoaderModuleMiddleware.js.map +1 -1
- package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js +0 -1
- package/build/src/start/server/middleware/createBuiltinAPIRequestHandler.js.map +1 -1
- package/build/src/start/server/middleware/metroOptions.js +19 -4
- package/build/src/start/server/middleware/metroOptions.js.map +1 -1
- package/build/src/start/server/platformBundlers.js +0 -2
- package/build/src/start/server/platformBundlers.js.map +1 -1
- package/build/src/start/server/serverLogLikeMetro.js +18 -18
- package/build/src/start/server/serverLogLikeMetro.js.map +1 -1
- package/build/src/start/server/webpack/WebpackBundlerDevServer.js +2 -2
- package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
- package/build/src/start/startAsync.js +5 -5
- package/build/src/start/startAsync.js.map +1 -1
- package/build/src/utils/downloadExpoGoAsync.js +0 -1
- package/build/src/utils/downloadExpoGoAsync.js.map +1 -1
- package/build/src/utils/errors.js.map +1 -1
- package/build/src/utils/exit.js +1 -2
- package/build/src/utils/exit.js.map +1 -1
- package/build/src/utils/nodeEnv.js +0 -1
- package/build/src/utils/nodeEnv.js.map +1 -1
- package/build/src/utils/npm.js +31 -0
- package/build/src/utils/npm.js.map +1 -1
- package/build/src/utils/plist.js +0 -1
- package/build/src/utils/plist.js.map +1 -1
- package/build/src/utils/progress.js +3 -4
- package/build/src/utils/progress.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 +21 -20
|
@@ -117,10 +117,20 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
117
117
|
return newObj;
|
|
118
118
|
}
|
|
119
119
|
const debug = require('debug')('expo:metro:logger');
|
|
120
|
+
const CONSOLE_METHODS = [
|
|
121
|
+
'trace',
|
|
122
|
+
'info',
|
|
123
|
+
'error',
|
|
124
|
+
'warn',
|
|
125
|
+
'log',
|
|
126
|
+
'group',
|
|
127
|
+
'groupCollapsed',
|
|
128
|
+
'groupEnd',
|
|
129
|
+
'debug'
|
|
130
|
+
];
|
|
120
131
|
const groupStack = [];
|
|
121
132
|
let collapsedGuardTimer;
|
|
122
133
|
function logLikeMetro(originalLogFunction, level, platform, ...data) {
|
|
123
|
-
// @ts-expect-error
|
|
124
134
|
const logFunction = console[level] && level !== 'trace' ? level : 'log';
|
|
125
135
|
const color = level === 'error' ? _chalk().default.inverse.red : level === 'warn' ? _chalk().default.inverse.yellow : _chalk().default.inverse.white;
|
|
126
136
|
if (level === 'group') {
|
|
@@ -203,7 +213,6 @@ function parseErrorStringToObject(errorString) {
|
|
|
203
213
|
}
|
|
204
214
|
function augmentLogsInternal(projectRoot) {
|
|
205
215
|
const augmentLog = (name, fn)=>{
|
|
206
|
-
// @ts-expect-error: TypeScript doesn't know about polyfilled functions.
|
|
207
216
|
if (fn.__polyfilled) {
|
|
208
217
|
return fn;
|
|
209
218
|
}
|
|
@@ -224,16 +233,18 @@ function augmentLogsInternal(projectRoot) {
|
|
|
224
233
|
try {
|
|
225
234
|
const parsedStack = (0, _LogBoxSymbolication.parseErrorStack)(customStack);
|
|
226
235
|
const symbolicatedStack = parsedStack.map((line)=>{
|
|
236
|
+
// TODO(@kitten): Is there overlap here with metro-source-map?
|
|
227
237
|
const mapped = (0, _sourcemapsupport().mapSourcePosition)({
|
|
238
|
+
// TODO(@kitten): Check if these non-null casts are correct and cannot fail
|
|
228
239
|
source: line.file,
|
|
229
240
|
line: line.lineNumber,
|
|
230
241
|
column: line.column
|
|
231
242
|
});
|
|
232
243
|
const fallbackName = mapped.name ?? '<unknown>';
|
|
233
244
|
return {
|
|
234
|
-
file: mapped.source,
|
|
235
|
-
lineNumber: mapped.line,
|
|
236
|
-
column: mapped.column,
|
|
245
|
+
file: mapped.source ?? null,
|
|
246
|
+
lineNumber: mapped.line ?? null,
|
|
247
|
+
column: mapped.column ?? null,
|
|
237
248
|
// Attempt to preserve the react component name if possible.
|
|
238
249
|
methodName: line.methodName ? line.methodName === '<unknown>' ? fallbackName : line.methodName : fallbackName,
|
|
239
250
|
arguments: line.arguments ?? []
|
|
@@ -257,20 +268,9 @@ function augmentLogsInternal(projectRoot) {
|
|
|
257
268
|
logWithStack.__polyfilled = true;
|
|
258
269
|
return logWithStack;
|
|
259
270
|
};
|
|
260
|
-
|
|
261
|
-
'trace',
|
|
262
|
-
'info',
|
|
263
|
-
'error',
|
|
264
|
-
'warn',
|
|
265
|
-
'log',
|
|
266
|
-
'group',
|
|
267
|
-
'groupCollapsed',
|
|
268
|
-
'groupEnd',
|
|
269
|
-
'debug'
|
|
270
|
-
].forEach((name)=>{
|
|
271
|
-
// @ts-expect-error
|
|
271
|
+
for (const name of CONSOLE_METHODS){
|
|
272
272
|
console[name] = augmentLog(name, console[name]);
|
|
273
|
-
}
|
|
273
|
+
}
|
|
274
274
|
}
|
|
275
275
|
function formatStackLikeMetro(projectRoot, stack) {
|
|
276
276
|
// Remove `Error: ` from the beginning of the stack trace.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/start/server/serverLogLikeMetro.ts"],"sourcesContent":["/**\n * Copyright © 2024 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport { INTERNAL_CALLSITES_REGEX } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport path from 'path';\n// @ts-expect-error\nimport { mapSourcePosition } from 'source-map-support';\nimport * as stackTraceParser from 'stacktrace-parser';\n\nimport { parseErrorStack, StackFrame } from './metro/log-box/LogBoxSymbolication';\nimport { env } from '../../utils/env';\nimport { memoize } from '../../utils/fn';\nimport { LogBoxLog } from './metro/log-box/LogBoxLog';\nimport { getStackAsFormattedLog } from './metro/metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst groupStack: any = [];\nlet collapsedGuardTimer: ReturnType<typeof setTimeout> | undefined;\n\nexport function logLikeMetro(\n originalLogFunction: (...args: any[]) => void,\n level: string,\n platform: 'BRIDGE' | 'NOBRIDGE' | 'λ' | null,\n ...data: any[]\n) {\n // @ts-expect-error\n const logFunction = console[level] && level !== 'trace' ? level : 'log';\n const color =\n level === 'error'\n ? chalk.inverse.red\n : level === 'warn'\n ? chalk.inverse.yellow\n : chalk.inverse.white;\n\n if (level === 'group') {\n groupStack.push(level);\n } else if (level === 'groupCollapsed') {\n groupStack.push(level);\n clearTimeout(collapsedGuardTimer);\n // Inform users that logs get swallowed if they forget to call `groupEnd`.\n collapsedGuardTimer = setTimeout(() => {\n if (groupStack.includes('groupCollapsed')) {\n originalLogFunction(\n chalk.inverse.yellow.bold(' WARN '),\n 'Expected `console.groupEnd` to be called after `console.groupCollapsed`.'\n );\n groupStack.length = 0;\n }\n }, 3000);\n return;\n } else if (level === 'groupEnd') {\n groupStack.pop();\n if (!groupStack.length) {\n clearTimeout(collapsedGuardTimer);\n }\n return;\n }\n\n if (!groupStack.includes('groupCollapsed')) {\n // Remove excess whitespace at the end of a log message, if possible.\n const lastItem = data[data.length - 1];\n if (typeof lastItem === 'string') {\n data[data.length - 1] = lastItem.trimEnd();\n }\n\n const modePrefix =\n platform && platform !== 'BRIDGE' && platform !== 'NOBRIDGE' ? chalk.bold`${platform} ` : '';\n originalLogFunction(\n modePrefix +\n color.bold(` ${logFunction.toUpperCase()} `) +\n ''.padEnd(groupStack.length * 2, ' '),\n ...data\n );\n }\n}\n\nconst escapedPathSep = path.sep === '\\\\' ? '\\\\\\\\' : path.sep;\nconst SERVER_STACK_MATCHER = new RegExp(\n `${escapedPathSep}(react-dom|metro-runtime|expo-router)${escapedPathSep}`\n);\n\nexport async function maybeSymbolicateAndFormatJSErrorStackLogAsync(\n projectRoot: string,\n level: 'error' | 'warn' | (string & {}),\n error: {\n message: string;\n stack: StackFrame[];\n }\n): Promise<{\n isFallback: boolean;\n stack: string;\n}> {\n const log = new LogBoxLog({\n level: level as 'error' | 'warn',\n message: {\n content: error.message,\n substitutions: [],\n },\n isComponentError: false,\n stack: error.stack,\n category: 'static',\n componentStack: [],\n });\n\n await new Promise((res) => log.symbolicate('stack', res));\n\n const formatted = getStackAsFormattedLog(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n });\n\n // NOTE: Message is printed above stack by the default Metro logic. So we don't need to include it here.\n const symbolicatedErrorStackLog = `\\n\\n${formatted.stack}`;\n\n return {\n isFallback: formatted.isFallback,\n stack: symbolicatedErrorStackLog,\n };\n}\n\n/**\n * Attempt to parse an error message string to an unsymbolicated stack.\n */\nexport function parseErrorStringToObject(errorString: string) {\n // Find the first line of the possible stack trace\n const stackStartIndex = errorString.indexOf('\\n at ');\n if (stackStartIndex === -1) {\n // No stack trace found, return the original error string\n return null;\n }\n const message = errorString.slice(0, stackStartIndex).trim();\n const stack = errorString.slice(stackStartIndex + 1);\n\n try {\n const parsedStack = parseErrorStack(stack);\n\n return {\n message,\n stack: parsedStack,\n };\n } catch (e) {\n // If parsing fails, return the original error string\n debug('Failed to parse error stack:', e);\n return null;\n }\n}\n\nfunction augmentLogsInternal(projectRoot: string) {\n const augmentLog = (name: string, fn: typeof console.log) => {\n // @ts-expect-error: TypeScript doesn't know about polyfilled functions.\n if (fn.__polyfilled) {\n return fn;\n }\n const originalFn = fn.bind(console);\n function logWithStack(...args: any[]) {\n const stack = new Error().stack;\n // Check if the log originates from the server.\n const isServerLog = !!stack?.match(SERVER_STACK_MATCHER);\n\n if (isServerLog) {\n if (name === 'error' || name === 'warn') {\n if (\n args.length === 2 &&\n typeof args[1] === 'string' &&\n args[1].trim().startsWith('at ')\n ) {\n // react-dom custom stacks which are always broken.\n // A stack string like:\n // at div\n // at http://localhost:8081/node_modules/expo-router/node/render.bundle?platform=web&dev=true&hot=false&transform.engine=hermes&transform.routerRoot=app&resolver.environment=node&transform.environment=node:38008:27\n // at Background (http://localhost:8081/node_modules/expo-router/node/render.bundle?platform=web&dev=true&hot=false&transform.engine=hermes&transform.routerRoot=app&resolver.environment=node&transform.environment=node:151009:7)\n const customStack = args[1];\n\n try {\n const parsedStack = parseErrorStack(customStack);\n const symbolicatedStack = parsedStack.map((line: any) => {\n const mapped = mapSourcePosition({\n source: line.file,\n line: line.lineNumber,\n column: line.column,\n }) as {\n // '/Users/evanbacon/Documents/GitHub/lab/sdk51-beta/node_modules/react-native-web/dist/exports/View/index.js',\n source: string;\n line: number;\n column: number;\n // 'hrefAttrs'\n name: string | null;\n };\n\n const fallbackName = mapped.name ?? '<unknown>';\n return {\n file: mapped.source,\n lineNumber: mapped.line,\n column: mapped.column,\n // Attempt to preserve the react component name if possible.\n methodName: line.methodName\n ? line.methodName === '<unknown>'\n ? fallbackName\n : line.methodName\n : fallbackName,\n arguments: line.arguments ?? [],\n };\n });\n\n // Replace args[1] with the formatted stack.\n args[1] = '\\n' + formatParsedStackLikeMetro(projectRoot, symbolicatedStack, true);\n } catch {\n // If symbolication fails, log the original stack.\n args.push('\\n' + formatStackLikeMetro(projectRoot, customStack));\n }\n } else {\n args.push('\\n' + formatStackLikeMetro(projectRoot, stack!));\n }\n }\n\n logLikeMetro(originalFn, name, 'λ', ...args);\n } else {\n originalFn(...args);\n }\n }\n logWithStack.__polyfilled = true;\n return logWithStack;\n };\n\n ['trace', 'info', 'error', 'warn', 'log', 'group', 'groupCollapsed', 'groupEnd', 'debug'].forEach(\n (name) => {\n // @ts-expect-error\n console[name] = augmentLog(name, console[name]);\n }\n );\n}\n\nexport function formatStackLikeMetro(projectRoot: string, stack: string) {\n // Remove `Error: ` from the beginning of the stack trace.\n // Dim traces that match `INTERNAL_CALLSITES_REGEX`\n\n const stackTrace = stackTraceParser.parse(stack);\n return formatParsedStackLikeMetro(projectRoot, stackTrace);\n}\n\nfunction formatParsedStackLikeMetro(\n projectRoot: string,\n stackTrace: stackTraceParser.StackFrame[],\n isComponentStack = false\n) {\n // Remove `Error: ` from the beginning of the stack trace.\n // Dim traces that match `INTERNAL_CALLSITES_REGEX`\n\n return stackTrace\n .filter(\n (line) =>\n line.file &&\n // Ignore unsymbolicated stack frames. It's not clear how this is possible but it sometimes happens when the graph changes.\n !/^https?:\\/\\//.test(line.file) &&\n (isComponentStack ? true : line.file !== '<anonymous>')\n )\n .map((line) => {\n // Use the same regex we use in Metro config to filter out traces:\n const isCollapsed = INTERNAL_CALLSITES_REGEX.test(line.file!);\n if (!isComponentStack && isCollapsed && !env.EXPO_DEBUG) {\n return null;\n }\n // If a file is collapsed, print it with dim styling.\n const style = isCollapsed ? chalk.dim : chalk.gray;\n // Use the `at` prefix to match Node.js\n let fileName = line.file!;\n if (fileName.startsWith(path.sep)) {\n fileName = path.relative(projectRoot, fileName);\n }\n if (line.lineNumber != null) {\n fileName += `:${line.lineNumber}`;\n if (line.column != null) {\n fileName += `:${line.column}`;\n }\n }\n\n return style(` ${line.methodName} (${fileName})`);\n })\n .filter(Boolean)\n .join('\\n');\n}\n\n/** Augment console logs to check the stack trace and format like Metro logs if we think the log came from the SSR renderer or an API route. */\nexport const augmentLogs = memoize(augmentLogsInternal);\n"],"names":["augmentLogs","formatStackLikeMetro","logLikeMetro","maybeSymbolicateAndFormatJSErrorStackLogAsync","parseErrorStringToObject","debug","require","groupStack","collapsedGuardTimer","originalLogFunction","level","platform","data","logFunction","console","color","chalk","inverse","red","yellow","white","push","clearTimeout","setTimeout","includes","bold","length","pop","lastItem","trimEnd","modePrefix","toUpperCase","padEnd","escapedPathSep","path","sep","SERVER_STACK_MATCHER","RegExp","projectRoot","error","log","LogBoxLog","message","content","substitutions","isComponentError","stack","category","componentStack","Promise","res","symbolicate","formatted","getStackAsFormattedLog","symbolicated","codeFrame","symbolicatedErrorStackLog","isFallback","errorString","stackStartIndex","indexOf","slice","trim","parsedStack","parseErrorStack","e","augmentLogsInternal","augmentLog","name","fn","__polyfilled","originalFn","bind","logWithStack","args","Error","isServerLog","match","startsWith","customStack","symbolicatedStack","map","line","mapped","mapSourcePosition","source","file","lineNumber","column","fallbackName","methodName","arguments","formatParsedStackLikeMetro","forEach","stackTrace","stackTraceParser","parse","isComponentStack","filter","test","isCollapsed","INTERNAL_CALLSITES_REGEX","env","EXPO_DEBUG","style","dim","gray","fileName","relative","Boolean","join","memoize"],"mappings":"AAAA;;;;;CAKC;;;;;;;;;;;IA2RYA,WAAW;eAAXA;;IAnDGC,oBAAoB;eAApBA;;IArNAC,YAAY;eAAZA;;IA8DMC,6CAA6C;eAA7CA;;IA0CNC,wBAAwB;eAAxBA;;;;yBA1HyB;;;;;;;gEACvB;;;;;;;gEACD;;;;;;;yBAEiB;;;;;;;iEACA;;;;;;qCAEU;qBACxB;oBACI;2BACE;qCACa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEvC,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,MAAMC,aAAkB,EAAE;AAC1B,IAAIC;AAEG,SAASN,aACdO,mBAA6C,EAC7CC,KAAa,EACbC,QAA4C,EAC5C,GAAGC,IAAW;IAEd,mBAAmB;IACnB,MAAMC,cAAcC,OAAO,CAACJ,MAAM,IAAIA,UAAU,UAAUA,QAAQ;IAClE,MAAMK,QACJL,UAAU,UACNM,gBAAK,CAACC,OAAO,CAACC,GAAG,GACjBR,UAAU,SACRM,gBAAK,CAACC,OAAO,CAACE,MAAM,GACpBH,gBAAK,CAACC,OAAO,CAACG,KAAK;IAE3B,IAAIV,UAAU,SAAS;QACrBH,WAAWc,IAAI,CAACX;IAClB,OAAO,IAAIA,UAAU,kBAAkB;QACrCH,WAAWc,IAAI,CAACX;QAChBY,aAAad;QACb,0EAA0E;QAC1EA,sBAAsBe,WAAW;YAC/B,IAAIhB,WAAWiB,QAAQ,CAAC,mBAAmB;gBACzCf,oBACEO,gBAAK,CAACC,OAAO,CAACE,MAAM,CAACM,IAAI,CAAC,WAC1B;gBAEFlB,WAAWmB,MAAM,GAAG;YACtB;QACF,GAAG;QACH;IACF,OAAO,IAAIhB,UAAU,YAAY;QAC/BH,WAAWoB,GAAG;QACd,IAAI,CAACpB,WAAWmB,MAAM,EAAE;YACtBJ,aAAad;QACf;QACA;IACF;IAEA,IAAI,CAACD,WAAWiB,QAAQ,CAAC,mBAAmB;QAC1C,qEAAqE;QACrE,MAAMI,WAAWhB,IAAI,CAACA,KAAKc,MAAM,GAAG,EAAE;QACtC,IAAI,OAAOE,aAAa,UAAU;YAChChB,IAAI,CAACA,KAAKc,MAAM,GAAG,EAAE,GAAGE,SAASC,OAAO;QAC1C;QAEA,MAAMC,aACJnB,YAAYA,aAAa,YAAYA,aAAa,aAAaK,gBAAK,CAACS,IAAI,CAAC,EAAEd,SAAS,CAAC,CAAC,GAAG;QAC5FF,oBACEqB,aACEf,MAAMU,IAAI,CAAC,CAAC,CAAC,EAAEZ,YAAYkB,WAAW,GAAG,CAAC,CAAC,IAC3C,GAAGC,MAAM,CAACzB,WAAWmB,MAAM,GAAG,GAAG,SAChCd;IAEP;AACF;AAEA,MAAMqB,iBAAiBC,eAAI,CAACC,GAAG,KAAK,OAAO,SAASD,eAAI,CAACC,GAAG;AAC5D,MAAMC,uBAAuB,IAAIC,OAC/B,GAAGJ,eAAe,qCAAqC,EAAEA,gBAAgB;AAGpE,eAAe9B,8CACpBmC,WAAmB,EACnB5B,KAAuC,EACvC6B,KAGC;QAoBQC,yBAAAA;IAfT,MAAMA,MAAM,IAAIC,oBAAS,CAAC;QACxB/B,OAAOA;QACPgC,SAAS;YACPC,SAASJ,MAAMG,OAAO;YACtBE,eAAe,EAAE;QACnB;QACAC,kBAAkB;QAClBC,OAAOP,MAAMO,KAAK;QAClBC,UAAU;QACVC,gBAAgB,EAAE;IACpB;IAEA,MAAM,IAAIC,QAAQ,CAACC,MAAQV,IAAIW,WAAW,CAAC,SAASD;IAEpD,MAAME,YAAYC,IAAAA,2CAAsB,EAACf,aAAa;QACpDQ,OAAON,EAAAA,oBAAAA,IAAIc,YAAY,sBAAhBd,0BAAAA,kBAAkBM,KAAK,qBAAvBN,wBAAyBM,KAAK,KAAI,EAAE;QAC3CS,WAAWf,IAAIe,SAAS;IAC1B;IAEA,wGAAwG;IACxG,MAAMC,4BAA4B,CAAC,IAAI,EAAEJ,UAAUN,KAAK,EAAE;IAE1D,OAAO;QACLW,YAAYL,UAAUK,UAAU;QAChCX,OAAOU;IACT;AACF;AAKO,SAASpD,yBAAyBsD,WAAmB;IAC1D,kDAAkD;IAClD,MAAMC,kBAAkBD,YAAYE,OAAO,CAAC;IAC5C,IAAID,oBAAoB,CAAC,GAAG;QAC1B,yDAAyD;QACzD,OAAO;IACT;IACA,MAAMjB,UAAUgB,YAAYG,KAAK,CAAC,GAAGF,iBAAiBG,IAAI;IAC1D,MAAMhB,QAAQY,YAAYG,KAAK,CAACF,kBAAkB;IAElD,IAAI;QACF,MAAMI,cAAcC,IAAAA,oCAAe,EAAClB;QAEpC,OAAO;YACLJ;YACAI,OAAOiB;QACT;IACF,EAAE,OAAOE,GAAG;QACV,qDAAqD;QACrD5D,MAAM,gCAAgC4D;QACtC,OAAO;IACT;AACF;AAEA,SAASC,oBAAoB5B,WAAmB;IAC9C,MAAM6B,aAAa,CAACC,MAAcC;QAChC,wEAAwE;QACxE,IAAIA,GAAGC,YAAY,EAAE;YACnB,OAAOD;QACT;QACA,MAAME,aAAaF,GAAGG,IAAI,CAAC1D;QAC3B,SAAS2D,aAAa,GAAGC,IAAW;YAClC,MAAM5B,QAAQ,IAAI6B,QAAQ7B,KAAK;YAC/B,+CAA+C;YAC/C,MAAM8B,cAAc,CAAC,EAAC9B,yBAAAA,MAAO+B,KAAK,CAACzC;YAEnC,IAAIwC,aAAa;gBACf,IAAIR,SAAS,WAAWA,SAAS,QAAQ;oBACvC,IACEM,KAAKhD,MAAM,KAAK,KAChB,OAAOgD,IAAI,CAAC,EAAE,KAAK,YACnBA,IAAI,CAAC,EAAE,CAACZ,IAAI,GAAGgB,UAAU,CAAC,QAC1B;wBACA,mDAAmD;wBACnD,uBAAuB;wBACvB,YAAY;wBACZ,yNAAyN;wBACzN,sOAAsO;wBACtO,MAAMC,cAAcL,IAAI,CAAC,EAAE;wBAE3B,IAAI;4BACF,MAAMX,cAAcC,IAAAA,oCAAe,EAACe;4BACpC,MAAMC,oBAAoBjB,YAAYkB,GAAG,CAAC,CAACC;gCACzC,MAAMC,SAASC,IAAAA,qCAAiB,EAAC;oCAC/BC,QAAQH,KAAKI,IAAI;oCACjBJ,MAAMA,KAAKK,UAAU;oCACrBC,QAAQN,KAAKM,MAAM;gCACrB;gCASA,MAAMC,eAAeN,OAAOf,IAAI,IAAI;gCACpC,OAAO;oCACLkB,MAAMH,OAAOE,MAAM;oCACnBE,YAAYJ,OAAOD,IAAI;oCACvBM,QAAQL,OAAOK,MAAM;oCACrB,4DAA4D;oCAC5DE,YAAYR,KAAKQ,UAAU,GACvBR,KAAKQ,UAAU,KAAK,cAClBD,eACAP,KAAKQ,UAAU,GACjBD;oCACJE,WAAWT,KAAKS,SAAS,IAAI,EAAE;gCACjC;4BACF;4BAEA,4CAA4C;4BAC5CjB,IAAI,CAAC,EAAE,GAAG,OAAOkB,2BAA2BtD,aAAa0C,mBAAmB;wBAC9E,EAAE,OAAM;4BACN,kDAAkD;4BAClDN,KAAKrD,IAAI,CAAC,OAAOpB,qBAAqBqC,aAAayC;wBACrD;oBACF,OAAO;wBACLL,KAAKrD,IAAI,CAAC,OAAOpB,qBAAqBqC,aAAaQ;oBACrD;gBACF;gBAEA5C,aAAaqE,YAAYH,MAAM,QAAQM;YACzC,OAAO;gBACLH,cAAcG;YAChB;QACF;QACAD,aAAaH,YAAY,GAAG;QAC5B,OAAOG;IACT;IAEA;QAAC;QAAS;QAAQ;QAAS;QAAQ;QAAO;QAAS;QAAkB;QAAY;KAAQ,CAACoB,OAAO,CAC/F,CAACzB;QACC,mBAAmB;QACnBtD,OAAO,CAACsD,KAAK,GAAGD,WAAWC,MAAMtD,OAAO,CAACsD,KAAK;IAChD;AAEJ;AAEO,SAASnE,qBAAqBqC,WAAmB,EAAEQ,KAAa;IACrE,0DAA0D;IAC1D,mDAAmD;IAEnD,MAAMgD,aAAaC,oBAAiBC,KAAK,CAAClD;IAC1C,OAAO8C,2BAA2BtD,aAAawD;AACjD;AAEA,SAASF,2BACPtD,WAAmB,EACnBwD,UAAyC,EACzCG,mBAAmB,KAAK;IAExB,0DAA0D;IAC1D,mDAAmD;IAEnD,OAAOH,WACJI,MAAM,CACL,CAAChB,OACCA,KAAKI,IAAI,IACT,2HAA2H;QAC3H,CAAC,eAAea,IAAI,CAACjB,KAAKI,IAAI,KAC7BW,CAAAA,mBAAmB,OAAOf,KAAKI,IAAI,KAAK,aAAY,GAExDL,GAAG,CAAC,CAACC;QACJ,kEAAkE;QAClE,MAAMkB,cAAcC,uCAAwB,CAACF,IAAI,CAACjB,KAAKI,IAAI;QAC3D,IAAI,CAACW,oBAAoBG,eAAe,CAACE,QAAG,CAACC,UAAU,EAAE;YACvD,OAAO;QACT;QACA,qDAAqD;QACrD,MAAMC,QAAQJ,cAAcpF,gBAAK,CAACyF,GAAG,GAAGzF,gBAAK,CAAC0F,IAAI;QAClD,uCAAuC;QACvC,IAAIC,WAAWzB,KAAKI,IAAI;QACxB,IAAIqB,SAAS7B,UAAU,CAAC5C,eAAI,CAACC,GAAG,GAAG;YACjCwE,WAAWzE,eAAI,CAAC0E,QAAQ,CAACtE,aAAaqE;QACxC;QACA,IAAIzB,KAAKK,UAAU,IAAI,MAAM;YAC3BoB,YAAY,CAAC,CAAC,EAAEzB,KAAKK,UAAU,EAAE;YACjC,IAAIL,KAAKM,MAAM,IAAI,MAAM;gBACvBmB,YAAY,CAAC,CAAC,EAAEzB,KAAKM,MAAM,EAAE;YAC/B;QACF;QAEA,OAAOgB,MAAM,CAAC,EAAE,EAAEtB,KAAKQ,UAAU,CAAC,EAAE,EAAEiB,SAAS,CAAC,CAAC;IACnD,GACCT,MAAM,CAACW,SACPC,IAAI,CAAC;AACV;AAGO,MAAM9G,cAAc+G,IAAAA,WAAO,EAAC7C"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/start/server/serverLogLikeMetro.ts"],"sourcesContent":["/**\n * Copyright © 2024 650 Industries.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport type { SourcePosition } from '@expo/metro/metro-source-map/Consumer/types';\nimport { INTERNAL_CALLSITES_REGEX } from '@expo/metro-config';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { mapSourcePosition } from 'source-map-support';\nimport * as stackTraceParser from 'stacktrace-parser';\n\nimport { parseErrorStack, StackFrame } from './metro/log-box/LogBoxSymbolication';\nimport { env } from '../../utils/env';\nimport { memoize } from '../../utils/fn';\nimport { LogBoxLog } from './metro/log-box/LogBoxLog';\nimport { getStackAsFormattedLog } from './metro/metroErrorInterface';\n\nconst debug = require('debug')('expo:metro:logger') as typeof console.log;\n\nconst CONSOLE_METHODS = [\n 'trace',\n 'info',\n 'error',\n 'warn',\n 'log',\n 'group',\n 'groupCollapsed',\n 'groupEnd',\n 'debug',\n] as const;\n\ntype ConsoleMethod = (typeof CONSOLE_METHODS)[number];\n\nconst groupStack: any = [];\nlet collapsedGuardTimer: ReturnType<typeof setTimeout> | undefined;\n\nexport function logLikeMetro(\n originalLogFunction: (...args: any[]) => void,\n level: ConsoleMethod,\n platform: 'BRIDGE' | 'NOBRIDGE' | 'λ' | null,\n ...data: any[]\n) {\n const logFunction = console[level] && level !== 'trace' ? level : 'log';\n const color =\n level === 'error'\n ? chalk.inverse.red\n : level === 'warn'\n ? chalk.inverse.yellow\n : chalk.inverse.white;\n\n if (level === 'group') {\n groupStack.push(level);\n } else if (level === 'groupCollapsed') {\n groupStack.push(level);\n clearTimeout(collapsedGuardTimer);\n // Inform users that logs get swallowed if they forget to call `groupEnd`.\n collapsedGuardTimer = setTimeout(() => {\n if (groupStack.includes('groupCollapsed')) {\n originalLogFunction(\n chalk.inverse.yellow.bold(' WARN '),\n 'Expected `console.groupEnd` to be called after `console.groupCollapsed`.'\n );\n groupStack.length = 0;\n }\n }, 3000);\n return;\n } else if (level === 'groupEnd') {\n groupStack.pop();\n if (!groupStack.length) {\n clearTimeout(collapsedGuardTimer);\n }\n return;\n }\n\n if (!groupStack.includes('groupCollapsed')) {\n // Remove excess whitespace at the end of a log message, if possible.\n const lastItem = data[data.length - 1];\n if (typeof lastItem === 'string') {\n data[data.length - 1] = lastItem.trimEnd();\n }\n\n const modePrefix =\n platform && platform !== 'BRIDGE' && platform !== 'NOBRIDGE' ? chalk.bold`${platform} ` : '';\n originalLogFunction(\n modePrefix +\n color.bold(` ${logFunction.toUpperCase()} `) +\n ''.padEnd(groupStack.length * 2, ' '),\n ...data\n );\n }\n}\n\nconst escapedPathSep = path.sep === '\\\\' ? '\\\\\\\\' : path.sep;\nconst SERVER_STACK_MATCHER = new RegExp(\n `${escapedPathSep}(react-dom|metro-runtime|expo-router)${escapedPathSep}`\n);\n\nexport async function maybeSymbolicateAndFormatJSErrorStackLogAsync(\n projectRoot: string,\n level: 'error' | 'warn' | (string & {}),\n error: {\n message: string;\n stack: StackFrame[];\n }\n): Promise<{\n isFallback: boolean;\n stack: string;\n}> {\n const log = new LogBoxLog({\n level: level as 'error' | 'warn',\n message: {\n content: error.message,\n substitutions: [],\n },\n isComponentError: false,\n stack: error.stack,\n category: 'static',\n componentStack: [],\n });\n\n await new Promise((res) => log.symbolicate('stack', res));\n\n const formatted = getStackAsFormattedLog(projectRoot, {\n stack: log.symbolicated?.stack?.stack ?? [],\n codeFrame: log.codeFrame,\n });\n\n // NOTE: Message is printed above stack by the default Metro logic. So we don't need to include it here.\n const symbolicatedErrorStackLog = `\\n\\n${formatted.stack}`;\n\n return {\n isFallback: formatted.isFallback,\n stack: symbolicatedErrorStackLog,\n };\n}\n\n/**\n * Attempt to parse an error message string to an unsymbolicated stack.\n */\nexport function parseErrorStringToObject(errorString: string) {\n // Find the first line of the possible stack trace\n const stackStartIndex = errorString.indexOf('\\n at ');\n if (stackStartIndex === -1) {\n // No stack trace found, return the original error string\n return null;\n }\n const message = errorString.slice(0, stackStartIndex).trim();\n const stack = errorString.slice(stackStartIndex + 1);\n\n try {\n const parsedStack = parseErrorStack(stack);\n\n return {\n message,\n stack: parsedStack,\n };\n } catch (e) {\n // If parsing fails, return the original error string\n debug('Failed to parse error stack:', e);\n return null;\n }\n}\n\ntype ConsoleLogAugmented = typeof console.log & {\n __polyfilled?: typeof console.log;\n};\n\nfunction augmentLogsInternal(projectRoot: string) {\n const augmentLog = (name: ConsoleMethod, fn: ConsoleLogAugmented) => {\n if (fn.__polyfilled) {\n return fn;\n }\n const originalFn = fn.bind(console);\n function logWithStack(...args: any[]) {\n const stack = new Error().stack;\n // Check if the log originates from the server.\n const isServerLog = !!stack?.match(SERVER_STACK_MATCHER);\n\n if (isServerLog) {\n if (name === 'error' || name === 'warn') {\n if (\n args.length === 2 &&\n typeof args[1] === 'string' &&\n args[1].trim().startsWith('at ')\n ) {\n // react-dom custom stacks which are always broken.\n // A stack string like:\n // at div\n // at http://localhost:8081/node_modules/expo-router/node/render.bundle?platform=web&dev=true&hot=false&transform.engine=hermes&transform.routerRoot=app&resolver.environment=node&transform.environment=node:38008:27\n // at Background (http://localhost:8081/node_modules/expo-router/node/render.bundle?platform=web&dev=true&hot=false&transform.engine=hermes&transform.routerRoot=app&resolver.environment=node&transform.environment=node:151009:7)\n const customStack = args[1];\n\n try {\n const parsedStack = parseErrorStack(customStack);\n const symbolicatedStack = parsedStack.map((line) => {\n // TODO(@kitten): Is there overlap here with metro-source-map?\n const mapped = mapSourcePosition({\n // TODO(@kitten): Check if these non-null casts are correct and cannot fail\n source: line.file!,\n line: line.lineNumber!,\n column: line.column!,\n }) as SourcePosition;\n\n const fallbackName = mapped.name ?? '<unknown>';\n return {\n file: mapped.source ?? null,\n lineNumber: mapped.line ?? null,\n column: mapped.column ?? null,\n // Attempt to preserve the react component name if possible.\n methodName: line.methodName\n ? line.methodName === '<unknown>'\n ? fallbackName\n : line.methodName\n : fallbackName,\n arguments: line.arguments ?? [],\n };\n });\n\n // Replace args[1] with the formatted stack.\n args[1] = '\\n' + formatParsedStackLikeMetro(projectRoot, symbolicatedStack, true);\n } catch {\n // If symbolication fails, log the original stack.\n args.push('\\n' + formatStackLikeMetro(projectRoot, customStack));\n }\n } else {\n args.push('\\n' + formatStackLikeMetro(projectRoot, stack!));\n }\n }\n\n logLikeMetro(originalFn, name, 'λ', ...args);\n } else {\n originalFn(...args);\n }\n }\n logWithStack.__polyfilled = true;\n return logWithStack;\n };\n\n for (const name of CONSOLE_METHODS) {\n console[name] = augmentLog(name, console[name]);\n }\n}\n\nexport function formatStackLikeMetro(projectRoot: string, stack: string) {\n // Remove `Error: ` from the beginning of the stack trace.\n // Dim traces that match `INTERNAL_CALLSITES_REGEX`\n\n const stackTrace = stackTraceParser.parse(stack);\n return formatParsedStackLikeMetro(projectRoot, stackTrace);\n}\n\nfunction formatParsedStackLikeMetro(\n projectRoot: string,\n stackTrace: stackTraceParser.StackFrame[],\n isComponentStack = false\n) {\n // Remove `Error: ` from the beginning of the stack trace.\n // Dim traces that match `INTERNAL_CALLSITES_REGEX`\n\n return stackTrace\n .filter(\n (line) =>\n line.file &&\n // Ignore unsymbolicated stack frames. It's not clear how this is possible but it sometimes happens when the graph changes.\n !/^https?:\\/\\//.test(line.file) &&\n (isComponentStack ? true : line.file !== '<anonymous>')\n )\n .map((line) => {\n // Use the same regex we use in Metro config to filter out traces:\n const isCollapsed = INTERNAL_CALLSITES_REGEX.test(line.file!);\n if (!isComponentStack && isCollapsed && !env.EXPO_DEBUG) {\n return null;\n }\n // If a file is collapsed, print it with dim styling.\n const style = isCollapsed ? chalk.dim : chalk.gray;\n // Use the `at` prefix to match Node.js\n let fileName = line.file!;\n if (fileName.startsWith(path.sep)) {\n fileName = path.relative(projectRoot, fileName);\n }\n if (line.lineNumber != null) {\n fileName += `:${line.lineNumber}`;\n if (line.column != null) {\n fileName += `:${line.column}`;\n }\n }\n\n return style(` ${line.methodName} (${fileName})`);\n })\n .filter(Boolean)\n .join('\\n');\n}\n\n/** Augment console logs to check the stack trace and format like Metro logs if we think the log came from the SSR renderer or an API route. */\nexport const augmentLogs = memoize(augmentLogsInternal);\n"],"names":["augmentLogs","formatStackLikeMetro","logLikeMetro","maybeSymbolicateAndFormatJSErrorStackLogAsync","parseErrorStringToObject","debug","require","CONSOLE_METHODS","groupStack","collapsedGuardTimer","originalLogFunction","level","platform","data","logFunction","console","color","chalk","inverse","red","yellow","white","push","clearTimeout","setTimeout","includes","bold","length","pop","lastItem","trimEnd","modePrefix","toUpperCase","padEnd","escapedPathSep","path","sep","SERVER_STACK_MATCHER","RegExp","projectRoot","error","log","LogBoxLog","message","content","substitutions","isComponentError","stack","category","componentStack","Promise","res","symbolicate","formatted","getStackAsFormattedLog","symbolicated","codeFrame","symbolicatedErrorStackLog","isFallback","errorString","stackStartIndex","indexOf","slice","trim","parsedStack","parseErrorStack","e","augmentLogsInternal","augmentLog","name","fn","__polyfilled","originalFn","bind","logWithStack","args","Error","isServerLog","match","startsWith","customStack","symbolicatedStack","map","line","mapped","mapSourcePosition","source","file","lineNumber","column","fallbackName","methodName","arguments","formatParsedStackLikeMetro","stackTrace","stackTraceParser","parse","isComponentStack","filter","test","isCollapsed","INTERNAL_CALLSITES_REGEX","env","EXPO_DEBUG","style","dim","gray","fileName","relative","Boolean","join","memoize"],"mappings":"AAAA;;;;;CAKC;;;;;;;;;;;IAmSYA,WAAW;eAAXA;;IAnDGC,oBAAoB;eAApBA;;IA/MAC,YAAY;eAAZA;;IA6DMC,6CAA6C;eAA7CA;;IA0CNC,wBAAwB;eAAxBA;;;;yBAtIyB;;;;;;;gEACvB;;;;;;;gEACD;;;;;;;yBACiB;;;;;;;iEACA;;;;;;qCAEU;qBACxB;oBACI;2BACE;qCACa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEvC,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,MAAMC,kBAAkB;IACtB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AAID,MAAMC,aAAkB,EAAE;AAC1B,IAAIC;AAEG,SAASP,aACdQ,mBAA6C,EAC7CC,KAAoB,EACpBC,QAA4C,EAC5C,GAAGC,IAAW;IAEd,MAAMC,cAAcC,OAAO,CAACJ,MAAM,IAAIA,UAAU,UAAUA,QAAQ;IAClE,MAAMK,QACJL,UAAU,UACNM,gBAAK,CAACC,OAAO,CAACC,GAAG,GACjBR,UAAU,SACRM,gBAAK,CAACC,OAAO,CAACE,MAAM,GACpBH,gBAAK,CAACC,OAAO,CAACG,KAAK;IAE3B,IAAIV,UAAU,SAAS;QACrBH,WAAWc,IAAI,CAACX;IAClB,OAAO,IAAIA,UAAU,kBAAkB;QACrCH,WAAWc,IAAI,CAACX;QAChBY,aAAad;QACb,0EAA0E;QAC1EA,sBAAsBe,WAAW;YAC/B,IAAIhB,WAAWiB,QAAQ,CAAC,mBAAmB;gBACzCf,oBACEO,gBAAK,CAACC,OAAO,CAACE,MAAM,CAACM,IAAI,CAAC,WAC1B;gBAEFlB,WAAWmB,MAAM,GAAG;YACtB;QACF,GAAG;QACH;IACF,OAAO,IAAIhB,UAAU,YAAY;QAC/BH,WAAWoB,GAAG;QACd,IAAI,CAACpB,WAAWmB,MAAM,EAAE;YACtBJ,aAAad;QACf;QACA;IACF;IAEA,IAAI,CAACD,WAAWiB,QAAQ,CAAC,mBAAmB;QAC1C,qEAAqE;QACrE,MAAMI,WAAWhB,IAAI,CAACA,KAAKc,MAAM,GAAG,EAAE;QACtC,IAAI,OAAOE,aAAa,UAAU;YAChChB,IAAI,CAACA,KAAKc,MAAM,GAAG,EAAE,GAAGE,SAASC,OAAO;QAC1C;QAEA,MAAMC,aACJnB,YAAYA,aAAa,YAAYA,aAAa,aAAaK,gBAAK,CAACS,IAAI,CAAC,EAAEd,SAAS,CAAC,CAAC,GAAG;QAC5FF,oBACEqB,aACEf,MAAMU,IAAI,CAAC,CAAC,CAAC,EAAEZ,YAAYkB,WAAW,GAAG,CAAC,CAAC,IAC3C,GAAGC,MAAM,CAACzB,WAAWmB,MAAM,GAAG,GAAG,SAChCd;IAEP;AACF;AAEA,MAAMqB,iBAAiBC,eAAI,CAACC,GAAG,KAAK,OAAO,SAASD,eAAI,CAACC,GAAG;AAC5D,MAAMC,uBAAuB,IAAIC,OAC/B,GAAGJ,eAAe,qCAAqC,EAAEA,gBAAgB;AAGpE,eAAe/B,8CACpBoC,WAAmB,EACnB5B,KAAuC,EACvC6B,KAGC;QAoBQC,yBAAAA;IAfT,MAAMA,MAAM,IAAIC,oBAAS,CAAC;QACxB/B,OAAOA;QACPgC,SAAS;YACPC,SAASJ,MAAMG,OAAO;YACtBE,eAAe,EAAE;QACnB;QACAC,kBAAkB;QAClBC,OAAOP,MAAMO,KAAK;QAClBC,UAAU;QACVC,gBAAgB,EAAE;IACpB;IAEA,MAAM,IAAIC,QAAQ,CAACC,MAAQV,IAAIW,WAAW,CAAC,SAASD;IAEpD,MAAME,YAAYC,IAAAA,2CAAsB,EAACf,aAAa;QACpDQ,OAAON,EAAAA,oBAAAA,IAAIc,YAAY,sBAAhBd,0BAAAA,kBAAkBM,KAAK,qBAAvBN,wBAAyBM,KAAK,KAAI,EAAE;QAC3CS,WAAWf,IAAIe,SAAS;IAC1B;IAEA,wGAAwG;IACxG,MAAMC,4BAA4B,CAAC,IAAI,EAAEJ,UAAUN,KAAK,EAAE;IAE1D,OAAO;QACLW,YAAYL,UAAUK,UAAU;QAChCX,OAAOU;IACT;AACF;AAKO,SAASrD,yBAAyBuD,WAAmB;IAC1D,kDAAkD;IAClD,MAAMC,kBAAkBD,YAAYE,OAAO,CAAC;IAC5C,IAAID,oBAAoB,CAAC,GAAG;QAC1B,yDAAyD;QACzD,OAAO;IACT;IACA,MAAMjB,UAAUgB,YAAYG,KAAK,CAAC,GAAGF,iBAAiBG,IAAI;IAC1D,MAAMhB,QAAQY,YAAYG,KAAK,CAACF,kBAAkB;IAElD,IAAI;QACF,MAAMI,cAAcC,IAAAA,oCAAe,EAAClB;QAEpC,OAAO;YACLJ;YACAI,OAAOiB;QACT;IACF,EAAE,OAAOE,GAAG;QACV,qDAAqD;QACrD7D,MAAM,gCAAgC6D;QACtC,OAAO;IACT;AACF;AAMA,SAASC,oBAAoB5B,WAAmB;IAC9C,MAAM6B,aAAa,CAACC,MAAqBC;QACvC,IAAIA,GAAGC,YAAY,EAAE;YACnB,OAAOD;QACT;QACA,MAAME,aAAaF,GAAGG,IAAI,CAAC1D;QAC3B,SAAS2D,aAAa,GAAGC,IAAW;YAClC,MAAM5B,QAAQ,IAAI6B,QAAQ7B,KAAK;YAC/B,+CAA+C;YAC/C,MAAM8B,cAAc,CAAC,EAAC9B,yBAAAA,MAAO+B,KAAK,CAACzC;YAEnC,IAAIwC,aAAa;gBACf,IAAIR,SAAS,WAAWA,SAAS,QAAQ;oBACvC,IACEM,KAAKhD,MAAM,KAAK,KAChB,OAAOgD,IAAI,CAAC,EAAE,KAAK,YACnBA,IAAI,CAAC,EAAE,CAACZ,IAAI,GAAGgB,UAAU,CAAC,QAC1B;wBACA,mDAAmD;wBACnD,uBAAuB;wBACvB,YAAY;wBACZ,yNAAyN;wBACzN,sOAAsO;wBACtO,MAAMC,cAAcL,IAAI,CAAC,EAAE;wBAE3B,IAAI;4BACF,MAAMX,cAAcC,IAAAA,oCAAe,EAACe;4BACpC,MAAMC,oBAAoBjB,YAAYkB,GAAG,CAAC,CAACC;gCACzC,8DAA8D;gCAC9D,MAAMC,SAASC,IAAAA,qCAAiB,EAAC;oCAC/B,2EAA2E;oCAC3EC,QAAQH,KAAKI,IAAI;oCACjBJ,MAAMA,KAAKK,UAAU;oCACrBC,QAAQN,KAAKM,MAAM;gCACrB;gCAEA,MAAMC,eAAeN,OAAOf,IAAI,IAAI;gCACpC,OAAO;oCACLkB,MAAMH,OAAOE,MAAM,IAAI;oCACvBE,YAAYJ,OAAOD,IAAI,IAAI;oCAC3BM,QAAQL,OAAOK,MAAM,IAAI;oCACzB,4DAA4D;oCAC5DE,YAAYR,KAAKQ,UAAU,GACvBR,KAAKQ,UAAU,KAAK,cAClBD,eACAP,KAAKQ,UAAU,GACjBD;oCACJE,WAAWT,KAAKS,SAAS,IAAI,EAAE;gCACjC;4BACF;4BAEA,4CAA4C;4BAC5CjB,IAAI,CAAC,EAAE,GAAG,OAAOkB,2BAA2BtD,aAAa0C,mBAAmB;wBAC9E,EAAE,OAAM;4BACN,kDAAkD;4BAClDN,KAAKrD,IAAI,CAAC,OAAOrB,qBAAqBsC,aAAayC;wBACrD;oBACF,OAAO;wBACLL,KAAKrD,IAAI,CAAC,OAAOrB,qBAAqBsC,aAAaQ;oBACrD;gBACF;gBAEA7C,aAAasE,YAAYH,MAAM,QAAQM;YACzC,OAAO;gBACLH,cAAcG;YAChB;QACF;QACAD,aAAaH,YAAY,GAAG;QAC5B,OAAOG;IACT;IAEA,KAAK,MAAML,QAAQ9D,gBAAiB;QAClCQ,OAAO,CAACsD,KAAK,GAAGD,WAAWC,MAAMtD,OAAO,CAACsD,KAAK;IAChD;AACF;AAEO,SAASpE,qBAAqBsC,WAAmB,EAAEQ,KAAa;IACrE,0DAA0D;IAC1D,mDAAmD;IAEnD,MAAM+C,aAAaC,oBAAiBC,KAAK,CAACjD;IAC1C,OAAO8C,2BAA2BtD,aAAauD;AACjD;AAEA,SAASD,2BACPtD,WAAmB,EACnBuD,UAAyC,EACzCG,mBAAmB,KAAK;IAExB,0DAA0D;IAC1D,mDAAmD;IAEnD,OAAOH,WACJI,MAAM,CACL,CAACf,OACCA,KAAKI,IAAI,IACT,2HAA2H;QAC3H,CAAC,eAAeY,IAAI,CAAChB,KAAKI,IAAI,KAC7BU,CAAAA,mBAAmB,OAAOd,KAAKI,IAAI,KAAK,aAAY,GAExDL,GAAG,CAAC,CAACC;QACJ,kEAAkE;QAClE,MAAMiB,cAAcC,uCAAwB,CAACF,IAAI,CAAChB,KAAKI,IAAI;QAC3D,IAAI,CAACU,oBAAoBG,eAAe,CAACE,QAAG,CAACC,UAAU,EAAE;YACvD,OAAO;QACT;QACA,qDAAqD;QACrD,MAAMC,QAAQJ,cAAcnF,gBAAK,CAACwF,GAAG,GAAGxF,gBAAK,CAACyF,IAAI;QAClD,uCAAuC;QACvC,IAAIC,WAAWxB,KAAKI,IAAI;QACxB,IAAIoB,SAAS5B,UAAU,CAAC5C,eAAI,CAACC,GAAG,GAAG;YACjCuE,WAAWxE,eAAI,CAACyE,QAAQ,CAACrE,aAAaoE;QACxC;QACA,IAAIxB,KAAKK,UAAU,IAAI,MAAM;YAC3BmB,YAAY,CAAC,CAAC,EAAExB,KAAKK,UAAU,EAAE;YACjC,IAAIL,KAAKM,MAAM,IAAI,MAAM;gBACvBkB,YAAY,CAAC,CAAC,EAAExB,KAAKM,MAAM,EAAE;YAC/B;QACF;QAEA,OAAOe,MAAM,CAAC,EAAE,EAAErB,KAAKQ,UAAU,CAAC,EAAE,EAAEgB,SAAS,CAAC,CAAC;IACnD,GACCT,MAAM,CAACW,SACPC,IAAI,CAAC;AACV;AAGO,MAAM9G,cAAc+G,IAAAA,WAAO,EAAC5C"}
|
|
@@ -126,8 +126,8 @@ class WebpackBundlerDevServer extends _BundlerDevServer.BundlerDevServer {
|
|
|
126
126
|
// Default webpack-dev-server sockets use "content-changed" instead of "reload" (what we use on native).
|
|
127
127
|
// For now, just manually convert the value so our CLI interface can be unified.
|
|
128
128
|
const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;
|
|
129
|
-
if ('sendMessage' in this.instance.server) {
|
|
130
|
-
//
|
|
129
|
+
if ('sendMessage' in this.instance.server && typeof this.instance.server.sendMessage === 'function') {
|
|
130
|
+
// NOTE: https://github.com/expo/expo/issues/21994#issuecomment-1517122501
|
|
131
131
|
this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);
|
|
132
132
|
} else {
|
|
133
133
|
this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/start/server/webpack/WebpackBundlerDevServer.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { Application } from 'express';\nimport fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\nimport type webpack from 'webpack';\nimport type WebpackDevServer from 'webpack-dev-server';\n\nimport { compileAsync } from './compile';\nimport {\n importExpoWebpackConfigFromProject,\n importWebpackDevServerFromProject,\n importWebpackFromProject,\n} from './resolveFromProject';\nimport { ensureEnvironmentSupportsTLSAsync } from './tls';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { getIpAddress } from '../../../utils/ip';\nimport { setNodeEnv } from '../../../utils/nodeEnv';\nimport { choosePortAsync } from '../../../utils/port';\nimport { createProgressBar } from '../../../utils/progress';\nimport { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo';\nimport { BundlerDevServer, BundlerStartOptions, DevServerInstance } from '../BundlerDevServer';\n\nconst debug = require('debug')('expo:start:server:webpack:devServer') as typeof console.log;\n\nexport type WebpackConfiguration = webpack.Configuration & {\n devServer?: {\n before?: (app: Application, server: WebpackDevServer, compiler: webpack.Compiler) => void;\n };\n};\n\nfunction assertIsWebpackDevServer(value: any): asserts value is WebpackDevServer {\n if (!value?.sockWrite && !value?.sendMessage) {\n throw new CommandError(\n 'WEBPACK',\n value\n ? 'Expected Webpack dev server, found: ' + (value.constructor?.name ?? value)\n : 'Webpack dev server not started yet.'\n );\n }\n}\n\nexport class WebpackBundlerDevServer extends BundlerDevServer {\n get name(): string {\n return 'webpack';\n }\n\n public async startTypeScriptServices(): Promise<void> {\n // noop -- this feature is Metro-only.\n }\n\n public broadcastMessage(\n method: string | 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ): void {\n if (!this.instance) {\n return;\n }\n\n assertIsWebpackDevServer(this.instance?.server);\n\n // TODO(EvanBacon): Custom Webpack overlay.\n // Default webpack-dev-server sockets use \"content-changed\" instead of \"reload\" (what we use on native).\n // For now, just manually convert the value so our CLI interface can be unified.\n const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;\n\n if ('sendMessage' in this.instance.server) {\n // @ts-expect-error: https://github.com/expo/expo/issues/21994#issuecomment-1517122501\n this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);\n } else {\n this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);\n }\n }\n\n isTargetingNative(): boolean {\n return false;\n }\n\n private async getAvailablePortAsync(options: { defaultPort?: number }): Promise<number> {\n try {\n const defaultPort = options?.defaultPort ?? 19006;\n const port = await choosePortAsync(this.projectRoot, {\n defaultPort,\n host: env.WEB_HOST,\n });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', `Port ${defaultPort} not available.`);\n }\n return port;\n } catch (error: any) {\n throw new CommandError('NO_PORT_FOUND', error.message);\n }\n }\n\n async bundleAsync({ mode, clear }: { mode: 'development' | 'production'; clear: boolean }) {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n\n if (clear) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n const config = await this.loadConfigAsync({\n isImageEditingEnabled: true,\n mode,\n });\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n const bar = createProgressBar(chalk`{bold Web} Bundling Javascript [:bar] :percent`, {\n width: 64,\n total: 100,\n clear: true,\n complete: '=',\n incomplete: ' ',\n });\n\n // NOTE(EvanBacon): Add a progress bar to the webpack logger if defined (e.g. not in CI).\n if (bar != null) {\n config.plugins.push(\n new webpack.ProgressPlugin((percent: number) => {\n bar?.update(percent);\n if (percent === 1) {\n bar?.terminate();\n }\n })\n );\n }\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n try {\n await compileAsync(compiler);\n } catch (error: any) {\n Log.error(chalk.red('Failed to compile'));\n throw error;\n } finally {\n bar?.terminate();\n }\n }\n\n protected async startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance> {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n const WebpackDevServer = importWebpackDevServerFromProject(this.projectRoot);\n\n await this.stopAsync();\n\n options.port = await this.getAvailablePortAsync({\n defaultPort: options.port,\n });\n const { resetDevServer, https, port, mode } = options;\n\n this.urlCreator = this.getUrlCreator({\n port,\n location: {\n scheme: https ? 'https' : 'http',\n },\n });\n\n debug('Starting webpack on port: ' + port);\n\n if (resetDevServer) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n if (https) {\n debug('Configuring TLS to enable HTTPS support');\n await ensureEnvironmentSupportsTLSAsync(this.projectRoot).catch((error) => {\n Log.error(`Error creating TLS certificates: ${error}`);\n });\n }\n\n const config = await this.loadConfigAsync(options);\n\n Log.log(chalk`Starting Webpack on port ${port} in {underline ${mode}} mode.`);\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n const server = new WebpackDevServer(compiler, config.devServer);\n // Launch WebpackDevServer.\n server.listen(port, env.WEB_HOST, function (this: http.Server, error) {\n if (error) {\n Log.error(error.message);\n }\n });\n\n // Extend the close method to ensure that we clean up the local info.\n const originalClose = server.close.bind(server);\n\n server.close = (callback?: (err?: Error) => void) => {\n return originalClose((err?: Error) => {\n this.instance = null;\n callback?.(err);\n });\n };\n\n const _host = getIpAddress();\n const protocol = https ? 'https' : 'http';\n\n return {\n // Server instance\n server,\n // URL Info\n location: {\n url: `${protocol}://${_host}:${port}`,\n port,\n protocol,\n host: _host,\n },\n middleware: null,\n // Match the native protocol.\n messageSocket: {\n broadcast: this.broadcastMessage,\n },\n };\n }\n\n /** Load the Webpack config. Exposed for testing. */\n getProjectConfigFilePath(): string | null {\n // Check if the project has a webpack.config.js in the root.\n return (\n this.getConfigModuleIds().reduce<string | null | undefined>(\n (prev, moduleId) => prev || resolveFrom.silent(this.projectRoot, moduleId),\n null\n ) ?? null\n );\n }\n\n async loadConfigAsync(\n options: Pick<BundlerStartOptions, 'mode' | 'isImageEditingEnabled' | 'https'>,\n argv?: string[]\n ): Promise<WebpackConfiguration> {\n // let bar: ProgressBar | null = null;\n\n const env = {\n projectRoot: this.projectRoot,\n pwa: !!options.isImageEditingEnabled,\n // TODO: Use a new loader in Webpack config...\n logger: {\n info() {},\n },\n mode: options.mode,\n https: options.https,\n };\n setNodeEnv(env.mode ?? 'development');\n require('@expo/env').load(env.projectRoot);\n // Check if the project has a webpack.config.js in the root.\n const projectWebpackConfig = this.getProjectConfigFilePath();\n let config: WebpackConfiguration;\n if (projectWebpackConfig) {\n const webpackConfig = require(projectWebpackConfig);\n if (typeof webpackConfig === 'function') {\n config = await webpackConfig(env, argv);\n } else {\n config = webpackConfig;\n }\n } else {\n // Fallback to the default expo webpack config.\n const loadDefaultConfigAsync = importExpoWebpackConfigFromProject(this.projectRoot);\n config = await loadDefaultConfigAsync(env, argv);\n }\n return config;\n }\n\n protected getConfigModuleIds(): string[] {\n return ['./webpack.config.js'];\n }\n\n protected async clearWebProjectCacheAsync(\n projectRoot: string,\n mode: string = 'development'\n ): Promise<void> {\n Log.log(chalk.dim(`Clearing Webpack ${mode} cache directory...`));\n\n const dir = await ensureDotExpoProjectDirectoryInitialized(projectRoot);\n const cacheFolder = path.join(dir, 'web/cache', mode);\n try {\n await fs.promises.rm(cacheFolder, { recursive: true, force: true });\n } catch (error: any) {\n Log.error(`Could not clear ${mode} web cache directory: ${error.message}`);\n }\n }\n}\n\nexport function getProjectWebpackConfigFilePath(projectRoot: string) {\n return resolveFrom.silent(projectRoot, './webpack.config.js');\n}\n"],"names":["WebpackBundlerDevServer","getProjectWebpackConfigFilePath","debug","require","assertIsWebpackDevServer","value","sockWrite","sendMessage","CommandError","constructor","name","BundlerDevServer","startTypeScriptServices","broadcastMessage","method","params","instance","server","hackyConvertedMessage","sockets","isTargetingNative","getAvailablePortAsync","options","defaultPort","port","choosePortAsync","projectRoot","host","env","WEB_HOST","error","message","bundleAsync","mode","clear","webpack","importWebpackFromProject","clearWebProjectCacheAsync","config","loadConfigAsync","isImageEditingEnabled","plugins","bar","createProgressBar","chalk","width","total","complete","incomplete","push","ProgressPlugin","percent","update","terminate","compiler","compileAsync","Log","red","startImplementationAsync","WebpackDevServer","importWebpackDevServerFromProject","stopAsync","resetDevServer","https","urlCreator","getUrlCreator","location","scheme","ensureEnvironmentSupportsTLSAsync","catch","log","devServer","listen","originalClose","close","bind","callback","err","_host","getIpAddress","protocol","url","middleware","messageSocket","broadcast","getProjectConfigFilePath","getConfigModuleIds","reduce","prev","moduleId","resolveFrom","silent","argv","pwa","logger","info","setNodeEnv","load","projectWebpackConfig","webpackConfig","loadDefaultConfigAsync","importExpoWebpackConfigFromProject","dim","dir","ensureDotExpoProjectDirectoryInitialized","cacheFolder","path","join","fs","promises","rm","recursive","force"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/start/server/webpack/WebpackBundlerDevServer.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { Application } from 'express';\nimport fs from 'node:fs';\nimport http from 'node:http';\nimport path from 'node:path';\nimport resolveFrom from 'resolve-from';\nimport type webpack from 'webpack';\nimport type WebpackDevServer from 'webpack-dev-server';\n\nimport { compileAsync } from './compile';\nimport {\n importExpoWebpackConfigFromProject,\n importWebpackDevServerFromProject,\n importWebpackFromProject,\n} from './resolveFromProject';\nimport { ensureEnvironmentSupportsTLSAsync } from './tls';\nimport * as Log from '../../../log';\nimport { env } from '../../../utils/env';\nimport { CommandError } from '../../../utils/errors';\nimport { getIpAddress } from '../../../utils/ip';\nimport { setNodeEnv } from '../../../utils/nodeEnv';\nimport { choosePortAsync } from '../../../utils/port';\nimport { createProgressBar } from '../../../utils/progress';\nimport { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo';\nimport { BundlerDevServer, BundlerStartOptions, DevServerInstance } from '../BundlerDevServer';\n\nconst debug = require('debug')('expo:start:server:webpack:devServer') as typeof console.log;\n\nexport type WebpackConfiguration = webpack.Configuration & {\n devServer?: {\n before?: (app: Application, server: WebpackDevServer, compiler: webpack.Compiler) => void;\n };\n};\n\nfunction assertIsWebpackDevServer(value: any): asserts value is WebpackDevServer {\n if (!value?.sockWrite && !value?.sendMessage) {\n throw new CommandError(\n 'WEBPACK',\n value\n ? 'Expected Webpack dev server, found: ' + (value.constructor?.name ?? value)\n : 'Webpack dev server not started yet.'\n );\n }\n}\n\nexport class WebpackBundlerDevServer extends BundlerDevServer {\n get name(): string {\n return 'webpack';\n }\n\n public async startTypeScriptServices(): Promise<void> {\n // noop -- this feature is Metro-only.\n }\n\n public broadcastMessage(\n method: string | 'reload' | 'devMenu' | 'sendDevCommand',\n params?: Record<string, any>\n ): void {\n if (!this.instance) {\n return;\n }\n\n assertIsWebpackDevServer(this.instance?.server);\n\n // TODO(EvanBacon): Custom Webpack overlay.\n // Default webpack-dev-server sockets use \"content-changed\" instead of \"reload\" (what we use on native).\n // For now, just manually convert the value so our CLI interface can be unified.\n const hackyConvertedMessage = method === 'reload' ? 'content-changed' : method;\n\n if (\n 'sendMessage' in this.instance.server &&\n typeof this.instance.server.sendMessage === 'function'\n ) {\n // NOTE: https://github.com/expo/expo/issues/21994#issuecomment-1517122501\n this.instance.server.sendMessage(this.instance.server.sockets, hackyConvertedMessage, params);\n } else {\n this.instance.server.sockWrite(this.instance.server.sockets, hackyConvertedMessage, params);\n }\n }\n\n isTargetingNative(): boolean {\n return false;\n }\n\n private async getAvailablePortAsync(options: { defaultPort?: number }): Promise<number> {\n try {\n const defaultPort = options?.defaultPort ?? 19006;\n const port = await choosePortAsync(this.projectRoot, {\n defaultPort,\n host: env.WEB_HOST,\n });\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', `Port ${defaultPort} not available.`);\n }\n return port;\n } catch (error: any) {\n throw new CommandError('NO_PORT_FOUND', error.message);\n }\n }\n\n async bundleAsync({ mode, clear }: { mode: 'development' | 'production'; clear: boolean }) {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n\n if (clear) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n const config = await this.loadConfigAsync({\n isImageEditingEnabled: true,\n mode,\n });\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n const bar = createProgressBar(chalk`{bold Web} Bundling Javascript [:bar] :percent`, {\n width: 64,\n total: 100,\n clear: true,\n complete: '=',\n incomplete: ' ',\n });\n\n // NOTE(EvanBacon): Add a progress bar to the webpack logger if defined (e.g. not in CI).\n if (bar != null) {\n config.plugins.push(\n new webpack.ProgressPlugin((percent: number) => {\n bar?.update(percent);\n if (percent === 1) {\n bar?.terminate();\n }\n })\n );\n }\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n try {\n await compileAsync(compiler);\n } catch (error: any) {\n Log.error(chalk.red('Failed to compile'));\n throw error;\n } finally {\n bar?.terminate();\n }\n }\n\n protected async startImplementationAsync(\n options: BundlerStartOptions\n ): Promise<DevServerInstance> {\n // Do this first to fail faster.\n const webpack = importWebpackFromProject(this.projectRoot);\n const WebpackDevServer = importWebpackDevServerFromProject(this.projectRoot);\n\n await this.stopAsync();\n\n options.port = await this.getAvailablePortAsync({\n defaultPort: options.port,\n });\n const { resetDevServer, https, port, mode } = options;\n\n this.urlCreator = this.getUrlCreator({\n port,\n location: {\n scheme: https ? 'https' : 'http',\n },\n });\n\n debug('Starting webpack on port: ' + port);\n\n if (resetDevServer) {\n await this.clearWebProjectCacheAsync(this.projectRoot, mode);\n }\n\n if (https) {\n debug('Configuring TLS to enable HTTPS support');\n await ensureEnvironmentSupportsTLSAsync(this.projectRoot).catch((error) => {\n Log.error(`Error creating TLS certificates: ${error}`);\n });\n }\n\n const config = await this.loadConfigAsync(options);\n\n Log.log(chalk`Starting Webpack on port ${port} in {underline ${mode}} mode.`);\n\n // Create a webpack compiler that is configured with custom messages.\n const compiler = webpack(config);\n\n const server = new WebpackDevServer(compiler, config.devServer);\n // Launch WebpackDevServer.\n server.listen(port, env.WEB_HOST, function (this: http.Server, error) {\n if (error) {\n Log.error(error.message);\n }\n });\n\n // Extend the close method to ensure that we clean up the local info.\n const originalClose = server.close.bind(server);\n\n server.close = (callback?: (err?: Error) => void) => {\n return originalClose((err?: Error) => {\n this.instance = null;\n callback?.(err);\n });\n };\n\n const _host = getIpAddress();\n const protocol = https ? 'https' : 'http';\n\n return {\n // Server instance\n server,\n // URL Info\n location: {\n url: `${protocol}://${_host}:${port}`,\n port,\n protocol,\n host: _host,\n },\n middleware: null,\n // Match the native protocol.\n messageSocket: {\n broadcast: this.broadcastMessage,\n },\n };\n }\n\n /** Load the Webpack config. Exposed for testing. */\n getProjectConfigFilePath(): string | null {\n // Check if the project has a webpack.config.js in the root.\n return (\n this.getConfigModuleIds().reduce<string | null | undefined>(\n (prev, moduleId) => prev || resolveFrom.silent(this.projectRoot, moduleId),\n null\n ) ?? null\n );\n }\n\n async loadConfigAsync(\n options: Pick<BundlerStartOptions, 'mode' | 'isImageEditingEnabled' | 'https'>,\n argv?: string[]\n ): Promise<WebpackConfiguration> {\n // let bar: ProgressBar | null = null;\n\n const env = {\n projectRoot: this.projectRoot,\n pwa: !!options.isImageEditingEnabled,\n // TODO: Use a new loader in Webpack config...\n logger: {\n info() {},\n },\n mode: options.mode,\n https: options.https,\n };\n setNodeEnv(env.mode ?? 'development');\n require('@expo/env').load(env.projectRoot);\n // Check if the project has a webpack.config.js in the root.\n const projectWebpackConfig = this.getProjectConfigFilePath();\n let config: WebpackConfiguration;\n if (projectWebpackConfig) {\n const webpackConfig = require(projectWebpackConfig);\n if (typeof webpackConfig === 'function') {\n config = await webpackConfig(env, argv);\n } else {\n config = webpackConfig;\n }\n } else {\n // Fallback to the default expo webpack config.\n const loadDefaultConfigAsync = importExpoWebpackConfigFromProject(this.projectRoot);\n config = await loadDefaultConfigAsync(env, argv);\n }\n return config;\n }\n\n protected getConfigModuleIds(): string[] {\n return ['./webpack.config.js'];\n }\n\n protected async clearWebProjectCacheAsync(\n projectRoot: string,\n mode: string = 'development'\n ): Promise<void> {\n Log.log(chalk.dim(`Clearing Webpack ${mode} cache directory...`));\n\n const dir = await ensureDotExpoProjectDirectoryInitialized(projectRoot);\n const cacheFolder = path.join(dir, 'web/cache', mode);\n try {\n await fs.promises.rm(cacheFolder, { recursive: true, force: true });\n } catch (error: any) {\n Log.error(`Could not clear ${mode} web cache directory: ${error.message}`);\n }\n }\n}\n\nexport function getProjectWebpackConfigFilePath(projectRoot: string) {\n return resolveFrom.silent(projectRoot, './webpack.config.js');\n}\n"],"names":["WebpackBundlerDevServer","getProjectWebpackConfigFilePath","debug","require","assertIsWebpackDevServer","value","sockWrite","sendMessage","CommandError","constructor","name","BundlerDevServer","startTypeScriptServices","broadcastMessage","method","params","instance","server","hackyConvertedMessage","sockets","isTargetingNative","getAvailablePortAsync","options","defaultPort","port","choosePortAsync","projectRoot","host","env","WEB_HOST","error","message","bundleAsync","mode","clear","webpack","importWebpackFromProject","clearWebProjectCacheAsync","config","loadConfigAsync","isImageEditingEnabled","plugins","bar","createProgressBar","chalk","width","total","complete","incomplete","push","ProgressPlugin","percent","update","terminate","compiler","compileAsync","Log","red","startImplementationAsync","WebpackDevServer","importWebpackDevServerFromProject","stopAsync","resetDevServer","https","urlCreator","getUrlCreator","location","scheme","ensureEnvironmentSupportsTLSAsync","catch","log","devServer","listen","originalClose","close","bind","callback","err","_host","getIpAddress","protocol","url","middleware","messageSocket","broadcast","getProjectConfigFilePath","getConfigModuleIds","reduce","prev","moduleId","resolveFrom","silent","argv","pwa","logger","info","setNodeEnv","load","projectWebpackConfig","webpackConfig","loadDefaultConfigAsync","importExpoWebpackConfigFromProject","dim","dir","ensureDotExpoProjectDirectoryInitialized","cacheFolder","path","join","fs","promises","rm","recursive","force"],"mappings":"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"}
|
|
@@ -157,12 +157,12 @@ async function startAsync(projectRoot, options, settings) {
|
|
|
157
157
|
// Open project on devices.
|
|
158
158
|
await (0, _profile.profile)(_openPlatforms.openPlatformsAsync)(devServerManager, options);
|
|
159
159
|
const defaultServerUrl = ((_devServerManager_getDefaultDevServer = devServerManager.getDefaultDevServer()) == null ? void 0 : _devServerManager_getDefaultDevServer.getDevServerUrl()) ?? '';
|
|
160
|
+
const mcpServer = await (0, _profile.profile)(_MCP.maybeCreateMCPServerAsync)({
|
|
161
|
+
projectRoot,
|
|
162
|
+
devServerUrl: defaultServerUrl
|
|
163
|
+
}) ?? undefined;
|
|
160
164
|
// Present the Terminal UI.
|
|
161
165
|
if ((0, _interactive.isInteractive)()) {
|
|
162
|
-
const mcpServer = await (0, _profile.profile)(_MCP.maybeCreateMCPServerAsync)({
|
|
163
|
-
projectRoot,
|
|
164
|
-
devServerUrl: defaultServerUrl
|
|
165
|
-
}) ?? undefined;
|
|
166
166
|
await (0, _profile.profile)(_startInterface.startInterfaceAsync)(devServerManager, {
|
|
167
167
|
platforms: exp.platforms ?? [
|
|
168
168
|
'ios',
|
|
@@ -171,7 +171,6 @@ async function startAsync(projectRoot, options, settings) {
|
|
|
171
171
|
],
|
|
172
172
|
mcpServer
|
|
173
173
|
});
|
|
174
|
-
mcpServer == null ? void 0 : mcpServer.start();
|
|
175
174
|
} else {
|
|
176
175
|
// Display the server location in CI...
|
|
177
176
|
if (defaultServerUrl) {
|
|
@@ -184,6 +183,7 @@ async function startAsync(projectRoot, options, settings) {
|
|
|
184
183
|
_log.log((0, _chalk().default)`Waiting on {underline ${defaultServerUrl}}`);
|
|
185
184
|
}
|
|
186
185
|
}
|
|
186
|
+
mcpServer == null ? void 0 : mcpServer.start();
|
|
187
187
|
// Final note about closing the server.
|
|
188
188
|
const logLocation = settings.webOnly ? 'in the browser console' : 'below';
|
|
189
189
|
_log.log((0, _chalk().default)`Logs for your project will appear ${logLocation}.${(0, _interactive.isInteractive)() ? _chalk().default.dim(` Press Ctrl+C to exit.`) : ''}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/start/startAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { SimulatorAppPrerequisite } from './doctor/apple/SimulatorAppPrerequisite';\nimport { getXcodeVersionAsync } from './doctor/apple/XcodePrerequisite';\nimport { validateDependenciesVersionsAsync } from './doctor/dependencies/validateDependenciesVersions';\nimport { WebSupportProjectPrerequisite } from './doctor/web/WebSupportProjectPrerequisite';\nimport { startInterfaceAsync } from './interface/startInterface';\nimport { Options, resolvePortsAsync } from './resolveOptions';\nimport * as Log from '../log';\nimport { BundlerStartOptions } from './server/BundlerDevServer';\nimport { DevServerManager, MultiBundlerStartOptions } from './server/DevServerManager';\nimport { openPlatformsAsync } from './server/openPlatforms';\nimport { getPlatformBundlers, PlatformBundlers } from './server/platformBundlers';\nimport { env } from '../utils/env';\nimport { isInteractive } from '../utils/interactive';\nimport { profile } from '../utils/profile';\nimport { maybeCreateMCPServerAsync } from './server/MCP';\n\nasync function getMultiBundlerStartOptions(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean },\n platformBundlers: PlatformBundlers\n): Promise<[BundlerStartOptions, MultiBundlerStartOptions]> {\n const commonOptions: BundlerStartOptions = {\n mode: options.dev ? 'development' : 'production',\n devClient: options.devClient,\n privateKeyPath: options.privateKeyPath ?? undefined,\n https: options.https,\n maxWorkers: options.maxWorkers,\n resetDevServer: options.clear,\n minify: options.minify,\n location: {\n hostType: options.host,\n scheme: options.scheme,\n },\n };\n const multiBundlerSettings = await resolvePortsAsync(projectRoot, options, settings);\n\n const optionalBundlers: Partial<PlatformBundlers> = { ...platformBundlers };\n // In the default case, we don't want to start multiple bundlers since this is\n // a bit slower. Our priority (for legacy) is native platforms.\n if (!options.web) {\n delete optionalBundlers['web'];\n }\n\n const bundlers = [...new Set(Object.values(optionalBundlers))];\n const multiBundlerStartOptions = bundlers.map((bundler) => {\n const port =\n bundler === 'webpack' ? multiBundlerSettings.webpackPort : multiBundlerSettings.metroPort;\n return {\n type: bundler,\n options: {\n ...commonOptions,\n port,\n },\n };\n });\n\n return [commonOptions, multiBundlerStartOptions];\n}\n\nexport async function startAsync(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean }\n) {\n Log.log(chalk.gray(`Starting project at ${projectRoot}`));\n\n const { exp, pkg } = profile(getConfig)(projectRoot);\n\n if (exp.platforms?.includes('ios') && process.platform !== 'win32') {\n // If Xcode could potentially be used, then we should eagerly perform the\n // assertions since they can take a while on cold boots.\n getXcodeVersionAsync({ silent: true });\n SimulatorAppPrerequisite.instance.assertAsync().catch(() => {\n // noop -- this will be thrown again when the user attempts to open the project.\n });\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const [defaultOptions, startOptions] = await getMultiBundlerStartOptions(\n projectRoot,\n options,\n settings,\n platformBundlers\n );\n\n const devServerManager = new DevServerManager(projectRoot, defaultOptions);\n\n // Validations\n\n if (options.web || settings.webOnly) {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n }\n\n // Start the server as soon as possible.\n await profile(devServerManager.startAsync.bind(devServerManager))(startOptions);\n\n if (!settings.webOnly) {\n await devServerManager.watchEnvironmentVariables();\n\n // After the server starts, we can start attempting to bootstrap TypeScript.\n await devServerManager.bootstrapTypeScriptAsync();\n }\n\n if (!env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly && !options.devClient) {\n await profile(validateDependenciesVersionsAsync)(projectRoot, exp, pkg);\n }\n\n // Open project on devices.\n await profile(openPlatformsAsync)(devServerManager, options);\n\n const defaultServerUrl = devServerManager.getDefaultDevServer()?.getDevServerUrl() ?? '';\n
|
|
1
|
+
{"version":3,"sources":["../../../src/start/startAsync.ts"],"sourcesContent":["import { getConfig } from '@expo/config';\nimport chalk from 'chalk';\n\nimport { SimulatorAppPrerequisite } from './doctor/apple/SimulatorAppPrerequisite';\nimport { getXcodeVersionAsync } from './doctor/apple/XcodePrerequisite';\nimport { validateDependenciesVersionsAsync } from './doctor/dependencies/validateDependenciesVersions';\nimport { WebSupportProjectPrerequisite } from './doctor/web/WebSupportProjectPrerequisite';\nimport { startInterfaceAsync } from './interface/startInterface';\nimport { Options, resolvePortsAsync } from './resolveOptions';\nimport * as Log from '../log';\nimport { BundlerStartOptions } from './server/BundlerDevServer';\nimport { DevServerManager, MultiBundlerStartOptions } from './server/DevServerManager';\nimport { openPlatformsAsync } from './server/openPlatforms';\nimport { getPlatformBundlers, PlatformBundlers } from './server/platformBundlers';\nimport { env } from '../utils/env';\nimport { isInteractive } from '../utils/interactive';\nimport { profile } from '../utils/profile';\nimport { maybeCreateMCPServerAsync } from './server/MCP';\n\nasync function getMultiBundlerStartOptions(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean },\n platformBundlers: PlatformBundlers\n): Promise<[BundlerStartOptions, MultiBundlerStartOptions]> {\n const commonOptions: BundlerStartOptions = {\n mode: options.dev ? 'development' : 'production',\n devClient: options.devClient,\n privateKeyPath: options.privateKeyPath ?? undefined,\n https: options.https,\n maxWorkers: options.maxWorkers,\n resetDevServer: options.clear,\n minify: options.minify,\n location: {\n hostType: options.host,\n scheme: options.scheme,\n },\n };\n const multiBundlerSettings = await resolvePortsAsync(projectRoot, options, settings);\n\n const optionalBundlers: Partial<PlatformBundlers> = { ...platformBundlers };\n // In the default case, we don't want to start multiple bundlers since this is\n // a bit slower. Our priority (for legacy) is native platforms.\n if (!options.web) {\n delete optionalBundlers['web'];\n }\n\n const bundlers = [...new Set(Object.values(optionalBundlers))];\n const multiBundlerStartOptions = bundlers.map((bundler) => {\n const port =\n bundler === 'webpack' ? multiBundlerSettings.webpackPort : multiBundlerSettings.metroPort;\n return {\n type: bundler,\n options: {\n ...commonOptions,\n port,\n },\n };\n });\n\n return [commonOptions, multiBundlerStartOptions];\n}\n\nexport async function startAsync(\n projectRoot: string,\n options: Options,\n settings: { webOnly?: boolean }\n) {\n Log.log(chalk.gray(`Starting project at ${projectRoot}`));\n\n const { exp, pkg } = profile(getConfig)(projectRoot);\n\n if (exp.platforms?.includes('ios') && process.platform !== 'win32') {\n // If Xcode could potentially be used, then we should eagerly perform the\n // assertions since they can take a while on cold boots.\n getXcodeVersionAsync({ silent: true });\n SimulatorAppPrerequisite.instance.assertAsync().catch(() => {\n // noop -- this will be thrown again when the user attempts to open the project.\n });\n }\n\n const platformBundlers = getPlatformBundlers(projectRoot, exp);\n\n const [defaultOptions, startOptions] = await getMultiBundlerStartOptions(\n projectRoot,\n options,\n settings,\n platformBundlers\n );\n\n const devServerManager = new DevServerManager(projectRoot, defaultOptions);\n\n // Validations\n\n if (options.web || settings.webOnly) {\n await devServerManager.ensureProjectPrerequisiteAsync(WebSupportProjectPrerequisite);\n }\n\n // Start the server as soon as possible.\n await profile(devServerManager.startAsync.bind(devServerManager))(startOptions);\n\n if (!settings.webOnly) {\n await devServerManager.watchEnvironmentVariables();\n\n // After the server starts, we can start attempting to bootstrap TypeScript.\n await devServerManager.bootstrapTypeScriptAsync();\n }\n\n if (!env.EXPO_NO_DEPENDENCY_VALIDATION && !settings.webOnly && !options.devClient) {\n await profile(validateDependenciesVersionsAsync)(projectRoot, exp, pkg);\n }\n\n // Open project on devices.\n await profile(openPlatformsAsync)(devServerManager, options);\n\n const defaultServerUrl = devServerManager.getDefaultDevServer()?.getDevServerUrl() ?? '';\n const mcpServer =\n (await profile(maybeCreateMCPServerAsync)({\n projectRoot,\n devServerUrl: defaultServerUrl,\n })) ?? undefined;\n\n // Present the Terminal UI.\n if (isInteractive()) {\n await profile(startInterfaceAsync)(devServerManager, {\n platforms: exp.platforms ?? ['ios', 'android', 'web'],\n mcpServer,\n });\n } else {\n // Display the server location in CI...\n if (defaultServerUrl) {\n if (env.__EXPO_E2E_TEST) {\n // Print the URL to stdout for tests\n console.info(`[__EXPO_E2E_TEST:server] ${JSON.stringify({ url: defaultServerUrl })}`);\n }\n Log.log(chalk`Waiting on {underline ${defaultServerUrl}}`);\n }\n }\n mcpServer?.start();\n\n // Final note about closing the server.\n const logLocation = settings.webOnly ? 'in the browser console' : 'below';\n Log.log(\n chalk`Logs for your project will appear ${logLocation}.${\n isInteractive() ? chalk.dim(` Press Ctrl+C to exit.`) : ''\n }`\n );\n}\n"],"names":["startAsync","getMultiBundlerStartOptions","projectRoot","options","settings","platformBundlers","commonOptions","mode","dev","devClient","privateKeyPath","undefined","https","maxWorkers","resetDevServer","clear","minify","location","hostType","host","scheme","multiBundlerSettings","resolvePortsAsync","optionalBundlers","web","bundlers","Set","Object","values","multiBundlerStartOptions","map","bundler","port","webpackPort","metroPort","type","exp","devServerManager","Log","log","chalk","gray","pkg","profile","getConfig","platforms","includes","process","platform","getXcodeVersionAsync","silent","SimulatorAppPrerequisite","instance","assertAsync","catch","getPlatformBundlers","defaultOptions","startOptions","DevServerManager","webOnly","ensureProjectPrerequisiteAsync","WebSupportProjectPrerequisite","bind","watchEnvironmentVariables","bootstrapTypeScriptAsync","env","EXPO_NO_DEPENDENCY_VALIDATION","validateDependenciesVersionsAsync","openPlatformsAsync","defaultServerUrl","getDefaultDevServer","getDevServerUrl","mcpServer","maybeCreateMCPServerAsync","devServerUrl","isInteractive","startInterfaceAsync","__EXPO_E2E_TEST","console","info","JSON","stringify","url","start","logLocation","dim"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/downloadExpoGoAsync.ts"],"sourcesContent":["import path from 'path';\nimport ProgressBar from 'progress';\nimport { gt } from 'semver';\n\nimport { downloadAppAsync } from './downloadAppAsync';\nimport { CommandError } from './errors';\nimport { ora } from './ora';\nimport { profile } from './profile';\nimport { createProgressBar } from './progress';\nimport { getVersionsAsync, SDKVersion } from '../api/getVersions';\nimport { getExpoHomeDirectory } from '../api/user/UserSettings';\nimport { Log } from '../log';\n\nconst debug = require('debug')('expo:utils:downloadExpoGo') as typeof console.log;\n\nconst platformSettings: Record<\n string,\n {\n shouldExtractResults: boolean;\n versionsKey: keyof SDKVersion;\n getFilePath: (filename: string) => string;\n }\n> = {\n ios: {\n versionsKey: 'iosClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'ios-simulator-app-cache', `${filename}.app`),\n shouldExtractResults: true,\n },\n android: {\n versionsKey: 'androidClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'android-apk-cache', `${filename}.apk`),\n shouldExtractResults: false,\n },\n};\n\n/**\n * @internal exposed for testing.\n * @returns the matching `SDKVersion` object from the Expo API.\n */\nexport async function getExpoGoVersionEntryAsync(sdkVersion: string): Promise<SDKVersion> {\n const { sdkVersions: versions } = await getVersionsAsync();\n let version: SDKVersion;\n\n if (sdkVersion.toUpperCase() === 'UNVERSIONED') {\n // find the latest version\n const latestVersionKey = Object.keys(versions).reduce((a, b) => {\n if (gt(b, a)) {\n return b;\n }\n return a;\n }, '0.0.0');\n\n Log.warn(\n `Downloading the latest Expo Go client (${latestVersionKey}). This will not fully conform to UNVERSIONED.`\n );\n version = versions[latestVersionKey];\n } else {\n version = versions[sdkVersion];\n }\n\n if (!version) {\n throw new CommandError(`Unable to find a version of Expo Go for SDK ${sdkVersion}`);\n }\n return version;\n}\n\n/** Download the Expo Go app from the Expo servers (if only it was this easy for every app). */\nexport async function downloadExpoGoAsync(\n platform: keyof typeof platformSettings,\n {\n url,\n sdkVersion,\n }: {\n url?: string;\n sdkVersion: string;\n }\n): Promise<string> {\n const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform];\n\n const spinner = ora({ text: 'Fetching Expo Go', color: 'white' }).start();\n\n let bar: ProgressBar | null = null;\n\n try {\n if (!url) {\n const version = await getExpoGoVersionEntryAsync(sdkVersion);\n\n debug(`Installing Expo Go version for SDK ${sdkVersion} at URL: ${version[versionsKey]}`);\n url = version[versionsKey] as string;\n }\n } catch (error) {\n spinner.fail();\n throw error;\n }\n\n const filename = path.parse(url).name;\n\n try {\n const outputPath = getFilePath(filename);\n debug(`Downloading Expo Go from \"${url}\" to \"${outputPath}\".`);\n debug(\n `The requested copy of Expo Go might already be cached in: \"${getExpoHomeDirectory()}\". You can disable the cache with EXPO_NO_CACHE=1`\n );\n await profile(downloadAppAsync)({\n url,\n // Save all encrypted cache data to `~/.expo/expo-go`\n cacheDirectory: 'expo-go',\n outputPath,\n extract: shouldExtractResults,\n onProgress({ progress, total }) {\n if (progress && total) {\n if (!bar) {\n if (spinner.isSpinning) {\n spinner.stop();\n }\n bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', {\n width: 64,\n total: 100,\n // clear: true,\n complete: '=',\n incomplete: ' ',\n });\n } else {\n bar
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/downloadExpoGoAsync.ts"],"sourcesContent":["import path from 'path';\nimport ProgressBar from 'progress';\nimport { gt } from 'semver';\n\nimport { downloadAppAsync } from './downloadAppAsync';\nimport { CommandError } from './errors';\nimport { ora } from './ora';\nimport { profile } from './profile';\nimport { createProgressBar } from './progress';\nimport { getVersionsAsync, SDKVersion } from '../api/getVersions';\nimport { getExpoHomeDirectory } from '../api/user/UserSettings';\nimport { Log } from '../log';\n\nconst debug = require('debug')('expo:utils:downloadExpoGo') as typeof console.log;\n\nconst platformSettings: Record<\n string,\n {\n shouldExtractResults: boolean;\n versionsKey: keyof SDKVersion;\n getFilePath: (filename: string) => string;\n }\n> = {\n ios: {\n versionsKey: 'iosClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'ios-simulator-app-cache', `${filename}.app`),\n shouldExtractResults: true,\n },\n android: {\n versionsKey: 'androidClientUrl',\n getFilePath: (filename) =>\n path.join(getExpoHomeDirectory(), 'android-apk-cache', `${filename}.apk`),\n shouldExtractResults: false,\n },\n};\n\n/**\n * @internal exposed for testing.\n * @returns the matching `SDKVersion` object from the Expo API.\n */\nexport async function getExpoGoVersionEntryAsync(sdkVersion: string): Promise<SDKVersion> {\n const { sdkVersions: versions } = await getVersionsAsync();\n let version: SDKVersion;\n\n if (sdkVersion.toUpperCase() === 'UNVERSIONED') {\n // find the latest version\n const latestVersionKey = Object.keys(versions).reduce((a, b) => {\n if (gt(b, a)) {\n return b;\n }\n return a;\n }, '0.0.0');\n\n Log.warn(\n `Downloading the latest Expo Go client (${latestVersionKey}). This will not fully conform to UNVERSIONED.`\n );\n version = versions[latestVersionKey];\n } else {\n version = versions[sdkVersion];\n }\n\n if (!version) {\n throw new CommandError(`Unable to find a version of Expo Go for SDK ${sdkVersion}`);\n }\n return version;\n}\n\n/** Download the Expo Go app from the Expo servers (if only it was this easy for every app). */\nexport async function downloadExpoGoAsync(\n platform: keyof typeof platformSettings,\n {\n url,\n sdkVersion,\n }: {\n url?: string;\n sdkVersion: string;\n }\n): Promise<string> {\n const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform];\n\n const spinner = ora({ text: 'Fetching Expo Go', color: 'white' }).start();\n\n let bar: ProgressBar | null = null;\n\n try {\n if (!url) {\n const version = await getExpoGoVersionEntryAsync(sdkVersion);\n\n debug(`Installing Expo Go version for SDK ${sdkVersion} at URL: ${version[versionsKey]}`);\n url = version[versionsKey] as string;\n }\n } catch (error) {\n spinner.fail();\n throw error;\n }\n\n const filename = path.parse(url).name;\n\n try {\n const outputPath = getFilePath(filename);\n debug(`Downloading Expo Go from \"${url}\" to \"${outputPath}\".`);\n debug(\n `The requested copy of Expo Go might already be cached in: \"${getExpoHomeDirectory()}\". You can disable the cache with EXPO_NO_CACHE=1`\n );\n await profile(downloadAppAsync)({\n url,\n // Save all encrypted cache data to `~/.expo/expo-go`\n cacheDirectory: 'expo-go',\n outputPath,\n extract: shouldExtractResults,\n onProgress({ progress, total }) {\n if (progress && total) {\n if (!bar) {\n if (spinner.isSpinning) {\n spinner.stop();\n }\n bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', {\n width: 64,\n total: 100,\n // clear: true,\n complete: '=',\n incomplete: ' ',\n });\n } else {\n bar.update(progress, total);\n }\n }\n },\n });\n return outputPath;\n } finally {\n spinner.stop();\n (bar as ProgressBar | null)?.terminate();\n }\n}\n"],"names":["downloadExpoGoAsync","getExpoGoVersionEntryAsync","debug","require","platformSettings","ios","versionsKey","getFilePath","filename","path","join","getExpoHomeDirectory","shouldExtractResults","android","sdkVersion","sdkVersions","versions","getVersionsAsync","version","toUpperCase","latestVersionKey","Object","keys","reduce","a","b","gt","Log","warn","CommandError","platform","url","spinner","ora","text","color","start","bar","error","fail","parse","name","outputPath","profile","downloadAppAsync","cacheDirectory","extract","onProgress","progress","total","isSpinning","stop","createProgressBar","width","complete","incomplete","update","terminate"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/errors.ts"],"sourcesContent":["import { AssertionError } from 'assert';\nimport chalk from 'chalk';\nimport { execSync } from 'child_process';\n\nimport { exit, exception, warn } from '../log';\n\nconst ERROR_PREFIX = 'Error: ';\n\n/**\n * General error, formatted as a message in red text when caught by expo-cli (no stack trace is printed). Should be used in favor of `log.error()` in most cases.\n */\nexport class CommandError extends Error {\n name = 'CommandError';\n readonly isCommandError = true;\n\n constructor(\n public code: string,\n message: string = ''\n ) {\n super('');\n // If e.toString() was called to get `message` we don't want it to look\n // like \"Error: Error:\".\n if (message.startsWith(ERROR_PREFIX)) {\n message = message.substring(ERROR_PREFIX.length);\n }\n\n this.message = message || code;\n }\n}\n\nexport class AbortCommandError extends CommandError {\n constructor() {\n super('ABORTED', 'Interactive prompt was cancelled.');\n }\n}\n\n/**\n * Used to end a CLI process without printing a stack trace in the Expo CLI. Should be used in favor of `process.exit`.\n */\nexport class SilentError extends CommandError {\n constructor(messageOrError?: string | Error) {\n const message =\n (typeof messageOrError === 'string' ? messageOrError : messageOrError?.message) ??\n 'This error should fail silently in the CLI';\n super('SILENT', message);\n if (typeof messageOrError !== 'string') {\n // forward the props of the incoming error for tests or processes outside of expo-cli that use expo cli internals.\n this.stack = messageOrError?.stack ?? this.stack;\n this.name = messageOrError?.name ?? this.name;\n }\n }\n}\n\nexport function logCmdError(error: any): never {\n if (!(error instanceof Error)) {\n throw error;\n }\n if (error instanceof AbortCommandError || error instanceof SilentError) {\n // Do nothing, this is used for prompts or other cases that were custom logged.\n process.exit(1);\n } else if (\n error instanceof CommandError ||\n error instanceof AssertionError ||\n error.name === 'ApiV2Error' ||\n error.name === 'ConfigError'\n ) {\n // Print the stack trace in debug mode only.\n exit(error);\n }\n\n const errorDetails = error.stack ? '\\n' + chalk.gray(error.stack) : '';\n\n exit(chalk.red(error.toString()) + errorDetails);\n}\n\n/** This should never be thrown in production. */\nexport class UnimplementedError extends Error {\n constructor() {\n super('Unimplemented');\n this.name = 'UnimplementedError';\n }\n}\n\n/**\n * Add additional information when EMFILE errors are encountered.\n * These errors originate from Metro's FSEventsWatcher due to `fsevents` going over MacOS system limit.\n * Unfortunately, these limits in macOS are relatively low compared to an average React Native project.\n *\n * @see https://github.com/expo/expo/issues/29083\n * @see https://github.com/facebook/metro/issues/834\n * @see https://github.com/fsevents/fsevents/issues/42#issuecomment-62632234\n */\nfunction handleTooManyOpenFileErrors(error: any) {\n // Only enable special logging when running on macOS and are running into the `EMFILE` error\n if ('code' in error && error.code === 'EMFILE' && process.platform === 'darwin') {\n try {\n // Try to recover watchman, if it's not installed this will throw\n execSync('watchman shutdown-server', { stdio: 'ignore' });\n // NOTE(cedric): this both starts the watchman server and resets all watchers\n execSync('watchman watch-del-all', { stdio: 'ignore' });\n\n warn(\n 'Watchman is installed but was likely not enabled when starting Metro, try starting your project again.\\nIf this problem persists, follow the troubleshooting guide of Watchman: https://facebook.github.io/watchman/docs/troubleshooting'\n );\n } catch {\n warn(\n `Your macOS system limit does not allow enough watchers for Metro, install Watchman instead. Learn more: https://facebook.github.io/watchman/docs/install`\n );\n }\n\n exception(error);\n process.exit(1);\n }\n\n throw error;\n}\n\nprocess.on('uncaughtException', handleTooManyOpenFileErrors);\n"],"names":["AbortCommandError","CommandError","SilentError","UnimplementedError","logCmdError","ERROR_PREFIX","Error","constructor","code","message","name","isCommandError","startsWith","substring","length","messageOrError","stack","error","process","exit","AssertionError","errorDetails","chalk","gray","red","toString","handleTooManyOpenFileErrors","platform","execSync","stdio","warn","exception","on"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/errors.ts"],"sourcesContent":["import { AssertionError } from 'assert';\nimport chalk from 'chalk';\nimport { execSync } from 'child_process';\n\nimport { exit, exception, warn } from '../log';\n\nconst ERROR_PREFIX = 'Error: ';\n\n/**\n * General error, formatted as a message in red text when caught by expo-cli (no stack trace is printed). Should be used in favor of `log.error()` in most cases.\n */\nexport class CommandError extends Error {\n name = 'CommandError';\n readonly isCommandError = true;\n [prop: string]: unknown;\n\n constructor(\n public code: string,\n message: string = ''\n ) {\n super('');\n // If e.toString() was called to get `message` we don't want it to look\n // like \"Error: Error:\".\n if (message.startsWith(ERROR_PREFIX)) {\n message = message.substring(ERROR_PREFIX.length);\n }\n\n this.message = message || code;\n }\n}\n\nexport class AbortCommandError extends CommandError {\n constructor() {\n super('ABORTED', 'Interactive prompt was cancelled.');\n }\n}\n\n/**\n * Used to end a CLI process without printing a stack trace in the Expo CLI. Should be used in favor of `process.exit`.\n */\nexport class SilentError extends CommandError {\n constructor(messageOrError?: string | Error) {\n const message =\n (typeof messageOrError === 'string' ? messageOrError : messageOrError?.message) ??\n 'This error should fail silently in the CLI';\n super('SILENT', message);\n if (typeof messageOrError !== 'string') {\n // forward the props of the incoming error for tests or processes outside of expo-cli that use expo cli internals.\n this.stack = messageOrError?.stack ?? this.stack;\n this.name = messageOrError?.name ?? this.name;\n }\n }\n}\n\nexport function logCmdError(error: any): never {\n if (!(error instanceof Error)) {\n throw error;\n }\n if (error instanceof AbortCommandError || error instanceof SilentError) {\n // Do nothing, this is used for prompts or other cases that were custom logged.\n process.exit(1);\n } else if (\n error instanceof CommandError ||\n error instanceof AssertionError ||\n error.name === 'ApiV2Error' ||\n error.name === 'ConfigError'\n ) {\n // Print the stack trace in debug mode only.\n exit(error);\n }\n\n const errorDetails = error.stack ? '\\n' + chalk.gray(error.stack) : '';\n\n exit(chalk.red(error.toString()) + errorDetails);\n}\n\n/** This should never be thrown in production. */\nexport class UnimplementedError extends Error {\n constructor() {\n super('Unimplemented');\n this.name = 'UnimplementedError';\n }\n}\n\n/**\n * Add additional information when EMFILE errors are encountered.\n * These errors originate from Metro's FSEventsWatcher due to `fsevents` going over MacOS system limit.\n * Unfortunately, these limits in macOS are relatively low compared to an average React Native project.\n *\n * @see https://github.com/expo/expo/issues/29083\n * @see https://github.com/facebook/metro/issues/834\n * @see https://github.com/fsevents/fsevents/issues/42#issuecomment-62632234\n */\nfunction handleTooManyOpenFileErrors(error: any) {\n // Only enable special logging when running on macOS and are running into the `EMFILE` error\n if ('code' in error && error.code === 'EMFILE' && process.platform === 'darwin') {\n try {\n // Try to recover watchman, if it's not installed this will throw\n execSync('watchman shutdown-server', { stdio: 'ignore' });\n // NOTE(cedric): this both starts the watchman server and resets all watchers\n execSync('watchman watch-del-all', { stdio: 'ignore' });\n\n warn(\n 'Watchman is installed but was likely not enabled when starting Metro, try starting your project again.\\nIf this problem persists, follow the troubleshooting guide of Watchman: https://facebook.github.io/watchman/docs/troubleshooting'\n );\n } catch {\n warn(\n `Your macOS system limit does not allow enough watchers for Metro, install Watchman instead. Learn more: https://facebook.github.io/watchman/docs/install`\n );\n }\n\n exception(error);\n process.exit(1);\n }\n\n throw error;\n}\n\nprocess.on('uncaughtException', handleTooManyOpenFileErrors);\n"],"names":["AbortCommandError","CommandError","SilentError","UnimplementedError","logCmdError","ERROR_PREFIX","Error","constructor","code","message","name","isCommandError","startsWith","substring","length","messageOrError","stack","error","process","exit","AssertionError","errorDetails","chalk","gray","red","toString","handleTooManyOpenFileErrors","platform","execSync","stdio","warn","exception","on"],"mappings":";;;;;;;;;;;IA+BaA,iBAAiB;eAAjBA;;IApBAC,YAAY;eAAZA;;IA6BAC,WAAW;eAAXA;;IAqCAC,kBAAkB;eAAlBA;;IAvBGC,WAAW;eAAXA;;;;yBAtDe;;;;;;;gEACb;;;;;;;yBACO;;;;;;qBAEa;;;;;;AAEtC,MAAMC,eAAe;AAKd,MAAMJ,qBAAqBK;IAKhCC,YACE,AAAOC,IAAY,EACnBC,UAAkB,EAAE,CACpB;QACA,KAAK,CAAC,UAHCD,OAAAA,WALTE,OAAO,qBACEC,iBAAiB;QAQxB,uEAAuE;QACvE,wBAAwB;QACxB,IAAIF,QAAQG,UAAU,CAACP,eAAe;YACpCI,UAAUA,QAAQI,SAAS,CAACR,aAAaS,MAAM;QACjD;QAEA,IAAI,CAACL,OAAO,GAAGA,WAAWD;IAC5B;AACF;AAEO,MAAMR,0BAA0BC;IACrCM,aAAc;QACZ,KAAK,CAAC,WAAW;IACnB;AACF;AAKO,MAAML,oBAAoBD;IAC/BM,YAAYQ,cAA+B,CAAE;QAC3C,MAAMN,UACJ,AAAC,CAAA,OAAOM,mBAAmB,WAAWA,iBAAiBA,kCAAAA,eAAgBN,OAAO,AAAD,KAC7E;QACF,KAAK,CAAC,UAAUA;QAChB,IAAI,OAAOM,mBAAmB,UAAU;YACtC,kHAAkH;YAClH,IAAI,CAACC,KAAK,GAAGD,CAAAA,kCAAAA,eAAgBC,KAAK,KAAI,IAAI,CAACA,KAAK;YAChD,IAAI,CAACN,IAAI,GAAGK,CAAAA,kCAAAA,eAAgBL,IAAI,KAAI,IAAI,CAACA,IAAI;QAC/C;IACF;AACF;AAEO,SAASN,YAAYa,KAAU;IACpC,IAAI,CAAEA,CAAAA,iBAAiBX,KAAI,GAAI;QAC7B,MAAMW;IACR;IACA,IAAIA,iBAAiBjB,qBAAqBiB,iBAAiBf,aAAa;QACtE,+EAA+E;QAC/EgB,QAAQC,IAAI,CAAC;IACf,OAAO,IACLF,iBAAiBhB,gBACjBgB,iBAAiBG,wBAAc,IAC/BH,MAAMP,IAAI,KAAK,gBACfO,MAAMP,IAAI,KAAK,eACf;QACA,4CAA4C;QAC5CS,IAAAA,SAAI,EAACF;IACP;IAEA,MAAMI,eAAeJ,MAAMD,KAAK,GAAG,OAAOM,gBAAK,CAACC,IAAI,CAACN,MAAMD,KAAK,IAAI;IAEpEG,IAAAA,SAAI,EAACG,gBAAK,CAACE,GAAG,CAACP,MAAMQ,QAAQ,MAAMJ;AACrC;AAGO,MAAMlB,2BAA2BG;IACtCC,aAAc;QACZ,KAAK,CAAC;QACN,IAAI,CAACG,IAAI,GAAG;IACd;AACF;AAEA;;;;;;;;CAQC,GACD,SAASgB,4BAA4BT,KAAU;IAC7C,4FAA4F;IAC5F,IAAI,UAAUA,SAASA,MAAMT,IAAI,KAAK,YAAYU,QAAQS,QAAQ,KAAK,UAAU;QAC/E,IAAI;YACF,iEAAiE;YACjEC,IAAAA,yBAAQ,EAAC,4BAA4B;gBAAEC,OAAO;YAAS;YACvD,6EAA6E;YAC7ED,IAAAA,yBAAQ,EAAC,0BAA0B;gBAAEC,OAAO;YAAS;YAErDC,IAAAA,SAAI,EACF;QAEJ,EAAE,OAAM;YACNA,IAAAA,SAAI,EACF,CAAC,wJAAwJ,CAAC;QAE9J;QAEAC,IAAAA,cAAS,EAACd;QACVC,QAAQC,IAAI,CAAC;IACf;IAEA,MAAMF;AACR;AAEAC,QAAQc,EAAE,CAAC,qBAAqBN"}
|
package/build/src/utils/exit.js
CHANGED
|
@@ -150,8 +150,7 @@ function ensureProcessExitsAfterDelay(waitUntilExitMs = 10000, startedAtMs = Dat
|
|
|
150
150
|
*/ function tryWarnActiveProcesses() {
|
|
151
151
|
let activeProcesses = [];
|
|
152
152
|
try {
|
|
153
|
-
const children = _nodeprocess().default
|
|
154
|
-
._getActiveHandles().filter((handle)=>handle instanceof _nodechild_process().ChildProcess);
|
|
153
|
+
const children = _nodeprocess().default._getActiveHandles().filter((handle)=>handle instanceof _nodechild_process().ChildProcess);
|
|
155
154
|
if (children.length) {
|
|
156
155
|
activeProcesses = children.map((child)=>child.spawnargs.join(' '));
|
|
157
156
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/exit.ts"],"sourcesContent":["import { ChildProcess } from 'node:child_process';\nimport process from 'node:process';\n\nimport { guardAsync } from './fn';\nimport { warn } from '../log';\n\nconst debug = require('debug')('expo:utils:exit') as typeof console.log;\n\ntype AsyncExitHook = (signal: NodeJS.Signals) => void | Promise<void>;\n\nconst PRE_EXIT_SIGNALS: NodeJS.Signals[] = ['SIGHUP', 'SIGINT', 'SIGTERM', 'SIGBREAK'];\n\n// We create a queue since Node.js throws an error if we try to append too many listeners:\n// (node:4405) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit\nconst queue: AsyncExitHook[] = [];\n\nlet unsubscribe: (() => void) | null = null;\n\n/** Add functions that run before the process exits. Returns a function for removing the listeners. */\nexport function installExitHooks(asyncExitHook: AsyncExitHook): () => void {\n // We need to instantiate the master listener the first time the queue is used.\n if (!queue.length) {\n // Track the master listener so we can remove it later.\n unsubscribe = attachMasterListener();\n }\n\n queue.push(asyncExitHook);\n\n return () => {\n const index = queue.indexOf(asyncExitHook);\n if (index >= 0) {\n queue.splice(index, 1);\n }\n // Clean up the master listener if we don't need it anymore.\n if (!queue.length) {\n unsubscribe?.();\n }\n };\n}\n\n// Create a function that runs before the process exits and guards against running multiple times.\nfunction createExitHook(signal: NodeJS.Signals) {\n return guardAsync(async () => {\n debug(`pre-exit (signal: ${signal}, queue length: ${queue.length})`);\n\n for (const [index, hookAsync] of Object.entries(queue)) {\n try {\n await hookAsync(signal);\n } catch (error: any) {\n debug(`Error in exit hook: %O (queue: ${index})`, error);\n }\n }\n\n debug(`post-exit (code: ${process.exitCode ?? 0})`);\n\n process.exit();\n });\n}\n\nfunction attachMasterListener() {\n const hooks: [NodeJS.Signals, () => any][] = [];\n for (const signal of PRE_EXIT_SIGNALS) {\n const hook = createExitHook(signal);\n hooks.push([signal, hook]);\n process.on(signal, hook);\n }\n return () => {\n for (const [signal, hook] of hooks) {\n process.removeListener(signal, hook);\n }\n };\n}\n\n/**\n * Monitor if the current process is exiting before the delay is reached.\n * If there are active resources, the process will be forced to exit after the delay is reached.\n *\n * @see https://nodejs.org/docs/latest-v18.x/api/process.html#processgetactiveresourcesinfo\n */\nexport function ensureProcessExitsAfterDelay(waitUntilExitMs = 10000, startedAtMs = Date.now()) {\n // Create a list of the expected active resources before exiting.\n // Note, the order is undeterministic\n const expectedResources = [\n process.stdout.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stderr.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stdin.isTTY ? 'TTYWrap' : 'PipeWrap',\n ];\n // Check active resources, besides the TTYWrap/PipeWrap (process.stdin, process.stdout, process.stderr)\n const activeResources = process.getActiveResourcesInfo() as string[];\n // Filter the active resource list by subtracting the expected resources, in undeterministic order\n const unexpectedActiveResources = activeResources.filter((activeResource) => {\n const index = expectedResources.indexOf(activeResource);\n if (index >= 0) {\n expectedResources.splice(index, 1);\n return false;\n }\n\n return true;\n });\n\n const canExitProcess = !unexpectedActiveResources.length;\n if (canExitProcess) {\n return debug('no active resources detected, process can safely exit');\n } else {\n debug(\n `process is trying to exit, but is stuck on unexpected active resources:`,\n unexpectedActiveResources\n );\n }\n\n // Check if the process needs to be force-closed\n const elapsedTime = Date.now() - startedAtMs;\n if (elapsedTime > waitUntilExitMs) {\n debug('active handles detected past the exit delay, forcefully exiting:', activeResources);\n tryWarnActiveProcesses();\n return process.exit(0);\n }\n\n const timeoutId = setTimeout(() => {\n // Ensure the timeout is cleared before checking the active resources\n clearTimeout(timeoutId);\n // Check if the process can exit\n ensureProcessExitsAfterDelay(waitUntilExitMs, startedAtMs);\n }, 100);\n}\n\n/**\n * Try to warn the user about unexpected active processes running in the background.\n * This uses the internal `process._getActiveHandles` method, within a try-catch block.\n * If active child processes are detected, the commands of these processes are logged.\n *\n * @example ```bash\n * Done writing bundle output\n * Detected 2 processes preventing Expo from exiting, forcefully exiting now.\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * ```\n */\nfunction tryWarnActiveProcesses() {\n let activeProcesses: string[] = [];\n\n try {\n const children: ChildProcess[] = process\n
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/exit.ts"],"sourcesContent":["import { ChildProcess } from 'node:child_process';\nimport process from 'node:process';\n\nimport { guardAsync } from './fn';\nimport { warn } from '../log';\n\nconst debug = require('debug')('expo:utils:exit') as typeof console.log;\n\n// NOTE: This is an internal method, not designed to be exposed. It's also our only way to get this info\ndeclare global {\n namespace NodeJS {\n interface Process {\n _getActiveHandles(): readonly any[];\n }\n }\n}\n\ntype AsyncExitHook = (signal: NodeJS.Signals) => void | Promise<void>;\n\nconst PRE_EXIT_SIGNALS: NodeJS.Signals[] = ['SIGHUP', 'SIGINT', 'SIGTERM', 'SIGBREAK'];\n\n// We create a queue since Node.js throws an error if we try to append too many listeners:\n// (node:4405) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. Use emitter.setMaxListeners() to increase limit\nconst queue: AsyncExitHook[] = [];\n\nlet unsubscribe: (() => void) | null = null;\n\n/** Add functions that run before the process exits. Returns a function for removing the listeners. */\nexport function installExitHooks(asyncExitHook: AsyncExitHook): () => void {\n // We need to instantiate the master listener the first time the queue is used.\n if (!queue.length) {\n // Track the master listener so we can remove it later.\n unsubscribe = attachMasterListener();\n }\n\n queue.push(asyncExitHook);\n\n return () => {\n const index = queue.indexOf(asyncExitHook);\n if (index >= 0) {\n queue.splice(index, 1);\n }\n // Clean up the master listener if we don't need it anymore.\n if (!queue.length) {\n unsubscribe?.();\n }\n };\n}\n\n// Create a function that runs before the process exits and guards against running multiple times.\nfunction createExitHook(signal: NodeJS.Signals) {\n return guardAsync(async () => {\n debug(`pre-exit (signal: ${signal}, queue length: ${queue.length})`);\n\n for (const [index, hookAsync] of Object.entries(queue)) {\n try {\n await hookAsync(signal);\n } catch (error: any) {\n debug(`Error in exit hook: %O (queue: ${index})`, error);\n }\n }\n\n debug(`post-exit (code: ${process.exitCode ?? 0})`);\n\n process.exit();\n });\n}\n\nfunction attachMasterListener() {\n const hooks: [NodeJS.Signals, () => any][] = [];\n for (const signal of PRE_EXIT_SIGNALS) {\n const hook = createExitHook(signal);\n hooks.push([signal, hook]);\n process.on(signal, hook);\n }\n return () => {\n for (const [signal, hook] of hooks) {\n process.removeListener(signal, hook);\n }\n };\n}\n\n/**\n * Monitor if the current process is exiting before the delay is reached.\n * If there are active resources, the process will be forced to exit after the delay is reached.\n *\n * @see https://nodejs.org/docs/latest-v18.x/api/process.html#processgetactiveresourcesinfo\n */\nexport function ensureProcessExitsAfterDelay(waitUntilExitMs = 10000, startedAtMs = Date.now()) {\n // Create a list of the expected active resources before exiting.\n // Note, the order is undeterministic\n const expectedResources = [\n process.stdout.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stderr.isTTY ? 'TTYWrap' : 'PipeWrap',\n process.stdin.isTTY ? 'TTYWrap' : 'PipeWrap',\n ];\n // Check active resources, besides the TTYWrap/PipeWrap (process.stdin, process.stdout, process.stderr)\n const activeResources = process.getActiveResourcesInfo() as string[];\n // Filter the active resource list by subtracting the expected resources, in undeterministic order\n const unexpectedActiveResources = activeResources.filter((activeResource) => {\n const index = expectedResources.indexOf(activeResource);\n if (index >= 0) {\n expectedResources.splice(index, 1);\n return false;\n }\n\n return true;\n });\n\n const canExitProcess = !unexpectedActiveResources.length;\n if (canExitProcess) {\n return debug('no active resources detected, process can safely exit');\n } else {\n debug(\n `process is trying to exit, but is stuck on unexpected active resources:`,\n unexpectedActiveResources\n );\n }\n\n // Check if the process needs to be force-closed\n const elapsedTime = Date.now() - startedAtMs;\n if (elapsedTime > waitUntilExitMs) {\n debug('active handles detected past the exit delay, forcefully exiting:', activeResources);\n tryWarnActiveProcesses();\n return process.exit(0);\n }\n\n const timeoutId = setTimeout(() => {\n // Ensure the timeout is cleared before checking the active resources\n clearTimeout(timeoutId);\n // Check if the process can exit\n ensureProcessExitsAfterDelay(waitUntilExitMs, startedAtMs);\n }, 100);\n}\n\n/**\n * Try to warn the user about unexpected active processes running in the background.\n * This uses the internal `process._getActiveHandles` method, within a try-catch block.\n * If active child processes are detected, the commands of these processes are logged.\n *\n * @example ```bash\n * Done writing bundle output\n * Detected 2 processes preventing Expo from exiting, forcefully exiting now.\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * - node /Users/cedric/../node_modules/nativewind/dist/metro/tailwind/v3/child.js\n * ```\n */\nfunction tryWarnActiveProcesses() {\n let activeProcesses: string[] = [];\n\n try {\n const children: ChildProcess[] = process\n ._getActiveHandles()\n .filter((handle: any) => handle instanceof ChildProcess);\n\n if (children.length) {\n activeProcesses = children.map((child) => child.spawnargs.join(' '));\n }\n } catch (error) {\n debug('failed to get active process information:', error);\n }\n\n if (!activeProcesses.length) {\n warn('Something prevented Expo from exiting, forcefully exiting now.');\n } else {\n const singularOrPlural =\n activeProcesses.length === 1 ? '1 process' : `${activeProcesses.length} processes`;\n\n warn(`Detected ${singularOrPlural} preventing Expo from exiting, forcefully exiting now.`);\n warn(' - ' + activeProcesses.join('\\n - '));\n }\n}\n"],"names":["ensureProcessExitsAfterDelay","installExitHooks","debug","require","PRE_EXIT_SIGNALS","queue","unsubscribe","asyncExitHook","length","attachMasterListener","push","index","indexOf","splice","createExitHook","signal","guardAsync","hookAsync","Object","entries","error","process","exitCode","exit","hooks","hook","on","removeListener","waitUntilExitMs","startedAtMs","Date","now","expectedResources","stdout","isTTY","stderr","stdin","activeResources","getActiveResourcesInfo","unexpectedActiveResources","filter","activeResource","canExitProcess","elapsedTime","tryWarnActiveProcesses","timeoutId","setTimeout","clearTimeout","activeProcesses","children","_getActiveHandles","handle","ChildProcess","map","child","spawnargs","join","warn","singularOrPlural"],"mappings":"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"}
|
|
@@ -67,7 +67,6 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
67
67
|
function setNodeEnv(mode) {
|
|
68
68
|
process.env.NODE_ENV = process.env.NODE_ENV || mode;
|
|
69
69
|
process.env.BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;
|
|
70
|
-
// @ts-expect-error: Add support for external React libraries being loaded in the same process.
|
|
71
70
|
globalThis.__DEV__ = process.env.NODE_ENV !== 'production';
|
|
72
71
|
}
|
|
73
72
|
function loadEnvFiles(projectRoot, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/nodeEnv.ts"],"sourcesContent":["import * as env from '@expo/env';\n\n/**\n * Set the environment to production or development\n * lots of tools use this to determine if they should run in a dev mode.\n */\nexport function setNodeEnv(mode: 'development' | 'production') {\n process.env.NODE_ENV = process.env.NODE_ENV || mode;\n process.env.BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;\n
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/nodeEnv.ts"],"sourcesContent":["import * as env from '@expo/env';\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\ndeclare namespace globalThis {\n let __DEV__: boolean | undefined;\n}\n\n/**\n * Set the environment to production or development\n * lots of tools use this to determine if they should run in a dev mode.\n */\nexport function setNodeEnv(mode: 'development' | 'production') {\n process.env.NODE_ENV = process.env.NODE_ENV || mode;\n process.env.BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;\n globalThis.__DEV__ = process.env.NODE_ENV !== 'production';\n}\n\n/**\n * Load the dotenv files into the current `process.env` scope.\n * Note, this requires `NODE_ENV` being set through `setNodeEnv`.\n */\nexport function loadEnvFiles(projectRoot: string, options?: Parameters<typeof env.load>[1]) {\n return env.load(projectRoot, options);\n}\n"],"names":["loadEnvFiles","setNodeEnv","mode","process","env","NODE_ENV","BABEL_ENV","globalThis","__DEV__","projectRoot","options","load"],"mappings":";;;;;;;;;;;IAsBgBA,YAAY;eAAZA;;IAVAC,UAAU;eAAVA;;;;iEAZK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYd,SAASA,WAAWC,IAAkC;IAC3DC,QAAQC,GAAG,CAACC,QAAQ,GAAGF,QAAQC,GAAG,CAACC,QAAQ,IAAIH;IAC/CC,QAAQC,GAAG,CAACE,SAAS,GAAGH,QAAQC,GAAG,CAACE,SAAS,IAAIH,QAAQC,GAAG,CAACC,QAAQ;IACrEE,WAAWC,OAAO,GAAGL,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAChD;AAMO,SAASL,aAAaS,WAAmB,EAAEC,OAAwC;IACxF,OAAON,OAAIO,IAAI,CAACF,aAAaC;AAC/B"}
|
package/build/src/utils/npm.js
CHANGED
|
@@ -27,6 +27,9 @@ _export(exports, {
|
|
|
27
27
|
npmViewAsync: function() {
|
|
28
28
|
return npmViewAsync;
|
|
29
29
|
},
|
|
30
|
+
packNpmTarballAsync: function() {
|
|
31
|
+
return packNpmTarballAsync;
|
|
32
|
+
},
|
|
30
33
|
sanitizeNpmPackageName: function() {
|
|
31
34
|
return sanitizeNpmPackageName;
|
|
32
35
|
}
|
|
@@ -59,6 +62,13 @@ function _fs() {
|
|
|
59
62
|
};
|
|
60
63
|
return data;
|
|
61
64
|
}
|
|
65
|
+
function _path() {
|
|
66
|
+
const data = /*#__PURE__*/ _interop_require_default(require("path"));
|
|
67
|
+
_path = function() {
|
|
68
|
+
return data;
|
|
69
|
+
};
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
62
72
|
function _slugify() {
|
|
63
73
|
const data = /*#__PURE__*/ _interop_require_default(require("slugify"));
|
|
64
74
|
_slugify = function() {
|
|
@@ -192,5 +202,26 @@ async function extractNpmTarballAsync(stream, props) {
|
|
|
192
202
|
}, fileList));
|
|
193
203
|
return hash.digest('hex');
|
|
194
204
|
}
|
|
205
|
+
async function packNpmTarballAsync(packageDir) {
|
|
206
|
+
var _stdout;
|
|
207
|
+
const cmdArgs = [
|
|
208
|
+
'pack',
|
|
209
|
+
'--json',
|
|
210
|
+
'--foreground-scripts=false'
|
|
211
|
+
];
|
|
212
|
+
const results = (_stdout = (await (0, _spawnasync().default)('npm', cmdArgs, {
|
|
213
|
+
env: {
|
|
214
|
+
...process.env
|
|
215
|
+
},
|
|
216
|
+
cwd: packageDir
|
|
217
|
+
})).stdout) == null ? void 0 : _stdout.trim();
|
|
218
|
+
try {
|
|
219
|
+
const [json] = JSON.parse(results);
|
|
220
|
+
return _path().default.resolve(packageDir, json.filename);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
const cmdString = `npm ${cmdArgs.join(' ')}`;
|
|
223
|
+
throw new Error(`Could not parse JSON returned from "${cmdString}".\n\n${results}\n\nError: ${error.message}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
195
226
|
|
|
196
227
|
//# sourceMappingURL=npm.js.map
|