import-in-the-middle 3.0.0 → 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.
Files changed (3) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/index.js +21 -1
  3. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
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
+
3
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)
4
11
 
5
12
 
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,6 +1,6 @@
1
1
  {
2
2
  "name": "import-in-the-middle",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Intercept imports in Node.js",
5
5
  "engines": {
6
6
  "node": ">=18"
@@ -8,7 +8,7 @@
8
8
  "main": "index.js",
9
9
  "scripts": {
10
10
  "test": "c8 --reporter lcov --check-coverage --lines 45 imhotap --files test/{hook,low-level,other,get-esm-exports,register}/*",
11
- "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",
12
12
  "test:ts": "c8 --reporter lcov imhotap --files test/typescript/*.test.mts",
13
13
  "coverage": "c8 --reporter html imhotap --files test/{hook,low-level,other,get-esm-exports,register}/* && echo \"\nNow open coverage/index.html\n\"",
14
14
  "lint": "eslint .",