@davidwells/extract-deps 0.0.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/README.md +211 -0
- package/_usage.js +175 -0
- package/examples/get-exports.js +31 -0
- package/package.json +27 -0
- package/src/detect-syntax.js +70 -0
- package/src/get-exports.js +299 -0
- package/src/get-imports.js +165 -0
- package/src/get-requires.js +104 -0
- package/src/index.js +90 -0
- package/src/utils.js +64 -0
- package/tests/detect-syntax.test.js +280 -0
- package/tests/get-exports.test.js +346 -0
- package/tests/get-imports.test.js +395 -0
- package/tests/get-requires.test.js +201 -0
- package/tests/index.test.js +202 -0
- package/tests/test-utils.js +30 -0
- package/tsconfig.json +19 -0
- package/types/detect-syntax.d.ts +39 -0
- package/types/detect-syntax.d.ts.map +1 -0
- package/types/extract-deps/_usage.d.ts +20 -0
- package/types/extract-deps/_usage.d.ts.map +1 -0
- package/types/extract-deps/examples/get-exports.d.ts +2 -0
- package/types/extract-deps/examples/get-exports.d.ts.map +1 -0
- package/types/extract-deps/src/detect-syntax.d.ts +39 -0
- package/types/extract-deps/src/detect-syntax.d.ts.map +1 -0
- package/types/extract-deps/src/get-exports.d.ts +52 -0
- package/types/extract-deps/src/get-exports.d.ts.map +1 -0
- package/types/extract-deps/src/get-imports.d.ts +53 -0
- package/types/extract-deps/src/get-imports.d.ts.map +1 -0
- package/types/extract-deps/src/get-requires.d.ts +34 -0
- package/types/extract-deps/src/get-requires.d.ts.map +1 -0
- package/types/extract-deps/src/index.d.ts +39 -0
- package/types/extract-deps/src/index.d.ts.map +1 -0
- package/types/extract-deps/src/utils.d.ts +4 -0
- package/types/extract-deps/src/utils.d.ts.map +1 -0
- package/types/extract-deps/tests/detect-syntax.test.d.ts +2 -0
- package/types/extract-deps/tests/detect-syntax.test.d.ts.map +1 -0
- package/types/extract-deps/tests/get-exports.test.d.ts +2 -0
- package/types/extract-deps/tests/get-exports.test.d.ts.map +1 -0
- package/types/extract-deps/tests/get-imports.test.d.ts +2 -0
- package/types/extract-deps/tests/get-imports.test.d.ts.map +1 -0
- package/types/extract-deps/tests/get-requires.test.d.ts +2 -0
- package/types/extract-deps/tests/get-requires.test.d.ts.map +1 -0
- package/types/extract-deps/tests/index.test.d.ts +18 -0
- package/types/extract-deps/tests/index.test.d.ts.map +1 -0
- package/types/extract-deps/tests/test-utils.d.ts +9 -0
- package/types/extract-deps/tests/test-utils.d.ts.map +1 -0
- package/types/get-exports.d.ts +52 -0
- package/types/get-exports.d.ts.map +1 -0
- package/types/get-imports.d.ts +53 -0
- package/types/get-imports.d.ts.map +1 -0
- package/types/get-requires.d.ts +34 -0
- package/types/get-requires.d.ts.map +1 -0
- package/types/index.d.ts +39 -0
- package/types/index.d.ts.map +1 -0
- package/types/packages-list/index.d.ts +138 -0
- package/types/packages-list/index.d.ts.map +1 -0
- package/types/utils.d.ts +4 -0
- package/types/utils.d.ts.map +1 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
const { getNames } = require('./utils')
|
|
2
|
+
|
|
3
|
+
// https://regex101.com/r/example/1
|
|
4
|
+
const EXPORT_DEFAULT_REGEX = /export\s+default\s+(?:function\s+([\w$]+)|class\s+([\w$]+)|([\w$]+|\([^)]*\)\s*=>|{[\s\S]*?}|\[[\s\S]*?\]|[\w$]+(?:\s*[+\-*/%]\s*[\w$]+)*))/gm
|
|
5
|
+
// https://regex101.com/r/example/2
|
|
6
|
+
const EXPORT_NAMED_REGEX = /export\s+(?:const|let|var|function|class|async\s+function)\s+([\w$]+)/gm
|
|
7
|
+
// https://regex101.com/r/example/3
|
|
8
|
+
const EXPORT_NAMED_DECLARATION_REGEX = /export\s*{([^}]+)}/gm
|
|
9
|
+
// https://regex101.com/r/example/4
|
|
10
|
+
const EXPORT_ALL_REGEX = /export\s*\*\s+from\s+["']([^"']+)["']/gm
|
|
11
|
+
// https://regex101.com/r/example/5
|
|
12
|
+
const EXPORT_AS_NAMESPACE_REGEX = /export\s*\*\s+as\s+([\w$]+)\s+from\s+["']([^"']+)["']/gm
|
|
13
|
+
// https://regex101.com/r/example/6
|
|
14
|
+
const EXPORT_TYPE_REGEX = /export\s+(?:type|interface)\s+([\w$]+)/gm
|
|
15
|
+
// https://regex101.com/r/example/7
|
|
16
|
+
const EXPORT_ASSERTION_REGEX = /export\s+(?:["'\s]*([\w*{}\n\r\t, ]+)from\s*)?["'\s](.*[@\w_-]+)["'\s]+(assert|with)\s*\{([^}]+)\};?$/gm
|
|
17
|
+
|
|
18
|
+
function getExports(code, options = {}) {
|
|
19
|
+
const defaultExports = getDefaultExports(code)
|
|
20
|
+
const namedExports = getNamedExports(code)
|
|
21
|
+
const namedDeclarationExports = getNamedDeclarationExports(code)
|
|
22
|
+
const allExports = getAllExports(code)
|
|
23
|
+
const namespaceExports = getNamespaceExports(code)
|
|
24
|
+
const typeExports = getTypeExports(code)
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
console.log('defaultExports', defaultExports)
|
|
28
|
+
console.log('namedExports', namedExports)
|
|
29
|
+
console.log('namedDeclarationExports', namedDeclarationExports)
|
|
30
|
+
console.log('allExports', allExports)
|
|
31
|
+
console.log('namespaceExports', namespaceExports)
|
|
32
|
+
console.log('typeExports', typeExports)
|
|
33
|
+
/** */
|
|
34
|
+
|
|
35
|
+
let allExportStatements = []
|
|
36
|
+
.concat(defaultExports)
|
|
37
|
+
.concat(namedExports)
|
|
38
|
+
.concat(namedDeclarationExports)
|
|
39
|
+
.concat(allExports)
|
|
40
|
+
.concat(namespaceExports)
|
|
41
|
+
.concat(typeExports)
|
|
42
|
+
|
|
43
|
+
if (options.includeAssertionExports) {
|
|
44
|
+
const assertionExports = getAssertionExports(code)
|
|
45
|
+
allExportStatements = allExportStatements.concat(assertionExports)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return allExportStatements.sort((a, b) => a.index - b.index)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getDefaultExports(targetText = '') {
|
|
52
|
+
let exportStatements = []
|
|
53
|
+
var result
|
|
54
|
+
while((result = EXPORT_DEFAULT_REGEX.exec(targetText)) !== null) {
|
|
55
|
+
const [ line, functionName, className, otherValue ] = result
|
|
56
|
+
let exportName, exportValue
|
|
57
|
+
|
|
58
|
+
if (functionName) {
|
|
59
|
+
exportName = functionName
|
|
60
|
+
exportValue = `function ${functionName}`
|
|
61
|
+
} else if (className) {
|
|
62
|
+
exportName = className
|
|
63
|
+
exportValue = `class ${className}`
|
|
64
|
+
} else {
|
|
65
|
+
exportName = extractExportName(otherValue)
|
|
66
|
+
exportValue = otherValue
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exportStatements.push({
|
|
70
|
+
line: line.trim(),
|
|
71
|
+
exportType: 'default',
|
|
72
|
+
exportName,
|
|
73
|
+
exportValue: exportValue.trim(),
|
|
74
|
+
index: result.index,
|
|
75
|
+
isExport: true
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
return exportStatements
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getNamedExports(targetText = '') {
|
|
82
|
+
let exportStatements = []
|
|
83
|
+
var result
|
|
84
|
+
while((result = EXPORT_NAMED_REGEX.exec(targetText)) !== null) {
|
|
85
|
+
const [ line, exportName ] = result
|
|
86
|
+
|
|
87
|
+
exportStatements.push({
|
|
88
|
+
line: line.trim(),
|
|
89
|
+
exportType: 'named',
|
|
90
|
+
exportName,
|
|
91
|
+
index: result.index,
|
|
92
|
+
isExport: true
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
return exportStatements
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function getNamedDeclarationExports(targetText = '') {
|
|
99
|
+
let exportStatements = []
|
|
100
|
+
var result
|
|
101
|
+
while((result = EXPORT_NAMED_DECLARATION_REGEX.exec(targetText)) !== null) {
|
|
102
|
+
const [ line, exportsList ] = result
|
|
103
|
+
const exports = parseExportsList(exportsList)
|
|
104
|
+
|
|
105
|
+
exports.forEach(exportItem => {
|
|
106
|
+
const name = exportItem.name.trim()
|
|
107
|
+
if (name === '') {
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
exportStatements.push({
|
|
111
|
+
line: line.trim(),
|
|
112
|
+
exportType: 'named',
|
|
113
|
+
exportName: name,
|
|
114
|
+
exportAlias: exportItem.alias,
|
|
115
|
+
index: result.index,
|
|
116
|
+
isExport: true
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
return exportStatements
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getAllExports(targetText = '') {
|
|
124
|
+
let exportStatements = []
|
|
125
|
+
var result
|
|
126
|
+
while((result = EXPORT_ALL_REGEX.exec(targetText)) !== null) {
|
|
127
|
+
const [ line, from ] = result
|
|
128
|
+
|
|
129
|
+
exportStatements.push({
|
|
130
|
+
line: line.trim(),
|
|
131
|
+
exportType: 'all',
|
|
132
|
+
from,
|
|
133
|
+
index: result.index,
|
|
134
|
+
isExport: true
|
|
135
|
+
})
|
|
136
|
+
}
|
|
137
|
+
return exportStatements
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function getNamespaceExports(targetText = '') {
|
|
141
|
+
let exportStatements = []
|
|
142
|
+
var result
|
|
143
|
+
while((result = EXPORT_AS_NAMESPACE_REGEX.exec(targetText)) !== null) {
|
|
144
|
+
const [ line, namespace, from ] = result
|
|
145
|
+
|
|
146
|
+
exportStatements.push({
|
|
147
|
+
line: line.trim(),
|
|
148
|
+
exportType: 'namespace',
|
|
149
|
+
namespace,
|
|
150
|
+
from,
|
|
151
|
+
index: result.index,
|
|
152
|
+
isExport: true
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
return exportStatements
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function getTypeExports(targetText = '') {
|
|
159
|
+
let exportStatements = []
|
|
160
|
+
var result
|
|
161
|
+
while((result = EXPORT_TYPE_REGEX.exec(targetText)) !== null) {
|
|
162
|
+
const [ line, typeName ] = result
|
|
163
|
+
|
|
164
|
+
exportStatements.push({
|
|
165
|
+
line: line.trim(),
|
|
166
|
+
exportType: 'type',
|
|
167
|
+
exportName: typeName,
|
|
168
|
+
index: result.index,
|
|
169
|
+
isExport: true
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
return exportStatements
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function getAssertionExports(targetText = '') {
|
|
176
|
+
let exportStatements = []
|
|
177
|
+
var result
|
|
178
|
+
while((result = EXPORT_ASSERTION_REGEX.exec(targetText)) !== null) {
|
|
179
|
+
let [ line, names, from, keyword, assertion ] = result
|
|
180
|
+
const namesValues = (names || '').trim()
|
|
181
|
+
// Remove leading newlines and whitespace from the line
|
|
182
|
+
line = line.replace(/^\s+|\s+$/g, '')
|
|
183
|
+
|
|
184
|
+
exportStatements.push({
|
|
185
|
+
line,
|
|
186
|
+
exportType: 'assertion',
|
|
187
|
+
exportName: namesValues,
|
|
188
|
+
definitions: getNames(namesValues),
|
|
189
|
+
from,
|
|
190
|
+
assertion: assertion.trim(),
|
|
191
|
+
assertionType: keyword,
|
|
192
|
+
index: result.index,
|
|
193
|
+
isExport: true,
|
|
194
|
+
isAssertion: true
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
return exportStatements
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function extractExportName(exportValue) {
|
|
201
|
+
// Handle function declarations
|
|
202
|
+
if (exportValue.includes('function') && !exportValue.includes('=>')) {
|
|
203
|
+
const match = exportValue.match(/function\s+([\w$]+)/)
|
|
204
|
+
return match ? match[1] : 'anonymous'
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Handle class declarations
|
|
208
|
+
if (exportValue.includes('class')) {
|
|
209
|
+
const match = exportValue.match(/class\s+([\w$]+)/)
|
|
210
|
+
return match ? match[1] : 'anonymous'
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Handle arrow functions
|
|
214
|
+
if (exportValue.includes('=>')) {
|
|
215
|
+
return 'anonymous'
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Handle object/array literals
|
|
219
|
+
if (exportValue.startsWith('{') || exportValue.startsWith('[')) {
|
|
220
|
+
return 'literal'
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Handle simple values
|
|
224
|
+
return exportValue.trim()
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function parseExportsList(exportsList) {
|
|
228
|
+
const exports = []
|
|
229
|
+
const items = exportsList.split(',').map(item => item.trim())
|
|
230
|
+
|
|
231
|
+
items.forEach(item => {
|
|
232
|
+
if (item.includes(' as ')) {
|
|
233
|
+
const [ name, alias ] = item.split(' as ')
|
|
234
|
+
exports.push({
|
|
235
|
+
name: name.trim(),
|
|
236
|
+
alias: alias.trim()
|
|
237
|
+
})
|
|
238
|
+
} else {
|
|
239
|
+
exports.push({
|
|
240
|
+
name: item,
|
|
241
|
+
alias: null
|
|
242
|
+
})
|
|
243
|
+
}
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
return exports
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if(require.main === module) {
|
|
250
|
+
const code = `
|
|
251
|
+
// Default exports
|
|
252
|
+
export default function myFunction() {}
|
|
253
|
+
export default class MyClass {}
|
|
254
|
+
export default { foo: 'bar' }
|
|
255
|
+
export default [1, 2, 3]
|
|
256
|
+
export default 'hello'
|
|
257
|
+
export default 42
|
|
258
|
+
|
|
259
|
+
// Named exports
|
|
260
|
+
export const myVariable = 'value'
|
|
261
|
+
export let anotherVariable = 'value'
|
|
262
|
+
export var thirdVariable = 'value'
|
|
263
|
+
export function myFunction() {}
|
|
264
|
+
export class MyClass {}
|
|
265
|
+
export async function asyncFunction() {}
|
|
266
|
+
|
|
267
|
+
// Named declaration exports
|
|
268
|
+
export { myFunction, anotherFunction }
|
|
269
|
+
export { myFunction as aliasedFunction, anotherFunction }
|
|
270
|
+
export { default } from './module'
|
|
271
|
+
export { default as aliasedDefault } from './module'
|
|
272
|
+
|
|
273
|
+
// Re-exports
|
|
274
|
+
export * from './module'
|
|
275
|
+
export * as namespace from './module'
|
|
276
|
+
|
|
277
|
+
// Type exports
|
|
278
|
+
export type MyType = string
|
|
279
|
+
export interface MyInterface {}
|
|
280
|
+
|
|
281
|
+
// Assertion exports
|
|
282
|
+
export { default } from './module' assert { type: 'json' }
|
|
283
|
+
export { Component } from './component' with { type: 'css' }
|
|
284
|
+
`
|
|
285
|
+
|
|
286
|
+
const exportsFound = getExports(code)
|
|
287
|
+
exportsFound.forEach(item => console.log(item))
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
module.exports = {
|
|
291
|
+
getExports,
|
|
292
|
+
getDefaultExports,
|
|
293
|
+
getNamedExports,
|
|
294
|
+
getNamedDeclarationExports,
|
|
295
|
+
getAllExports,
|
|
296
|
+
getNamespaceExports,
|
|
297
|
+
getTypeExports,
|
|
298
|
+
getAssertionExports
|
|
299
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const { isRelativeImport, isRelativeImportWithQuotes, getNames } = require('./utils')
|
|
2
|
+
|
|
3
|
+
// https://regex101.com/r/cfEmlm/1
|
|
4
|
+
const IMPORT_REGEX = /import(?:["'\s]*([\w*{}\n\r\t, ]+)from\s*)?["'\s](.*[@\w_-]+)["'\s]+;?$/gm
|
|
5
|
+
// https://regex101.com/r/UDmXlb/1
|
|
6
|
+
const IMPORT_TYPE_REGEX = /import\(['"](.*)['"]\)\.?([A-Za-z_0-9.]*)?/gm
|
|
7
|
+
// https://regex101.com/r/UDjMoV/1
|
|
8
|
+
const DYNAMIC_IMPORT_REGEX = /(?:(const|var|let)\s+([\w*{}\n\r\t,:= ]+)\s*=\s*)?await\s+import\(([^()]+(?:\([^()]*\)[^()]*)*)\)/gm
|
|
9
|
+
// https://regex101.com/r/example/1
|
|
10
|
+
const ASSERTION_IMPORT_REGEX = /(?:^|\n)\s*import\s+(?:["'\s]*([\w*{}\n\r\t, ]+)from\s*)?["'\s](.*[@\w_-]+)["'\s]+(assert|with)\s*\{([^}]+)\};?$/gm
|
|
11
|
+
|
|
12
|
+
function getImports(code, options = {}) {
|
|
13
|
+
const staticImports = getStaticImports(code)
|
|
14
|
+
const dynamicImports = getDynamicImports(code)
|
|
15
|
+
if (options.includeAssertionImports) {
|
|
16
|
+
const assertionImports = getAssertionImports(code)
|
|
17
|
+
return staticImports.concat(dynamicImports).concat(assertionImports).sort((a, b) => a.index - b.index)
|
|
18
|
+
}
|
|
19
|
+
return staticImports.concat(dynamicImports).sort((a, b) => a.index - b.index)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// https://regex101.com/r/cfEmlm/1
|
|
23
|
+
function getStaticImports(targetText = '') {
|
|
24
|
+
let importStatements = []
|
|
25
|
+
var result;
|
|
26
|
+
while((result = IMPORT_REGEX.exec(targetText)) !== null) {
|
|
27
|
+
const [ line, names, from ] = result
|
|
28
|
+
const namesValues = (names || '').trim()
|
|
29
|
+
importStatements.push({
|
|
30
|
+
line,
|
|
31
|
+
varType: 'const',
|
|
32
|
+
varName: namesValues,
|
|
33
|
+
definitions: getNames(namesValues),
|
|
34
|
+
from,
|
|
35
|
+
index: result.index,
|
|
36
|
+
isImport: true,
|
|
37
|
+
isRelative: isRelativeImport(from)
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
return importStatements
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getTypeImports(targetText = '') {
|
|
44
|
+
let importStatements = []
|
|
45
|
+
var result;
|
|
46
|
+
while((result = IMPORT_TYPE_REGEX.exec(targetText)) !== null) {
|
|
47
|
+
const [ importStatement, importPath, importName ] = result
|
|
48
|
+
// console.log('result', result)
|
|
49
|
+
importStatements.push({
|
|
50
|
+
importStatement,
|
|
51
|
+
importPath,
|
|
52
|
+
importName: (importName || '').trim(),
|
|
53
|
+
index: result.index,
|
|
54
|
+
isImport: true,
|
|
55
|
+
isRelative: isRelativeImport(importPath)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
return importStatements
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getDynamicImports(targetText = '') {
|
|
62
|
+
let importStatements = []
|
|
63
|
+
var result;
|
|
64
|
+
while((result = DYNAMIC_IMPORT_REGEX.exec(targetText)) !== null) {
|
|
65
|
+
const [ line, varType, names, from ] = result
|
|
66
|
+
let namesValues = (names || '').trim()
|
|
67
|
+
|
|
68
|
+
importStatements.push({
|
|
69
|
+
line,
|
|
70
|
+
varType: varType || '',
|
|
71
|
+
varName: namesValues,
|
|
72
|
+
definitions: names ? getNames(namesValues) : null,
|
|
73
|
+
from: from.trim(),
|
|
74
|
+
index: result.index,
|
|
75
|
+
isImport: true,
|
|
76
|
+
isRelative: isRelativeImport(from) || isRelativeImportWithQuotes(from),
|
|
77
|
+
isDynamic: true
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
return importStatements
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getAssertionImports(targetText = '') {
|
|
84
|
+
let importStatements = []
|
|
85
|
+
var result;
|
|
86
|
+
while((result = ASSERTION_IMPORT_REGEX.exec(targetText)) !== null) {
|
|
87
|
+
let [ line, names, from, keyword, assertion ] = result
|
|
88
|
+
const namesValues = (names || '').trim()
|
|
89
|
+
// Remove leading newlines and whitespace from the line
|
|
90
|
+
line = line.replace(/^\s+|\s+$/g, '')
|
|
91
|
+
|
|
92
|
+
importStatements.push({
|
|
93
|
+
line,
|
|
94
|
+
varType: 'const',
|
|
95
|
+
varName: namesValues,
|
|
96
|
+
definitions: getNames(namesValues),
|
|
97
|
+
from,
|
|
98
|
+
assertion: assertion.trim(),
|
|
99
|
+
assertionType: keyword,
|
|
100
|
+
index: result.index,
|
|
101
|
+
isImport: true,
|
|
102
|
+
isRelative: isRelativeImport(from),
|
|
103
|
+
isAssertion: true
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
return importStatements
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if(require.main === module) {
|
|
110
|
+
const code = `
|
|
111
|
+
import {
|
|
112
|
+
Component
|
|
113
|
+
} from '@angular2/core';
|
|
114
|
+
import defaultMember from "module-name";
|
|
115
|
+
import * as name from "module-name ";
|
|
116
|
+
import React from react"
|
|
117
|
+
import { member } from " module-name";
|
|
118
|
+
import { member as alias } from "module-name";
|
|
119
|
+
import { member1 ,
|
|
120
|
+
member2 } from "module-name";
|
|
121
|
+
import { member1 , member2 as alias2 , member3 as alias3 } from "module-name";
|
|
122
|
+
import defaultMember, { member, member } from "module-name";
|
|
123
|
+
import defaultMember, * as name from "module-name";
|
|
124
|
+
import "module-name";
|
|
125
|
+
import * from './smdn';
|
|
126
|
+
`
|
|
127
|
+
|
|
128
|
+
const dynamicCode = `
|
|
129
|
+
// Basic dynamic import
|
|
130
|
+
const module = await import('./module.js')
|
|
131
|
+
|
|
132
|
+
// With variable
|
|
133
|
+
const moduleName = './utils.js'
|
|
134
|
+
const utils = await import(moduleName)
|
|
135
|
+
|
|
136
|
+
// With template literals
|
|
137
|
+
const folder = 'components'
|
|
138
|
+
const component = await import(\`./src/$\{folder}/Button.js\`)
|
|
139
|
+
|
|
140
|
+
// With path building
|
|
141
|
+
const modulePath = path.join('./src', 'helpers', 'api.js')
|
|
142
|
+
const api = await import(modulePath)
|
|
143
|
+
|
|
144
|
+
// Destructuring
|
|
145
|
+
const { default: Component, helper } = await import('./Component.js')
|
|
146
|
+
|
|
147
|
+
// Variable assignment
|
|
148
|
+
const dynamicModule = await import(getModulePath())
|
|
149
|
+
`
|
|
150
|
+
const dynamicImports = getDynamicImports(dynamicCode)
|
|
151
|
+
dynamicImports.forEach(item => console.log(item))
|
|
152
|
+
|
|
153
|
+
/*
|
|
154
|
+
const imports = getStaticImports(code)
|
|
155
|
+
imports.forEach(item => console.log(item))
|
|
156
|
+
/** */
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
module.exports = {
|
|
160
|
+
getImports,
|
|
161
|
+
getStaticImports,
|
|
162
|
+
getTypeImports,
|
|
163
|
+
getDynamicImports,
|
|
164
|
+
getAssertionImports
|
|
165
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const { isRelativeImport, getNames } = require('./utils')
|
|
2
|
+
|
|
3
|
+
// Updated regex to exclude ES6 dynamic imports
|
|
4
|
+
const REQUIRE_REGEX = /(?!.*await\s+import)(const|var|let)(?:["'\s]*([\w*{}:=\n\r\t,:= ]+)\s*=\s*require\(\s*)?["'\s](.*[@\w_-]+)["'\s]+\);?$|(?!.*await\s+import)require\(["'\s](.*[@\w_-]+)["'\s]\)/gm
|
|
5
|
+
// https://regex101.com/r/kZ5xCk/3
|
|
6
|
+
const DYNAMIC_REQUIRE_REGEX = /(?:(const|var|let)\s+([\w*{}\n\r\t,:= ]+)\s*=\s*)?require\(([^()'"]+(?:\([^()]*\)[^()'"]*)*)\)/gm
|
|
7
|
+
|
|
8
|
+
function getDynamicRequires(code) {
|
|
9
|
+
const results = []
|
|
10
|
+
let match
|
|
11
|
+
|
|
12
|
+
while ((match = DYNAMIC_REQUIRE_REGEX.exec(code)) !== null) {
|
|
13
|
+
const [line, varType, names, from] = match
|
|
14
|
+
/*
|
|
15
|
+
console.log('line', line)
|
|
16
|
+
console.log('varType', varType)
|
|
17
|
+
console.log('names', names || 'no names')
|
|
18
|
+
console.log('from', from)
|
|
19
|
+
/** */
|
|
20
|
+
let namesValues = (names || '').trim()
|
|
21
|
+
|
|
22
|
+
results.push({
|
|
23
|
+
line,
|
|
24
|
+
varType: varType || '',
|
|
25
|
+
varName: namesValues,
|
|
26
|
+
definitions: names ? getNames(namesValues) : null,
|
|
27
|
+
from: from.trim(),
|
|
28
|
+
index: match.index,
|
|
29
|
+
isRequire: true,
|
|
30
|
+
isRelative: false,
|
|
31
|
+
isDynamic: true
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return results
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// https://regex101.com/r/sR1TIP/1
|
|
39
|
+
function getStaticRequires(targetText = '') {
|
|
40
|
+
let requireStatements = []
|
|
41
|
+
var result;
|
|
42
|
+
while((result = REQUIRE_REGEX.exec(targetText)) !== null) {
|
|
43
|
+
const [ line, varType, names, from, fromTwo ] = result
|
|
44
|
+
// console.log('getStaticRequires result', result)
|
|
45
|
+
const importLocation = from || fromTwo
|
|
46
|
+
const importItems = (names || '').trim()
|
|
47
|
+
requireStatements.push({
|
|
48
|
+
line,
|
|
49
|
+
varType: varType || '',
|
|
50
|
+
varName: importItems,
|
|
51
|
+
definitions: importItems ? getNames(importItems) : null,
|
|
52
|
+
from: importLocation,
|
|
53
|
+
index: result.index,
|
|
54
|
+
isRequire: true,
|
|
55
|
+
isRelative: isRelativeImport(importLocation),
|
|
56
|
+
isDynamic: false
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return requireStatements
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function getRequires(code) {
|
|
64
|
+
const staticRequires = getStaticRequires(code)
|
|
65
|
+
const dynamicRequires = getDynamicRequires(code)
|
|
66
|
+
return staticRequires.concat(dynamicRequires).sort((a, b) => a.index - b.index)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (require.main === module) {
|
|
70
|
+
const code = `
|
|
71
|
+
const moduleName = 'fs'
|
|
72
|
+
const dynamicRequire = require(moduleName)
|
|
73
|
+
const path = require('path')
|
|
74
|
+
const relative = require('./relative')
|
|
75
|
+
const dynamicPath = require(path.join(__dirname, 'utils'))
|
|
76
|
+
const foo = require('foo-pkg')
|
|
77
|
+
require(\`./$\{folder}/file\`)
|
|
78
|
+
const { test : funky, foo = false } = require(moduleTwo)
|
|
79
|
+
`
|
|
80
|
+
|
|
81
|
+
const failCase = `
|
|
82
|
+
// Dynamic imports
|
|
83
|
+
const dynamicModule = await import('./utils')
|
|
84
|
+
const config = await import('./config.js')
|
|
85
|
+
`
|
|
86
|
+
|
|
87
|
+
//*
|
|
88
|
+
const dynamicRequires = getDynamicRequires(code)
|
|
89
|
+
dynamicRequires.forEach(item => console.log(item))
|
|
90
|
+
/** */
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
//*
|
|
94
|
+
const requires = getRequires(failCase)
|
|
95
|
+
console.log('requires', requires)
|
|
96
|
+
requires.forEach(item => console.log(item))
|
|
97
|
+
/** */
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = {
|
|
101
|
+
getRequires,
|
|
102
|
+
getStaticRequires,
|
|
103
|
+
getDynamicRequires,
|
|
104
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const { getImports, getStaticImports, getDynamicImports } = require('./get-imports')
|
|
2
|
+
const { getRequires, getStaticRequires, getDynamicRequires } = require('./get-requires')
|
|
3
|
+
const {
|
|
4
|
+
getExports,
|
|
5
|
+
getDefaultExports,
|
|
6
|
+
getNamedExports,
|
|
7
|
+
getNamedDeclarationExports,
|
|
8
|
+
getAllExports,
|
|
9
|
+
getNamespaceExports,
|
|
10
|
+
getTypeExports
|
|
11
|
+
} = require('./get-exports')
|
|
12
|
+
|
|
13
|
+
// Alt approach import parseImports from 'parse-imports'
|
|
14
|
+
// https://github.com/ganeshkbhat/get-imports/blob/main/index.js
|
|
15
|
+
// Alt get imports https://github.com/beenotung/fix-esm-import-path/blob/master/fix-esm-import-path.js#L186
|
|
16
|
+
|
|
17
|
+
function extractDeps(code, filePath = '') {
|
|
18
|
+
const imports = getImports(code)
|
|
19
|
+
//console.log('imports', imports)
|
|
20
|
+
const requires = getRequires(code)
|
|
21
|
+
// console.log('requires', requires)
|
|
22
|
+
const foundExports = getExports(code)
|
|
23
|
+
// console.log('exports', exports)
|
|
24
|
+
return { imports, requires, exports: foundExports }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (require.main === module) {
|
|
28
|
+
const code = `
|
|
29
|
+
const { test : testTwo, lol: lolTwo } = require('uvu')
|
|
30
|
+
const assert = require('uvu/assert')
|
|
31
|
+
import { test } from 'uvu'
|
|
32
|
+
import assert from 'uvu/assert'
|
|
33
|
+
import funky from '../my-local-module'
|
|
34
|
+
import { test } from 'uvu'
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
foo,
|
|
39
|
+
bar,
|
|
40
|
+
}
|
|
41
|
+
`
|
|
42
|
+
|
|
43
|
+
const failCase = `
|
|
44
|
+
const { test } = require('uvu')
|
|
45
|
+
const assert = require('uvu/assert')
|
|
46
|
+
import { extractDeps } from './src/index'
|
|
47
|
+
import path from 'path'
|
|
48
|
+
import fs from 'fs'
|
|
49
|
+
|
|
50
|
+
// Dynamic imports
|
|
51
|
+
const dynamicModule = await import('./utils')
|
|
52
|
+
const config = await import('./config.js')
|
|
53
|
+
|
|
54
|
+
// More requires
|
|
55
|
+
const lerna = require('lerna')
|
|
56
|
+
const { execSync, spawnSync } = require('child_process')
|
|
57
|
+
`
|
|
58
|
+
const result = extractDeps(code)
|
|
59
|
+
|
|
60
|
+
const { imports, requires } = result
|
|
61
|
+
|
|
62
|
+
function logDefinitions(item) {
|
|
63
|
+
console.log(item)
|
|
64
|
+
const definitions = item.definitions
|
|
65
|
+
console.log(definitions)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
imports.forEach(logDefinitions)
|
|
69
|
+
requires.forEach(logDefinitions)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = {
|
|
73
|
+
extractDeps,
|
|
74
|
+
/* Requires */
|
|
75
|
+
getRequires,
|
|
76
|
+
getDynamicRequires,
|
|
77
|
+
getStaticRequires,
|
|
78
|
+
/* Imports */
|
|
79
|
+
getImports,
|
|
80
|
+
getStaticImports,
|
|
81
|
+
getDynamicImports,
|
|
82
|
+
/* Exports */
|
|
83
|
+
getExports,
|
|
84
|
+
getDefaultExports,
|
|
85
|
+
getNamedExports,
|
|
86
|
+
getNamedDeclarationExports,
|
|
87
|
+
getAllExports,
|
|
88
|
+
getNamespaceExports,
|
|
89
|
+
getTypeExports,
|
|
90
|
+
}
|