import-in-the-middle 2.0.3 → 2.0.5
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/CHANGELOG.md +14 -0
- package/create-hook.mjs +98 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.0.5](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.4...import-in-the-middle-v2.0.5) (2026-01-20)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* handle lazy initialization and circular dependencies ([#229](https://github.com/nodejs/import-in-the-middle/issues/229)) ([d1421dc](https://github.com/nodejs/import-in-the-middle/commit/d1421dc0ae65ce6da5de5cb58f41af99f9d87371))
|
|
9
|
+
|
|
10
|
+
## [2.0.4](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.3...import-in-the-middle-v2.0.4) (2026-01-14)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* do not instrument the top level module ([#225](https://github.com/nodejs/import-in-the-middle/issues/225)) ([b563b35](https://github.com/nodejs/import-in-the-middle/commit/b563b35c74b96554b5112905391ec3842162b7ee))
|
|
16
|
+
|
|
3
17
|
## [2.0.3](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.2...import-in-the-middle-v2.0.3) (2026-01-13)
|
|
4
18
|
|
|
5
19
|
|
package/create-hook.mjs
CHANGED
|
@@ -24,7 +24,7 @@ const HANDLED_FORMATS = new Set(['builtin', 'module', 'commonjs'])
|
|
|
24
24
|
const TRACE_WARNINGS = process.execArgv.includes('--trace-warnings')
|
|
25
25
|
|
|
26
26
|
let getExports
|
|
27
|
-
if (NODE_MAJOR
|
|
27
|
+
if (NODE_MAJOR > 16 || (NODE_MAJOR === 16 && NODE_MINOR >= 16)) {
|
|
28
28
|
getExports = getExportsImpl
|
|
29
29
|
} else {
|
|
30
30
|
getExports = (url) => import(url).then(Object.keys)
|
|
@@ -295,13 +295,25 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
|
|
|
295
295
|
|
|
296
296
|
addSetter(n, `
|
|
297
297
|
let ${variableName}
|
|
298
|
+
__overridden[${objectKey}] = false
|
|
299
|
+
let ${variableName}Defer = false
|
|
298
300
|
try {
|
|
299
301
|
${variableName} = _[${objectKey}] = namespace[${objectKey}]
|
|
300
302
|
} catch (err) {
|
|
301
303
|
if (!(err instanceof ReferenceError)) throw err
|
|
304
|
+
${variableName}Defer = true
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (${variableName}Defer || ${variableName} === undefined) {
|
|
308
|
+
__pending.push(__makeUpdater(
|
|
309
|
+
${objectKey},
|
|
310
|
+
() => namespace[${objectKey}],
|
|
311
|
+
(v) => { ${variableName} = _[${objectKey}] = v }
|
|
312
|
+
))
|
|
302
313
|
}
|
|
303
314
|
export { ${variableName} as ${reExportedName} }
|
|
304
315
|
set[${objectKey}] = (v) => {
|
|
316
|
+
__overridden[${objectKey}] = true
|
|
305
317
|
${variableName} = v
|
|
306
318
|
return true
|
|
307
319
|
}
|
|
@@ -375,10 +387,20 @@ export function createHook (meta) {
|
|
|
375
387
|
if (isWin && parentURL.indexOf('file:node') === 0) {
|
|
376
388
|
context.parentURL = ''
|
|
377
389
|
}
|
|
378
|
-
const result = await parentResolve(newSpecifier, context
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
390
|
+
const result = await parentResolve(newSpecifier, context)
|
|
391
|
+
|
|
392
|
+
// Do not wrap the entrypoint module. Many CLIs check whether they are the
|
|
393
|
+
// "main" module (e.g. require.main === module). Wrapping changes how they
|
|
394
|
+
// are evaluated, and can make them exit without doing anything.
|
|
395
|
+
if (parentURL === '') {
|
|
396
|
+
if (!EXTENSION_RE.test(result.url) && !hasIitm(result.url)) {
|
|
397
|
+
entrypoint = result.url
|
|
398
|
+
return { url: result.url, format: 'commonjs' }
|
|
399
|
+
}
|
|
400
|
+
if (NODE_MAJOR > 16 || (NODE_MAJOR === 16 && NODE_MINOR >= 16)) {
|
|
401
|
+
entrypoint = result.url
|
|
402
|
+
return result
|
|
403
|
+
}
|
|
382
404
|
}
|
|
383
405
|
|
|
384
406
|
// For included/excluded modules, we check the specifier to match libraries
|
|
@@ -472,9 +494,65 @@ ${experimentalPatchInternals ? `import { setExperimentalPatchInternals } from '$
|
|
|
472
494
|
const _ = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } })
|
|
473
495
|
const set = {}
|
|
474
496
|
const get = {}
|
|
497
|
+
const __overridden = Object.create(null)
|
|
498
|
+
let __pending = []
|
|
499
|
+
|
|
500
|
+
function __makeUpdater (key, read, assign) {
|
|
501
|
+
return () => {
|
|
502
|
+
if (__overridden[key] === true) return true
|
|
503
|
+
try {
|
|
504
|
+
const v = read()
|
|
505
|
+
if (v !== undefined) {
|
|
506
|
+
assign(v)
|
|
507
|
+
return true
|
|
508
|
+
}
|
|
509
|
+
return false
|
|
510
|
+
} catch (err) {
|
|
511
|
+
if (err instanceof ReferenceError) return false
|
|
512
|
+
throw err
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function __flushPendingOnce () {
|
|
518
|
+
if (__pending.length === 0) return
|
|
519
|
+
const next = []
|
|
520
|
+
for (const fn of __pending) {
|
|
521
|
+
// If it still throws ReferenceError, keep it for the (single) next attempt.
|
|
522
|
+
if (fn() !== true) next.push(fn)
|
|
523
|
+
}
|
|
524
|
+
__pending = next
|
|
525
|
+
}
|
|
475
526
|
|
|
476
527
|
${Array.from(setters.values()).join('\n')}
|
|
477
528
|
|
|
529
|
+
if (__pending.length > 0) {
|
|
530
|
+
queueMicrotask(() => {
|
|
531
|
+
__flushPendingOnce()
|
|
532
|
+
|
|
533
|
+
if (__pending.length > 0) {
|
|
534
|
+
const __retryDelays = [0, 10, 50]
|
|
535
|
+
const __schedulePending = (i) => {
|
|
536
|
+
if (__pending.length === 0) return
|
|
537
|
+
if (i >= __retryDelays.length) {
|
|
538
|
+
// Give up: leave exports as-is to avoid unbounded retries.
|
|
539
|
+
__pending = []
|
|
540
|
+
return
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const t = setTimeout(() => {
|
|
544
|
+
__flushPendingOnce()
|
|
545
|
+
__schedulePending(i + 1)
|
|
546
|
+
}, __retryDelays[i])
|
|
547
|
+
// Don't keep the process alive just for best-effort retries.
|
|
548
|
+
if (t && typeof t.unref === 'function') t.unref()
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
__schedulePending(0)
|
|
552
|
+
}
|
|
553
|
+
})
|
|
554
|
+
}
|
|
555
|
+
|
|
478
556
|
register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpecifier)})
|
|
479
557
|
`
|
|
480
558
|
}
|
|
@@ -502,21 +580,28 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpeci
|
|
|
502
580
|
}
|
|
503
581
|
}
|
|
504
582
|
|
|
505
|
-
return parentGetSource(url, context
|
|
583
|
+
return parentGetSource(url, context)
|
|
506
584
|
}
|
|
507
585
|
|
|
508
586
|
// For Node.js 16.12.0 and higher.
|
|
509
587
|
async function load (url, context, parentLoad) {
|
|
510
588
|
if (hasIitm(url)) {
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
589
|
+
const result = await getSource(url, context, parentLoad)
|
|
590
|
+
// If wrapping failed, `getSource()` may have fallen back to `parentLoad`,
|
|
591
|
+
// which can legally return `source: null` (e.g. for non-JS formats).
|
|
592
|
+
if (result && typeof result === 'object' && result.source != null) {
|
|
593
|
+
return {
|
|
594
|
+
source: result.source,
|
|
595
|
+
shortCircuit: true,
|
|
596
|
+
format: 'module'
|
|
597
|
+
}
|
|
516
598
|
}
|
|
599
|
+
|
|
600
|
+
// Fall back to the parent loader with the original (non-iitm) URL.
|
|
601
|
+
return parentLoad(deleteIitm(url), context)
|
|
517
602
|
}
|
|
518
603
|
|
|
519
|
-
return parentLoad(url, context
|
|
604
|
+
return parentLoad(url, context)
|
|
520
605
|
}
|
|
521
606
|
|
|
522
607
|
if (NODE_MAJOR >= 17 || (NODE_MAJOR === 16 && NODE_MINOR >= 12)) {
|
|
@@ -539,7 +624,7 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpeci
|
|
|
539
624
|
}
|
|
540
625
|
}
|
|
541
626
|
|
|
542
|
-
return parentGetFormat(url, context
|
|
627
|
+
return parentGetFormat(url, context)
|
|
543
628
|
}
|
|
544
629
|
}
|
|
545
630
|
}
|