import-in-the-middle 1.13.1 → 1.14.0

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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.13.1"
2
+ ".": "1.14.0"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.14.0](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v1.13.2...import-in-the-middle-v1.14.0) (2025-05-24)
4
+
5
+
6
+ ### Features
7
+
8
+ * Optionally hook internal paths like `require-in-the-middle` ([#194](https://github.com/nodejs/import-in-the-middle/issues/194)) ([976d032](https://github.com/nodejs/import-in-the-middle/commit/976d0320426dcbf8e6260504eccbb62d83513f5a))
9
+
10
+ ## [1.13.2](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v1.13.1...import-in-the-middle-v1.13.2) (2025-05-12)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * Don't attempt to wrap TypeScript modules ([#191](https://github.com/nodejs/import-in-the-middle/issues/191)) ([6deb87e](https://github.com/nodejs/import-in-the-middle/commit/6deb87ea069ec2ee749ce2297ea47ce071d18cf9))
16
+
3
17
  ## [1.13.1](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v1.13.0...import-in-the-middle-v1.13.1) (2025-02-28)
4
18
 
5
19
 
package/README.md CHANGED
@@ -109,6 +109,23 @@ fs.readFileSync('file.txt')
109
109
  node --import=./instrument.mjs ./my-app.mjs
110
110
  ```
111
111
 
112
+ ### Experimental `experimentalPatchInternals` option
113
+
114
+ It was found that `import-in-the-middle` didn't match the hooking behavior of `require-in-the-middle` in some cases:
115
+ https://github.com/nodejs/import-in-the-middle/issues/185
116
+
117
+ The `experimentalPatchInternals` option forces the loader to match the behavior of `require-in-the-middle` in these cases.
118
+
119
+ This option is experimental and may be removed or made the default in the future.
120
+
121
+ ```js
122
+ import { register } from 'module'
123
+
124
+ register('import-in-the-middle/hook.mjs', import.meta.url, {
125
+ data: { experimentalPatchInternals: true }
126
+ })
127
+ ```
128
+
112
129
  ## Limitations
113
130
 
114
131
  * You cannot add new exports to a module. You can only modify existing ones.
package/hook.js CHANGED
@@ -7,6 +7,7 @@ const { inspect } = require('util')
7
7
  const { builtinModules } = require('module')
8
8
  const specifiers = new Map()
9
9
  const isWin = process.platform === 'win32'
10
+ let experimentalPatchInternals = false
10
11
 
11
12
  // FIXME: Typescript extensions are added temporarily until we find a better
12
13
  // way of supporting arbitrary extensions
@@ -14,6 +15,7 @@ const EXTENSION_RE = /\.(js|mjs|cjs|ts|mts|cts)$/
14
15
  const NODE_VERSION = process.versions.node.split('.')
15
16
  const NODE_MAJOR = Number(NODE_VERSION[0])
16
17
  const NODE_MINOR = Number(NODE_VERSION[1])
18
+ const HANDLED_FORMATS = new Set(['builtin', 'module', 'commonjs'])
17
19
 
18
20
  let entrypoint
19
21
 
@@ -291,6 +293,10 @@ function createHook (meta) {
291
293
  global.__import_in_the_middle_initialized__ = true
292
294
 
293
295
  if (data) {
296
+ if (data.experimentalPatchInternals) {
297
+ experimentalPatchInternals = true
298
+ }
299
+
294
300
  includeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.include, 'include')
295
301
  excludeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.exclude, 'exclude')
296
302
 
@@ -349,6 +355,10 @@ function createHook (meta) {
349
355
  return each === specifier || each === result.url || (result.url.startsWith('file:') && each === fileURLToPath(result.url))
350
356
  }
351
357
 
358
+ if (result.format && !HANDLED_FORMATS.has(result.format)) {
359
+ return result
360
+ }
361
+
352
362
  if (includeModules && !includeModules.some(match)) {
353
363
  return result
354
364
  }
@@ -405,6 +415,7 @@ function createHook (meta) {
405
415
  source: `
406
416
  import { register } from '${iitmURL}'
407
417
  import * as namespace from ${JSON.stringify(realUrl)}
418
+ ${experimentalPatchInternals ? `import { setExperimentalPatchInternals } from '${iitmURL}'\nsetExperimentalPatchInternals(true)` : ''}
408
419
 
409
420
  // Mimic a Module object (https://tc39.es/ecma262/#sec-module-namespace-objects).
410
421
  const _ = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } })
package/index.js CHANGED
@@ -10,7 +10,8 @@ const { MessageChannel } = require('worker_threads')
10
10
  const {
11
11
  importHooks,
12
12
  specifiers,
13
- toHook
13
+ toHook,
14
+ getExperimentalPatchInternals
14
15
  } = require('./lib/register')
15
16
 
16
17
  function addHook (hook) {
@@ -144,7 +145,7 @@ function Hook (modules, options, hookFn) {
144
145
  if (internals) {
145
146
  name = name + path.sep + path.relative(baseDir, fileURLToPath(filename))
146
147
  } else {
147
- if (!baseDir.endsWith(specifiers.get(filename))) continue
148
+ if (!getExperimentalPatchInternals() && !baseDir.endsWith(specifiers.get(filename))) continue
148
149
  }
149
150
  }
150
151
  callHookFn(hookFn, namespace, name, baseDir)
package/lib/register.js CHANGED
@@ -43,7 +43,19 @@ function register (name, namespace, set, get, specifier) {
43
43
  toHook.push([name, proxy])
44
44
  }
45
45
 
46
+ let experimentalPatchInternals = false
47
+
48
+ function getExperimentalPatchInternals () {
49
+ return experimentalPatchInternals
50
+ }
51
+
52
+ function setExperimentalPatchInternals (value) {
53
+ experimentalPatchInternals = value
54
+ }
55
+
46
56
  exports.register = register
47
57
  exports.importHooks = importHooks
48
58
  exports.specifiers = specifiers
49
59
  exports.toHook = toHook
60
+ exports.getExperimentalPatchInternals = getExperimentalPatchInternals
61
+ exports.setExperimentalPatchInternals = setExperimentalPatchInternals
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "import-in-the-middle",
3
- "version": "1.13.1",
3
+ "version": "1.14.0",
4
4
  "description": "Intercept imports in Node.js",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -50,7 +50,7 @@
50
50
  "eslint-plugin-promise": "^6.1.1",
51
51
  "got": "^14.3.0",
52
52
  "imhotap": "^2.1.0",
53
- "openai": "^4.47.2",
53
+ "openai": "4.47.2",
54
54
  "ts-node": "^10.9.1",
55
55
  "typescript": "^4.7.4",
56
56
  "vue": "^3.4.31"
@@ -0,0 +1,7 @@
1
+ export type { Debugger } from 'node:inspector'
2
+
3
+ export const foo: number = 42
4
+
5
+ export function bar(): number {
6
+ return foo
7
+ }
@@ -0,0 +1,8 @@
1
+ import { strictEqual } from 'assert'
2
+
3
+ const mod = await import('../fixtures/something.mts')
4
+
5
+ strictEqual(mod.foo, 42)
6
+ strictEqual(typeof mod.bar, 'function')
7
+ strictEqual(mod.bar(), 42)
8
+ strictEqual(Object.keys(mod).length, 2)
@@ -0,0 +1,14 @@
1
+ import { register } from 'module'
2
+ import Hook from '../../index.js'
3
+ import { strictEqual } from 'assert'
4
+
5
+ register('../../hook.mjs', import.meta.url, { data: { experimentalPatchInternals: true } })
6
+
7
+ Hook(['c8'], (exports, name) => {
8
+ strictEqual(name, 'c8')
9
+ exports.Report = () => 42
10
+ })
11
+
12
+ const { Report } = await import('c8/index.js')
13
+
14
+ strictEqual(Report({}), 42)