版博士V2.0程序
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

397 Zeilen
10 KiB

  1. import 'acorn';
  2. import { builtinModules } from 'node:module';
  3. import 'node:fs';
  4. import { pathToFileURL } from 'node:url';
  5. import 'pathe';
  6. import assert from 'node:assert';
  7. import process$1 from 'node:process';
  8. import 'node:path';
  9. import v8 from 'node:v8';
  10. import { format, inspect } from 'node:util';
  11. const BUILTIN_MODULES = new Set(builtinModules);
  12. /**
  13. * @typedef ErrnoExceptionFields
  14. * @property {number | undefined} [errnode]
  15. * @property {string | undefined} [code]
  16. * @property {string | undefined} [path]
  17. * @property {string | undefined} [syscall]
  18. * @property {string | undefined} [url]
  19. *
  20. * @typedef {Error & ErrnoExceptionFields} ErrnoException
  21. */
  22. const isWindows = process$1.platform === 'win32';
  23. const own$1 = {}.hasOwnProperty;
  24. /**
  25. * Create a list string in the form like 'A and B' or 'A, B, ..., and Z'.
  26. * We cannot use Intl.ListFormat because it's not available in
  27. * --without-intl builds.
  28. *
  29. * @param {Array<string>} array
  30. * An array of strings.
  31. * @param {string} [type]
  32. * The list type to be inserted before the last element.
  33. * @returns {string}
  34. */
  35. function formatList(array, type = 'and') {
  36. return array.length < 3
  37. ? array.join(` ${type} `)
  38. : `${array.slice(0, -1).join(', ')}, ${type} ${array[array.length - 1]}`
  39. }
  40. /** @type {Map<string, MessageFunction|string>} */
  41. const messages = new Map();
  42. const nodeInternalPrefix = '__node_internal_';
  43. /** @type {number} */
  44. let userStackTraceLimit;
  45. createError(
  46. 'ERR_INVALID_MODULE_SPECIFIER',
  47. /**
  48. * @param {string} request
  49. * @param {string} reason
  50. * @param {string} [base]
  51. */
  52. (request, reason, base = undefined) => {
  53. return `Invalid module "${request}" ${reason}${
  54. base ? ` imported from ${base}` : ''
  55. }`
  56. },
  57. TypeError
  58. );
  59. createError(
  60. 'ERR_INVALID_PACKAGE_CONFIG',
  61. /**
  62. * @param {string} path
  63. * @param {string} [base]
  64. * @param {string} [message]
  65. */
  66. (path, base, message) => {
  67. return `Invalid package config ${path}${
  68. base ? ` while importing ${base}` : ''
  69. }${message ? `. ${message}` : ''}`
  70. },
  71. Error
  72. );
  73. createError(
  74. 'ERR_INVALID_PACKAGE_TARGET',
  75. /**
  76. * @param {string} pkgPath
  77. * @param {string} key
  78. * @param {unknown} target
  79. * @param {boolean} [isImport=false]
  80. * @param {string} [base]
  81. */
  82. (pkgPath, key, target, isImport = false, base = undefined) => {
  83. const relError =
  84. typeof target === 'string' &&
  85. !isImport &&
  86. target.length > 0 &&
  87. !target.startsWith('./');
  88. if (key === '.') {
  89. assert(isImport === false);
  90. return (
  91. `Invalid "exports" main target ${JSON.stringify(target)} defined ` +
  92. `in the package config ${pkgPath}package.json${
  93. base ? ` imported from ${base}` : ''
  94. }${relError ? '; targets must start with "./"' : ''}`
  95. )
  96. }
  97. return `Invalid "${
  98. isImport ? 'imports' : 'exports'
  99. }" target ${JSON.stringify(
  100. target
  101. )} defined for '${key}' in the package config ${pkgPath}package.json${
  102. base ? ` imported from ${base}` : ''
  103. }${relError ? '; targets must start with "./"' : ''}`
  104. },
  105. Error
  106. );
  107. createError(
  108. 'ERR_MODULE_NOT_FOUND',
  109. /**
  110. * @param {string} path
  111. * @param {string} base
  112. * @param {string} [type]
  113. */
  114. (path, base, type = 'package') => {
  115. return `Cannot find ${type} '${path}' imported from ${base}`
  116. },
  117. Error
  118. );
  119. createError(
  120. 'ERR_NETWORK_IMPORT_DISALLOWED',
  121. "import of '%s' by %s is not supported: %s",
  122. Error
  123. );
  124. createError(
  125. 'ERR_PACKAGE_IMPORT_NOT_DEFINED',
  126. /**
  127. * @param {string} specifier
  128. * @param {string} packagePath
  129. * @param {string} base
  130. */
  131. (specifier, packagePath, base) => {
  132. return `Package import specifier "${specifier}" is not defined${
  133. packagePath ? ` in package ${packagePath}package.json` : ''
  134. } imported from ${base}`
  135. },
  136. TypeError
  137. );
  138. createError(
  139. 'ERR_PACKAGE_PATH_NOT_EXPORTED',
  140. /**
  141. * @param {string} pkgPath
  142. * @param {string} subpath
  143. * @param {string} [base]
  144. */
  145. (pkgPath, subpath, base = undefined) => {
  146. if (subpath === '.')
  147. return `No "exports" main defined in ${pkgPath}package.json${
  148. base ? ` imported from ${base}` : ''
  149. }`
  150. return `Package subpath '${subpath}' is not defined by "exports" in ${pkgPath}package.json${
  151. base ? ` imported from ${base}` : ''
  152. }`
  153. },
  154. Error
  155. );
  156. createError(
  157. 'ERR_UNSUPPORTED_DIR_IMPORT',
  158. "Directory import '%s' is not supported " +
  159. 'resolving ES modules imported from %s',
  160. Error
  161. );
  162. createError(
  163. 'ERR_UNKNOWN_FILE_EXTENSION',
  164. /**
  165. * @param {string} ext
  166. * @param {string} path
  167. */
  168. (ext, path) => {
  169. return `Unknown file extension "${ext}" for ${path}`
  170. },
  171. TypeError
  172. );
  173. createError(
  174. 'ERR_INVALID_ARG_VALUE',
  175. /**
  176. * @param {string} name
  177. * @param {unknown} value
  178. * @param {string} [reason='is invalid']
  179. */
  180. (name, value, reason = 'is invalid') => {
  181. let inspected = inspect(value);
  182. if (inspected.length > 128) {
  183. inspected = `${inspected.slice(0, 128)}...`;
  184. }
  185. const type = name.includes('.') ? 'property' : 'argument';
  186. return `The ${type} '${name}' ${reason}. Received ${inspected}`
  187. },
  188. TypeError
  189. // Note: extra classes have been shaken out.
  190. // , RangeError
  191. );
  192. createError(
  193. 'ERR_UNSUPPORTED_ESM_URL_SCHEME',
  194. /**
  195. * @param {URL} url
  196. * @param {Array<string>} supported
  197. */
  198. (url, supported) => {
  199. let message = `Only URLs with a scheme in: ${formatList(
  200. supported
  201. )} are supported by the default ESM loader`;
  202. if (isWindows && url.protocol.length === 2) {
  203. message += '. On Windows, absolute paths must be valid file:// URLs';
  204. }
  205. message += `. Received protocol '${url.protocol}'`;
  206. return message
  207. },
  208. Error
  209. );
  210. /**
  211. * Utility function for registering the error codes. Only used here. Exported
  212. * *only* to allow for testing.
  213. * @param {string} sym
  214. * @param {MessageFunction|string} value
  215. * @param {ErrorConstructor} def
  216. * @returns {new (...args: Array<any>) => Error}
  217. */
  218. function createError(sym, value, def) {
  219. // Special case for SystemError that formats the error message differently
  220. // The SystemErrors only have SystemError as their base classes.
  221. messages.set(sym, value);
  222. return makeNodeErrorWithCode(def, sym)
  223. }
  224. /**
  225. * @param {ErrorConstructor} Base
  226. * @param {string} key
  227. * @returns {ErrorConstructor}
  228. */
  229. function makeNodeErrorWithCode(Base, key) {
  230. // @ts-expect-error It’s a Node error.
  231. return NodeError
  232. /**
  233. * @param {Array<unknown>} args
  234. */
  235. function NodeError(...args) {
  236. const limit = Error.stackTraceLimit;
  237. if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0;
  238. const error = new Base();
  239. // Reset the limit and setting the name property.
  240. if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit;
  241. const message = getMessage(key, args, error);
  242. Object.defineProperties(error, {
  243. // Note: no need to implement `kIsNodeError` symbol, would be hard,
  244. // probably.
  245. message: {
  246. value: message,
  247. enumerable: false,
  248. writable: true,
  249. configurable: true
  250. },
  251. toString: {
  252. /** @this {Error} */
  253. value() {
  254. return `${this.name} [${key}]: ${this.message}`
  255. },
  256. enumerable: false,
  257. writable: true,
  258. configurable: true
  259. }
  260. });
  261. captureLargerStackTrace(error);
  262. // @ts-expect-error It’s a Node error.
  263. error.code = key;
  264. return error
  265. }
  266. }
  267. /**
  268. * @returns {boolean}
  269. */
  270. function isErrorStackTraceLimitWritable() {
  271. // Do no touch Error.stackTraceLimit as V8 would attempt to install
  272. // it again during deserialization.
  273. try {
  274. // @ts-expect-error: not in types?
  275. if (v8.startupSnapshot.isBuildingSnapshot()) {
  276. return false
  277. }
  278. } catch {}
  279. const desc = Object.getOwnPropertyDescriptor(Error, 'stackTraceLimit');
  280. if (desc === undefined) {
  281. return Object.isExtensible(Error)
  282. }
  283. return own$1.call(desc, 'writable') && desc.writable !== undefined
  284. ? desc.writable
  285. : desc.set !== undefined
  286. }
  287. /**
  288. * This function removes unnecessary frames from Node.js core errors.
  289. * @template {(...args: unknown[]) => unknown} T
  290. * @param {T} fn
  291. * @returns {T}
  292. */
  293. function hideStackFrames(fn) {
  294. // We rename the functions that will be hidden to cut off the stacktrace
  295. // at the outermost one
  296. const hidden = nodeInternalPrefix + fn.name;
  297. Object.defineProperty(fn, 'name', {value: hidden});
  298. return fn
  299. }
  300. const captureLargerStackTrace = hideStackFrames(
  301. /**
  302. * @param {Error} error
  303. * @returns {Error}
  304. */
  305. // @ts-expect-error: fine
  306. function (error) {
  307. const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable();
  308. if (stackTraceLimitIsWritable) {
  309. userStackTraceLimit = Error.stackTraceLimit;
  310. Error.stackTraceLimit = Number.POSITIVE_INFINITY;
  311. }
  312. Error.captureStackTrace(error);
  313. // Reset the limit
  314. if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit;
  315. return error
  316. }
  317. );
  318. /**
  319. * @param {string} key
  320. * @param {Array<unknown>} args
  321. * @param {Error} self
  322. * @returns {string}
  323. */
  324. function getMessage(key, args, self) {
  325. const message = messages.get(key);
  326. assert(typeof message !== 'undefined', 'expected `message` to be found');
  327. if (typeof message === 'function') {
  328. assert(
  329. message.length <= args.length, // Default options do not count.
  330. `Code: ${key}; The provided arguments length (${args.length}) does not ` +
  331. `match the required ones (${message.length}).`
  332. );
  333. return Reflect.apply(message, self, args)
  334. }
  335. const regex = /%[dfijoOs]/g;
  336. let expectedLength = 0;
  337. while (regex.exec(message) !== null) expectedLength++;
  338. assert(
  339. expectedLength === args.length,
  340. `Code: ${key}; The provided arguments length (${args.length}) does not ` +
  341. `match the required ones (${expectedLength}).`
  342. );
  343. if (args.length === 0) return message
  344. args.unshift(message);
  345. return Reflect.apply(format, null, args)
  346. }
  347. function isNodeBuiltin(id = "") {
  348. id = id.replace(/^node:/, "").split("/")[0];
  349. return BUILTIN_MODULES.has(id);
  350. }
  351. pathToFileURL(process.cwd());
  352. const CJS_RE = /([\s;]|^)(module.exports\b|exports\.\w|require\s*\(|global\.\w)/m;
  353. function hasCJSSyntax(code) {
  354. return CJS_RE.test(code);
  355. }
  356. export { hasCJSSyntax as h, isNodeBuiltin as i };