import-in-the-middle 1.0.1 → 1.2.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.
- package/LICENSE-3rdparty.csv +1 -0
- package/README.md +10 -8
- package/fuck.mjs +12 -0
- package/hook.mjs +40 -9
- package/index.d.ts +68 -7
- package/index.js +74 -19
- package/lib/register.js +36 -0
- package/package.json +7 -3
- package/test/README.md +13 -0
- package/test/hook/define-property.js +20 -0
- package/test/hook/dynamic-import-default.js +29 -0
- package/test/hook/dynamic-import-default.mjs +23 -0
- package/test/hook/dynamic-import.js +27 -0
- package/test/{dynamic-import.mjs → hook/dynamic-import.mjs} +8 -6
- package/test/hook/remove.mjs +23 -0
- package/test/hook/static-import-default.mjs +26 -0
- package/test/hook/static-import-disabled.mjs +15 -0
- package/test/hook/static-import-package-internals-enabled.mjs +15 -0
- package/test/hook/static-import-package-internals.mjs +15 -0
- package/test/hook/static-import-package.mjs +15 -0
- package/test/hook/static-import.mjs +24 -0
- package/test/{dynamic-import-default.js → low-level/dynamic-import-default.js} +3 -3
- package/test/{dynamic-import-default.mjs → low-level/dynamic-import-default.mjs} +3 -3
- package/test/{dynamic-import.js → low-level/dynamic-import.js} +7 -5
- package/test/{remove.mjs → low-level/remove.mjs} +4 -4
- package/test/{static-import-default.mjs → low-level/static-import-default.mjs} +3 -3
- package/test/{static-import-disabled.mjs → low-level/static-import-disabled.mjs} +3 -3
- package/test/{static-import.mjs → low-level/static-import.mjs} +7 -5
- package/test/other/executable +6 -0
- package/test/other/import-executable.mjs +11 -0
package/LICENSE-3rdparty.csv
CHANGED
package/README.md
CHANGED
|
@@ -7,23 +7,25 @@ time.
|
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The API for
|
|
11
|
+
`require-in-the-middle` is followed as closely as possible as the default
|
|
12
|
+
export. There are lower-level `addHook` and `removeHook` exports available which
|
|
13
|
+
don't do any filtering of modules, and present the full file URL as a parameter
|
|
14
|
+
to the hook. See the Typescript definition file for detailed API docs.
|
|
11
15
|
|
|
12
16
|
You can modify anything exported from any given ESM or CJS module that's
|
|
13
17
|
imported in ESM files, regardless of whether they're imported statically or
|
|
14
18
|
dynamically.
|
|
15
19
|
|
|
16
20
|
```js
|
|
17
|
-
import
|
|
18
|
-
import { foo } from '
|
|
21
|
+
import Hook from 'import-in-the-middle'
|
|
22
|
+
import { foo } from 'package-i-want-to-modify'
|
|
19
23
|
|
|
20
24
|
console.log(foo) // whatever that module exported
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
Hook(['package-i-want-to-modify'], (exported, name, baseDir) => {
|
|
23
27
|
// `exported` is effectively `import * as exported from ${url}`
|
|
24
|
-
|
|
25
|
-
exported.foo += 1
|
|
26
|
-
}
|
|
28
|
+
exported.foo += 1
|
|
27
29
|
})
|
|
28
30
|
|
|
29
31
|
console.log(foo) // 1 more than whatever that module exported
|
|
@@ -33,7 +35,7 @@ This requires the use of an ESM loader hook, which can be added with the followi
|
|
|
33
35
|
command-line option.
|
|
34
36
|
|
|
35
37
|
```
|
|
36
|
-
--loader
|
|
38
|
+
--loader=import-in-the-middle/hook.mjs
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## Limitations
|
package/fuck.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import vm from 'vm'
|
|
2
|
+
|
|
3
|
+
const context = vm.createContext()
|
|
4
|
+
console.log(vm)
|
|
5
|
+
const mod = new vm.SourceTextModule(`
|
|
6
|
+
export const bar = 5
|
|
7
|
+
`, { context })
|
|
8
|
+
await mod.link(async () => {
|
|
9
|
+
return new vm.SyntheticModule([], function () {
|
|
10
|
+
}, { context })
|
|
11
|
+
})
|
|
12
|
+
console.log(Reflect.ownKeys(mod.namespace))
|
package/hook.mjs
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
+
const specifiers = new Map()
|
|
6
|
+
|
|
7
|
+
const EXTENSION_RE = /\.(js|mjs|cjs)$/
|
|
8
|
+
|
|
9
|
+
let entrypoint
|
|
10
|
+
|
|
5
11
|
export async function resolve (specifier, context, parentResolve) {
|
|
6
12
|
const { parentURL = '' } = context
|
|
7
13
|
|
|
@@ -10,11 +16,17 @@ export async function resolve (specifier, context, parentResolve) {
|
|
|
10
16
|
}
|
|
11
17
|
const url = await parentResolve(specifier, context, parentResolve)
|
|
12
18
|
|
|
13
|
-
if (parentURL ===
|
|
14
|
-
|
|
19
|
+
if (parentURL === '' && !EXTENSION_RE.test(url.url)) {
|
|
20
|
+
entrypoint = url.url
|
|
21
|
+
return { url: url.url, format: 'commonjs' }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (parentURL === import.meta.url || parentURL.startsWith('iitm:')) {
|
|
15
25
|
return url
|
|
16
26
|
}
|
|
17
27
|
|
|
28
|
+
specifiers.set(url.url, specifier)
|
|
29
|
+
|
|
18
30
|
return {
|
|
19
31
|
url: `iitm:${url.url}`
|
|
20
32
|
}
|
|
@@ -26,22 +38,27 @@ export function getFormat (url, context, parentGetFormat) {
|
|
|
26
38
|
format: 'module'
|
|
27
39
|
}
|
|
28
40
|
}
|
|
41
|
+
if (url === entrypoint) {
|
|
42
|
+
return {
|
|
43
|
+
format: 'commonjs'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
29
46
|
|
|
30
47
|
return parentGetFormat(url, context, parentGetFormat)
|
|
31
48
|
}
|
|
32
49
|
|
|
33
|
-
const iitmURL = new URL('
|
|
50
|
+
const iitmURL = new URL('lib/register.js', import.meta.url).toString()
|
|
34
51
|
export async function getSource (url, context, parentGetSource) {
|
|
35
52
|
if (url.startsWith('iitm:')) {
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
53
|
+
const realUrl = url.replace('iitm:', '')
|
|
54
|
+
const realModule = await import(realUrl)
|
|
55
|
+
const exportNames = Object.keys(realModule)
|
|
39
56
|
return {
|
|
40
57
|
source: `
|
|
41
|
-
import {
|
|
58
|
+
import { register } from '${iitmURL}'
|
|
42
59
|
import * as namespace from '${url}'
|
|
43
60
|
const set = {}
|
|
44
|
-
${
|
|
61
|
+
${exportNames.map((n) => `
|
|
45
62
|
let $${n} = namespace.${n}
|
|
46
63
|
export { $${n} as ${n} }
|
|
47
64
|
set.${n} = (v) => {
|
|
@@ -49,10 +66,24 @@ set.${n} = (v) => {
|
|
|
49
66
|
return true
|
|
50
67
|
}
|
|
51
68
|
`).join('\n')}
|
|
52
|
-
|
|
69
|
+
register('${realUrl}', namespace, set, '${specifiers.get(realUrl)}')
|
|
53
70
|
`
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
|
|
57
74
|
return parentGetSource(url, context, parentGetSource)
|
|
58
75
|
}
|
|
76
|
+
|
|
77
|
+
// For Node.js 16.12.0 and higher.
|
|
78
|
+
export async function load (url, context, parentLoad) {
|
|
79
|
+
if (url.startsWith('iitm:')) {
|
|
80
|
+
const { source } = await getSource(url, context)
|
|
81
|
+
return {
|
|
82
|
+
source,
|
|
83
|
+
format: 'module'
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return parentLoad(url, context, parentLoad)
|
|
88
|
+
}
|
|
89
|
+
|
package/index.d.ts
CHANGED
|
@@ -2,24 +2,85 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Property bag representing a module's exports, including the `default` if
|
|
7
|
+
* present.
|
|
8
|
+
*/
|
|
9
|
+
export type Namespace = { [key: string]: any }
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
12
|
* A hook function to be run against loaded modules.
|
|
13
|
+
* Not to be confused with `HookFunction`, used by the lower-level API.
|
|
14
|
+
* @param {exported} { [string]: any } An object representing the exported
|
|
15
|
+
* items of a module.
|
|
16
|
+
* @param {name} string The name of the module. If it is (or is part of) a
|
|
17
|
+
* package in a node_modules directory, this will be the path of the file
|
|
18
|
+
* starting from the package name.
|
|
19
|
+
* @param {baseDir} string The absolute path of the module, if not provided in
|
|
20
|
+
* `name`.
|
|
21
|
+
* @return any A value that can will be assigned to `exports.default`. This is
|
|
22
|
+
* equivalent to doing that assignment in the body of this function.
|
|
23
|
+
*/
|
|
24
|
+
export type HookFn = (exported: Namespace, name: string, baseDir: string|void) => any
|
|
25
|
+
|
|
26
|
+
export type Options = {
|
|
27
|
+
internals?: boolean
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare class Hook {
|
|
31
|
+
/**
|
|
32
|
+
* Creates a hook to be run on any already loaded modules and any that will
|
|
33
|
+
* be loaded in the future. It will be run once per loaded module. If
|
|
34
|
+
* statically imported, any variables bound directly to exported items will
|
|
35
|
+
* be re-bound if those items are re-assigned in the hook function.
|
|
36
|
+
* @param {Array<string>} [modules] A list of modules to run this hook on. If
|
|
37
|
+
* omitted, it will run on every import everywhere.
|
|
38
|
+
* @param {Options} [options] An options object. If omitted, the default is
|
|
39
|
+
* `{ internals: false }`. If internals is true, then the hook will operate
|
|
40
|
+
* on internal modules of packages in node_modules. Otherwise it will not,
|
|
41
|
+
* unless they are mentioned specifically in the modules array.
|
|
42
|
+
* @param {HookFunction} hookFn The function to be run on each module.
|
|
43
|
+
*/
|
|
44
|
+
constructor (modules: Array<string>, options: Options, hookFn: HookFn)
|
|
45
|
+
constructor (modules: Array<string>, hookFn: HookFn)
|
|
46
|
+
constructor (hookFn: HookFn)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Disables this hook. It will no longer be run against any subsequently
|
|
50
|
+
* loaded modules.
|
|
51
|
+
*/
|
|
52
|
+
unhook(): void
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default Hook
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A hook function to be run against loaded modules. To be used with the
|
|
59
|
+
* lower-level APIs `addHook` and `removeHook`.
|
|
7
60
|
* @param {url} string The absolute path of the module, as a `file:` URL string.
|
|
8
|
-
* @param {exported} { [string]: any } An object representing the exported
|
|
61
|
+
* @param {exported} { [string]: any } An object representing the exported
|
|
62
|
+
* items of a module.
|
|
9
63
|
*/
|
|
10
|
-
export type HookFunction = (url: string, exported:
|
|
64
|
+
export type HookFunction = (url: string, exported: Namespace) => void
|
|
11
65
|
|
|
12
66
|
/**
|
|
13
|
-
* Adds a hook to be run on any already loaded modules and any that will be
|
|
14
|
-
* It will be run once per loaded module. If statically
|
|
15
|
-
* exported items will be re-bound if
|
|
67
|
+
* Adds a hook to be run on any already loaded modules and any that will be
|
|
68
|
+
* loaded in the future. It will be run once per loaded module. If statically
|
|
69
|
+
* imported, any variables bound directly to exported items will be re-bound if
|
|
70
|
+
* those items are re-assigned in the hook.
|
|
71
|
+
*
|
|
72
|
+
* This is the lower-level API for hook creation. It will be run on every
|
|
73
|
+
* single imported module, rather than with any filtering.
|
|
16
74
|
* @param {HookFunction} hookFn The function to be run on each module.
|
|
17
75
|
*/
|
|
18
76
|
export declare function addHook(hookFn: HookFunction): void
|
|
19
77
|
|
|
20
78
|
/**
|
|
21
|
-
* Removes a hook that has been previously added with `addHook`. It will no
|
|
22
|
-
* any subsequently loaded modules.
|
|
79
|
+
* Removes a hook that has been previously added with `addHook`. It will no
|
|
80
|
+
* longer be run against any subsequently loaded modules.
|
|
81
|
+
*
|
|
82
|
+
* This is the lower-level API for hook removal, and cannot be used with the
|
|
83
|
+
* `Hook` class.
|
|
23
84
|
* @param {HookFunction} hookFn The function to be removed.
|
|
24
85
|
*/
|
|
25
86
|
export declare function removeHook(hookFn: HookFunction): void
|
package/index.js
CHANGED
|
@@ -2,33 +2,88 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const parse = require('module-details-from-path')
|
|
7
|
+
const { fileURLToPath } = require('url')
|
|
6
8
|
|
|
7
|
-
const
|
|
9
|
+
const {
|
|
10
|
+
importHooks,
|
|
11
|
+
specifiers,
|
|
12
|
+
toHook
|
|
13
|
+
} = require('./lib/register')
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const proxyHandler = {
|
|
12
|
-
set(target, name, value) {
|
|
13
|
-
return setters.get(target)[name](value)
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
exports._register = function _register(name, namespace, set) {
|
|
18
|
-
setters.set(namespace, set)
|
|
19
|
-
const proxy = new Proxy(namespace, proxyHandler)
|
|
20
|
-
importHooks.forEach(hook => hook(name, proxy))
|
|
21
|
-
toHook.push([name, proxy])
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
exports.addHook = function addHook(hook) {
|
|
15
|
+
function addHook(hook) {
|
|
25
16
|
importHooks.push(hook)
|
|
26
17
|
toHook.forEach(([name, namespace]) => hook(name, namespace))
|
|
27
18
|
}
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
function removeHook(hook) {
|
|
30
21
|
const index = importHooks.indexOf(hook)
|
|
31
22
|
if (index > -1) {
|
|
32
23
|
importHooks.splice(index, 1)
|
|
33
24
|
}
|
|
34
25
|
}
|
|
26
|
+
|
|
27
|
+
function callHookFn(hookFn, namespace, name, baseDir) {
|
|
28
|
+
const newDefault = hookFn(namespace, name, baseDir)
|
|
29
|
+
if (newDefault && newDefault !== namespace) {
|
|
30
|
+
namespace.default = newDefault
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function Hook(modules, options, hookFn) {
|
|
35
|
+
if ((this instanceof Hook) === false) return new Hook(modules, options, hookFn)
|
|
36
|
+
if (typeof modules === 'function') {
|
|
37
|
+
hookFn = modules
|
|
38
|
+
modules = null
|
|
39
|
+
options = null
|
|
40
|
+
} else if (typeof options === 'function') {
|
|
41
|
+
hookFn = options
|
|
42
|
+
options = null
|
|
43
|
+
}
|
|
44
|
+
const internals = options ? options.internals === true : false
|
|
45
|
+
|
|
46
|
+
this._iitmHook = (name, namespace) => {
|
|
47
|
+
const filename = name
|
|
48
|
+
const isBuiltin = name.startsWith('node:')
|
|
49
|
+
let baseDir
|
|
50
|
+
|
|
51
|
+
if (isBuiltin) {
|
|
52
|
+
name = name.replace(/^node:/, '')
|
|
53
|
+
} else {
|
|
54
|
+
name = name.replace(/^file:\/\//, '')
|
|
55
|
+
const details = parse(name)
|
|
56
|
+
if (details) {
|
|
57
|
+
name = details.name
|
|
58
|
+
baseDir = details.basedir
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (modules) {
|
|
63
|
+
for (const moduleName of modules) {
|
|
64
|
+
if (moduleName === name) {
|
|
65
|
+
if (baseDir) {
|
|
66
|
+
if (internals) {
|
|
67
|
+
name = name + path.sep + path.relative(baseDir, fileURLToPath(filename))
|
|
68
|
+
} else {
|
|
69
|
+
if (!baseDir.endsWith(specifiers.get(filename))) continue
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
callHookFn(hookFn, namespace, name, baseDir)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
callHookFn(hookFn, namespace, name, baseDir)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
addHook(this._iitmHook)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
Hook.prototype.unhook = function () {
|
|
84
|
+
removeHook(this._iitmHook)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = Hook
|
|
88
|
+
module.exports.addHook = addHook
|
|
89
|
+
module.exports.removeHook = removeHook
|
package/lib/register.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const importHooks = [] // TODO should this be a Set?
|
|
7
|
+
const setters = new WeakMap()
|
|
8
|
+
const specifiers = new Map()
|
|
9
|
+
const toHook = []
|
|
10
|
+
|
|
11
|
+
const proxyHandler = {
|
|
12
|
+
set(target, name, value) {
|
|
13
|
+
return setters.get(target)[name](value)
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
defineProperty(target, property, descriptor) {
|
|
17
|
+
if ((!('value' in descriptor))) {
|
|
18
|
+
throw new Error('Getters/setters are not supported for exports property descriptors.')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return setters.get(target)[property](descriptor.value)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function register(name, namespace, set, specifier) {
|
|
26
|
+
specifiers.set(name, specifier)
|
|
27
|
+
setters.set(namespace, set)
|
|
28
|
+
const proxy = new Proxy(namespace, proxyHandler)
|
|
29
|
+
importHooks.forEach(hook => hook(name, proxy))
|
|
30
|
+
toHook.push([name, proxy])
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
exports.register = register
|
|
34
|
+
exports.importHooks = importHooks
|
|
35
|
+
exports.specifiers = specifiers
|
|
36
|
+
exports.toHook = toHook
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "import-in-the-middle",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Intercept imports in Node.js",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "c8 --check-coverage --lines
|
|
7
|
+
"test": "c8 --check-coverage --lines 90 imhotap --runner test/runtest --files test/{hook,low-level,other}/*",
|
|
8
|
+
"coverage": "c8 --reporter html imhotap --runner test/runtest --files test/{hook,low-level,other}/* && echo '\nNow open coverage/index.html\n'"
|
|
8
9
|
},
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
@@ -26,6 +27,9 @@
|
|
|
26
27
|
"homepage": "https://github.com/DataDog/import-in-the-middle#readme",
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"c8": "^7.8.0",
|
|
29
|
-
"imhotap": "^
|
|
30
|
+
"imhotap": "^2.0.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"module-details-from-path": "^1.0.3"
|
|
30
34
|
}
|
|
31
35
|
}
|
package/test/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
These tests are organized as follows:
|
|
2
|
+
|
|
3
|
+
* Located in the `hook` directory if they use the `Hook` class.
|
|
4
|
+
* Located in the `low-level` directory if they use the "low-level" API,
|
|
5
|
+
`addHook` and `removeHook`.
|
|
6
|
+
|
|
7
|
+
The tests should be run with the `runtest` command found in this directory. If
|
|
8
|
+
the command exits with a non-zero code, then it's a test failure.
|
|
9
|
+
|
|
10
|
+
Running of all the tests can be done with `npm test`.
|
|
11
|
+
|
|
12
|
+
Coverage must be 100% according to `c8`. If you don't have 100% coverage, you
|
|
13
|
+
can run `npm run coverage` to get coverage data in HTML form.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
const Hook = require('../../index.js')
|
|
6
|
+
const { rejects } = require('assert')
|
|
7
|
+
|
|
8
|
+
Hook((exports, name) => {
|
|
9
|
+
if (name === 'os') {
|
|
10
|
+
Object.defineProperty(exports, 'freemem', {
|
|
11
|
+
get: () => () => 47
|
|
12
|
+
})
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
;(async () => {
|
|
17
|
+
rejects(async () => {
|
|
18
|
+
await import('os')
|
|
19
|
+
})
|
|
20
|
+
})()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
const Hook = require('../../index.js')
|
|
6
|
+
const { strictEqual } = require('assert')
|
|
7
|
+
|
|
8
|
+
Hook((exports, name) => {
|
|
9
|
+
if (name.match(/something.js/)) {
|
|
10
|
+
const orig = exports.default
|
|
11
|
+
exports.default = function bar() {
|
|
12
|
+
return orig() + 15
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (name.match(/something.mjs/)) {
|
|
16
|
+
const orig = exports.default
|
|
17
|
+
return function bar() {
|
|
18
|
+
return orig() + 15
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
;(async () => {
|
|
24
|
+
const { default: barMjs } = await import('../fixtures/something.mjs')
|
|
25
|
+
const { default: barJs } = await import('../fixtures/something.js')
|
|
26
|
+
|
|
27
|
+
strictEqual(barMjs(), 57)
|
|
28
|
+
strictEqual(barJs(), 57)
|
|
29
|
+
})()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
import Hook from '../../index.js'
|
|
6
|
+
import { strictEqual } from 'assert'
|
|
7
|
+
|
|
8
|
+
Hook((exports, name) => {
|
|
9
|
+
if (name.match(/something\.m?js/)) {
|
|
10
|
+
const orig = exports.default
|
|
11
|
+
exports.default = function bar() {
|
|
12
|
+
return orig() + 15
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
;(async () => {
|
|
18
|
+
const { default: barMjs } = await import('../fixtures/something.mjs')
|
|
19
|
+
const { default: barJs } = await import('../fixtures/something.js')
|
|
20
|
+
|
|
21
|
+
strictEqual(barMjs(), 57)
|
|
22
|
+
strictEqual(barJs(), 57)
|
|
23
|
+
})()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
const Hook = require('../../index.js')
|
|
6
|
+
const { strictEqual } = require('assert')
|
|
7
|
+
|
|
8
|
+
Hook((exports, name) => {
|
|
9
|
+
if (name.match(/something\.m?js/)) {
|
|
10
|
+
exports.foo += 15
|
|
11
|
+
}
|
|
12
|
+
if (name === 'os') {
|
|
13
|
+
Object.defineProperty(exports, 'freemem', {
|
|
14
|
+
value: () => 47
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
;(async () => {
|
|
20
|
+
const { foo: fooMjs } = await import('../fixtures/something.mjs')
|
|
21
|
+
const { foo: fooJs } = await import('../fixtures/something.js')
|
|
22
|
+
const { freemem } = await import('os')
|
|
23
|
+
|
|
24
|
+
strictEqual(fooMjs, 57)
|
|
25
|
+
strictEqual(fooJs, 57)
|
|
26
|
+
strictEqual(freemem(), 47)
|
|
27
|
+
})()
|
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import Hook from '../../index.js'
|
|
6
6
|
import { strictEqual } from 'assert'
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Hook((exports, name) => {
|
|
9
9
|
if (name.match(/something\.m?js/)) {
|
|
10
10
|
exports.foo += 15
|
|
11
11
|
}
|
|
12
|
-
if (name
|
|
13
|
-
|
|
12
|
+
if (name === 'os') {
|
|
13
|
+
Object.defineProperty(exports, 'freemem', {
|
|
14
|
+
value: () => 47
|
|
15
|
+
})
|
|
14
16
|
}
|
|
15
17
|
})
|
|
16
18
|
|
|
17
19
|
;(async () => {
|
|
18
|
-
const { foo: fooMjs } = await import('
|
|
19
|
-
const { foo: fooJs } = await import('
|
|
20
|
+
const { foo: fooMjs } = await import('../fixtures/something.mjs')
|
|
21
|
+
const { foo: fooJs } = await import('../fixtures/something.js')
|
|
20
22
|
const { freemem } = await import('os')
|
|
21
23
|
|
|
22
24
|
strictEqual(fooMjs, 57)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
import Hook from '../../index.js'
|
|
6
|
+
import { strictEqual } from 'assert'
|
|
7
|
+
|
|
8
|
+
const hook = new Hook((exports, name) => {
|
|
9
|
+
if (name.match(/something\.m?js/)) {
|
|
10
|
+
exports.foo += 15
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
;(async () => {
|
|
15
|
+
const { foo: fooMjs } = await import('../fixtures/something.mjs')
|
|
16
|
+
|
|
17
|
+
hook.unhook()
|
|
18
|
+
|
|
19
|
+
const { foo: fooJs } = await import('../fixtures/something.js')
|
|
20
|
+
|
|
21
|
+
strictEqual(fooMjs, 57)
|
|
22
|
+
strictEqual(fooJs, 42)
|
|
23
|
+
})()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
import Hook from '../../index.js'
|
|
6
|
+
import barMjs from '../fixtures/something.mjs'
|
|
7
|
+
import barJs from '../fixtures/something.js'
|
|
8
|
+
import { strictEqual } from 'assert'
|
|
9
|
+
|
|
10
|
+
Hook((exports, name) => {
|
|
11
|
+
if (name.match(/something.mjs/)) {
|
|
12
|
+
const orig = exports.default
|
|
13
|
+
exports.default = function bar() {
|
|
14
|
+
return orig() + 15
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (name.match(/something.js/)) {
|
|
18
|
+
const orig = exports.default
|
|
19
|
+
return function bar() {
|
|
20
|
+
return orig() + 15
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
strictEqual(barMjs(), 57)
|
|
26
|
+
strictEqual(barJs(), 57)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
import Hook from '../../index.js'
|
|
6
|
+
import { foo as fooMjs } from '../fixtures/something.mjs'
|
|
7
|
+
import { foo as fooJs } from '../fixtures/something.js'
|
|
8
|
+
import { strictEqual, fail } from 'assert'
|
|
9
|
+
|
|
10
|
+
Hook(() => {
|
|
11
|
+
fail('should not have been called at all')
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
strictEqual(fooMjs, 42)
|
|
15
|
+
strictEqual(fooJs, 42)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Hook from '../../index.js'
|
|
2
|
+
import { Report } from 'c8/index.js'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import { fileURLToPath } from 'url'
|
|
5
|
+
import { strictEqual } from 'assert'
|
|
6
|
+
|
|
7
|
+
const c8Dir = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'node_modules', 'c8')
|
|
8
|
+
|
|
9
|
+
Hook(['c8'], { internals: true }, (exports, name, baseDir) => {
|
|
10
|
+
strictEqual(name, 'c8/index.js')
|
|
11
|
+
strictEqual(baseDir, c8Dir)
|
|
12
|
+
exports.Report = () => 42
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
strictEqual(Report({}), 42)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Hook from '../../index.js'
|
|
2
|
+
import { Report } from 'c8/index.js'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import { fileURLToPath } from 'url'
|
|
5
|
+
import { strictEqual, notStrictEqual } from 'assert'
|
|
6
|
+
|
|
7
|
+
const c8Dir = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'node_modules', 'c8')
|
|
8
|
+
|
|
9
|
+
Hook(['c8'], (exports, name, baseDir) => {
|
|
10
|
+
strictEqual(name, 'c8')
|
|
11
|
+
strictEqual(baseDir, c8Dir)
|
|
12
|
+
exports.Report = () => 42
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
notStrictEqual(Report({}), 42)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Hook from '../../index.js'
|
|
2
|
+
import { Report } from 'c8'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import { fileURLToPath } from 'url'
|
|
5
|
+
import { strictEqual } from 'assert'
|
|
6
|
+
|
|
7
|
+
const c8Dir = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'node_modules', 'c8')
|
|
8
|
+
|
|
9
|
+
Hook(['c8'], (exports, name, baseDir) => {
|
|
10
|
+
strictEqual(name, 'c8')
|
|
11
|
+
strictEqual(baseDir, c8Dir)
|
|
12
|
+
exports.Report = () => 42
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
strictEqual(Report({}), 42)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
import Hook from '../../index.js'
|
|
6
|
+
import { foo as fooMjs } from '../fixtures/something.mjs'
|
|
7
|
+
import { foo as fooJs } from '../fixtures/something.js'
|
|
8
|
+
import { freemem } from 'os'
|
|
9
|
+
import { strictEqual } from 'assert'
|
|
10
|
+
|
|
11
|
+
Hook((exports, name) => {
|
|
12
|
+
if (name.match(/something\.m?js/)) {
|
|
13
|
+
exports.foo += 15
|
|
14
|
+
}
|
|
15
|
+
if (name === 'os') {
|
|
16
|
+
Object.defineProperty(exports, 'freemem', {
|
|
17
|
+
value: () => 47
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
strictEqual(fooMjs, 57)
|
|
23
|
+
strictEqual(fooJs, 57)
|
|
24
|
+
strictEqual(freemem(), 47)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
const { addHook } = require('
|
|
5
|
+
const { addHook } = require('../../index.js')
|
|
6
6
|
const { strictEqual } = require('assert')
|
|
7
7
|
|
|
8
8
|
addHook((name, exports) => {
|
|
@@ -15,8 +15,8 @@ addHook((name, exports) => {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
;(async () => {
|
|
18
|
-
const { default: barMjs } = await import('
|
|
19
|
-
const { default: barJs } = await import('
|
|
18
|
+
const { default: barMjs } = await import('../fixtures/something.mjs')
|
|
19
|
+
const { default: barJs } = await import('../fixtures/something.js')
|
|
20
20
|
|
|
21
21
|
strictEqual(barMjs(), 57)
|
|
22
22
|
strictEqual(barJs(), 57)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
import { addHook } from '
|
|
5
|
+
import { addHook } from '../../index.js'
|
|
6
6
|
import { strictEqual } from 'assert'
|
|
7
7
|
|
|
8
8
|
addHook((name, exports) => {
|
|
@@ -15,8 +15,8 @@ addHook((name, exports) => {
|
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
;(async () => {
|
|
18
|
-
const { default: barMjs } = await import('
|
|
19
|
-
const { default: barJs } = await import('
|
|
18
|
+
const { default: barMjs } = await import('../fixtures/something.mjs')
|
|
19
|
+
const { default: barJs } = await import('../fixtures/something.js')
|
|
20
20
|
|
|
21
21
|
strictEqual(barMjs(), 57)
|
|
22
22
|
strictEqual(barJs(), 57)
|
|
@@ -2,21 +2,23 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
const { addHook } = require('
|
|
5
|
+
const { addHook } = require('../../index.js')
|
|
6
6
|
const { strictEqual } = require('assert')
|
|
7
7
|
|
|
8
8
|
addHook((name, exports) => {
|
|
9
9
|
if (name.match(/something\.m?js/)) {
|
|
10
10
|
exports.foo += 15
|
|
11
11
|
}
|
|
12
|
-
if (name
|
|
13
|
-
|
|
12
|
+
if (name === 'node:os') {
|
|
13
|
+
Object.defineProperty(exports, 'freemem', {
|
|
14
|
+
value: () => 47
|
|
15
|
+
})
|
|
14
16
|
}
|
|
15
17
|
})
|
|
16
18
|
|
|
17
19
|
;(async () => {
|
|
18
|
-
const { foo: fooMjs } = await import('
|
|
19
|
-
const { foo: fooJs } = await import('
|
|
20
|
+
const { foo: fooMjs } = await import('../fixtures/something.mjs')
|
|
21
|
+
const { foo: fooJs } = await import('../fixtures/something.js')
|
|
20
22
|
const { freemem } = await import('os')
|
|
21
23
|
|
|
22
24
|
strictEqual(fooMjs, 57)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
import { addHook, removeHook } from '
|
|
6
|
-
import { strictEqual
|
|
5
|
+
import { addHook, removeHook } from '../../index.js'
|
|
6
|
+
import { strictEqual } from 'assert'
|
|
7
7
|
|
|
8
8
|
const hook = (name, exports) => {
|
|
9
9
|
if (name.match(/something\.m?js/)) {
|
|
@@ -14,11 +14,11 @@ const hook = (name, exports) => {
|
|
|
14
14
|
addHook(hook)
|
|
15
15
|
|
|
16
16
|
;(async () => {
|
|
17
|
-
const { foo: fooMjs } = await import('
|
|
17
|
+
const { foo: fooMjs } = await import('../fixtures/something.mjs')
|
|
18
18
|
|
|
19
19
|
removeHook(hook)
|
|
20
20
|
|
|
21
|
-
const { foo: fooJs } = await import('
|
|
21
|
+
const { foo: fooJs } = await import('../fixtures/something.js')
|
|
22
22
|
|
|
23
23
|
strictEqual(fooMjs, 57)
|
|
24
24
|
strictEqual(fooJs, 42)
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
import { addHook } from '
|
|
6
|
-
import barMjs from '
|
|
7
|
-
import barJs from '
|
|
5
|
+
import { addHook } from '../../index.js'
|
|
6
|
+
import barMjs from '../fixtures/something.mjs'
|
|
7
|
+
import barJs from '../fixtures/something.js'
|
|
8
8
|
import { strictEqual } from 'assert'
|
|
9
9
|
|
|
10
10
|
addHook((name, exports) => {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
import { addHook } from '
|
|
6
|
-
import { foo as fooMjs } from '
|
|
7
|
-
import { foo as fooJs } from '
|
|
5
|
+
import { addHook } from '../../index.js'
|
|
6
|
+
import { foo as fooMjs } from '../fixtures/something.mjs'
|
|
7
|
+
import { foo as fooJs } from '../fixtures/something.js'
|
|
8
8
|
import { strictEqual, fail } from 'assert'
|
|
9
9
|
|
|
10
10
|
addHook(() => {
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
import { addHook } from '
|
|
6
|
-
import { foo as fooMjs } from '
|
|
7
|
-
import { foo as fooJs } from '
|
|
5
|
+
import { addHook } from '../../index.js'
|
|
6
|
+
import { foo as fooMjs } from '../fixtures/something.mjs'
|
|
7
|
+
import { foo as fooJs } from '../fixtures/something.js'
|
|
8
8
|
import { freemem } from 'os'
|
|
9
9
|
import { strictEqual } from 'assert'
|
|
10
10
|
|
|
@@ -12,8 +12,10 @@ addHook((name, exports) => {
|
|
|
12
12
|
if (name.match(/something\.m?js/)) {
|
|
13
13
|
exports.foo += 15
|
|
14
14
|
}
|
|
15
|
-
if (name
|
|
16
|
-
|
|
15
|
+
if (name === 'node:os') {
|
|
16
|
+
Object.defineProperty(exports, 'freemem', {
|
|
17
|
+
value: () => 47
|
|
18
|
+
})
|
|
17
19
|
}
|
|
18
20
|
})
|
|
19
21
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
3
|
+
//
|
|
4
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
5
|
+
|
|
6
|
+
// This script doesn't actually have to do anything.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2.0 License.
|
|
2
|
+
//
|
|
3
|
+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
|
+
|
|
5
|
+
import { rejects } from 'assert'
|
|
6
|
+
(async () => {
|
|
7
|
+
await rejects(() => import('./executable'), {
|
|
8
|
+
name: 'TypeError',
|
|
9
|
+
code: 'ERR_UNKNOWN_FILE_EXTENSION'
|
|
10
|
+
})
|
|
11
|
+
})()
|