import-in-the-middle 2.0.1 → 2.0.3
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 +25 -0
- package/README.md +1 -1
- package/create-hook.mjs +42 -6
- package/index.js +15 -5
- package/lib/get-exports.mjs +133 -8
- package/lib/register.js +14 -2
- package/package.json +18 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [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
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* add missing JSDoc type information ([40c1009](https://github.com/nodejs/import-in-the-middle/commit/40c1009ef3acc45b5eec89ed1b866866933edace))
|
|
9
|
+
* add missing name for fast builtin lookup ([40c1009](https://github.com/nodejs/import-in-the-middle/commit/40c1009ef3acc45b5eec89ed1b866866933edace))
|
|
10
|
+
* do not crash on missing setters ([#223](https://github.com/nodejs/import-in-the-middle/issues/223)) ([fe44778](https://github.com/nodejs/import-in-the-middle/commit/fe4477832aa9a3422ebecf0a2460cf77be3b3581))
|
|
11
|
+
* handle undefined exports properly ([40c1009](https://github.com/nodejs/import-in-the-middle/commit/40c1009ef3acc45b5eec89ed1b866866933edace))
|
|
12
|
+
* multiple minor issues ([#221](https://github.com/nodejs/import-in-the-middle/issues/221)) ([40c1009](https://github.com/nodejs/import-in-the-middle/commit/40c1009ef3acc45b5eec89ed1b866866933edace))
|
|
13
|
+
* remove small memory leak ([40c1009](https://github.com/nodejs/import-in-the-middle/commit/40c1009ef3acc45b5eec89ed1b866866933edace))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Performance Improvements
|
|
17
|
+
|
|
18
|
+
* improve perf by calculating less stack frames and fast paths ([#224](https://github.com/nodejs/import-in-the-middle/issues/224)) ([09ae8bf](https://github.com/nodejs/import-in-the-middle/commit/09ae8bfdeedf6c1c8c81c7338858004447e68233))
|
|
19
|
+
|
|
20
|
+
## [2.0.2](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.1...import-in-the-middle-v2.0.2) (2026-01-11)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* grammar issue in README.md ([#216](https://github.com/nodejs/import-in-the-middle/issues/216)) ([46e4a2a](https://github.com/nodejs/import-in-the-middle/commit/46e4a2a9ad250c06fb52c9b782370071a6d1f3cc))
|
|
26
|
+
* properly handle internals when specifier matches ([#220](https://github.com/nodejs/import-in-the-middle/issues/220)) ([05e4216](https://github.com/nodejs/import-in-the-middle/commit/05e4216e10d11c7eb996d4124f36e476f3a6d42f))
|
|
27
|
+
|
|
3
28
|
## [2.0.1](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v2.0.0...import-in-the-middle-v2.0.1) (2025-12-18)
|
|
4
29
|
|
|
5
30
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# import-in-the-middle
|
|
2
2
|
|
|
3
|
-
**`import-in-the-middle`** is
|
|
3
|
+
**`import-in-the-middle`** is a module loading interceptor inspired by
|
|
4
4
|
[`require-in-the-middle`](https://npm.im/require-in-the-middle), but
|
|
5
5
|
specifically for ESM modules. In fact, it can even modify modules after loading
|
|
6
6
|
time.
|
package/create-hook.mjs
CHANGED
|
@@ -21,6 +21,7 @@ const NODE_VERSION = process.versions.node.split('.')
|
|
|
21
21
|
const NODE_MAJOR = Number(NODE_VERSION[0])
|
|
22
22
|
const NODE_MINOR = Number(NODE_VERSION[1])
|
|
23
23
|
const HANDLED_FORMATS = new Set(['builtin', 'module', 'commonjs'])
|
|
24
|
+
const TRACE_WARNINGS = process.execArgv.includes('--trace-warnings')
|
|
24
25
|
|
|
25
26
|
let getExports
|
|
26
27
|
if (NODE_MAJOR >= 20 || (NODE_MAJOR === 18 && NODE_MINOR >= 19)) {
|
|
@@ -32,6 +33,10 @@ if (NODE_MAJOR >= 20 || (NODE_MAJOR === 18 && NODE_MINOR >= 19)) {
|
|
|
32
33
|
let entrypoint
|
|
33
34
|
|
|
34
35
|
function hasIitm (url) {
|
|
36
|
+
// Fast path: avoid URL parsing on the hot path when there's clearly no iitm.
|
|
37
|
+
if (typeof url !== 'string' || url.indexOf('iitm') === -1) {
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
35
40
|
try {
|
|
36
41
|
return new URL(url).searchParams.has('iitm')
|
|
37
42
|
} catch {
|
|
@@ -44,8 +49,14 @@ function isIitm (url, meta) {
|
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
function deleteIitm (url) {
|
|
52
|
+
// Fast path: avoid URL parsing / try-catch on bare specifiers and normal file URLs.
|
|
53
|
+
if (typeof url !== 'string' || url.indexOf('iitm') === -1) {
|
|
54
|
+
return url
|
|
55
|
+
}
|
|
47
56
|
let resultUrl
|
|
57
|
+
const stackTraceLimit = Error.stackTraceLimit
|
|
48
58
|
try {
|
|
59
|
+
Error.stackTraceLimit = 0
|
|
49
60
|
const urlObj = new URL(url)
|
|
50
61
|
if (urlObj.searchParams.has('iitm')) {
|
|
51
62
|
urlObj.searchParams.delete('iitm')
|
|
@@ -62,6 +73,7 @@ function deleteIitm (url) {
|
|
|
62
73
|
} catch {
|
|
63
74
|
resultUrl = url
|
|
64
75
|
}
|
|
76
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
65
77
|
return resultUrl
|
|
66
78
|
}
|
|
67
79
|
|
|
@@ -115,12 +127,16 @@ function isBareSpecifier (specifier) {
|
|
|
115
127
|
return !URL.canParse(specifier)
|
|
116
128
|
}
|
|
117
129
|
|
|
130
|
+
const stackTraceLimit = Error.stackTraceLimit
|
|
118
131
|
try {
|
|
132
|
+
Error.stackTraceLimit = 0
|
|
119
133
|
// eslint-disable-next-line no-new
|
|
120
134
|
new URL(specifier)
|
|
121
135
|
return false
|
|
122
136
|
} catch (err) {
|
|
123
137
|
return true
|
|
138
|
+
} finally {
|
|
139
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
124
140
|
}
|
|
125
141
|
}
|
|
126
142
|
|
|
@@ -141,7 +157,9 @@ function isBareSpecifierFileUrlOrRegex (input) {
|
|
|
141
157
|
return false
|
|
142
158
|
}
|
|
143
159
|
|
|
160
|
+
const stackTraceLimit = Error.stackTraceLimit
|
|
144
161
|
try {
|
|
162
|
+
Error.stackTraceLimit = 0
|
|
145
163
|
// eslint-disable-next-line no-new
|
|
146
164
|
const url = new URL(input)
|
|
147
165
|
// We consider node: URLs bare specifiers in this context
|
|
@@ -149,6 +167,8 @@ function isBareSpecifierFileUrlOrRegex (input) {
|
|
|
149
167
|
} catch (err) {
|
|
150
168
|
// Anything that fails parsing is a bare specifier
|
|
151
169
|
return true
|
|
170
|
+
} finally {
|
|
171
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
152
172
|
}
|
|
153
173
|
}
|
|
154
174
|
|
|
@@ -185,7 +205,7 @@ function emitWarning (err) {
|
|
|
185
205
|
// Unfortunately, process.emitWarning does not output the full error
|
|
186
206
|
// with error.cause like console.warn does so we need to inspect it when
|
|
187
207
|
// tracing warnings
|
|
188
|
-
const warnMessage =
|
|
208
|
+
const warnMessage = TRACE_WARNINGS ? inspect(err) : err
|
|
189
209
|
process.emitWarning(warnMessage)
|
|
190
210
|
}
|
|
191
211
|
|
|
@@ -196,12 +216,13 @@ function emitWarning (err) {
|
|
|
196
216
|
* @param {string} params.srcUrl The full URL to the module to process.
|
|
197
217
|
* @param {object} params.context Provided by the loaders API.
|
|
198
218
|
* @param {Function} params.parentGetSource Provides the source code for the parent module.
|
|
199
|
-
* @param {
|
|
219
|
+
* @param {Function} params.parentResolve Provides the resolve function for the parent module.
|
|
220
|
+
* @param {boolean} [params.excludeDefault = false] Exclude the default export.
|
|
200
221
|
*
|
|
201
222
|
* @returns {Promise<Map<string, string>>} The shimmed setters for all the exports
|
|
202
223
|
* from the module and any transitive export all modules.
|
|
203
224
|
*/
|
|
204
|
-
async function processModule ({ srcUrl, context, parentGetSource, parentResolve, excludeDefault }) {
|
|
225
|
+
async function processModule ({ srcUrl, context, parentGetSource, parentResolve, excludeDefault = false }) {
|
|
205
226
|
const exportNames = await getExports(srcUrl, context, parentGetSource)
|
|
206
227
|
const starExports = new Set()
|
|
207
228
|
const setters = new Map()
|
|
@@ -365,12 +386,21 @@ export function createHook (meta) {
|
|
|
365
386
|
//
|
|
366
387
|
// For non-bare specifier imports, we match to the full file URL because
|
|
367
388
|
// using relative paths would be very error prone!
|
|
389
|
+
let resultPath
|
|
390
|
+
if (result.url.startsWith('file:')) {
|
|
391
|
+
const stackTraceLimit = Error.stackTraceLimit
|
|
392
|
+
Error.stackTraceLimit = 0
|
|
393
|
+
try {
|
|
394
|
+
resultPath = fileURLToPath(result.url)
|
|
395
|
+
} catch {}
|
|
396
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
397
|
+
}
|
|
368
398
|
function match (each) {
|
|
369
399
|
if (each instanceof RegExp) {
|
|
370
400
|
return each.test(result.url)
|
|
371
401
|
}
|
|
372
402
|
|
|
373
|
-
return each === specifier || each === result.url || (
|
|
403
|
+
return each === specifier || each === result.url || (resultPath && each === resultPath)
|
|
374
404
|
}
|
|
375
405
|
|
|
376
406
|
if (result.format && !HANDLED_FORMATS.has(result.format)) {
|
|
@@ -385,7 +415,7 @@ export function createHook (meta) {
|
|
|
385
415
|
return result
|
|
386
416
|
}
|
|
387
417
|
|
|
388
|
-
if (isIitm(parentURL, meta) || hasIitm(parentURL)) {
|
|
418
|
+
if (isIitm(parentURL, meta) || (parentURL && hasIitm(parentURL))) {
|
|
389
419
|
return result
|
|
390
420
|
}
|
|
391
421
|
|
|
@@ -421,6 +451,7 @@ export function createHook (meta) {
|
|
|
421
451
|
async function getSource (url, context, parentGetSource) {
|
|
422
452
|
if (hasIitm(url)) {
|
|
423
453
|
const realUrl = deleteIitm(url)
|
|
454
|
+
const originalSpecifier = specifiers.get(realUrl)
|
|
424
455
|
|
|
425
456
|
try {
|
|
426
457
|
const setters = await processModule({
|
|
@@ -429,6 +460,8 @@ export function createHook (meta) {
|
|
|
429
460
|
parentGetSource,
|
|
430
461
|
parentResolve: cachedResolve
|
|
431
462
|
})
|
|
463
|
+
// If the module loaded successfully, we can remove the specifier to reduce memory usage early.
|
|
464
|
+
specifiers.delete(realUrl)
|
|
432
465
|
return {
|
|
433
466
|
source: `
|
|
434
467
|
import { register } from '${iitmURL}'
|
|
@@ -442,10 +475,13 @@ const get = {}
|
|
|
442
475
|
|
|
443
476
|
${Array.from(setters.values()).join('\n')}
|
|
444
477
|
|
|
445
|
-
register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(
|
|
478
|
+
register(${JSON.stringify(realUrl)}, _, set, get, ${JSON.stringify(originalSpecifier)})
|
|
446
479
|
`
|
|
447
480
|
}
|
|
448
481
|
} catch (cause) {
|
|
482
|
+
// If the module failed loading, the specifier will not be used again, so
|
|
483
|
+
// we can remove it to prevent a memory leak.
|
|
484
|
+
specifiers.delete(realUrl)
|
|
449
485
|
// If there are other ESM loader hooks registered as well as iitm,
|
|
450
486
|
// depending on the order they are registered, source might not be
|
|
451
487
|
// JavaScript.
|
package/index.js
CHANGED
|
@@ -29,7 +29,12 @@ function removeHook (hook) {
|
|
|
29
29
|
function callHookFn (hookFn, namespace, name, baseDir) {
|
|
30
30
|
const newDefault = hookFn(namespace, name, baseDir)
|
|
31
31
|
if (newDefault && newDefault !== namespace) {
|
|
32
|
-
|
|
32
|
+
// Only ESM modules that actually export `default` can have it reassigned.
|
|
33
|
+
// Some hooks return a value unconditionally; avoid crashing when the module
|
|
34
|
+
// has no default export (see issue #188).
|
|
35
|
+
if ('default' in namespace) {
|
|
36
|
+
namespace.default = newDefault
|
|
37
|
+
}
|
|
33
38
|
}
|
|
34
39
|
}
|
|
35
40
|
|
|
@@ -127,9 +132,12 @@ function Hook (modules, options, hookFn) {
|
|
|
127
132
|
name = name.replace(/^node:/, '')
|
|
128
133
|
} else {
|
|
129
134
|
if (name.startsWith('file://')) {
|
|
135
|
+
const stackTraceLimit = Error.stackTraceLimit
|
|
136
|
+
Error.stackTraceLimit = 0
|
|
130
137
|
try {
|
|
131
138
|
name = fileURLToPath(name)
|
|
132
139
|
} catch (e) {}
|
|
140
|
+
Error.stackTraceLimit = stackTraceLimit
|
|
133
141
|
}
|
|
134
142
|
const details = parse(name)
|
|
135
143
|
if (details) {
|
|
@@ -140,14 +148,16 @@ function Hook (modules, options, hookFn) {
|
|
|
140
148
|
|
|
141
149
|
if (modules) {
|
|
142
150
|
for (const moduleName of modules) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
const nameMatch = moduleName === name
|
|
152
|
+
const specMatch = moduleName === specifier
|
|
153
|
+
if (nameMatch || specMatch) {
|
|
146
154
|
if (baseDir) {
|
|
147
155
|
if (internals) {
|
|
148
156
|
name = name + path.sep + path.relative(baseDir, fileURLToPath(filename))
|
|
149
157
|
} else {
|
|
150
|
-
if (!getExperimentalPatchInternals() && !baseDir.endsWith(specifiers.get(filename)))
|
|
158
|
+
if (!getExperimentalPatchInternals() && !specMatch && !baseDir.endsWith(specifiers.get(filename))) {
|
|
159
|
+
continue
|
|
160
|
+
}
|
|
151
161
|
}
|
|
152
162
|
}
|
|
153
163
|
callHookFn(hookFn, namespace, name, baseDir)
|
package/lib/get-exports.mjs
CHANGED
|
@@ -16,13 +16,134 @@ function addDefault (arr) {
|
|
|
16
16
|
return new Set(['default', ...arr])
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
function hasEsmSyntax (source) {
|
|
20
|
+
// Lightweight scan (no full parse) to determine if the *source code*
|
|
21
|
+
// contains ESM-specific syntax. This is used only when:
|
|
22
|
+
// - the loader chain didn't tell us a `format`, and
|
|
23
|
+
// - `getEsmExports()` found no exports.
|
|
24
|
+
//
|
|
25
|
+
// Notes:
|
|
26
|
+
// - We ignore comments and strings to reduce false positives.
|
|
27
|
+
// - We treat `import.meta` and static `import ...` as ESM.
|
|
28
|
+
// - We do NOT treat `import(` (dynamic import) as ESM because it is allowed
|
|
29
|
+
// in CJS as an expression.
|
|
30
|
+
if (source.indexOf('import') === -1) return false
|
|
31
|
+
|
|
32
|
+
const isIdentCharCode = (code) => (
|
|
33
|
+
(code >= 48 && code <= 57) || // 0-9
|
|
34
|
+
(code >= 65 && code <= 90) || // A-Z
|
|
35
|
+
(code >= 97 && code <= 122) || // a-z
|
|
36
|
+
code === 95 || // _
|
|
37
|
+
code === 36 // $
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const skipWhitespace = (idx) => {
|
|
41
|
+
while (idx < source.length) {
|
|
42
|
+
const c = source.charCodeAt(idx)
|
|
43
|
+
// space, tab, cr, lf
|
|
44
|
+
if (c !== 32 && c !== 9 && c !== 13 && c !== 10) break
|
|
45
|
+
idx++
|
|
46
|
+
}
|
|
47
|
+
return idx
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let i = 0
|
|
51
|
+
while (i < source.length) {
|
|
52
|
+
const ch = source[i]
|
|
53
|
+
|
|
54
|
+
// Line comment
|
|
55
|
+
if (ch === '/' && source[i + 1] === '/') {
|
|
56
|
+
i += 2
|
|
57
|
+
while (i < source.length && source[i] !== '\n') i++
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Block comment
|
|
62
|
+
if (ch === '/' && source[i + 1] === '*') {
|
|
63
|
+
i += 2
|
|
64
|
+
while (i < source.length && !(source[i] === '*' && source[i + 1] === '/')) i++
|
|
65
|
+
i += 2
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Strings: '...' or "..."
|
|
70
|
+
if (ch === '\'' || ch === '"') {
|
|
71
|
+
const quote = ch
|
|
72
|
+
i++
|
|
73
|
+
while (i < source.length) {
|
|
74
|
+
const c = source[i]
|
|
75
|
+
if (c === '\\') {
|
|
76
|
+
i += 2
|
|
77
|
+
continue
|
|
78
|
+
}
|
|
79
|
+
if (c === quote) {
|
|
80
|
+
i++
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
i++
|
|
84
|
+
}
|
|
85
|
+
continue
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Template strings: `...`
|
|
89
|
+
if (ch === '`') {
|
|
90
|
+
i++
|
|
91
|
+
while (i < source.length) {
|
|
92
|
+
const c = source[i]
|
|
93
|
+
if (c === '\\') {
|
|
94
|
+
i += 2
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
if (c === '`') {
|
|
98
|
+
i++
|
|
99
|
+
break
|
|
100
|
+
}
|
|
101
|
+
i++
|
|
102
|
+
}
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Keyword scan (word-boundary): import
|
|
107
|
+
if (ch === 'i') {
|
|
108
|
+
const prev = source.charCodeAt(i - 1)
|
|
109
|
+
if (i > 0 && isIdentCharCode(prev)) {
|
|
110
|
+
i++
|
|
111
|
+
continue
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (source.startsWith('import', i)) {
|
|
115
|
+
const next = source.charCodeAt(i + 6)
|
|
116
|
+
if (isIdentCharCode(next)) {
|
|
117
|
+
i++
|
|
118
|
+
continue
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const j = skipWhitespace(i + 6)
|
|
122
|
+
// `import.meta` is ESM-only
|
|
123
|
+
if (source[j] === '.') return true
|
|
124
|
+
// `import(` is dynamic import, allowed in CJS
|
|
125
|
+
if (source[j] === '(') {
|
|
126
|
+
i = j + 1
|
|
127
|
+
continue
|
|
128
|
+
}
|
|
129
|
+
// Otherwise assume it's a static import form
|
|
130
|
+
return true
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
i++
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return false
|
|
138
|
+
}
|
|
139
|
+
|
|
19
140
|
// Cached exports for Node built-in modules
|
|
20
141
|
const BUILT_INS = new Map()
|
|
21
142
|
|
|
22
143
|
let require
|
|
23
144
|
|
|
24
145
|
function getExportsForNodeBuiltIn (name) {
|
|
25
|
-
let exports = BUILT_INS.get()
|
|
146
|
+
let exports = BUILT_INS.get(name)
|
|
26
147
|
|
|
27
148
|
if (!require) {
|
|
28
149
|
require = createRequire(import.meta.url)
|
|
@@ -96,7 +217,7 @@ function resolvePackageImports (specifier, fromUrl) {
|
|
|
96
217
|
|
|
97
218
|
async function getCjsExports (url, context, parentLoad, source) {
|
|
98
219
|
if (urlsBeingProcessed.has(url)) {
|
|
99
|
-
return
|
|
220
|
+
return new Set()
|
|
100
221
|
}
|
|
101
222
|
urlsBeingProcessed.add(url)
|
|
102
223
|
|
|
@@ -201,13 +322,17 @@ export async function getExports (url, context, parentLoad) {
|
|
|
201
322
|
// At this point our `format` is either undefined or not known by us. Fall
|
|
202
323
|
// back to parsing as ESM/CJS.
|
|
203
324
|
const esmExports = getEsmExports(source)
|
|
204
|
-
if (!esmExports.
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
325
|
+
if (!esmExports.size) {
|
|
326
|
+
// If there's strong evidence this is ESM (static import/import.meta),
|
|
327
|
+
// prefer returning the empty ESM export set over incorrectly treating it
|
|
328
|
+
// as CJS.
|
|
329
|
+
if (!hasEsmSyntax(source)) {
|
|
330
|
+
// It might be possible to get here if the format
|
|
331
|
+
// isn't set at first and yet we have an ESM module with no exports.
|
|
332
|
+
return await getCjsExports(url, context, parentLoad, source)
|
|
333
|
+
}
|
|
210
334
|
}
|
|
335
|
+
return esmExports
|
|
211
336
|
} catch (cause) {
|
|
212
337
|
const err = new Error(`Failed to parse '${url}'`)
|
|
213
338
|
err.cause = cause
|
package/lib/register.js
CHANGED
|
@@ -10,7 +10,14 @@ const toHook = []
|
|
|
10
10
|
|
|
11
11
|
const proxyHandler = {
|
|
12
12
|
set (target, name, value) {
|
|
13
|
-
|
|
13
|
+
const set = setters.get(target)
|
|
14
|
+
const setter = set && set[name]
|
|
15
|
+
if (typeof setter === 'function') {
|
|
16
|
+
return setter(value)
|
|
17
|
+
}
|
|
18
|
+
// If a module doesn't export the property being assigned (e.g. no default
|
|
19
|
+
// export), there is no setter to call. Don't crash userland code.
|
|
20
|
+
return true
|
|
14
21
|
},
|
|
15
22
|
|
|
16
23
|
get (target, name) {
|
|
@@ -30,7 +37,12 @@ const proxyHandler = {
|
|
|
30
37
|
throw new Error('Getters/setters are not supported for exports property descriptors.')
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
const set = setters.get(target)
|
|
41
|
+
const setter = set && set[property]
|
|
42
|
+
if (typeof setter === 'function') {
|
|
43
|
+
return setter(descriptor.value)
|
|
44
|
+
}
|
|
45
|
+
return true
|
|
34
46
|
}
|
|
35
47
|
}
|
|
36
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "import-in-the-middle",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Intercept imports in Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,31 +34,31 @@
|
|
|
34
34
|
"test-env": "NODE_OPTIONS=--no-warnings --require ./test/version-check.js --experimental-loader ./test/generic-loader.mjs"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@babel/core": "^7.
|
|
38
|
-
"@babel/eslint-parser": "^7.
|
|
39
|
-
"@babel/plugin-syntax-import-assertions": "^7.
|
|
40
|
-
"@node-rs/crc32": "^1.10.
|
|
37
|
+
"@babel/core": "^7.28.5",
|
|
38
|
+
"@babel/eslint-parser": "^7.28.5",
|
|
39
|
+
"@babel/plugin-syntax-import-assertions": "^7.27.1",
|
|
40
|
+
"@node-rs/crc32": "^1.10.6",
|
|
41
41
|
"@react-email/components": "^0.0.19",
|
|
42
42
|
"@types/node": "^18.0.6",
|
|
43
|
-
"c8": "^7.
|
|
43
|
+
"c8": "^7.14.0",
|
|
44
44
|
"date-fns": "^3.6.0",
|
|
45
|
-
"eslint": "^8.
|
|
45
|
+
"eslint": "^8.57.1",
|
|
46
46
|
"eslint-config-standard": "^17.1.0",
|
|
47
|
-
"eslint-plugin-import": "^2.
|
|
48
|
-
"eslint-plugin-n": "^16.
|
|
47
|
+
"eslint-plugin-import": "^2.32.0",
|
|
48
|
+
"eslint-plugin-n": "^16.6.2",
|
|
49
49
|
"eslint-plugin-node": "^11.1.0",
|
|
50
|
-
"eslint-plugin-promise": "^6.
|
|
51
|
-
"got": "^14.
|
|
52
|
-
"imhotap": "^2.
|
|
50
|
+
"eslint-plugin-promise": "^6.6.0",
|
|
51
|
+
"got": "^14.6.6",
|
|
52
|
+
"imhotap": "^2.2.0",
|
|
53
53
|
"openai": "4.47.2",
|
|
54
|
-
"ts-node": "^10.9.
|
|
55
|
-
"typescript": "^4.
|
|
56
|
-
"vue": "^3.
|
|
54
|
+
"ts-node": "^10.9.2",
|
|
55
|
+
"typescript": "^4.9.5",
|
|
56
|
+
"vue": "^3.5.26"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"acorn": "^8.
|
|
59
|
+
"acorn": "^8.15.0",
|
|
60
60
|
"acorn-import-attributes": "^1.9.5",
|
|
61
|
-
"cjs-module-lexer": "^
|
|
62
|
-
"module-details-from-path": "^1.0.
|
|
61
|
+
"cjs-module-lexer": "^2.2.0",
|
|
62
|
+
"module-details-from-path": "^1.0.4"
|
|
63
63
|
}
|
|
64
64
|
}
|