import-in-the-middle 1.7.0 → 1.7.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.
- package/hook.js +6 -71
- package/lib/get-esm-exports.js +52 -151
- package/lib/get-exports.js +2 -2
- package/package.json +4 -6
- package/test/get-esm-exports/v18.19-get-esm-exports.js +1 -1
- package/lib/get-pkg-json-type-module.js +0 -46
- package/lib/helpers.js +0 -5
- package/test/fixtures/a.mjs +0 -7
- package/test/fixtures/b.mjs +0 -6
- package/test/fixtures/env.mjs +0 -8
- package/test/fixtures/export-types/declarations.mjs +0 -19
- package/test/fixtures/export-types/default-class-anon.mjs +0 -1
- package/test/fixtures/export-types/default-class.mjs +0 -1
- package/test/fixtures/export-types/default-expression-array.mjs +0 -1
- package/test/fixtures/export-types/default-expression-num.mjs +0 -1
- package/test/fixtures/export-types/default-expression-string.mjs +0 -1
- package/test/fixtures/export-types/default-function-anon.mjs +0 -1
- package/test/fixtures/export-types/default-function.mjs +0 -1
- package/test/fixtures/export-types/default-generator-anon.mjs +0 -1
- package/test/fixtures/export-types/default-generator.mjs +0 -1
- package/test/fixtures/export-types/list.mjs +0 -12
- package/test/fixtures/reassign-let.mjs +0 -5
- package/test/fixtures/test-undefined-format/a.js +0 -8
- package/test/fixtures/test-undefined-format/b.js +0 -7
- package/test/fixtures/test-undefined-format/package.json +0 -9
- package/test/fixtures/use-env.mjs +0 -5
- package/test/hook/default-exports.mjs +0 -71
- package/test/hook/v16-declaration-exports.mjs +0 -84
- package/test/hook/v16-list-exports.mjs +0 -34
- package/test/other/v16-cyclical-dependency.mjs +0 -29
- package/test/other/v16-reassign-let.mjs +0 -29
- package/test/other/v16-test-undefined-format.mjs +0 -26
- /package/test/get-esm-exports/{v16-get-esm-exports.js → v20-get-esm-exports.js} +0 -0
package/hook.js
CHANGED
|
@@ -2,41 +2,25 @@
|
|
|
2
2
|
//
|
|
3
3
|
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021 Datadog, Inc.
|
|
4
4
|
|
|
5
|
-
const fs = require('fs')
|
|
6
|
-
const { fileURLToPath } = require('url')
|
|
7
5
|
const specifiers = new Map()
|
|
8
6
|
const isWin = process.platform === "win32"
|
|
9
|
-
const warn = require('./lib/helpers')
|
|
10
7
|
|
|
11
8
|
// FIXME: Typescript extensions are added temporarily until we find a better
|
|
12
9
|
// way of supporting arbitrary extensions
|
|
13
10
|
const EXTENSION_RE = /\.(js|mjs|cjs|ts|mts|cts)$/
|
|
14
|
-
const EXTENSION_MJS_RE = /\.mjs$/
|
|
15
|
-
const EXTENSION_JS_RE = /\.js$/
|
|
16
11
|
const NODE_VERSION = process.versions.node.split('.')
|
|
17
12
|
const NODE_MAJOR = Number(NODE_VERSION[0])
|
|
18
13
|
const NODE_MINOR = Number(NODE_VERSION[1])
|
|
19
|
-
const FILE_NAME = 'hook.js'
|
|
20
14
|
|
|
21
15
|
let entrypoint
|
|
22
|
-
let getExports
|
|
23
|
-
let getEsmExports
|
|
24
|
-
let getPkgJsonTypeModule
|
|
25
16
|
|
|
17
|
+
let getExports
|
|
26
18
|
if (NODE_MAJOR >= 20 || (NODE_MAJOR == 18 && NODE_MINOR >= 19)) {
|
|
27
19
|
getExports = require('./lib/get-exports.js')
|
|
28
20
|
} else {
|
|
29
21
|
getExports = (url) => import(url).then(Object.keys)
|
|
30
22
|
}
|
|
31
23
|
|
|
32
|
-
if (NODE_MAJOR >= 16) {
|
|
33
|
-
getEsmExports = require('./lib/get-esm-exports.js')
|
|
34
|
-
getPkgJsonTypeModule = require('./lib/get-pkg-json-type-module.js')
|
|
35
|
-
} else {
|
|
36
|
-
getEsmExports = undefined
|
|
37
|
-
getPkgJsonTypeModule = undefined
|
|
38
|
-
}
|
|
39
|
-
|
|
40
24
|
function hasIitm (url) {
|
|
41
25
|
try {
|
|
42
26
|
return new URL(url).searchParams.has('iitm')
|
|
@@ -124,23 +108,12 @@ function createHook (meta) {
|
|
|
124
108
|
) {
|
|
125
109
|
return url
|
|
126
110
|
}
|
|
127
|
-
|
|
128
|
-
// on Node's 16.0.0-16.12.0, url.format is undefined for the cyclical dependency test files ./test/fixtures/a.mjs & ./test/fixtures/b.mjs
|
|
129
|
-
// so explicitly set format to 'module' for files with a .mjs extension or cjs files that have type 'module in their package.json
|
|
130
|
-
// so that they can go through the ast parsing patch for Node >= 16
|
|
131
|
-
if (NODE_MAJOR === 16 && NODE_MINOR < 13) {
|
|
132
|
-
if (
|
|
133
|
-
(url.format === undefined && EXTENSION_MJS_RE.test(url.url)) ||
|
|
134
|
-
(EXTENSION_JS_RE.test(url.url) && getPkgJsonTypeModule(fileURLToPath(url.url)))
|
|
135
|
-
) {
|
|
136
|
-
url.format = 'module'
|
|
137
|
-
}
|
|
138
|
-
}
|
|
111
|
+
|
|
139
112
|
|
|
140
113
|
specifiers.set(url.url, specifier)
|
|
141
114
|
|
|
142
115
|
return {
|
|
143
|
-
url:
|
|
116
|
+
url: addIitm(url.url),
|
|
144
117
|
shortCircuit: true,
|
|
145
118
|
format: url.format
|
|
146
119
|
}
|
|
@@ -149,12 +122,9 @@ function createHook (meta) {
|
|
|
149
122
|
const iitmURL = new URL('lib/register.js', meta.url).toString()
|
|
150
123
|
async function getSource (url, context, parentGetSource) {
|
|
151
124
|
if (hasIitm(url)) {
|
|
152
|
-
|
|
153
125
|
const realUrl = deleteIitm(url)
|
|
154
|
-
|
|
155
126
|
const exportNames = await getExports(realUrl, context, parentGetSource)
|
|
156
|
-
|
|
157
|
-
return {
|
|
127
|
+
return {
|
|
158
128
|
source: `
|
|
159
129
|
import { register } from '${iitmURL}'
|
|
160
130
|
import * as namespace from ${JSON.stringify(url)}
|
|
@@ -169,41 +139,6 @@ set.${n} = (v) => {
|
|
|
169
139
|
`).join('\n')}
|
|
170
140
|
register(${JSON.stringify(realUrl)}, namespace, set, ${JSON.stringify(specifiers.get(realUrl))})
|
|
171
141
|
`
|
|
172
|
-
}
|
|
173
|
-
} else if (NODE_MAJOR >= 16 && context.format === 'module') {
|
|
174
|
-
let fileContents
|
|
175
|
-
const realPath = fileURLToPath(url)
|
|
176
|
-
try {
|
|
177
|
-
fileContents = fs.readFileSync(realPath, 'utf8')
|
|
178
|
-
} catch (parseError) {
|
|
179
|
-
warn(`Had trouble reading file: ${fileContents}, got error: ${parseError}`, FILE_NAME)
|
|
180
|
-
return parentGetSource(url, context, parentGetSource)
|
|
181
|
-
}
|
|
182
|
-
try {
|
|
183
|
-
const outPut = getEsmExports(fileContents, true, url)
|
|
184
|
-
fileContents = outPut.code
|
|
185
|
-
exportAlias = outPut.exportAlias
|
|
186
|
-
} catch (parseError) {
|
|
187
|
-
warn(`Tried AST parsing ${realPath}, got error: ${parseError}`, FILE_NAME)
|
|
188
|
-
return parentGetSource(url, context, parentGetSource)
|
|
189
|
-
}
|
|
190
|
-
const src = `${fileContents}
|
|
191
|
-
import { register as DATADOG_REGISTER_FUNC } from '${iitmURL}'
|
|
192
|
-
{
|
|
193
|
-
const set = {}
|
|
194
|
-
const namespace = {}
|
|
195
|
-
${Object.entries(exportAlias).map(([key, value]) => `
|
|
196
|
-
set.${key} = (v) => {
|
|
197
|
-
${value} = v
|
|
198
|
-
return true
|
|
199
|
-
}
|
|
200
|
-
namespace.${key} = ${value}
|
|
201
|
-
`).join('\n')}
|
|
202
|
-
DATADOG_REGISTER_FUNC(${JSON.stringify(url)}, namespace, set, ${JSON.stringify(specifiers.get(url))})
|
|
203
|
-
}
|
|
204
|
-
`
|
|
205
|
-
return {
|
|
206
|
-
source: src
|
|
207
142
|
}
|
|
208
143
|
}
|
|
209
144
|
|
|
@@ -212,7 +147,7 @@ DATADOG_REGISTER_FUNC(${JSON.stringify(url)}, namespace, set, ${JSON.stringify(s
|
|
|
212
147
|
|
|
213
148
|
// For Node.js 16.12.0 and higher.
|
|
214
149
|
async function load (url, context, parentLoad) {
|
|
215
|
-
if (hasIitm(url)
|
|
150
|
+
if (hasIitm(url)) {
|
|
216
151
|
const { source } = await getSource(url, context, parentLoad)
|
|
217
152
|
return {
|
|
218
153
|
source,
|
|
@@ -232,7 +167,7 @@ DATADOG_REGISTER_FUNC(${JSON.stringify(url)}, namespace, set, ${JSON.stringify(s
|
|
|
232
167
|
resolve,
|
|
233
168
|
getSource,
|
|
234
169
|
getFormat (url, context, parentGetFormat) {
|
|
235
|
-
if (hasIitm(url)
|
|
170
|
+
if (hasIitm(url)) {
|
|
236
171
|
return {
|
|
237
172
|
format: 'module'
|
|
238
173
|
}
|
package/lib/get-esm-exports.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const recast = require('recast')
|
|
4
3
|
const { Parser } = require('acorn')
|
|
5
|
-
const { importAssertions } = require('acorn-import-assertions')
|
|
6
|
-
const warn = require('./helpers')
|
|
7
|
-
|
|
8
|
-
const TS_EXTENSION_RE = /\.(ts|mts|cts)$/
|
|
4
|
+
const { importAssertions } = require('acorn-import-assertions');
|
|
9
5
|
|
|
10
6
|
const acornOpts = {
|
|
11
7
|
ecmaVersion: 'latest',
|
|
@@ -13,182 +9,87 @@ const acornOpts = {
|
|
|
13
9
|
}
|
|
14
10
|
|
|
15
11
|
const parser = Parser.extend(importAssertions)
|
|
16
|
-
const FILE_NAME = 'get-esm-exports'
|
|
17
|
-
|
|
18
|
-
function getEsmExports(moduleStr, generate=false, url=undefined) {
|
|
19
|
-
const exportSpecifierNames = new Set()
|
|
20
|
-
const exportAlias = {}
|
|
21
|
-
let ast
|
|
22
|
-
|
|
23
|
-
// if it's a typescript file, we need to parse it with recasts typescript parser
|
|
24
|
-
if (url && TS_EXTENSION_RE.test(url)) {
|
|
25
|
-
ast = recast.parse(moduleStr, {parser: require("recast/parsers/typescript")})
|
|
26
|
-
} else {
|
|
27
|
-
ast = recast.parse(moduleStr, {parser: {
|
|
28
|
-
parse(source) {
|
|
29
|
-
return parser.parse(source, acornOpts)
|
|
30
|
-
}
|
|
31
|
-
}})
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const iitmRenamedExport = 'iitmRenamedExport';
|
|
35
|
-
|
|
36
|
-
// Loop through the top-level declarations of the AST
|
|
37
|
-
for (const statement of ast.program.body) {
|
|
38
|
-
if (statement.type === 'ExportNamedDeclaration') {
|
|
39
|
-
const node = statement;
|
|
40
|
-
|
|
41
|
-
if (node.declaration) {
|
|
42
|
-
parseDeclaration(node.declaration, exportAlias);
|
|
43
|
-
} else {
|
|
44
|
-
parseSpecifiers(node.specifiers, exportAlias, exportSpecifierNames);
|
|
45
|
-
}
|
|
46
|
-
} else if (statement.type === 'ExportDefaultDeclaration') {
|
|
47
|
-
const node = statement;
|
|
48
12
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
type: 'VariableDeclaration',
|
|
52
|
-
kind: 'let',
|
|
53
|
-
declarations: [
|
|
54
|
-
{
|
|
55
|
-
type: 'VariableDeclarator',
|
|
56
|
-
id: {
|
|
57
|
-
type: 'Identifier',
|
|
58
|
-
name: iitmRenamedExport,
|
|
59
|
-
},
|
|
60
|
-
init: node.declaration,
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// Replace the current ExportDefaultDeclaration with the new VariableDeclaration
|
|
66
|
-
ast.program.body.splice(ast.program.body.indexOf(statement), 1, variableDeclaration);
|
|
67
|
-
|
|
68
|
-
const newExportDefaultDeclaration = {
|
|
69
|
-
type: 'ExportDefaultDeclaration',
|
|
70
|
-
declaration: {
|
|
71
|
-
type: 'Identifier',
|
|
72
|
-
name: iitmRenamedExport,
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// Insert the new ExportDefaultDeclaration after the VariableDeclaration
|
|
77
|
-
ast.program.body.splice(ast.program.body.indexOf(variableDeclaration) + 1, 0, newExportDefaultDeclaration);
|
|
78
|
-
} else if (['FunctionDeclaration', 'Identifier', 'ClassDeclaration'].includes(node.declaration.type) && generate) {
|
|
79
|
-
node.declaration.id = { type: 'Identifier', name: iitmRenamedExport };
|
|
80
|
-
}
|
|
81
|
-
exportAlias['default'] = iitmRenamedExport;
|
|
82
|
-
} else if (statement.type === 'ExportAllDeclaration') {
|
|
83
|
-
const node = statement;
|
|
84
|
-
const exportedName = node.exported ? node.exported.name : '*';
|
|
85
|
-
|
|
86
|
-
exportAlias[exportedName] = exportedName;
|
|
87
|
-
} else if (statement.type === 'ExportSpecifier') {
|
|
88
|
-
const node = statement;
|
|
89
|
-
exportSpecifierNames.add(node.local.name);
|
|
90
|
-
|
|
91
|
-
if (node.exported.name) {
|
|
92
|
-
exportAlias[node.exported.name] = node.local.name;
|
|
93
|
-
} else if (node.exported.value) {
|
|
94
|
-
exportAlias[node.exported.value] = node.local.name;
|
|
95
|
-
} else {
|
|
96
|
-
warn('unrecognized specifier export: ' + node.exported, FILE_NAME);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (exportSpecifierNames.size !== 0 && generate) {
|
|
102
|
-
convertExportSpecifierToLet(exportSpecifierNames, ast);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (generate) {
|
|
106
|
-
return {
|
|
107
|
-
exportAlias: exportAlias,
|
|
108
|
-
code: recast.print(ast).code,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return Object.keys(exportAlias);
|
|
13
|
+
function warn (txt) {
|
|
14
|
+
process.emitWarning(txt, 'get-esm-exports')
|
|
113
15
|
}
|
|
114
16
|
|
|
115
|
-
function
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
17
|
+
function getEsmExports (moduleStr) {
|
|
18
|
+
const exportedNames = new Set()
|
|
19
|
+
const tree = parser.parse(moduleStr, acornOpts)
|
|
20
|
+
for (const node of tree.body) {
|
|
21
|
+
if (!node.type.startsWith('Export')) continue
|
|
22
|
+
switch (node.type) {
|
|
23
|
+
case 'ExportNamedDeclaration':
|
|
24
|
+
if (node.declaration) {
|
|
25
|
+
parseDeclaration(node, exportedNames)
|
|
26
|
+
} else {
|
|
27
|
+
parseSpecifiers(node, exportedNames)
|
|
126
28
|
}
|
|
127
|
-
|
|
29
|
+
break
|
|
30
|
+
case 'ExportDefaultDeclaration':
|
|
31
|
+
exportedNames.add('default')
|
|
32
|
+
break
|
|
33
|
+
case 'ExportAllDeclaration':
|
|
34
|
+
if (node.exported) {
|
|
35
|
+
exportedNames.add(node.exported.name)
|
|
36
|
+
} else {
|
|
37
|
+
exportedNames.add('*')
|
|
38
|
+
}
|
|
39
|
+
break
|
|
40
|
+
default:
|
|
41
|
+
warn('unrecognized export type: ' + node.type)
|
|
128
42
|
}
|
|
129
43
|
}
|
|
44
|
+
return Array.from(exportedNames)
|
|
130
45
|
}
|
|
131
46
|
|
|
132
|
-
function parseDeclaration(
|
|
133
|
-
switch (declaration.type) {
|
|
47
|
+
function parseDeclaration (node, exportedNames) {
|
|
48
|
+
switch (node.declaration.type) {
|
|
134
49
|
case 'FunctionDeclaration':
|
|
135
|
-
|
|
136
|
-
exportAlias[declaration.id.name] = declaration.id.name
|
|
50
|
+
exportedNames.add(node.declaration.id.name)
|
|
137
51
|
break
|
|
138
52
|
case 'VariableDeclaration':
|
|
139
|
-
for (const varDecl of declaration.declarations) {
|
|
140
|
-
|
|
141
|
-
declaration.kind = 'let'
|
|
142
|
-
}
|
|
143
|
-
parseVariableDeclaration(varDecl, exportAlias)
|
|
53
|
+
for (const varDecl of node.declaration.declarations) {
|
|
54
|
+
parseVariableDeclaration(varDecl, exportedNames)
|
|
144
55
|
}
|
|
145
56
|
break
|
|
57
|
+
case 'ClassDeclaration':
|
|
58
|
+
exportedNames.add(node.declaration.id.name)
|
|
59
|
+
break
|
|
146
60
|
default:
|
|
147
|
-
warn('unknown declaration type: ' +
|
|
61
|
+
warn('unknown declaration type: ' + node.delcaration.type)
|
|
148
62
|
}
|
|
149
63
|
}
|
|
150
64
|
|
|
151
|
-
function parseVariableDeclaration(
|
|
152
|
-
switch (
|
|
65
|
+
function parseVariableDeclaration (node, exportedNames) {
|
|
66
|
+
switch (node.id.type) {
|
|
153
67
|
case 'Identifier':
|
|
154
|
-
|
|
68
|
+
exportedNames.add(node.id.name)
|
|
155
69
|
break
|
|
156
70
|
case 'ObjectPattern':
|
|
157
|
-
for (const prop of
|
|
158
|
-
|
|
71
|
+
for (const prop of node.id.properties) {
|
|
72
|
+
exportedNames.add(prop.value.name)
|
|
159
73
|
}
|
|
160
74
|
break
|
|
161
75
|
case 'ArrayPattern':
|
|
162
|
-
for (const elem of
|
|
163
|
-
|
|
164
|
-
exportAlias[elem.name] = elem.name
|
|
165
|
-
}
|
|
76
|
+
for (const elem of node.id.elements) {
|
|
77
|
+
exportedNames.add(elem.name)
|
|
166
78
|
}
|
|
167
79
|
break
|
|
168
80
|
default:
|
|
169
|
-
warn('unknown variable declaration type: ' +
|
|
81
|
+
warn('unknown variable declaration type: ' + node.id.type)
|
|
170
82
|
}
|
|
171
83
|
}
|
|
172
84
|
|
|
173
|
-
function parseSpecifiers(
|
|
174
|
-
for (const specifier of specifiers) {
|
|
175
|
-
if (specifier.type === '
|
|
176
|
-
|
|
177
|
-
if (specifier.exported && specifier.exported.name) {
|
|
178
|
-
exportAlias[specifier.exported.name] = specifier.local.name
|
|
179
|
-
} else if (specifier.exported && specifier.exported.value) {
|
|
180
|
-
exportAlias[specifier.exported.value] = specifier.local.name
|
|
181
|
-
} else {
|
|
182
|
-
warn('unrecognized specifier export: ' + specifier, FILE_NAME)
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
else if (specifier.exported.type === 'Identifier') {
|
|
186
|
-
exportAlias[specifier.exported.name] = specifier.exported.name
|
|
85
|
+
function parseSpecifiers (node, exportedNames) {
|
|
86
|
+
for (const specifier of node.specifiers) {
|
|
87
|
+
if (specifier.exported.type === 'Identifier') {
|
|
88
|
+
exportedNames.add(specifier.exported.name)
|
|
187
89
|
} else if (specifier.exported.type === 'Literal') {
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
warn('unrecognized specifier type: ' + specifier.exported.type, FILE_NAME)
|
|
90
|
+
exportedNames.add(specifier.exported.value)
|
|
91
|
+
} else {
|
|
92
|
+
warn('unrecognized specifier type: ' + specifier.exported.type)
|
|
192
93
|
}
|
|
193
94
|
}
|
|
194
95
|
}
|
package/lib/get-exports.js
CHANGED
|
@@ -30,7 +30,7 @@ async function getExports (url, context, parentLoad) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (format === 'module') {
|
|
33
|
-
return getEsmExports(source
|
|
33
|
+
return getEsmExports(source)
|
|
34
34
|
}
|
|
35
35
|
if (format === 'commonjs') {
|
|
36
36
|
return addDefault(getCjsExports(source).exports)
|
|
@@ -38,7 +38,7 @@ async function getExports (url, context, parentLoad) {
|
|
|
38
38
|
|
|
39
39
|
// At this point our `format` is either undefined or not known by us. Fall
|
|
40
40
|
// back to parsing as ESM/CJS.
|
|
41
|
-
const esmExports = getEsmExports(source
|
|
41
|
+
const esmExports = getEsmExports(source)
|
|
42
42
|
if (!esmExports.length) {
|
|
43
43
|
// TODO(bengl) it's might be possible to get here if somehow the format
|
|
44
44
|
// isn't set at first and yet we have an ESM module with no exports.
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "import-in-the-middle",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
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 85 imhotap --runner 'node test/runtest' --files test/{hook,low-level,other,get-esm-exports}/*",
|
|
8
8
|
"test:ts": "c8 imhotap --runner 'node test/runtest' --files test/typescript/*.test.mts",
|
|
9
9
|
"coverage": "c8 --reporter html imhotap --runner 'node test/runtest' --files test/{hook,low-level,other,get-esm-exports}/* && echo '\nNow open coverage/index.html\n'"
|
|
10
10
|
},
|
|
@@ -34,11 +34,9 @@
|
|
|
34
34
|
"typescript": "^4.7.4"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"
|
|
38
|
-
"acorn": "^8.11.2",
|
|
37
|
+
"acorn": "^8.8.2",
|
|
39
38
|
"acorn-import-assertions": "^1.9.0",
|
|
40
39
|
"cjs-module-lexer": "^1.2.2",
|
|
41
|
-
"module-details-from-path": "^1.0.3"
|
|
42
|
-
"recast": "^0.23.4"
|
|
40
|
+
"module-details-from-path": "^1.0.3"
|
|
43
41
|
}
|
|
44
42
|
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const warn = require('./helpers')
|
|
4
|
-
|
|
5
|
-
const FILE_NAME = 'get-pkg-json-type-module'
|
|
6
|
-
|
|
7
|
-
function findNearestPackageJson(filePath) {
|
|
8
|
-
let currentDir = path.dirname(filePath)
|
|
9
|
-
|
|
10
|
-
while (currentDir !== '/') {
|
|
11
|
-
const packageJsonPath = path.join(currentDir, 'package.json')
|
|
12
|
-
try {
|
|
13
|
-
const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8')
|
|
14
|
-
return packageJsonContent;
|
|
15
|
-
} catch (error) {
|
|
16
|
-
// File does not exist, continue searching in the parent directory
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
currentDir = path.dirname(currentDir)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return null
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function isModuleType(filePath) {
|
|
26
|
-
const packageJsonContent = findNearestPackageJson(filePath)
|
|
27
|
-
|
|
28
|
-
if (!packageJsonContent) {
|
|
29
|
-
return false
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
const packageJson = JSON.parse(packageJsonContent)
|
|
34
|
-
|
|
35
|
-
if (packageJson.type === 'module') {
|
|
36
|
-
return true
|
|
37
|
-
} else {
|
|
38
|
-
return false
|
|
39
|
-
}
|
|
40
|
-
} catch (error) {
|
|
41
|
-
warn('Error reading or parsing package.json: ' + error.message, FILE_NAME)
|
|
42
|
-
return false
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
module.exports = isModuleType
|
package/lib/helpers.js
DELETED
package/test/fixtures/a.mjs
DELETED
package/test/fixtures/b.mjs
DELETED
package/test/fixtures/env.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const o = { name5: 1, name6: 1 };
|
|
2
|
-
const array = [1, 1]
|
|
3
|
-
|
|
4
|
-
// Exporting declarations
|
|
5
|
-
export let name1 = 1, name2 = 1/*, … */; // also var
|
|
6
|
-
export const name3 = 1, name4 = 1/*, … */; // also var, let
|
|
7
|
-
export function functionName() { return 1 }
|
|
8
|
-
export class ClassName { getFoo() { return 1 } }
|
|
9
|
-
export function* generatorFunctionName() { return 1 }
|
|
10
|
-
export const { name5, name6: bar } = o;
|
|
11
|
-
export const [ name7, name8 ] = array;
|
|
12
|
-
export async function asyncFunctionName() { return 1 }
|
|
13
|
-
export async function* asyncGeneratorFunctionName() { yield 1 }
|
|
14
|
-
export const arrowFunction = () => {
|
|
15
|
-
return 1;
|
|
16
|
-
}
|
|
17
|
-
export const asyncArrowFunction = async () => {
|
|
18
|
-
return 1;
|
|
19
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class { getFoo() { return 1 } }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default class ClassName { getFoo() { return 1 } }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default [1]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default 1
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default 'dog'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function () { return 1 }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function functionName() { return 1 }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function* () { return 1 }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function* generatorFunctionName() { return 1 }
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Export list
|
|
2
|
-
const name1 = 1
|
|
3
|
-
const name2 = 1
|
|
4
|
-
const name5 = 1
|
|
5
|
-
const variable1 = 1
|
|
6
|
-
const variable2 = 1
|
|
7
|
-
const variable3 = 1
|
|
8
|
-
const name6 = 1
|
|
9
|
-
export { name1, name2 };
|
|
10
|
-
export { variable1 as name3, variable2 as name4, /* …, */ name5 };
|
|
11
|
-
export { variable3 as "name" };
|
|
12
|
-
export { name6 as default /*, … */ };
|
|
@@ -1,71 +0,0 @@
|
|
|
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 a from '../fixtures/export-types/default-expression-array.mjs'
|
|
7
|
-
import n from '../fixtures/export-types/default-expression-num.mjs'
|
|
8
|
-
import s from '../fixtures/export-types/default-expression-string.mjs'
|
|
9
|
-
import fn from '../fixtures/export-types/default-function.mjs'
|
|
10
|
-
import cn from '../fixtures/export-types/default-class.mjs'
|
|
11
|
-
import gfn from '../fixtures/export-types/default-generator.mjs'
|
|
12
|
-
import afn from '../fixtures/export-types/default-function-anon.mjs'
|
|
13
|
-
import acn from '../fixtures/export-types/default-class-anon.mjs'
|
|
14
|
-
import agfn from '../fixtures/export-types/default-generator-anon.mjs'
|
|
15
|
-
import { strictEqual } from 'assert'
|
|
16
|
-
|
|
17
|
-
Hook((exports, name) => {
|
|
18
|
-
if (name.match(/default-expression-array\.m?js/)) {
|
|
19
|
-
exports.default[0] += 1
|
|
20
|
-
} else if (name.match(/default-expression-num\.m?js/)) {
|
|
21
|
-
exports.default += 1
|
|
22
|
-
}
|
|
23
|
-
else if (name.match(/default-expression-string\.m?js/)) {
|
|
24
|
-
exports.default += 'dawg'
|
|
25
|
-
}
|
|
26
|
-
else if (name.match(/default-function\.m?js/)) {
|
|
27
|
-
const orig = exports.default
|
|
28
|
-
exports.default = function () {
|
|
29
|
-
return orig() + 1
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
else if (name.match(/default-class\.m?js/)) {
|
|
33
|
-
exports.default.prototype.getFoo = function () {
|
|
34
|
-
return 2
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
else if (name.match(/default-generator\.m?js/)) {
|
|
38
|
-
const orig2 = exports.default
|
|
39
|
-
exports.default = function* () {
|
|
40
|
-
return orig2().next().value + 1
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else if (name.match(/default-function-anon\.m?js/)) {
|
|
44
|
-
const orig = exports.default
|
|
45
|
-
exports.default = function () {
|
|
46
|
-
return orig() + 1
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else if (name.match(/default-class-anon\.m?js/)) {
|
|
50
|
-
exports.default.prototype.getFoo = function () {
|
|
51
|
-
return 2
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else if (name.match(/default-generator-anon\.m?js/)) {
|
|
55
|
-
const orig2 = exports.default
|
|
56
|
-
exports.default = function* () {
|
|
57
|
-
return orig2().next().value + 1
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
strictEqual(a[0], 2)
|
|
63
|
-
strictEqual(fn(), 2)
|
|
64
|
-
strictEqual(new cn().getFoo(), 2)
|
|
65
|
-
strictEqual(gfn().next().value, 2)
|
|
66
|
-
strictEqual(afn(), 2)
|
|
67
|
-
strictEqual(new acn().getFoo(), 2)
|
|
68
|
-
strictEqual(agfn().next().value, 2)
|
|
69
|
-
// the below tests won't work because literal default exports are static
|
|
70
|
-
// strictEqual(n, 2)
|
|
71
|
-
// strictEqual(s, 'dogdawg')
|
|
@@ -1,84 +0,0 @@
|
|
|
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 {
|
|
7
|
-
name1 as n1,
|
|
8
|
-
name2 as n2,
|
|
9
|
-
name3 as n3,
|
|
10
|
-
name4 as n4,
|
|
11
|
-
functionName as fn,
|
|
12
|
-
ClassName as cn,
|
|
13
|
-
generatorFunctionName as gfn,
|
|
14
|
-
name5 as n5,
|
|
15
|
-
bar as n6,
|
|
16
|
-
name7 as n7,
|
|
17
|
-
name8 as n8,
|
|
18
|
-
asyncFunctionName as afn,
|
|
19
|
-
asyncGeneratorFunctionName as agfn,
|
|
20
|
-
arrowFunction as arfn,
|
|
21
|
-
asyncArrowFunction as aarfn,
|
|
22
|
-
} from '../fixtures/export-types/declarations.mjs'
|
|
23
|
-
import { strictEqual } from 'assert'
|
|
24
|
-
|
|
25
|
-
Hook((exports, name) => {
|
|
26
|
-
if (name.match(/declarations\.m?js/)) {
|
|
27
|
-
exports.name1 += 1
|
|
28
|
-
exports.name2 += 1
|
|
29
|
-
exports.name3 += 1
|
|
30
|
-
exports.name4 += 1
|
|
31
|
-
const orig = exports.functionName
|
|
32
|
-
exports.functionName = function () {
|
|
33
|
-
return orig() + 1
|
|
34
|
-
}
|
|
35
|
-
exports.ClassName.prototype.getFoo = function () {
|
|
36
|
-
return 2
|
|
37
|
-
}
|
|
38
|
-
const orig2 = exports.generatorFunctionName
|
|
39
|
-
exports.generatorFunctionName = function* () {
|
|
40
|
-
return orig2().next().value + 1
|
|
41
|
-
}
|
|
42
|
-
exports.name5 += 1
|
|
43
|
-
exports.bar += 1
|
|
44
|
-
exports.name7 += 1
|
|
45
|
-
exports.name8 += 1
|
|
46
|
-
const asyncOrig = exports.asyncFunctionName
|
|
47
|
-
exports.asyncFunctionName = async function () {
|
|
48
|
-
return await asyncOrig() + 1
|
|
49
|
-
}
|
|
50
|
-
const asyncOrig2 = exports.asyncGeneratorFunctionName
|
|
51
|
-
exports.asyncGeneratorFunctionName = async function* () {
|
|
52
|
-
for await (const value of asyncOrig2()) {
|
|
53
|
-
yield value + 1;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
const arrowOrig = exports.arrowFunction
|
|
57
|
-
exports.arrowFunction = () => {
|
|
58
|
-
return arrowOrig() + 1
|
|
59
|
-
}
|
|
60
|
-
const asyncArrowOrig = exports.asyncArrowFunction
|
|
61
|
-
exports.asyncArrowFunction = async () => {
|
|
62
|
-
return await asyncArrowOrig() + 1
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
strictEqual(n1, 2)
|
|
68
|
-
strictEqual(n2, 2)
|
|
69
|
-
strictEqual(n3, 2)
|
|
70
|
-
strictEqual(n4, 2)
|
|
71
|
-
strictEqual(fn(), 2)
|
|
72
|
-
strictEqual(new cn().getFoo(), 2)
|
|
73
|
-
strictEqual(gfn().next().value, 2)
|
|
74
|
-
strictEqual(n5, 2)
|
|
75
|
-
strictEqual(n6, 2)
|
|
76
|
-
strictEqual(n7, 2)
|
|
77
|
-
strictEqual(n8, 2)
|
|
78
|
-
strictEqual(await afn(), 2)
|
|
79
|
-
for await (const value of agfn()) {
|
|
80
|
-
strictEqual(value, 2)
|
|
81
|
-
}
|
|
82
|
-
strictEqual(arfn(), 2)
|
|
83
|
-
strictEqual(await aarfn(), 2)
|
|
84
|
-
|
|
@@ -1,34 +0,0 @@
|
|
|
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 n, {
|
|
7
|
-
name1 as n1,
|
|
8
|
-
name2 as n2,
|
|
9
|
-
name3 as n3,
|
|
10
|
-
name4 as n4,
|
|
11
|
-
name5 as n5,
|
|
12
|
-
"name" as n6,
|
|
13
|
-
} from '../fixtures/export-types/list.mjs'
|
|
14
|
-
import { strictEqual } from 'assert'
|
|
15
|
-
|
|
16
|
-
Hook((exports, name) => {
|
|
17
|
-
if (name.match(/list\.m?js/)) {
|
|
18
|
-
exports.name1 += 1
|
|
19
|
-
exports.name2 += 1
|
|
20
|
-
exports.name3 += 1
|
|
21
|
-
exports.name4 += 1
|
|
22
|
-
exports.name5 += 1
|
|
23
|
-
exports.name += 1
|
|
24
|
-
exports.default += 1
|
|
25
|
-
}
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
strictEqual(n1, 2)
|
|
29
|
-
strictEqual(n2, 2)
|
|
30
|
-
strictEqual(n3, 2)
|
|
31
|
-
strictEqual(n4, 2)
|
|
32
|
-
strictEqual(n5, 2)
|
|
33
|
-
strictEqual(n6, 2)
|
|
34
|
-
strictEqual(n, 2)
|
|
@@ -1,29 +0,0 @@
|
|
|
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 { spawn } from 'child_process'
|
|
6
|
-
import { strictEqual } from 'assert'
|
|
7
|
-
|
|
8
|
-
const nodeProcess = spawn('node', [
|
|
9
|
-
'--loader',
|
|
10
|
-
'./hook.mjs',
|
|
11
|
-
'./test/fixtures/a.mjs'
|
|
12
|
-
])
|
|
13
|
-
|
|
14
|
-
const expectedOutput = 'testB\ntestA'
|
|
15
|
-
let stdout = ''
|
|
16
|
-
let stderr = ''
|
|
17
|
-
|
|
18
|
-
nodeProcess.stdout.on('data', (data) => {
|
|
19
|
-
stdout += data.toString()
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
nodeProcess.stderr.on('data', (data) => {
|
|
23
|
-
stderr += data.toString()
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
nodeProcess.on('close', (code) => {
|
|
27
|
-
strictEqual(stderr, '', 'There should be no errors on stderr')
|
|
28
|
-
strictEqual(stdout.trim(), expectedOutput, 'The stdout should match the expected output')
|
|
29
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
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 { spawn } from 'child_process'
|
|
6
|
-
import { strictEqual } from 'assert'
|
|
7
|
-
|
|
8
|
-
const nodeProcess = spawn('node', [
|
|
9
|
-
'--loader',
|
|
10
|
-
'./hook.mjs',
|
|
11
|
-
'./test/fixtures/reassign-let.mjs'
|
|
12
|
-
])
|
|
13
|
-
|
|
14
|
-
const expectedOutput = 'setting env, env.FOO is bar\nusing env from another module, env.FOO is bar'
|
|
15
|
-
let stdout = ''
|
|
16
|
-
let stderr = ''
|
|
17
|
-
|
|
18
|
-
nodeProcess.stdout.on('data', (data) => {
|
|
19
|
-
stdout += data.toString()
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
nodeProcess.stderr.on('data', (data) => {
|
|
23
|
-
stderr += data.toString()
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
nodeProcess.on('close', (code) => {
|
|
27
|
-
strictEqual(stderr, '', 'There should be no errors on stderr')
|
|
28
|
-
strictEqual(stdout.trim(), expectedOutput, 'The stdout should match the expected output')
|
|
29
|
-
})
|
|
@@ -1,26 +0,0 @@
|
|
|
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 { spawn } from 'child_process'
|
|
6
|
-
import { strictEqual } from 'assert'
|
|
7
|
-
|
|
8
|
-
const nodeProcess = spawn('node', ['--loader', '../../../hook.mjs', './a.js'], {
|
|
9
|
-
cwd: './test/fixtures/test-undefined-format/'})
|
|
10
|
-
|
|
11
|
-
const expectedOutput = 'testB\ntestA'
|
|
12
|
-
let stdout = ''
|
|
13
|
-
let stderr = ''
|
|
14
|
-
|
|
15
|
-
nodeProcess.stdout.on('data', (data) => {
|
|
16
|
-
stdout += data.toString()
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
nodeProcess.stderr.on('data', (data) => {
|
|
20
|
-
stderr += data.toString()
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
nodeProcess.on('close', (code) => {
|
|
24
|
-
strictEqual(stderr, '', 'There should be no errors on stderr')
|
|
25
|
-
strictEqual(stdout.trim(), expectedOutput, 'The stdout should match the expected output')
|
|
26
|
-
});
|
|
File without changes
|