import-in-the-middle 1.13.2 → 1.14.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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.13.2"
2
+ ".": "1.14.1"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.14.1](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v1.14.0...import-in-the-middle-v1.14.1) (2025-06-12)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * Account for invalid identifiers ([#198](https://github.com/nodejs/import-in-the-middle/issues/198)) ([2cc8207](https://github.com/nodejs/import-in-the-middle/commit/2cc82070a5ca947463b70f28647b03496a9526f0))
9
+
10
+ ## [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)
11
+
12
+
13
+ ### Features
14
+
15
+ * 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))
16
+
3
17
  ## [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)
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
@@ -253,19 +254,23 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
253
254
  addSetter(name, setter, true)
254
255
  }
255
256
  } else {
257
+ const variableName = `$${n.replace(/[^a-zA-Z0-9_]/g, '_')}`
258
+ const objectKey = JSON.stringify(n)
259
+ const reExportedName = n === 'default' || NODE_MAJOR < 16 ? n : objectKey
260
+
256
261
  addSetter(n, `
257
- let $${n}
262
+ let ${variableName}
258
263
  try {
259
- $${n} = _.${n} = namespace.${n}
264
+ ${variableName} = _[${objectKey}] = namespace[${objectKey}]
260
265
  } catch (err) {
261
266
  if (!(err instanceof ReferenceError)) throw err
262
267
  }
263
- export { $${n} as ${n} }
264
- set.${n} = (v) => {
265
- $${n} = v
268
+ export { ${variableName} as ${reExportedName} }
269
+ set[${objectKey}] = (v) => {
270
+ ${variableName} = v
266
271
  return true
267
272
  }
268
- get.${n} = () => $${n}
273
+ get[${objectKey}] = () => ${variableName}
269
274
  `)
270
275
  }
271
276
  }
@@ -292,6 +297,10 @@ function createHook (meta) {
292
297
  global.__import_in_the_middle_initialized__ = true
293
298
 
294
299
  if (data) {
300
+ if (data.experimentalPatchInternals) {
301
+ experimentalPatchInternals = true
302
+ }
303
+
295
304
  includeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.include, 'include')
296
305
  excludeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.exclude, 'exclude')
297
306
 
@@ -410,6 +419,7 @@ function createHook (meta) {
410
419
  source: `
411
420
  import { register } from '${iitmURL}'
412
421
  import * as namespace from ${JSON.stringify(realUrl)}
422
+ ${experimentalPatchInternals ? `import { setExperimentalPatchInternals } from '${iitmURL}'\nsetExperimentalPatchInternals(true)` : ''}
413
423
 
414
424
  // Mimic a Module object (https://tc39.es/ecma262/#sec-module-namespace-objects).
415
425
  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.2",
3
+ "version": "1.14.1",
4
4
  "description": "Intercept imports in Node.js",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -0,0 +1,5 @@
1
+ // These export identifiers are only supported in Node 16+
2
+ exports['one.two'] = () => console.log('b')
3
+
4
+ // See: https://github.com/nodejs/import-in-the-middle/issues/94
5
+ exports['unsigned short'] = 'something'
@@ -0,0 +1,7 @@
1
+ // Regression test for https://github.com/nodejs/import-in-the-middle/issues/196
2
+
3
+ export default function foo () {
4
+ // do nothing
5
+ }
6
+
7
+ export { foo as 'module.exports' }
@@ -0,0 +1,4 @@
1
+ import ui from '../fixtures/module-exports-cjs-shim.mjs'
2
+ import { notStrictEqual } from 'assert'
3
+
4
+ notStrictEqual(ui, undefined)
@@ -0,0 +1,5 @@
1
+ import * as lib from '../fixtures/invalid-identifier.js'
2
+ import { strictEqual } from 'assert'
3
+
4
+ strictEqual(typeof lib['one.two'], 'function')
5
+ strictEqual(typeof lib['unsigned short'], 'string')
@@ -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)