import-in-the-middle 2.0.6 → 3.0.1
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 +18 -0
- package/create-hook.mjs +4 -56
- package/hook.mjs +2 -2
- package/index.js +21 -1
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.0.1](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v3.0.0...import-in-the-middle-v3.0.1) (2026-04-07)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* handle file specifiers from turbopacked packages better ([#246](https://github.com/nodejs/import-in-the-middle/issues/246)) ([04539fb](https://github.com/nodejs/import-in-the-middle/commit/04539fb5ceb9e4816933bd4310c1334077af1643))
|
|
9
|
+
|
|
10
|
+
## [3.0.0](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.6...import-in-the-middle-v3.0.0) (2026-01-30)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### ⚠ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* drop support for Node.js < v18 ([#230](https://github.com/nodejs/import-in-the-middle/issues/230))
|
|
16
|
+
|
|
17
|
+
### Miscellaneous Chores
|
|
18
|
+
|
|
19
|
+
* drop support for Node.js < v18 ([#230](https://github.com/nodejs/import-in-the-middle/issues/230)) ([f463b13](https://github.com/nodejs/import-in-the-middle/commit/f463b1342ca946608432c9be39fecb86e7f7cbf0))
|
|
20
|
+
|
|
3
21
|
## [2.0.6](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.5...import-in-the-middle-v2.0.6) (2026-01-27)
|
|
4
22
|
|
|
5
23
|
|
package/create-hook.mjs
CHANGED
|
@@ -29,8 +29,6 @@ if (NODE_MAJOR > 16 || (NODE_MAJOR === 16 && NODE_MINOR >= 16)) {
|
|
|
29
29
|
getExports = (url) => import(url).then(Object.keys)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
let entrypoint
|
|
33
|
-
|
|
34
32
|
function hasIitm (url) {
|
|
35
33
|
// Fast path: avoid URL parsing on the hot path when there's clearly no iitm.
|
|
36
34
|
if (typeof url !== 'string' || url.indexOf('iitm') === -1) {
|
|
@@ -73,28 +71,6 @@ function deleteIitm (url) {
|
|
|
73
71
|
return resultUrl
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
function isNodeMajor16AndMinor17OrGreater () {
|
|
77
|
-
return NODE_MAJOR === 16 && NODE_MINOR >= 17
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function isFileProtocol (urlObj) {
|
|
81
|
-
return urlObj.protocol === 'file:'
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function isNodeProtocol (urlObj) {
|
|
85
|
-
return urlObj.protocol === 'node:'
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function needsToAddFileProtocol (urlObj) {
|
|
89
|
-
if (NODE_MAJOR === 17) {
|
|
90
|
-
return !isFileProtocol(urlObj)
|
|
91
|
-
}
|
|
92
|
-
if (isNodeMajor16AndMinor17OrGreater()) {
|
|
93
|
-
return !isFileProtocol(urlObj) && !isNodeProtocol(urlObj)
|
|
94
|
-
}
|
|
95
|
-
return !isFileProtocol(urlObj) && NODE_MAJOR < 18
|
|
96
|
-
}
|
|
97
|
-
|
|
98
74
|
/**
|
|
99
75
|
* Determines if a specifier represents an export all ESM line.
|
|
100
76
|
* Note that the expected `line` isn't 100% valid ESM. It is derived
|
|
@@ -287,7 +263,7 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
|
|
|
287
263
|
} else {
|
|
288
264
|
const variableName = `$${n.replace(/[^a-zA-Z0-9_$]/g, '_')}`
|
|
289
265
|
const objectKey = JSON.stringify(n)
|
|
290
|
-
const reExportedName = n === 'default'
|
|
266
|
+
const reExportedName = n === 'default' ? n : objectKey
|
|
291
267
|
|
|
292
268
|
addSetter(n, `
|
|
293
269
|
let ${variableName}
|
|
@@ -324,7 +300,7 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
|
|
|
324
300
|
function addIitm (url) {
|
|
325
301
|
const urlObj = new URL(url)
|
|
326
302
|
urlObj.searchParams.set('iitm', 'true')
|
|
327
|
-
return
|
|
303
|
+
return urlObj.href
|
|
328
304
|
}
|
|
329
305
|
|
|
330
306
|
export function createHook (meta) {
|
|
@@ -386,13 +362,9 @@ export function createHook (meta) {
|
|
|
386
362
|
// are evaluated, and can make them exit without doing anything.
|
|
387
363
|
if (parentURL === '') {
|
|
388
364
|
if (!EXTENSION_RE.test(result.url) && !hasIitm(result.url)) {
|
|
389
|
-
entrypoint = result.url
|
|
390
365
|
return { url: result.url, format: 'commonjs' }
|
|
391
366
|
}
|
|
392
|
-
|
|
393
|
-
entrypoint = result.url
|
|
394
|
-
return result
|
|
395
|
-
}
|
|
367
|
+
return result
|
|
396
368
|
}
|
|
397
369
|
|
|
398
370
|
// For included/excluded modules, we check the specifier to match libraries
|
|
@@ -574,7 +546,6 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpeci
|
|
|
574
546
|
return parentGetSource(url, context)
|
|
575
547
|
}
|
|
576
548
|
|
|
577
|
-
// For Node.js 16.12.0 and higher.
|
|
578
549
|
async function load (url, context, parentLoad) {
|
|
579
550
|
if (hasIitm(url)) {
|
|
580
551
|
const result = await getSource(url, context, parentLoad)
|
|
@@ -595,28 +566,5 @@ register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpeci
|
|
|
595
566
|
return parentLoad(url, context)
|
|
596
567
|
}
|
|
597
568
|
|
|
598
|
-
|
|
599
|
-
return { initialize, load, resolve }
|
|
600
|
-
} else {
|
|
601
|
-
return {
|
|
602
|
-
initialize,
|
|
603
|
-
load,
|
|
604
|
-
resolve,
|
|
605
|
-
getSource,
|
|
606
|
-
getFormat (url, context, parentGetFormat) {
|
|
607
|
-
if (hasIitm(url)) {
|
|
608
|
-
return {
|
|
609
|
-
format: 'module'
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
if (url === entrypoint) {
|
|
613
|
-
return {
|
|
614
|
-
format: 'commonjs'
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
return parentGetFormat(url, context)
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
}
|
|
569
|
+
return { initialize, load, resolve }
|
|
622
570
|
}
|
package/hook.mjs
CHANGED
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import { createHook } from './create-hook.mjs'
|
|
6
6
|
|
|
7
|
-
const { initialize, load, resolve
|
|
7
|
+
const { initialize, load, resolve } = createHook(import.meta)
|
|
8
8
|
|
|
9
|
-
export { initialize, load, resolve
|
|
9
|
+
export { initialize, load, resolve }
|
package/index.js
CHANGED
|
@@ -18,6 +18,26 @@ const {
|
|
|
18
18
|
toHook
|
|
19
19
|
} = require('./lib/register')
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Checks turbopack specifiers separately (for Next.js 16+).
|
|
23
|
+
*
|
|
24
|
+
* If turbopack is used, specifiers will have an additional hash appended to the end.
|
|
25
|
+
* Something like "ai" might become "ai-5e7181a616786b24". This only happens in Next.js 16+.
|
|
26
|
+
* Just checking if the baseDir ends with this new specifier won't match, as the baseDir still has the plain package.
|
|
27
|
+
*
|
|
28
|
+
* This logic isolates a new check for checking the actual name in the case turbopack is being used.
|
|
29
|
+
*
|
|
30
|
+
* @param specifier {string}
|
|
31
|
+
* @param baseDir {string}
|
|
32
|
+
*/
|
|
33
|
+
function isTurbopackSpecifier (specifier, baseDir) {
|
|
34
|
+
const usingTurbopack = process.env.TURBOPACK ?? process.argv.includes('--turbo')
|
|
35
|
+
if (!usingTurbopack) return false
|
|
36
|
+
|
|
37
|
+
const specifierWithoutTurbopackHash = specifier.slice(0, specifier.lastIndexOf('-'))
|
|
38
|
+
return baseDir.endsWith(specifierWithoutTurbopackHash)
|
|
39
|
+
}
|
|
40
|
+
|
|
21
41
|
function addHook (hook) {
|
|
22
42
|
importHooks.push(hook)
|
|
23
43
|
toHook.forEach(([name, namespace, specifier]) => hook(name, namespace, specifier))
|
|
@@ -167,7 +187,7 @@ function Hook (modules, options, hookFn) {
|
|
|
167
187
|
if (!baseDir) {
|
|
168
188
|
// built-in module (or unexpected non file:// name?)
|
|
169
189
|
callHookFn(hookFn, namespace, name, baseDir)
|
|
170
|
-
} else if (baseDir.endsWith(specifiers.get(loadUrl))) {
|
|
190
|
+
} else if (baseDir.endsWith(specifiers.get(loadUrl)) || isTurbopackSpecifier(specifiers.get(loadUrl), baseDir)) {
|
|
171
191
|
// An import of the top-level module (e.g. `import 'ioredis'`).
|
|
172
192
|
// Note: Slight behaviour difference from RITM. RITM uses
|
|
173
193
|
// `require.resolve(name)` to see if filename is the module
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "import-in-the-middle",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Intercept imports in Node.js",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=18"
|
|
7
|
+
},
|
|
5
8
|
"main": "index.js",
|
|
6
9
|
"scripts": {
|
|
7
10
|
"test": "c8 --reporter lcov --check-coverage --lines 45 imhotap --files test/{hook,low-level,other,get-esm-exports,register}/*",
|
|
8
|
-
"test:e2e": "node test/check-exports/test.mjs",
|
|
11
|
+
"test:e2e": "node test/check-exports/test.mjs && node test/integration-tests/turbopack-dev.mjs && node test/integration-tests/turbopack-build-start.mjs",
|
|
9
12
|
"test:ts": "c8 --reporter lcov imhotap --files test/typescript/*.test.mts",
|
|
10
13
|
"coverage": "c8 --reporter html imhotap --files test/{hook,low-level,other,get-esm-exports,register}/* && echo \"\nNow open coverage/index.html\n\"",
|
|
11
14
|
"lint": "eslint .",
|