@openclaw/diagnostics-otel 2026.7.1-beta.1 → 2026.7.1-beta.4
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/dist/index.js +1 -2406
- package/dist/runtime-api-BUlvn2ET.js +2589 -0
- package/dist/runtime-api.js +2 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/assert/strict.d.ts +10 -1
- package/node_modules/@types/node/assert.d.ts +144 -17
- package/node_modules/@types/node/async_hooks.d.ts +9 -9
- package/node_modules/@types/node/buffer.d.ts +64 -30
- package/node_modules/@types/node/child_process.d.ts +17 -21
- package/node_modules/@types/node/cluster.d.ts +13 -13
- package/node_modules/@types/node/console.d.ts +1 -1
- package/node_modules/@types/node/crypto.d.ts +471 -575
- package/node_modules/@types/node/diagnostics_channel.d.ts +274 -32
- package/node_modules/@types/node/dns.d.ts +15 -15
- package/node_modules/@types/node/events.d.ts +3 -3
- package/node_modules/@types/node/ffi.d.ts +486 -0
- package/node_modules/@types/node/fs/promises.d.ts +7 -4
- package/node_modules/@types/node/fs.d.ts +24 -18
- package/node_modules/@types/node/globals.d.ts +4 -4
- package/node_modules/@types/node/http.d.ts +30 -5
- package/node_modules/@types/node/http2.d.ts +5 -1
- package/node_modules/@types/node/index.d.ts +1 -3
- package/node_modules/@types/node/inspector.d.ts +1 -1
- package/node_modules/@types/node/module.d.ts +16 -45
- package/node_modules/@types/node/net.d.ts +1 -1
- package/node_modules/@types/node/os.d.ts +2 -2
- package/node_modules/@types/node/package.json +4 -4
- package/node_modules/@types/node/perf_hooks.d.ts +1 -9
- package/node_modules/@types/node/process.d.ts +25 -12
- package/node_modules/@types/node/quic.d.ts +92 -11
- package/node_modules/@types/node/readline.d.ts +12 -11
- package/node_modules/@types/node/repl.d.ts +10 -10
- package/node_modules/@types/node/sqlite.d.ts +56 -1
- package/node_modules/@types/node/stream/iter.d.ts +150 -0
- package/node_modules/@types/node/stream/promises.d.ts +2 -2
- package/node_modules/@types/node/stream/web.d.ts +1 -1
- package/node_modules/@types/node/stream.d.ts +37 -5
- package/node_modules/@types/node/test/reporters.d.ts +1 -1
- package/node_modules/@types/node/test.d.ts +120 -10
- package/node_modules/@types/node/tls.d.ts +1 -1
- package/node_modules/@types/node/ts5.6/index.d.ts +2 -4
- package/node_modules/@types/node/ts5.7/index.d.ts +1 -3
- package/node_modules/@types/node/url.d.ts +3 -3
- package/node_modules/@types/node/util/types.d.ts +1 -1
- package/node_modules/@types/node/util.d.ts +22 -22
- package/node_modules/@types/node/v8.d.ts +85 -3
- package/node_modules/@types/node/vm.d.ts +9 -9
- package/node_modules/@types/node/web-globals/domexception.d.ts +15 -0
- package/node_modules/@types/node/worker_threads.d.ts +10 -12
- package/node_modules/@types/node/zlib.d.ts +3 -3
- package/node_modules/acorn/CHANGELOG.md +14 -0
- package/node_modules/acorn/README.md +3 -0
- package/node_modules/acorn/dist/acorn.d.mts +6 -0
- package/node_modules/acorn/dist/acorn.d.ts +6 -0
- package/node_modules/acorn/dist/acorn.js +87 -49
- package/node_modules/acorn/dist/acorn.mjs +87 -49
- package/node_modules/acorn/package.json +2 -2
- package/node_modules/import-in-the-middle/CHANGELOG.md +21 -0
- package/node_modules/import-in-the-middle/README.md +60 -0
- package/node_modules/import-in-the-middle/create-hook.mjs +375 -146
- package/node_modules/import-in-the-middle/lib/get-exports.mjs +88 -52
- package/node_modules/import-in-the-middle/lib/io.mjs +78 -0
- package/node_modules/import-in-the-middle/package.json +1 -1
- package/node_modules/import-in-the-middle/register-hooks.d.ts +35 -0
- package/node_modules/import-in-the-middle/register-hooks.mjs +63 -0
- package/node_modules/undici-types/agent.d.ts +0 -2
- package/node_modules/undici-types/client.d.ts +25 -19
- package/node_modules/undici-types/dispatcher.d.ts +7 -33
- package/node_modules/undici-types/dispatcher1-wrapper.d.ts +7 -0
- package/node_modules/undici-types/fetch.d.ts +24 -4
- package/node_modules/undici-types/h2c-client.d.ts +6 -6
- package/node_modules/undici-types/handlers.d.ts +1 -2
- package/node_modules/undici-types/header.d.ts +5 -0
- package/node_modules/undici-types/index.d.ts +3 -1
- package/node_modules/undici-types/interceptors.d.ts +1 -1
- package/node_modules/undici-types/package.json +1 -1
- package/node_modules/undici-types/pool.d.ts +0 -2
- package/node_modules/undici-types/proxy-agent.d.ts +2 -2
- package/node_modules/undici-types/round-robin-pool.d.ts +0 -2
- package/node_modules/undici-types/snapshot-agent.d.ts +4 -0
- package/node_modules/undici-types/socks5-proxy-agent.d.ts +2 -2
- package/node_modules/undici-types/webidl.d.ts +0 -1
- package/node_modules/yargs/CHANGELOG.md +330 -0
- package/node_modules/yargs/build/index.cjs +1 -1
- package/node_modules/yargs/package.json +6 -4
- package/node_modules/yargs/yargs +5 -9
- package/node_modules/yargs/yargs.cjs +15 -0
- package/npm-shrinkwrap.json +18 -18
- package/package.json +4 -4
- package/node_modules/@types/node/compatibility/iterators.d.ts +0 -21
- package/node_modules/yargs/browser.d.ts +0 -5
|
@@ -6,9 +6,10 @@ import { URL, fileURLToPath } from 'url'
|
|
|
6
6
|
import { inspect } from 'util'
|
|
7
7
|
import { builtinModules } from 'module'
|
|
8
8
|
import {
|
|
9
|
-
getExports
|
|
9
|
+
getExports,
|
|
10
10
|
hasModuleExportsCJSDefault
|
|
11
11
|
} from './lib/get-exports.mjs'
|
|
12
|
+
import { RESOLVE, driveSync, driveAsync } from './lib/io.mjs'
|
|
12
13
|
|
|
13
14
|
const specifiers = new Map()
|
|
14
15
|
const isWin = process.platform === 'win32'
|
|
@@ -16,17 +17,34 @@ const isWin = process.platform === 'win32'
|
|
|
16
17
|
// FIXME: Typescript extensions are added temporarily until we find a better
|
|
17
18
|
// way of supporting arbitrary extensions
|
|
18
19
|
const EXTENSION_RE = /\.(js|mjs|cjs|ts|mts|cts)$/
|
|
19
|
-
const NODE_VERSION = process.versions.node.split('.')
|
|
20
|
-
const NODE_MAJOR = Number(NODE_VERSION[0])
|
|
21
|
-
const NODE_MINOR = Number(NODE_VERSION[1])
|
|
22
20
|
const HANDLED_FORMATS = new Set(['builtin', 'module', 'commonjs'])
|
|
23
21
|
const TRACE_WARNINGS = process.execArgv.includes('--trace-warnings')
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
// process.versions.node is always "major.minor.patch" (nightlies add a suffix
|
|
24
|
+
// the regex ignores).
|
|
25
|
+
const [, NODE_MAJOR, NODE_MINOR, NODE_PATCH] =
|
|
26
|
+
process.versions.node.match(/^(\d+)\.(\d+)\.(\d+)/).map(Number)
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether the running Node.js can correctly run the synchronous loader via
|
|
30
|
+
* `module.registerHooks`.
|
|
31
|
+
*
|
|
32
|
+
* `module.registerHooks` exists since v22.15, but its synchronous load hook
|
|
33
|
+
* rejected the nullish CommonJS `source` the loader returns for `require()`s
|
|
34
|
+
* pulled into the ESM graph (throwing `ERR_INVALID_RETURN_PROPERTY_VALUE`) until
|
|
35
|
+
* https://github.com/nodejs/node/pull/59929, released in 22.22.3, 24.11.1,
|
|
36
|
+
* 25.1.0 and 26.0.0. Earlier 24.x (<= 24.11.0) and 25.0.0 ship `registerHooks`
|
|
37
|
+
* but predate the fix, so the synchronous loader must fall back to the
|
|
38
|
+
* asynchronous one there.
|
|
39
|
+
*
|
|
40
|
+
* @returns {boolean}
|
|
41
|
+
*/
|
|
42
|
+
export function supportsSyncHooks () {
|
|
43
|
+
if (NODE_MAJOR >= 26) return true
|
|
44
|
+
if (NODE_MAJOR === 25) return NODE_MINOR >= 1
|
|
45
|
+
if (NODE_MAJOR === 24) return NODE_MINOR > 11 || (NODE_MINOR === 11 && NODE_PATCH >= 1)
|
|
46
|
+
if (NODE_MAJOR === 22) return NODE_MINOR > 22 || (NODE_MINOR === 22 && NODE_PATCH >= 3)
|
|
47
|
+
return false
|
|
30
48
|
}
|
|
31
49
|
|
|
32
50
|
function hasIitm (url) {
|
|
@@ -181,21 +199,81 @@ function emitWarning (err) {
|
|
|
181
199
|
process.emitWarning(warnMessage)
|
|
182
200
|
}
|
|
183
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Builds the setter/getter/re-export block injected into the wrapper module for
|
|
204
|
+
* a single named export. This is pure string generation, identical regardless
|
|
205
|
+
* of how the loader is driven, so both the synchronous and asynchronous paths
|
|
206
|
+
* share it.
|
|
207
|
+
*
|
|
208
|
+
* @param {string} n The exported name.
|
|
209
|
+
* @param {string} srcUrl The URL of the module the export belongs to.
|
|
210
|
+
* @returns {string}
|
|
211
|
+
*/
|
|
212
|
+
function buildSetter (n, srcUrl) {
|
|
213
|
+
const variableName = `$${n.replace(/[^a-zA-Z0-9_$]/g, '_')}`
|
|
214
|
+
const objectKey = JSON.stringify(n)
|
|
215
|
+
const reExportedName = n === 'default' ? n : objectKey
|
|
216
|
+
|
|
217
|
+
// For the module.exports synthetic export (Node 23+), fall back to $default
|
|
218
|
+
// when namespace['module.exports'] is not exposed by the native ESM namespace
|
|
219
|
+
// (builtins don't expose it). This ensures the IITM hook proxy returns the
|
|
220
|
+
// actual CJS value (e.g. EventEmitter) when an instrumentor reads
|
|
221
|
+
// capturedExports['module.exports'], rather than undefined.
|
|
222
|
+
const moduleExportsFallback = n === 'module.exports' ? ' ?? $default' : ''
|
|
223
|
+
|
|
224
|
+
const reExportLine = (n === 'module.exports' && (srcUrl.startsWith('node:') || builtinModules.includes(srcUrl)))
|
|
225
|
+
? ''
|
|
226
|
+
: `export { ${variableName} as ${reExportedName} }`
|
|
227
|
+
|
|
228
|
+
return `
|
|
229
|
+
let ${variableName}
|
|
230
|
+
__overridden[${objectKey}] = false
|
|
231
|
+
let ${variableName}Defer = false
|
|
232
|
+
try {
|
|
233
|
+
${variableName} = _[${objectKey}] = namespace[${objectKey}]${moduleExportsFallback}
|
|
234
|
+
} catch (err) {
|
|
235
|
+
if (!(err instanceof ReferenceError)) throw err
|
|
236
|
+
${variableName}Defer = true
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (${variableName}Defer || ${variableName} === undefined) {
|
|
240
|
+
__pending.push(__makeUpdater(
|
|
241
|
+
${objectKey},
|
|
242
|
+
() => namespace[${objectKey}]${moduleExportsFallback},
|
|
243
|
+
(v) => { ${variableName} = _[${objectKey}] = v }
|
|
244
|
+
))
|
|
245
|
+
}
|
|
246
|
+
${reExportLine}
|
|
247
|
+
set[${objectKey}] = (v) => {
|
|
248
|
+
__overridden[${objectKey}] = true
|
|
249
|
+
${variableName} = v
|
|
250
|
+
return true
|
|
251
|
+
}
|
|
252
|
+
get[${objectKey}] = () => ${variableName}
|
|
253
|
+
`
|
|
254
|
+
}
|
|
255
|
+
|
|
184
256
|
/**
|
|
185
257
|
* Processes a module's exports and builds a set of setter blocks.
|
|
186
258
|
*
|
|
259
|
+
* Written as a "sans-io" generator (see `lib/io.mjs`): instead of calling the
|
|
260
|
+
* loader's resolve/load hooks directly it `yield`s `[RESOLVE, ...]` to resolve
|
|
261
|
+
* star re-exports and `[LOAD, ...]` (via {@link getExports}) to read source,
|
|
262
|
+
* and is driven by either {@link driveSync} (for
|
|
263
|
+
* `module.registerHooks`) or {@link driveAsync} (for `module.register`). The
|
|
264
|
+
* body is identical for both, so there is a single implementation to maintain.
|
|
265
|
+
*
|
|
187
266
|
* @param {object} params
|
|
188
267
|
* @param {string} params.srcUrl The full URL to the module to process.
|
|
189
268
|
* @param {object} params.context Provided by the loaders API.
|
|
190
|
-
* @param {Function} params.parentGetSource Provides the source code for the parent module.
|
|
191
|
-
* @param {Function} params.parentResolve Provides the resolve function for the parent module.
|
|
192
269
|
* @param {boolean} [params.excludeDefault = false] Exclude the default export.
|
|
193
270
|
*
|
|
194
|
-
* @returns {
|
|
271
|
+
* @returns {Generator<Array, Map<string, string>>} A generator that yields I/O
|
|
272
|
+
* operations and ultimately returns the shimmed setters for all the exports
|
|
195
273
|
* from the module and any transitive export all modules.
|
|
196
274
|
*/
|
|
197
|
-
|
|
198
|
-
const exportNames =
|
|
275
|
+
function * processModule ({ srcUrl, context, excludeDefault = false }) {
|
|
276
|
+
const exportNames = yield * getExports(srcUrl, context)
|
|
199
277
|
const starExports = new Set()
|
|
200
278
|
const setters = new Map()
|
|
201
279
|
|
|
@@ -243,17 +321,14 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
|
|
|
243
321
|
|
|
244
322
|
// Relative paths need to be resolved relative to the parent module
|
|
245
323
|
const newSpecifier = isBareSpecifier(modFile) ? modFile : new URL(modFile, srcUrl).href
|
|
246
|
-
// We need to
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
|
|
250
|
-
const result = await parentResolve(newSpecifier, { parentURL: srcUrl })
|
|
324
|
+
// We need to resolve bare specifiers to a full URL. We also need to
|
|
325
|
+
// resolve all sub-modules to get the `format`. We can't rely on the
|
|
326
|
+
// parent's `format` to know if this sub-module is ESM or CJS!
|
|
327
|
+
const result = yield [RESOLVE, newSpecifier, { parentURL: srcUrl }]
|
|
251
328
|
|
|
252
|
-
const subSetters =
|
|
329
|
+
const subSetters = yield * processModule({
|
|
253
330
|
srcUrl: result.url,
|
|
254
331
|
context: { ...context, format: result.format },
|
|
255
|
-
parentGetSource,
|
|
256
|
-
parentResolve,
|
|
257
332
|
excludeDefault: true
|
|
258
333
|
})
|
|
259
334
|
|
|
@@ -261,36 +336,7 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
|
|
|
261
336
|
addSetter(name, setter, true)
|
|
262
337
|
}
|
|
263
338
|
} else {
|
|
264
|
-
|
|
265
|
-
const objectKey = JSON.stringify(n)
|
|
266
|
-
const reExportedName = n === 'default' ? n : objectKey
|
|
267
|
-
|
|
268
|
-
addSetter(n, `
|
|
269
|
-
let ${variableName}
|
|
270
|
-
__overridden[${objectKey}] = false
|
|
271
|
-
let ${variableName}Defer = false
|
|
272
|
-
try {
|
|
273
|
-
${variableName} = _[${objectKey}] = namespace[${objectKey}]
|
|
274
|
-
} catch (err) {
|
|
275
|
-
if (!(err instanceof ReferenceError)) throw err
|
|
276
|
-
${variableName}Defer = true
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (${variableName}Defer || ${variableName} === undefined) {
|
|
280
|
-
__pending.push(__makeUpdater(
|
|
281
|
-
${objectKey},
|
|
282
|
-
() => namespace[${objectKey}],
|
|
283
|
-
(v) => { ${variableName} = _[${objectKey}] = v }
|
|
284
|
-
))
|
|
285
|
-
}
|
|
286
|
-
export { ${variableName} as ${reExportedName} }
|
|
287
|
-
set[${objectKey}] = (v) => {
|
|
288
|
-
__overridden[${objectKey}] = true
|
|
289
|
-
${variableName} = v
|
|
290
|
-
return true
|
|
291
|
-
}
|
|
292
|
-
get[${objectKey}] = () => ${variableName}
|
|
293
|
-
`)
|
|
339
|
+
addSetter(n, buildSetter(n, srcUrl))
|
|
294
340
|
}
|
|
295
341
|
}
|
|
296
342
|
|
|
@@ -307,56 +353,105 @@ export function createHook (meta) {
|
|
|
307
353
|
let cachedResolve
|
|
308
354
|
const iitmURL = new URL('lib/register.js', meta.url).toString()
|
|
309
355
|
let includeModules, excludeModules
|
|
356
|
+
let shouldInclude = defaultShouldInclude
|
|
357
|
+
|
|
358
|
+
// Track CJS module URLs that IITM has wrapped. On Node 24+, CJS modules loaded
|
|
359
|
+
// via loadCJSModule (in an ESM import chain) have their require() calls for
|
|
360
|
+
// builtins routed through the ESM resolver. Without this guard, IITM would
|
|
361
|
+
// intercept those require() calls and return an ESM namespace object instead
|
|
362
|
+
// of the native CJS module value (e.g. EventEmitter constructor), breaking
|
|
363
|
+
// patterns like `class App extends require('events') {}`.
|
|
364
|
+
const cjsInIitmChain = new Set()
|
|
365
|
+
|
|
366
|
+
// Default matcher, used unless the consumer supplies its own `shouldInclude`
|
|
367
|
+
// (see applyOptions). It applies the include/exclude lists, so finishResolve
|
|
368
|
+
// always has a predicate to call and never has to special-case its absence.
|
|
369
|
+
//
|
|
370
|
+
// We check the specifier to match libraries loaded with bare specifiers from
|
|
371
|
+
// node_modules, and the full file URL for non-bare specifier imports (relative
|
|
372
|
+
// paths would be error prone). An absolute path entry added via Hook over the
|
|
373
|
+
// message port matches the resolved file path, so it is resolved here.
|
|
374
|
+
function defaultShouldInclude (url, specifier) {
|
|
375
|
+
let resultPath
|
|
376
|
+
if (url.startsWith('file:')) {
|
|
377
|
+
const stackTraceLimit = Error.stackTraceLimit
|
|
378
|
+
Error.stackTraceLimit = 0
|
|
379
|
+
try {
|
|
380
|
+
resultPath = fileURLToPath(url)
|
|
381
|
+
} catch {}
|
|
382
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
383
|
+
}
|
|
384
|
+
function match (each) {
|
|
385
|
+
if (each instanceof RegExp) {
|
|
386
|
+
return each.test(url)
|
|
387
|
+
}
|
|
310
388
|
|
|
311
|
-
|
|
312
|
-
if (global.__import_in_the_middle_initialized__) {
|
|
313
|
-
process.emitWarning("The 'import-in-the-middle' hook has already been initialized")
|
|
389
|
+
return each === specifier || each === url || (resultPath && each === resultPath)
|
|
314
390
|
}
|
|
315
391
|
|
|
316
|
-
|
|
392
|
+
if (includeModules && !includeModules.some(match)) {
|
|
393
|
+
return false
|
|
394
|
+
}
|
|
317
395
|
|
|
318
|
-
if (
|
|
319
|
-
|
|
320
|
-
|
|
396
|
+
if (excludeModules && excludeModules.some(match)) {
|
|
397
|
+
return false
|
|
398
|
+
}
|
|
321
399
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
if (includeModules === undefined) {
|
|
325
|
-
includeModules = []
|
|
326
|
-
}
|
|
400
|
+
return true
|
|
401
|
+
}
|
|
327
402
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
403
|
+
// Applies the include/exclude/message-port configuration. Shared by the
|
|
404
|
+
// asynchronous `initialize` (off-thread `module.register`, which receives
|
|
405
|
+
// `data` over the registration boundary) and by synchronous registration
|
|
406
|
+
// (`module.registerHooks`), which has no `initialize` step and passes the
|
|
407
|
+
// same options directly.
|
|
408
|
+
function applyOptions (data) {
|
|
409
|
+
includeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.include, 'include')
|
|
410
|
+
excludeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.exclude, 'exclude')
|
|
411
|
+
|
|
412
|
+
// A consumer can supply its own matcher as `shouldInclude(url, specifier)`,
|
|
413
|
+
// taking ownership of the include/exclude decision instead of expressing it
|
|
414
|
+
// as bare-specifier / file-URL / regex lists. It replaces the default list
|
|
415
|
+
// matcher and is called with the resolved URL and specifier; otherwise the
|
|
416
|
+
// default applies the include/exclude options.
|
|
417
|
+
shouldInclude = typeof data.shouldInclude === 'function' ? data.shouldInclude : defaultShouldInclude
|
|
418
|
+
|
|
419
|
+
if (data.addHookMessagePort) {
|
|
420
|
+
data.addHookMessagePort.on('message', (modules) => {
|
|
421
|
+
if (includeModules === undefined) {
|
|
422
|
+
includeModules = []
|
|
423
|
+
}
|
|
332
424
|
|
|
333
|
-
|
|
425
|
+
for (const each of modules) {
|
|
426
|
+
if (!each.startsWith('node:') && builtinModules.includes(each)) {
|
|
427
|
+
includeModules.push(`node:${each}`)
|
|
334
428
|
}
|
|
335
429
|
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
430
|
+
includeModules.push(each)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
data.addHookMessagePort.postMessage('ack')
|
|
434
|
+
}).unref()
|
|
339
435
|
}
|
|
340
436
|
}
|
|
341
437
|
|
|
342
|
-
async function
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
// See https://github.com/nodejs/import-in-the-middle/pull/76.
|
|
346
|
-
if (specifier === iitmURL) {
|
|
347
|
-
return {
|
|
348
|
-
url: specifier,
|
|
349
|
-
shortCircuit: true
|
|
350
|
-
}
|
|
438
|
+
async function initialize (data) {
|
|
439
|
+
if (global.__import_in_the_middle_initialized__) {
|
|
440
|
+
process.emitWarning("The 'import-in-the-middle' hook has already been initialized")
|
|
351
441
|
}
|
|
352
442
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (
|
|
356
|
-
|
|
443
|
+
global.__import_in_the_middle_initialized__ = true
|
|
444
|
+
|
|
445
|
+
if (data) {
|
|
446
|
+
applyOptions(data)
|
|
357
447
|
}
|
|
358
|
-
|
|
448
|
+
}
|
|
359
449
|
|
|
450
|
+
// Shared post-processing for the `resolve` hook: everything that happens
|
|
451
|
+
// once the parent loader has turned the specifier into a resolved URL. The
|
|
452
|
+
// only difference between the asynchronous and synchronous hooks is whether
|
|
453
|
+
// that resolution was awaited, so all the wrapping decisions live here.
|
|
454
|
+
function finishResolve (result, specifier, context, parentURL) {
|
|
360
455
|
// Do not wrap the entrypoint module. Many CLIs check whether they are the
|
|
361
456
|
// "main" module (e.g. require.main === module). Wrapping changes how they
|
|
362
457
|
// are evaluated, and can make them exit without doing anything.
|
|
@@ -367,37 +462,28 @@ export function createHook (meta) {
|
|
|
367
462
|
return result
|
|
368
463
|
}
|
|
369
464
|
|
|
370
|
-
//
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
// For non-bare specifier imports, we match to the full file URL because
|
|
374
|
-
// using relative paths would be very error prone!
|
|
375
|
-
let resultPath
|
|
376
|
-
if (result.url.startsWith('file:')) {
|
|
377
|
-
const stackTraceLimit = Error.stackTraceLimit
|
|
378
|
-
Error.stackTraceLimit = 0
|
|
379
|
-
try {
|
|
380
|
-
resultPath = fileURLToPath(result.url)
|
|
381
|
-
} catch {}
|
|
382
|
-
Error.stackTraceLimit = stackTraceLimit
|
|
383
|
-
}
|
|
384
|
-
function match (each) {
|
|
385
|
-
if (each instanceof RegExp) {
|
|
386
|
-
return each.test(result.url)
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return each === specifier || each === result.url || (resultPath && each === resultPath)
|
|
390
|
-
}
|
|
391
|
-
|
|
465
|
+
// Never wrap a module whose format we don't handle (e.g. json, wasm); this
|
|
466
|
+
// holds regardless of how inclusion is decided below.
|
|
392
467
|
if (result.format && !HANDLED_FORMATS.has(result.format)) {
|
|
393
468
|
return result
|
|
394
469
|
}
|
|
395
470
|
|
|
396
|
-
|
|
471
|
+
// The synchronous hooks (`module.registerHooks`) fire for `require()` as well
|
|
472
|
+
// as `import`, but iitm only owns the ESM graph: CommonJS modules are
|
|
473
|
+
// instrumented separately through require-in-the-middle, and `require()` must
|
|
474
|
+
// return the native, mutable module value (e.g. graceful-fs does
|
|
475
|
+
// `Object.defineProperty(require('fs'), ...)`, which throws on a frozen ESM
|
|
476
|
+
// namespace). Node reports the active module system in `context.conditions`
|
|
477
|
+
// ('require' vs 'import'), so leave any require() resolution untouched. The
|
|
478
|
+
// asynchronous hook never sees the 'require' condition, so this is a no-op
|
|
479
|
+
// there and only affects the synchronous path.
|
|
480
|
+
if (context.conditions?.includes('require')) {
|
|
397
481
|
return result
|
|
398
482
|
}
|
|
399
483
|
|
|
400
|
-
|
|
484
|
+
// `shouldInclude` is always set (the include/exclude list matcher by default,
|
|
485
|
+
// a consumer-provided predicate otherwise), so no nullish check is needed.
|
|
486
|
+
if (!shouldInclude(result.url, specifier)) {
|
|
401
487
|
return result
|
|
402
488
|
}
|
|
403
489
|
|
|
@@ -405,6 +491,17 @@ export function createHook (meta) {
|
|
|
405
491
|
return result
|
|
406
492
|
}
|
|
407
493
|
|
|
494
|
+
// When a CJS module is loaded by an IITM shim, its require() calls for
|
|
495
|
+
// builtins may be routed through the ESM resolver on Node 24+. Skip IITM
|
|
496
|
+
// wrapping in that case so require() returns the native module value.
|
|
497
|
+
// We also propagate the membership to the resolved child so that its own
|
|
498
|
+
// transitive require() calls are likewise skipped (the entire synchronous
|
|
499
|
+
// CJS require chain must remain unwrapped to avoid ERR_VM_MODULE_LINK_FAILURE).
|
|
500
|
+
if (cjsInIitmChain.has(parentURL)) {
|
|
501
|
+
cjsInIitmChain.add(result.url)
|
|
502
|
+
return result
|
|
503
|
+
}
|
|
504
|
+
|
|
408
505
|
// We don't want to attempt to wrap native modules
|
|
409
506
|
if (result.url.endsWith('.node')) {
|
|
410
507
|
return result
|
|
@@ -430,26 +527,63 @@ export function createHook (meta) {
|
|
|
430
527
|
return {
|
|
431
528
|
url: addIitm(result.url),
|
|
432
529
|
shortCircuit: true,
|
|
433
|
-
format:
|
|
530
|
+
// Node's synchronous resolver drops `format: 'builtin'` for bare builtin
|
|
531
|
+
// specifiers (`require('crypto')` -> `node:crypto`), so restore it;
|
|
532
|
+
// otherwise the load hook reads `node:crypto` from disk and throws ENOENT.
|
|
533
|
+
format: result.format ?? (result.url.startsWith('node:') ? 'builtin' : undefined)
|
|
434
534
|
}
|
|
435
535
|
}
|
|
436
536
|
|
|
437
|
-
async function
|
|
438
|
-
|
|
439
|
-
const realUrl = deleteIitm(url)
|
|
440
|
-
const originalSpecifier = specifiers.get(realUrl)
|
|
537
|
+
async function resolve (specifier, context, parentResolve) {
|
|
538
|
+
cachedResolve = parentResolve
|
|
441
539
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
540
|
+
// See https://github.com/nodejs/import-in-the-middle/pull/76.
|
|
541
|
+
if (specifier === iitmURL) {
|
|
542
|
+
return {
|
|
543
|
+
url: specifier,
|
|
544
|
+
shortCircuit: true
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const { parentURL = '' } = context
|
|
549
|
+
const newSpecifier = deleteIitm(specifier)
|
|
550
|
+
if (isWin && parentURL.indexOf('file:node') === 0) {
|
|
551
|
+
context.parentURL = ''
|
|
552
|
+
}
|
|
553
|
+
const result = await parentResolve(newSpecifier, context)
|
|
554
|
+
|
|
555
|
+
return finishResolve(result, specifier, context, parentURL)
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Synchronous counterpart to `resolve`, for `module.registerHooks`. The
|
|
559
|
+
// synchronous `nextResolve` returns its result directly. We stash it so the
|
|
560
|
+
// synchronous `load` hook can resolve star re-exports later, mirroring how
|
|
561
|
+
// `resolve` caches `parentResolve`.
|
|
562
|
+
function resolveSync (specifier, context, nextResolve) {
|
|
563
|
+
cachedResolve = nextResolve
|
|
564
|
+
|
|
565
|
+
if (specifier === iitmURL) {
|
|
566
|
+
return {
|
|
567
|
+
url: specifier,
|
|
568
|
+
shortCircuit: true
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
const { parentURL = '' } = context
|
|
573
|
+
const newSpecifier = deleteIitm(specifier)
|
|
574
|
+
if (isWin && parentURL.indexOf('file:node') === 0) {
|
|
575
|
+
context.parentURL = ''
|
|
576
|
+
}
|
|
577
|
+
const result = nextResolve(newSpecifier, context)
|
|
578
|
+
|
|
579
|
+
return finishResolve(result, specifier, context, parentURL)
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Builds the wrapper module source that re-exports the real module through
|
|
583
|
+
// iitm's proxy. Pure string generation shared by the asynchronous and
|
|
584
|
+
// synchronous `load` paths.
|
|
585
|
+
function buildWrapperSource (realUrl, setters, originalSpecifier) {
|
|
586
|
+
return `
|
|
453
587
|
import { register } from '${iitmURL}'
|
|
454
588
|
import * as namespace from ${JSON.stringify(realUrl)}
|
|
455
589
|
|
|
@@ -518,26 +652,46 @@ if (__pending.length > 0) {
|
|
|
518
652
|
|
|
519
653
|
register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpecifier)})
|
|
520
654
|
`
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Bookkeeping shared by the async and sync wrap paths once `processModule`
|
|
658
|
+
// succeeds: free the specifier entry early, and remember CJS modules so their
|
|
659
|
+
// transitive require() chain bypasses iitm (see `load`). Returns the wrapper
|
|
660
|
+
// module source.
|
|
661
|
+
function onWrapSuccess (realUrl, context, originalSpecifier, setters) {
|
|
662
|
+
specifiers.delete(realUrl)
|
|
663
|
+
// context.format is set to 'commonjs' by getCjsExports during processModule.
|
|
664
|
+
if (context.format === 'commonjs') {
|
|
665
|
+
cjsInIitmChain.add(realUrl)
|
|
666
|
+
}
|
|
667
|
+
return buildWrapperSource(realUrl, setters, originalSpecifier)
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Bookkeeping shared by the async and sync wrap paths when `processModule`
|
|
671
|
+
// throws. iitm falls back to the parent loader so the module loads unwrapped
|
|
672
|
+
// (it just can't be Hook'ed) rather than taking down the whole app. We free
|
|
673
|
+
// the specifier entry to avoid a leak, and log because a failure here is
|
|
674
|
+
// usually an iitm bug and would otherwise be very tricky to debug.
|
|
675
|
+
function onWrapFailure (realUrl, cause) {
|
|
676
|
+
specifiers.delete(realUrl)
|
|
677
|
+
const err = new Error(`'import-in-the-middle' failed to wrap '${realUrl}'`)
|
|
678
|
+
err.cause = cause
|
|
679
|
+
emitWarning(err)
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
async function getSource (url, context, parentGetSource) {
|
|
683
|
+
if (hasIitm(url)) {
|
|
684
|
+
const realUrl = deleteIitm(url)
|
|
685
|
+
const originalSpecifier = specifiers.get(realUrl)
|
|
540
686
|
|
|
687
|
+
try {
|
|
688
|
+
const setters = await driveAsync(
|
|
689
|
+
processModule({ srcUrl: realUrl, context }),
|
|
690
|
+
{ resolve: cachedResolve, load: parentGetSource }
|
|
691
|
+
)
|
|
692
|
+
return { source: onWrapSuccess(realUrl, context, originalSpecifier, setters) }
|
|
693
|
+
} catch (cause) {
|
|
694
|
+
onWrapFailure(realUrl, cause)
|
|
541
695
|
// Revert back to the non-iitm URL
|
|
542
696
|
url = realUrl
|
|
543
697
|
}
|
|
@@ -546,6 +700,29 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpeci
|
|
|
546
700
|
return parentGetSource(url, context)
|
|
547
701
|
}
|
|
548
702
|
|
|
703
|
+
// Synchronous counterpart to `getSource`, for `module.registerHooks`. Drives
|
|
704
|
+
// `processModule` straight through; all bookkeeping and source generation is
|
|
705
|
+
// shared with `getSource`.
|
|
706
|
+
function getSourceSync (url, context, nextLoad) {
|
|
707
|
+
if (hasIitm(url)) {
|
|
708
|
+
const realUrl = deleteIitm(url)
|
|
709
|
+
const originalSpecifier = specifiers.get(realUrl)
|
|
710
|
+
|
|
711
|
+
try {
|
|
712
|
+
const setters = driveSync(
|
|
713
|
+
processModule({ srcUrl: realUrl, context }),
|
|
714
|
+
{ resolve: cachedResolve, load: nextLoad }
|
|
715
|
+
)
|
|
716
|
+
return { source: onWrapSuccess(realUrl, context, originalSpecifier, setters) }
|
|
717
|
+
} catch (cause) {
|
|
718
|
+
onWrapFailure(realUrl, cause)
|
|
719
|
+
url = realUrl
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return nextLoad(url, context)
|
|
724
|
+
}
|
|
725
|
+
|
|
549
726
|
async function load (url, context, parentLoad) {
|
|
550
727
|
if (hasIitm(url)) {
|
|
551
728
|
const result = await getSource(url, context, parentLoad)
|
|
@@ -563,8 +740,60 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpeci
|
|
|
563
740
|
return parentLoad(deleteIitm(url), context)
|
|
564
741
|
}
|
|
565
742
|
|
|
743
|
+
// On Node 22+, when a CJS module is loaded through the ESM translator and
|
|
744
|
+
// another loader hook provides its source (instead of leaving source null
|
|
745
|
+
// for Node to read natively), require() calls inside that CJS module for
|
|
746
|
+
// packages using the "module-sync" exports condition fail with
|
|
747
|
+
// ERR_VM_MODULE_LINK_FAILURE. Work around this Node bug by stripping
|
|
748
|
+
// hook-provided source for CJS modules in the synchronous require chain,
|
|
749
|
+
// forcing Node to use its native CJS loader which handles this correctly.
|
|
750
|
+
if (cjsInIitmChain.has(url)) {
|
|
751
|
+
const result = await parentLoad(url, context)
|
|
752
|
+
if (result.format === 'commonjs' && result.source != null) {
|
|
753
|
+
return {
|
|
754
|
+
format: result.format,
|
|
755
|
+
source: undefined
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return result
|
|
759
|
+
}
|
|
760
|
+
|
|
566
761
|
return parentLoad(url, context)
|
|
567
762
|
}
|
|
568
763
|
|
|
569
|
-
|
|
764
|
+
// Synchronous counterpart to `load`, for `module.registerHooks`. Mirrors the
|
|
765
|
+
// async `load` exactly — wrapping via `getSourceSync` and applying the same
|
|
766
|
+
// CJS-in-iitm-chain source stripping — only without awaiting.
|
|
767
|
+
function loadSync (url, context, nextLoad) {
|
|
768
|
+
if (hasIitm(url)) {
|
|
769
|
+
const result = getSourceSync(url, context, nextLoad)
|
|
770
|
+
// If wrapping failed, `getSourceSync()` may have fallen back to `nextLoad`,
|
|
771
|
+
// which can legally return `source: null` (e.g. for non-JS formats).
|
|
772
|
+
if (result && typeof result === 'object' && result.source != null) {
|
|
773
|
+
return {
|
|
774
|
+
source: result.source,
|
|
775
|
+
shortCircuit: true,
|
|
776
|
+
format: 'module'
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// Fall back to the parent loader with the original (non-iitm) URL.
|
|
781
|
+
return nextLoad(deleteIitm(url), context)
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (cjsInIitmChain.has(url)) {
|
|
785
|
+
const result = nextLoad(url, context)
|
|
786
|
+
if (result.format === 'commonjs' && result.source != null) {
|
|
787
|
+
return {
|
|
788
|
+
format: result.format,
|
|
789
|
+
source: undefined
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
return result
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
return nextLoad(url, context)
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
return { initialize, load, resolve, resolveSync, loadSync, applyOptions }
|
|
570
799
|
}
|