@davidwells/extract-deps 0.1.2 → 0.1.3
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/package.json +1 -1
- package/src/detect-syntax.js +9 -10
- package/src/get-exports.js +4 -2
- package/src/get-imports.js +4 -2
- package/src/utils.js +21 -0
- package/tests/get-exports.test.js +31 -0
- package/tests/get-imports.test.js +27 -0
package/package.json
CHANGED
package/src/detect-syntax.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// via https://github.com/unjs/mlly/blob/6bf5ad4d784e314319f872a8df41d64edd4e5505/src/syntax.ts#L7
|
|
2
|
+
const { stripComments } = require('./utils')
|
|
2
3
|
|
|
3
4
|
const ESM_RE =
|
|
4
5
|
/([\s;]|^)(import\b[\s\w*,{}]*from|import\b\s*["'*{]|export\b\s*(?:[*{]|default|class|type|interface|enum|function|const|var|let|async function)|import\.meta\b)/m;
|
|
@@ -6,8 +7,6 @@ const ESM_RE =
|
|
|
6
7
|
const CJS_RE =
|
|
7
8
|
/([\s;]|^)(module\.exports\b|exports\.\w|require\s*\(|global\.\w)/m;
|
|
8
9
|
|
|
9
|
-
const COMMENT_RE = /\/\*.+?\*\/|\/\/.*(?:\r?\n|$)/g;
|
|
10
|
-
|
|
11
10
|
const BUILTIN_EXTENSIONS = new Set([".mjs", ".cjs", ".node", ".wasm"]);
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -25,8 +24,8 @@ const BUILTIN_EXTENSIONS = new Set([".mjs", ".cjs", ".node", ".wasm"]);
|
|
|
25
24
|
*/
|
|
26
25
|
function hasESMSyntax(code, opts = {}) {
|
|
27
26
|
// Always strip comments to avoid false positives from commented syntax
|
|
28
|
-
code = code
|
|
29
|
-
return ESM_RE.test(code)
|
|
27
|
+
code = stripComments(code)
|
|
28
|
+
return ESM_RE.test(code)
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/**
|
|
@@ -38,8 +37,8 @@ function hasESMSyntax(code, opts = {}) {
|
|
|
38
37
|
*/
|
|
39
38
|
function hasCJSSyntax(code, opts = {}) {
|
|
40
39
|
// Always strip comments to avoid false positives from commented syntax
|
|
41
|
-
code = code
|
|
42
|
-
return CJS_RE.test(code)
|
|
40
|
+
code = stripComments(code)
|
|
41
|
+
return CJS_RE.test(code)
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
/**
|
|
@@ -51,16 +50,16 @@ function hasCJSSyntax(code, opts = {}) {
|
|
|
51
50
|
*/
|
|
52
51
|
function detectSyntax(code, opts = {}) {
|
|
53
52
|
// Always strip comments to avoid false positives from commented syntax
|
|
54
|
-
code = code
|
|
53
|
+
code = stripComments(code)
|
|
55
54
|
// We strip comments once hence not passing opts down to hasESMSyntax and hasCJSSyntax
|
|
56
|
-
const hasESM = hasESMSyntax(code, {})
|
|
57
|
-
const hasCJS = hasCJSSyntax(code, {})
|
|
55
|
+
const hasESM = hasESMSyntax(code, {})
|
|
56
|
+
const hasCJS = hasCJSSyntax(code, {})
|
|
58
57
|
|
|
59
58
|
return {
|
|
60
59
|
hasESM,
|
|
61
60
|
hasCJS,
|
|
62
61
|
isMixed: hasESM && hasCJS,
|
|
63
|
-
}
|
|
62
|
+
}
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
module.exports = {
|
package/src/get-exports.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { getNames, extractExportName } = require('./utils')
|
|
1
|
+
const { getNames, extractExportName, stripComments } = require('./utils')
|
|
2
2
|
|
|
3
3
|
// https://regex101.com/r/example/1
|
|
4
4
|
const EXPORT_DEFAULT_REGEX = /export\s+default\s+(?:(?:async\s+)?function\s+([\w$]+)|class\s+([\w$]+)|([\w$]+|\([^)]*\)\s*=>|{[\s\S]*?}|\[[\s\S]*?\]|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*`|[\w$]+(?:\s*[+\-*/%]\s*[\w$]+)*))/gm
|
|
@@ -15,7 +15,9 @@ const EXPORT_TYPE_REGEX = /export\s+(?:type|interface)\s+([\w$]+)/gm
|
|
|
15
15
|
// https://regex101.com/r/example/7
|
|
16
16
|
const EXPORT_ASSERTION_REGEX = /export\s+(?:["'\s]*([\w*{}\n\r\t, ]+)from\s*)?["'\s](.*[@\w_-]+)["'\s]+(assert|with)\s*\{([^}]+)\};?$/gm
|
|
17
17
|
|
|
18
|
-
function getExports(code, options = {}) {
|
|
18
|
+
function getExports(code = '', options = {}) {
|
|
19
|
+
// Strip comments to avoid false positives
|
|
20
|
+
code = stripComments(code)
|
|
19
21
|
const defaultExports = getDefaultExports(code)
|
|
20
22
|
const namedExports = getNamedExports(code)
|
|
21
23
|
const namedDeclarationExports = getNamedDeclarationExports(code)
|
package/src/get-imports.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { isBuiltIn, isRelativeImport, isRelativeImportWithQuotes, getNames } = require('./utils')
|
|
1
|
+
const { isBuiltIn, isRelativeImport, isRelativeImportWithQuotes, getNames, stripComments } = require('./utils')
|
|
2
2
|
|
|
3
3
|
// https://regex101.com/r/cfEmlm/1
|
|
4
4
|
const IMPORT_REGEX = /import(?:["'\s]*([\w*{}\n\r\t, ]+)from\s*)?["'\s](.*[@\w_-]+)["'\s]+;?$/gm
|
|
@@ -9,7 +9,9 @@ const DYNAMIC_IMPORT_REGEX = /(?:(const|var|let)\s+([\w*{}\n\r\t,:= ]+)\s*=\s*)?
|
|
|
9
9
|
// https://regex101.com/r/example/1
|
|
10
10
|
const ASSERTION_IMPORT_REGEX = /(?:^|\n)\s*import\s+(?:["'\s]*([\w*{}\n\r\t, ]+)from\s*)?["'\s](.*[@\w_-]+)["'\s]+(assert|with)\s*\{([^}]+)\};?$/gm
|
|
11
11
|
|
|
12
|
-
function getImports(code, options = {}) {
|
|
12
|
+
function getImports(code = '', options = {}) {
|
|
13
|
+
// Strip comments to avoid false positives
|
|
14
|
+
code = stripComments(code)
|
|
13
15
|
const staticImports = getStaticImports(code)
|
|
14
16
|
const dynamicImports = getDynamicImports(code)
|
|
15
17
|
if (options.includeAssertionImports) {
|
package/src/utils.js
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
const { inspectParameters, getParametersNames } = require('./vendor/inspect-parameters-declaration')
|
|
2
2
|
const builtinModules = require('module').builtinModules
|
|
3
3
|
|
|
4
|
+
const COMMENT_RE = /\/\*[\s\S]*?\*\/|\/\/.*(?:\r?\n|$)/g
|
|
5
|
+
const PROTOCOL_PLACEHOLDER = '__PROTO_SLASH__'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Strip comments from code, preserving :// in URLs
|
|
9
|
+
* @param {string} code
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
12
|
+
function stripComments(code) {
|
|
13
|
+
const hasProtocol = code.indexOf('://') > -1
|
|
14
|
+
if (hasProtocol) {
|
|
15
|
+
code = code.replace(/:\/\//g, PROTOCOL_PLACEHOLDER)
|
|
16
|
+
}
|
|
17
|
+
code = code.replace(COMMENT_RE, '')
|
|
18
|
+
if (hasProtocol) {
|
|
19
|
+
code = code.replace(/__PROTO_SLASH__/g, '://')
|
|
20
|
+
}
|
|
21
|
+
return code
|
|
22
|
+
}
|
|
23
|
+
|
|
4
24
|
/**
|
|
5
25
|
* Check if a module specifier is a Node.js built-in
|
|
6
26
|
* @param {string} moduleName - The module specifier (e.g., 'fs', 'node:fs/promises')
|
|
@@ -211,6 +231,7 @@ function extractExportName(exportValue) {
|
|
|
211
231
|
}
|
|
212
232
|
|
|
213
233
|
module.exports = {
|
|
234
|
+
stripComments,
|
|
214
235
|
isBuiltIn,
|
|
215
236
|
isRelativeImport,
|
|
216
237
|
isRelativeImportWithQuotes,
|
|
@@ -532,4 +532,35 @@ export {
|
|
|
532
532
|
assert.equal(foundExports[0].exportAlias, 'myHandler', 'exportAlias should be "myHandler" without trailing comma')
|
|
533
533
|
})
|
|
534
534
|
|
|
535
|
+
test('should ignore commented-out exports', () => {
|
|
536
|
+
const code = `
|
|
537
|
+
// export const foo = 'foo'
|
|
538
|
+
/* export default bar */
|
|
539
|
+
/*
|
|
540
|
+
export const multiLine = 'test'
|
|
541
|
+
*/
|
|
542
|
+
export const realExport = 'real'
|
|
543
|
+
`
|
|
544
|
+
|
|
545
|
+
const foundExports = getExports(code)
|
|
546
|
+
|
|
547
|
+
assert.equal(foundExports.length, 1, 'Should only find 1 real export')
|
|
548
|
+
assert.equal(foundExports[0].exportName, 'realExport', 'Should find realExport')
|
|
549
|
+
})
|
|
550
|
+
|
|
551
|
+
test('should preserve URLs with :// in strings', () => {
|
|
552
|
+
const code = `
|
|
553
|
+
export const url = 'http://example.com/path'
|
|
554
|
+
export const https = 'https://secure.com'
|
|
555
|
+
export const real = 'value' // this comment should be stripped
|
|
556
|
+
`
|
|
557
|
+
|
|
558
|
+
const foundExports = getExports(code)
|
|
559
|
+
|
|
560
|
+
assert.equal(foundExports.length, 3, 'Should find 3 exports')
|
|
561
|
+
assert.equal(foundExports[0].exportName, 'url', 'Should find url export')
|
|
562
|
+
assert.equal(foundExports[1].exportName, 'https', 'Should find https export')
|
|
563
|
+
assert.equal(foundExports[2].exportName, 'real', 'Should find real export')
|
|
564
|
+
})
|
|
565
|
+
|
|
535
566
|
test.run()
|
|
@@ -412,4 +412,31 @@ import styles from './styles.css' with { type: 'css' }
|
|
|
412
412
|
assert.is(hasWithImport, true, 'Should have with import')
|
|
413
413
|
})
|
|
414
414
|
|
|
415
|
+
test('should ignore commented-out imports', () => {
|
|
416
|
+
const code = `
|
|
417
|
+
// import foo from 'foo'
|
|
418
|
+
/* import bar from 'bar' */
|
|
419
|
+
/*
|
|
420
|
+
import multiLine from 'multi'
|
|
421
|
+
*/
|
|
422
|
+
import realImport from 'real'
|
|
423
|
+
`
|
|
424
|
+
|
|
425
|
+
const importsFound = getImports(code)
|
|
426
|
+
|
|
427
|
+
assert.equal(importsFound.length, 1, 'Should only find 1 real import')
|
|
428
|
+
assert.equal(importsFound[0].from, 'real', 'Should find real import')
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
test('should preserve URLs with :// in strings', () => {
|
|
432
|
+
const code = `
|
|
433
|
+
import foo from 'foo' // http://example.com
|
|
434
|
+
`
|
|
435
|
+
|
|
436
|
+
const importsFound = getImports(code)
|
|
437
|
+
|
|
438
|
+
assert.equal(importsFound.length, 1, 'Should find 1 import')
|
|
439
|
+
assert.equal(importsFound[0].from, 'foo', 'Should find foo import')
|
|
440
|
+
})
|
|
441
|
+
|
|
415
442
|
test.run()
|