-
Notifications
You must be signed in to change notification settings - Fork 53
fix: ensure the callback 'name' arg is the module name when matching the module main file, even when 'internals: true' option is used #241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3ed5244
747d2ca
5a299f0
f61aee9
a083bc7
8506ccd
0e5f6be
1cec328
cadefca
2f55c6e
da36243
6198e19
35b437b
b703995
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,7 +3,7 @@ | |
| // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc. | ||
|
|
||
| const path = require('path') | ||
| const parse = require('module-details-from-path') | ||
| const moduleDetailsFromPath = require('module-details-from-path') | ||
| const { fileURLToPath } = require('url') | ||
| const { MessageChannel } = require('worker_threads') | ||
|
|
||
|
|
@@ -128,9 +128,9 @@ function Hook (modules, options, hookFn) { | |
| } | ||
|
|
||
| this._iitmHook = (name, namespace, specifier) => { | ||
| const filename = name | ||
| const isNodeUrl = name.startsWith('node:') | ||
| let baseDir | ||
| const loadUrl = name | ||
| const isNodeUrl = loadUrl.startsWith('node:') | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reviewer note: The name change to |
||
| let filePath, baseDir | ||
|
|
||
| if (isNodeUrl) { | ||
| // Normalize builtin module name to *not* have 'node:' prefix, unless | ||
|
|
@@ -140,38 +140,43 @@ function Hook (modules, options, hookFn) { | |
| if (isBuiltin(unprefixed)) { | ||
| name = unprefixed | ||
| } | ||
| } else { | ||
| if (name.startsWith('file://')) { | ||
| const stackTraceLimit = Error.stackTraceLimit | ||
| Error.stackTraceLimit = 0 | ||
| try { | ||
| name = fileURLToPath(name) | ||
| } catch (e) {} | ||
| Error.stackTraceLimit = stackTraceLimit | ||
| } | ||
| const details = parse(name) | ||
| if (details) { | ||
| name = details.name | ||
| baseDir = details.basedir | ||
| } else if (loadUrl.startsWith('file://')) { | ||
| const stackTraceLimit = Error.stackTraceLimit | ||
| Error.stackTraceLimit = 0 | ||
| try { | ||
| filePath = fileURLToPath(name) | ||
| name = filePath | ||
| } catch (e) {} | ||
| Error.stackTraceLimit = stackTraceLimit | ||
|
|
||
| if (filePath) { | ||
| const details = moduleDetailsFromPath(filePath) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reviewer note: This section changes to only do the |
||
| if (details) { | ||
| name = details.name | ||
| baseDir = details.basedir | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (modules) { | ||
| for (const matchArg of modules) { | ||
| if (matchArg === name) { | ||
| if (filePath && matchArg === filePath) { | ||
| // abspath match | ||
| callHookFn(hookFn, namespace, filePath, undefined) | ||
| } else if (matchArg === name) { | ||
| if (!baseDir) { | ||
| // built-in module (or unexpected non file:// name?) | ||
| callHookFn(hookFn, namespace, name, baseDir) | ||
| } else if (internals) { | ||
| const internalPath = name + path.sep + path.relative(baseDir, fileURLToPath(filename)) | ||
| callHookFn(hookFn, namespace, internalPath, baseDir) | ||
| } else if (baseDir.endsWith(specifiers.get(filename))) { | ||
| } else if (baseDir.endsWith(specifiers.get(loadUrl))) { | ||
| // An import of the top-level module (e.g. `import 'ioredis'`). | ||
| // Note: Slight behaviour difference from RITM. RITM uses | ||
| // `require.resolve(name)` to see if `filename` is the module | ||
| // `require.resolve(name)` to see if filename is the module | ||
| // main file, which will catch `require('ioredis/built/index.js')`. | ||
| // The check here will not catch `import 'ioredis/built/index.js'`. | ||
| callHookFn(hookFn, namespace, name, baseDir) | ||
| } else if (internals) { | ||
| const internalPath = name + path.sep + path.relative(baseDir, filePath) | ||
| callHookFn(hookFn, namespace, internalPath, baseDir) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reviewer note: This part of the change (that moves the The rest of the changes in "index.js" are for the absolute-paths fix. |
||
| } | ||
| } else if (matchArg === specifier) { | ||
| callHookFn(hookFn, namespace, specifier, baseDir) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import path from 'path' | ||
| import { fileURLToPath } from 'url' | ||
| import { deepStrictEqual } from 'assert' | ||
| import Hook from '../../index.js' | ||
|
|
||
| const hooked = [] | ||
| const TOP = path.resolve(fileURLToPath(import.meta.url), '../../../') | ||
| Hook([ | ||
| `${TOP}/test/fixtures/index.js`, | ||
| `${TOP}/test/fixtures/something.js`, | ||
| `${TOP}/test/fixtures/node_modules/some-external-module/index.mjs`, | ||
| `${TOP}/test/fixtures/node_modules/some-external-module/sub.mjs` | ||
| ], (_, name, baseDir) => { | ||
| hooked.push([name, baseDir]) | ||
| }) | ||
|
|
||
| ;(async () => { | ||
| // Import an absolute path. | ||
| await import(`${TOP}/test/fixtures/index.js`) | ||
|
|
||
| // Import a relative path. | ||
| await import('../fixtures/something.js') | ||
|
|
||
| // Absolute path, note the file happens to be in a `node_modules` dir. | ||
| await import(`${TOP}/test/fixtures/node_modules/some-external-module/index.mjs`) | ||
|
|
||
| // Relative path, note the file happens to be in a `node_modules` dir. | ||
| await import('../fixtures/node_modules/some-external-module/sub.mjs') | ||
|
|
||
| deepStrictEqual( | ||
| hooked, | ||
| [ | ||
| [`${TOP}/test/fixtures/index.js`, undefined], | ||
| [`${TOP}/test/fixtures/something.js`, undefined], | ||
| [`${TOP}/test/fixtures/node_modules/some-external-module/index.mjs`, undefined], | ||
| [`${TOP}/test/fixtures/node_modules/some-external-module/sub.mjs`, undefined] | ||
| ] | ||
| ) | ||
| })() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍