import-in-the-middle 1.9.1 → 1.10.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.9.1"
2
+ ".": "1.10.0"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.10.0](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v1.9.1...import-in-the-middle-v1.10.0) (2024-07-22)
4
+
5
+
6
+ ### Features
7
+
8
+ * Allow regex for `include` and `exclude` options ([#148](https://github.com/nodejs/import-in-the-middle/issues/148)) ([697b0d2](https://github.com/nodejs/import-in-the-middle/commit/697b0d239b9a738f4952bb0f77c521c4a398ac79))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Use correct `format` when resolving exports from relative paths ([#145](https://github.com/nodejs/import-in-the-middle/issues/145)) ([632802f](https://github.com/nodejs/import-in-the-middle/commit/632802f4e7c797215b4e052ffdfa0fbda1780166))
14
+
3
15
  ## [1.9.1](https://github.com/nodejs/import-in-the-middle/compare/import-in-the-middle-v1.9.0...import-in-the-middle-v1.9.1) (2024-07-15)
4
16
 
5
17
 
package/README.md CHANGED
@@ -54,9 +54,9 @@ node --import=./my-loader.mjs ./my-code.mjs
54
54
  ```
55
55
 
56
56
  When registering the loader hook programmatically, it's possible to pass a list
57
- of modules or file URLs to either exclude or specifically include which modules
58
- are intercepted. This is useful if a module is not compatible with the loader
59
- hook.
57
+ of modules, file URLs or regular expressions to either exclude or specifically
58
+ include which modules are intercepted. This is useful if a module is not
59
+ compatible with the loader hook.
60
60
  ```js
61
61
  import * as module from 'module'
62
62
 
package/hook.js CHANGED
@@ -116,7 +116,11 @@ function isBareSpecifier (specifier) {
116
116
  }
117
117
  }
118
118
 
119
- function isBareSpecifierOrFileUrl (input) {
119
+ function isBareSpecifierFileUrlOrRegex (input) {
120
+ if (input instanceof RegExp) {
121
+ return true
122
+ }
123
+
120
124
  // Relative and absolute paths
121
125
  if (
122
126
  input.startsWith('.') ||
@@ -134,15 +138,15 @@ function isBareSpecifierOrFileUrl (input) {
134
138
  }
135
139
  }
136
140
 
137
- function ensureArrayWithBareSpecifiersAndFileUrls (array, type) {
141
+ function ensureArrayWithBareSpecifiersFileUrlsAndRegex (array, type) {
138
142
  if (!Array.isArray(array)) {
139
143
  return undefined
140
144
  }
141
145
 
142
- const invalid = array.filter(s => !isBareSpecifierOrFileUrl(s))
146
+ const invalid = array.filter(s => !isBareSpecifierFileUrlOrRegex(s))
143
147
 
144
148
  if (invalid.length) {
145
- throw new Error(`'${type}' option only supports bare specifiers and file URLs. Invalid entries: ${inspect(invalid)}`)
149
+ throw new Error(`'${type}' option only supports bare specifiers, file URLs or regular expressions. Invalid entries: ${inspect(invalid)}`)
146
150
  }
147
151
 
148
152
  return array
@@ -206,19 +210,24 @@ async function processModule ({ srcUrl, context, parentGetSource, parentResolve,
206
210
  if (isStarExportLine(n) === true) {
207
211
  const [, modFile] = n.split('* from ')
208
212
 
209
- async function processSubModule (url, ctx) {
210
- const setters = await processModule({ srcUrl: url, context: ctx, parentGetSource, parentResolve, excludeDefault: true })
211
- for (const [name, setter] of setters.entries()) {
212
- addSetter(name, setter, true)
213
- }
214
- }
215
-
216
- if (isBareSpecifier(modFile)) {
217
- // Bare specifiers need to be resolved relative to the parent module.
218
- const result = await parentResolve(modFile, { parentURL: srcUrl })
219
- await processSubModule(result.url, { ...context, format: result.format })
220
- } else {
221
- await processSubModule(new URL(modFile, srcUrl).href, context)
213
+ // Relative paths need to be resolved relative to the parent module
214
+ const newSpecifier = isBareSpecifier(modFile) ? modFile : new URL(modFile, srcUrl).href
215
+ // We need to call `parentResolve` to resolve bare specifiers to a full
216
+ // URL. We also need to call `parentResolve` for all sub-modules to get
217
+ // the `format`. We can't rely on the parents `format` to know if this
218
+ // sub-module is ESM or CJS!
219
+ const result = await parentResolve(newSpecifier, { parentURL: srcUrl })
220
+
221
+ const subSetters = await processModule({
222
+ srcUrl: result.url,
223
+ context: { ...context, format: result.format },
224
+ parentGetSource,
225
+ parentResolve,
226
+ excludeDefault: true
227
+ })
228
+
229
+ for (const [name, setter] of subSetters.entries()) {
230
+ addSetter(name, setter, true)
222
231
  }
223
232
  } else {
224
233
  addSetter(n, `
@@ -248,8 +257,8 @@ function createHook (meta) {
248
257
 
249
258
  async function initialize (data) {
250
259
  if (data) {
251
- includeModules = ensureArrayWithBareSpecifiersAndFileUrls(data.include, 'include')
252
- excludeModules = ensureArrayWithBareSpecifiersAndFileUrls(data.exclude, 'exclude')
260
+ includeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.include, 'include')
261
+ excludeModules = ensureArrayWithBareSpecifiersFileUrlsAndRegex(data.exclude, 'exclude')
253
262
  }
254
263
  }
255
264
 
@@ -278,13 +287,21 @@ function createHook (meta) {
278
287
  // For included/excluded modules, we check the specifier to match libraries
279
288
  // that are loaded with bare specifiers from node_modules.
280
289
  //
281
- // For non-bare specifier imports, we only support matching file URL strings
282
- // because using relative paths would be very error prone!
283
- if (includeModules && !includeModules.some(lib => lib === specifier || lib === result.url.url)) {
290
+ // For non-bare specifier imports, we match to the full file URL because
291
+ // using relative paths would be very error prone!
292
+ function match (each) {
293
+ if (each instanceof RegExp) {
294
+ return each.test(result.url)
295
+ }
296
+
297
+ return each === specifier || each === result.url
298
+ }
299
+
300
+ if (includeModules && !includeModules.some(match)) {
284
301
  return result
285
302
  }
286
303
 
287
- if (excludeModules && excludeModules.some(lib => lib === specifier || lib === result.url.url)) {
304
+ if (excludeModules && excludeModules.some(match)) {
288
305
  return result
289
306
  }
290
307
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "import-in-the-middle",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "Intercept imports in Node.js",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -1,5 +1,8 @@
1
- // https://github.com/nodejs/import-in-the-middle/issues/139
2
1
  import { strictEqual } from 'assert'
3
- import * as lib from 'vue/server-renderer'
2
+ // https://github.com/nodejs/import-in-the-middle/issues/139
3
+ import * as libServer from 'vue/server-renderer'
4
+ // https://github.com/nodejs/import-in-the-middle/issues/144
5
+ import * as lib from 'vue'
4
6
 
5
- strictEqual(typeof lib.renderToString, 'function')
7
+ strictEqual(typeof libServer.renderToString, 'function')
8
+ strictEqual(typeof lib.ref, 'function')
@@ -0,0 +1,16 @@
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: { exclude: [/openai/] } })
6
+
7
+ const hooked = new Set()
8
+
9
+ Hook((_, name) => {
10
+ hooked.add(name)
11
+ })
12
+
13
+ await import('openai')
14
+
15
+ strictEqual(hooked.has('openai'), false)
16
+ strictEqual(hooked.has('fs'), true)