@davidwells/extract-deps 0.0.4 → 0.0.5

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.
Files changed (33) hide show
  1. package/examples/verify-basic.js +43 -0
  2. package/examples/verify-build-graph.js +58 -0
  3. package/examples/verify-build-order.js +113 -0
  4. package/examples/verify-find-dependents.js +74 -0
  5. package/examples/verify-impact-analysis.js +97 -0
  6. package/package.json +5 -1
  7. package/src/dep-graph.js +277 -0
  8. package/tests/dep-graph.test.js +213 -0
  9. package/tests/fixtures/cjs-deep-example/d-one.js +10 -0
  10. package/tests/fixtures/cjs-deep-example/d-sub-folder/d-sub-sub-folder/d-three.js +7 -0
  11. package/tests/fixtures/cjs-deep-example/d-sub-folder/d-two-a.js +8 -0
  12. package/tests/fixtures/cjs-deep-example/d-sub-folder/d-two-b.js +8 -0
  13. package/tests/fixtures/cjs-deep-example/d-sub-folder/d-two.js +8 -0
  14. package/tests/fixtures/cjs-deep-example/index.js +8 -0
  15. package/tests/fixtures/cjs-example/index.js +8 -0
  16. package/tests/fixtures/cjs-example/one.js +9 -0
  17. package/tests/fixtures/cjs-example/sub-folder/sub-sub-folder/three.js +6 -0
  18. package/tests/fixtures/cjs-example/sub-folder/two.js +8 -0
  19. package/tests/fixtures/cjs-parent.js +5 -0
  20. package/tests/fixtures/esm-fixture/index.js +8 -0
  21. package/tests/fixtures/esm-fixture/one.js +9 -0
  22. package/tests/fixtures/esm-fixture/sub-folder/sub-sub-folder/three.js +6 -0
  23. package/tests/fixtures/esm-fixture/sub-folder/two.js +8 -0
  24. package/types/dep-graph.d.ts +22 -0
  25. package/types/dep-graph.d.ts.map +1 -0
  26. package/types/get-cjs-exports.d.ts +35 -0
  27. package/types/get-cjs-exports.d.ts.map +1 -0
  28. package/types/get-exports.d.ts +3 -1
  29. package/types/get-exports.d.ts.map +1 -1
  30. package/types/index.d.ts +7 -3
  31. package/types/index.d.ts.map +1 -1
  32. package/types/utils.d.ts +2 -1
  33. package/types/utils.d.ts.map +1 -1
@@ -0,0 +1,43 @@
1
+ // Basic verification of dependency graph
2
+ const path = require('path')
3
+ const { depGraph } = require('../src/dep-graph')
4
+
5
+ const cjsFixture = path.resolve(__dirname, '../tests/fixtures/cjs-example/index.js')
6
+ const esmFixture = path.resolve(__dirname, '../tests/fixtures/esm-fixture/index.js')
7
+
8
+ console.log('Verifying CJS fixture...')
9
+ try {
10
+ const graph = depGraph(cjsFixture)
11
+ console.log('✓ CJS fixture is valid - all imports resolve correctly')
12
+ console.log(` Found ${graph.size} files in dependency graph\n`)
13
+ } catch (error) {
14
+ console.error('✗ CJS fixture has errors:')
15
+ console.error(error.message)
16
+ }
17
+
18
+ console.log('Verifying ESM fixture...')
19
+ try {
20
+ const graph = depGraph(esmFixture)
21
+ console.log('✓ ESM fixture is valid - all imports resolve correctly')
22
+ console.log(` Found ${graph.size} files in dependency graph\n`)
23
+ } catch (error) {
24
+ console.error('✗ ESM fixture has errors:')
25
+ console.error(error.message)
26
+ }
27
+
28
+ console.log('Verifying with throwOnFirstError option...')
29
+ try {
30
+ depGraph(cjsFixture, { throwOnFirstError: true })
31
+ console.log('✓ Validation passed (would have thrown on first error)\n')
32
+ } catch (error) {
33
+ console.error('✗ First error encountered:')
34
+ console.error(error.message)
35
+ }
36
+
37
+ console.log('Building graph without verification (faster)...')
38
+ const graph = depGraph(cjsFixture, { verifyGraph: false })
39
+ console.log(`✓ Graph built without verification - ${graph.size} files`)
40
+
41
+ console.log('\nVerification only (no graph building)...')
42
+ depGraph(cjsFixture, { buildGraph: false })
43
+ console.log('✓ Verification passed (no graph returned)')
@@ -0,0 +1,58 @@
1
+ // Build and explore dependency graph
2
+ const path = require('path')
3
+ const { depGraph } = require('../src/dep-graph')
4
+
5
+ const fixture = path.resolve(__dirname, '../tests/fixtures/cjs-deep-example/index.js')
6
+
7
+ console.log('Building dependency graph...\n')
8
+
9
+ const graph = depGraph(fixture)
10
+
11
+ console.log('=== Dependency Graph ===\n')
12
+
13
+ // Display the graph
14
+ for (const [file, deps] of graph) {
15
+ const fileName = path.basename(file)
16
+ const fileDir = path.relative(__dirname, path.dirname(file))
17
+
18
+ console.log(`${fileName} (${fileDir})`)
19
+
20
+ if (deps.length === 0) {
21
+ console.log(' └─ (no dependencies - leaf node)\n')
22
+ } else {
23
+ deps.forEach((dep, idx) => {
24
+ const depName = path.basename(dep)
25
+ const isLast = idx === deps.length - 1
26
+ const prefix = isLast ? ' └─' : ' ├─'
27
+ console.log(`${prefix} ${depName}`)
28
+ })
29
+ console.log()
30
+ }
31
+ }
32
+
33
+ console.log(`\nTotal files: ${graph.size}`)
34
+
35
+ // Find leaf nodes (files with no dependencies)
36
+ const leafNodes = []
37
+ for (const [file, deps] of graph) {
38
+ if (deps.length === 0) {
39
+ leafNodes.push(path.basename(file))
40
+ }
41
+ }
42
+
43
+ console.log(`Leaf nodes: ${leafNodes.join(', ')}`)
44
+
45
+ // Find root nodes (files not depended on by others in the graph)
46
+ const allDeps = new Set()
47
+ for (const deps of graph.values()) {
48
+ deps.forEach(dep => allDeps.add(dep))
49
+ }
50
+
51
+ const rootNodes = []
52
+ for (const file of graph.keys()) {
53
+ if (!allDeps.has(file)) {
54
+ rootNodes.push(path.basename(file))
55
+ }
56
+ }
57
+
58
+ console.log(`Root nodes: ${rootNodes.join(', ')}`)
@@ -0,0 +1,113 @@
1
+ // Calculate build order using topological sort
2
+ const path = require('path')
3
+ const { depGraph } = require('../src/dep-graph')
4
+
5
+ /**
6
+ * Calculate build order using topological sort (Kahn's algorithm)
7
+ * @param {Map<string, string[]>} graph - Dependency graph
8
+ * @returns {string[]} - Files in build order (dependencies first)
9
+ */
10
+ function calculateBuildOrder(graph) {
11
+ // Calculate in-degree (number of dependencies) for each file
12
+ const inDegree = new Map()
13
+ for (const [file, deps] of graph) {
14
+ inDegree.set(file, deps.length)
15
+ }
16
+
17
+ // Queue of files with no dependencies (can be built first)
18
+ const queue = []
19
+ for (const [file, degree] of inDegree) {
20
+ if (degree === 0) {
21
+ queue.push(file)
22
+ }
23
+ }
24
+
25
+ const buildOrder = []
26
+
27
+ while (queue.length > 0) {
28
+ const file = queue.shift()
29
+ buildOrder.push(file)
30
+
31
+ // Find all files that depend on this file and decrement their in-degree
32
+ for (const [dependent, deps] of graph) {
33
+ if (deps.includes(file)) {
34
+ const newDegree = inDegree.get(dependent) - 1
35
+ inDegree.set(dependent, newDegree)
36
+ if (newDegree === 0) {
37
+ queue.push(dependent)
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ return buildOrder
44
+ }
45
+
46
+ /**
47
+ * Group files by build level (parallel build opportunities)
48
+ * @param {Map<string, string[]>} graph - Dependency graph
49
+ * @returns {Array<string[]>} - Array of levels, each containing files that can be built in parallel
50
+ */
51
+ function calculateBuildLevels(graph) {
52
+ const inDegree = new Map()
53
+ for (const [file, deps] of graph) {
54
+ inDegree.set(file, deps.length)
55
+ }
56
+
57
+ const levels = []
58
+ const processed = new Set()
59
+
60
+ while (processed.size < graph.size) {
61
+ const currentLevel = []
62
+
63
+ for (const [file, degree] of inDegree) {
64
+ if (degree === 0 && !processed.has(file)) {
65
+ currentLevel.push(file)
66
+ }
67
+ }
68
+
69
+ if (currentLevel.length === 0) break
70
+
71
+ levels.push(currentLevel)
72
+
73
+ for (const file of currentLevel) {
74
+ processed.add(file)
75
+ for (const [dependent, deps] of graph) {
76
+ if (deps.includes(file)) {
77
+ inDegree.set(dependent, inDegree.get(dependent) - 1)
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ return levels
84
+ }
85
+
86
+ const fixture = path.resolve(__dirname, '../tests/fixtures/cjs-deep-example/index.js')
87
+ const graph = depGraph(fixture)
88
+
89
+ console.log('=== Build Order Analysis ===\n')
90
+
91
+ // Sequential build order
92
+ const buildOrder = calculateBuildOrder(graph)
93
+ console.log('Sequential build order (dependencies first):\n')
94
+ buildOrder.forEach((file, index) => {
95
+ console.log(`${index + 1}. ${path.basename(file)}`)
96
+ })
97
+
98
+ console.log('\n=== Parallel Build Opportunities ===\n')
99
+
100
+ // Parallel build levels
101
+ const levels = calculateBuildLevels(graph)
102
+ console.log('Files grouped by build level (same level can build in parallel):\n')
103
+
104
+ levels.forEach((level, index) => {
105
+ console.log(`Level ${index + 1}: (${level.length} file${level.length === 1 ? '' : 's'})`)
106
+ level.forEach(file => {
107
+ console.log(` - ${path.basename(file)}`)
108
+ })
109
+ console.log()
110
+ })
111
+
112
+ console.log(`Total build levels: ${levels.length}`)
113
+ console.log(`Maximum parallelism: ${Math.max(...levels.map(l => l.length))} files`)
@@ -0,0 +1,74 @@
1
+ // Find all files that depend on a specific file
2
+ const path = require('path')
3
+ const { depGraph } = require('../src/dep-graph')
4
+
5
+ /**
6
+ * Find all files that directly depend on a target file
7
+ * @param {Map<string, string[]>} graph - Dependency graph
8
+ * @param {string} targetFile - File to find dependents for
9
+ * @returns {string[]} - Array of files that depend on targetFile
10
+ */
11
+ function findDirectDependents(graph, targetFile) {
12
+ const dependents = []
13
+ for (const [file, deps] of graph) {
14
+ if (deps.includes(targetFile)) {
15
+ dependents.push(file)
16
+ }
17
+ }
18
+ return dependents
19
+ }
20
+
21
+ /**
22
+ * Find all files that transitively depend on a target file
23
+ * @param {Map<string, string[]>} graph - Dependency graph
24
+ * @param {string} targetFile - File to find dependents for
25
+ * @returns {Set<string>} - Set of all files that depend on targetFile (directly or indirectly)
26
+ */
27
+ function findAllDependents(graph, targetFile) {
28
+ const allDependents = new Set()
29
+ const queue = [targetFile]
30
+
31
+ while (queue.length > 0) {
32
+ const current = queue.shift()
33
+ const directDependents = findDirectDependents(graph, current)
34
+
35
+ for (const dependent of directDependents) {
36
+ if (!allDependents.has(dependent)) {
37
+ allDependents.add(dependent)
38
+ queue.push(dependent)
39
+ }
40
+ }
41
+ }
42
+
43
+ return allDependents
44
+ }
45
+
46
+ const fixture = path.resolve(__dirname, '../tests/fixtures/cjs-deep-example/index.js')
47
+ const graph = depGraph(fixture)
48
+
49
+ // Find a commonly used file
50
+ const targetFile = Array.from(graph.keys()).find(key => key.includes('d-three.js'))
51
+
52
+ if (targetFile) {
53
+ console.log(`Analyzing dependencies for: ${path.basename(targetFile)}\n`)
54
+
55
+ const directDeps = findDirectDependents(graph, targetFile)
56
+ console.log('Direct dependents:')
57
+ if (directDeps.length === 0) {
58
+ console.log(' (none)')
59
+ } else {
60
+ directDeps.forEach(dep => {
61
+ console.log(` - ${path.basename(dep)}`)
62
+ })
63
+ }
64
+
65
+ const allDeps = findAllDependents(graph, targetFile)
66
+ console.log(`\nAll dependents (transitive): ${allDeps.size}`)
67
+ if (allDeps.size > 0) {
68
+ Array.from(allDeps).forEach(dep => {
69
+ console.log(` - ${path.basename(dep)}`)
70
+ })
71
+ }
72
+
73
+ console.log(`\nImpact: Changing this file affects ${allDeps.size} other file(s)`)
74
+ }
@@ -0,0 +1,97 @@
1
+ // Analyze impact of changing files in the dependency graph
2
+ const path = require('path')
3
+ const { depGraph } = require('../src/dep-graph')
4
+
5
+ /**
6
+ * Calculate impact metrics for each file in the graph
7
+ * @param {Map<string, string[]>} graph - Dependency graph
8
+ * @returns {Map<string, object>} - Map of file paths to impact metrics
9
+ */
10
+ function analyzeImpact(graph) {
11
+ const impact = new Map()
12
+
13
+ for (const file of graph.keys()) {
14
+ // Count direct dependencies
15
+ const directDeps = graph.get(file).length
16
+
17
+ // Count direct dependents
18
+ let directDependents = 0
19
+ for (const [_, deps] of graph) {
20
+ if (deps.includes(file)) {
21
+ directDependents++
22
+ }
23
+ }
24
+
25
+ // Calculate transitive dependents
26
+ const transitiveDependents = new Set()
27
+ const queue = [file]
28
+ const visited = new Set([file])
29
+
30
+ while (queue.length > 0) {
31
+ const current = queue.shift()
32
+ for (const [f, deps] of graph) {
33
+ if (deps.includes(current) && !visited.has(f)) {
34
+ visited.add(f)
35
+ transitiveDependents.add(f)
36
+ queue.push(f)
37
+ }
38
+ }
39
+ }
40
+
41
+ impact.set(file, {
42
+ directDeps,
43
+ directDependents,
44
+ transitiveDependents: transitiveDependents.size,
45
+ isLeaf: directDeps === 0,
46
+ isRoot: directDependents === 0
47
+ })
48
+ }
49
+
50
+ return impact
51
+ }
52
+
53
+ const fixture = path.resolve(__dirname, '../tests/fixtures/cjs-deep-example/index.js')
54
+ const graph = depGraph(fixture)
55
+
56
+ console.log('=== Dependency Impact Analysis ===\n')
57
+
58
+ const impact = analyzeImpact(graph)
59
+
60
+ // Sort files by impact (most dependents first)
61
+ const sortedFiles = Array.from(impact.entries())
62
+ .sort((a, b) => b[1].transitiveDependents - a[1].transitiveDependents)
63
+
64
+ console.log('Files sorted by impact (files that affect the most others):\n')
65
+
66
+ sortedFiles.forEach(([file, metrics], index) => {
67
+ const fileName = path.basename(file)
68
+ const impactLevel = metrics.transitiveDependents > 3 ? '🔴 HIGH' :
69
+ metrics.transitiveDependents > 1 ? '🟡 MEDIUM' :
70
+ '🟢 LOW'
71
+
72
+ console.log(`${index + 1}. ${fileName}`)
73
+ console.log(` Impact: ${impactLevel}`)
74
+ console.log(` Direct dependencies: ${metrics.directDeps}`)
75
+ console.log(` Direct dependents: ${metrics.directDependents}`)
76
+ console.log(` Total files affected: ${metrics.transitiveDependents}`)
77
+
78
+ if (metrics.isLeaf) {
79
+ console.log(` Type: Leaf node (no dependencies)`)
80
+ }
81
+ if (metrics.isRoot) {
82
+ console.log(` Type: Root node (nothing depends on it)`)
83
+ }
84
+
85
+ console.log()
86
+ })
87
+
88
+ console.log('=== Summary ===')
89
+ console.log(`Total files: ${graph.size}`)
90
+
91
+ const leafNodes = Array.from(impact.values()).filter(m => m.isLeaf).length
92
+ const rootNodes = Array.from(impact.values()).filter(m => m.isRoot).length
93
+ const highImpact = sortedFiles.filter(([_, m]) => m.transitiveDependents > 3).length
94
+
95
+ console.log(`Leaf nodes: ${leafNodes}`)
96
+ console.log(`Root nodes: ${rootNodes}`)
97
+ console.log(`High impact files: ${highImpact}`)
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "@davidwells/extract-deps",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Get imports and requires from a codebase without AST",
5
5
  "main": "src/index.js",
6
+ "exports": {
7
+ ".": "./src/index.js",
8
+ "./dep-graph": "./src/dep-graph.js"
9
+ },
6
10
  "types": "types/index.d.ts",
7
11
  "author": "David Wells",
8
12
  "license": "MIT",
@@ -0,0 +1,277 @@
1
+ // Build dependency graph and optionally verify imports
2
+ const path = require('path')
3
+ const fs = require('fs')
4
+ const { extractDeps } = require('./index')
5
+
6
+ function fsExistsSync(path) {
7
+ try {
8
+ fs.accessSync(path, fs.constants.F_OK)
9
+ return true
10
+ } catch (error) {
11
+ return false
12
+ }
13
+ }
14
+
15
+ /**
16
+ * Resolve a relative import to an actual file path
17
+ * @param {string} baseDir - Directory containing the importing file
18
+ * @param {string} importPath - The relative import path
19
+ * @returns {string|null} - Resolved file path or null if not found
20
+ */
21
+ function resolveImportPath(baseDir, importPath) {
22
+ const possibleExtensions = ['.js', '.mjs', '.ts', '.json', '']
23
+
24
+ // Try direct file resolution
25
+ for (const ext of possibleExtensions) {
26
+ const testPath = path.resolve(baseDir, importPath + ext)
27
+ if (fsExistsSync(testPath)) {
28
+ return testPath
29
+ }
30
+ }
31
+
32
+ // Try directory with index file
33
+ const indexExtensions = ['/index.js', '/index.mjs', '/index.ts']
34
+ for (const indexExt of indexExtensions) {
35
+ const testPath = path.resolve(baseDir, importPath + indexExt)
36
+ if (fsExistsSync(testPath)) {
37
+ return testPath
38
+ }
39
+ }
40
+
41
+ return null
42
+ }
43
+
44
+ /**
45
+ * Verify that imported values are exported from a file
46
+ * @param {object} dep - Dependency object with import info
47
+ * @param {object} targetDeps - Extracted deps from the target file
48
+ * @param {string} targetPath - Path to the target file
49
+ * @param {string} sourcePath - Path to the file doing the importing
50
+ * @param {Array<Error>} errors - Array to collect errors
51
+ * @param {boolean} throwOnFirstError - Whether to throw immediately on first error
52
+ */
53
+ function verifyImportedValuesExist(dep, targetDeps, targetPath, sourcePath, errors, throwOnFirstError) {
54
+ // Check if this is a destructured import
55
+ if (dep.definitions && dep.definitions.expectsDestructuring && dep.definitions.destructuredParameters) {
56
+ const importedNames = dep.definitions.destructuredParameters.map(p => p.name.replace(/,$/, ''))
57
+
58
+ // Check CommonJS exports
59
+ const exportedNames = new Set()
60
+ if (targetDeps.moduleExports && targetDeps.moduleExports.length > 0) {
61
+ for (const exp of targetDeps.moduleExports) {
62
+ if (exp.exportType === 'named') {
63
+ exportedNames.add(exp.exportName)
64
+ } else if (exp.exportType === 'default' && exp.keys) {
65
+ exp.keys.forEach(key => exportedNames.add(key))
66
+ }
67
+ }
68
+ }
69
+
70
+ // Check ESM exports
71
+ if (targetDeps.exports && targetDeps.exports.length > 0) {
72
+ for (const exp of targetDeps.exports) {
73
+ const exportedName = exp.exportAlias || exp.exportName
74
+ if (exportedName) {
75
+ exportedNames.add(exportedName)
76
+ }
77
+ }
78
+ }
79
+
80
+ // Verify each imported name is exported
81
+ for (const importedName of importedNames) {
82
+ if (!exportedNames.has(importedName)) {
83
+ const error = new Error(
84
+ `Import not found: "${importedName}" is not exported from "${targetPath}".\n` +
85
+ `Import statement: ${dep.line}\n` +
86
+ `Importing from: ${sourcePath}\n` +
87
+ `Available exports: ${Array.from(exportedNames).join(', ') || 'none'}`
88
+ )
89
+ if (throwOnFirstError) {
90
+ throw error
91
+ }
92
+ errors.push(error)
93
+ }
94
+ }
95
+ }
96
+ // For non-destructured imports, just verify there's a default export
97
+ else {
98
+ const hasDefaultExport =
99
+ (targetDeps.moduleExports && targetDeps.moduleExports.length > 0) ||
100
+ (targetDeps.exports && targetDeps.exports.some(exp => exp.exportType === 'default'))
101
+
102
+ if (!hasDefaultExport) {
103
+ const error = new Error(
104
+ `Import not found: "${targetPath}" does not have a default export.\n` +
105
+ `Import statement: ${dep.line}\n` +
106
+ `Importing from: ${sourcePath}`
107
+ )
108
+ if (throwOnFirstError) {
109
+ throw error
110
+ }
111
+ errors.push(error)
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Recursively build dependency graph and optionally validate imports
118
+ * @param {string} filePath - File to process
119
+ * @param {Array<Error>} errors - Array to collect errors
120
+ * @param {boolean} throwOnFirstError - Whether to throw immediately on first error
121
+ * @param {boolean} verify - Whether to verify imports/exports
122
+ * @param {Map<string, string[]>|null} graph - Optional map to collect dependency graph
123
+ * @param {Set} visited - Set of already-visited file paths to avoid cycles
124
+ */
125
+ function buildGraphRecursively(filePath, errors, throwOnFirstError, verify, graph = null, visited = new Set()) {
126
+ // Avoid infinite loops
127
+ const normalizedPath = fs.realpathSync(filePath)
128
+ if (visited.has(normalizedPath)) {
129
+ return
130
+ }
131
+ visited.add(normalizedPath)
132
+
133
+ // Initialize graph entry for this file if building graph
134
+ if (graph !== null && !graph.has(normalizedPath)) {
135
+ graph.set(normalizedPath, [])
136
+ }
137
+
138
+ // Read and extract deps from this file
139
+ const content = fs.readFileSync(filePath, 'utf8')
140
+ const deps = extractDeps(content)
141
+
142
+ // Collect all relative dependencies
143
+ const relativeDeps = []
144
+ if (deps.requires && deps.requires.length > 0) {
145
+ relativeDeps.push(...deps.requires.filter(req => req.isRelative))
146
+ }
147
+ if (deps.imports && deps.imports.length > 0) {
148
+ relativeDeps.push(...deps.imports.filter(imp => imp.isRelative))
149
+ }
150
+
151
+ // Process each relative dependency
152
+ const fileDir = path.dirname(filePath)
153
+ for (const dep of relativeDeps) {
154
+ const { from, line } = dep
155
+
156
+ // Resolve the import path
157
+ const resolvedPath = resolveImportPath(fileDir, from)
158
+
159
+ if (!resolvedPath) {
160
+ const error = new Error(
161
+ `"${line}" could not be resolved in ${filePath}\n\n` +
162
+ `Fix by ensuring "${path.resolve(fileDir, from)}" exists and is valid.`
163
+ )
164
+ if (throwOnFirstError) {
165
+ throw error
166
+ }
167
+ errors.push(error)
168
+ continue
169
+ }
170
+
171
+ // Add edge to graph if building
172
+ if (graph !== null) {
173
+ const normalizedResolvedPath = fs.realpathSync(resolvedPath)
174
+ graph.get(normalizedPath).push(normalizedResolvedPath)
175
+ }
176
+
177
+ // Verify imports if verification is enabled
178
+ if (verify) {
179
+ // Extract deps from the imported file
180
+ const targetContent = fs.readFileSync(resolvedPath, 'utf8')
181
+ const targetDeps = extractDeps(targetContent)
182
+
183
+ // Verify the imported values are exported
184
+ verifyImportedValuesExist(dep, targetDeps, resolvedPath, filePath, errors, throwOnFirstError)
185
+ }
186
+
187
+ // Recursively process the imported file
188
+ buildGraphRecursively(resolvedPath, errors, throwOnFirstError, verify, graph, visited)
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Build dependency graph for a file and its dependencies
194
+ * @param {string} filePath - File to analyze
195
+ * @param {object} options - Options
196
+ * @param {boolean} [options.buildGraph] - If true, build and return dependency graph. Default: true
197
+ * @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
198
+ * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
199
+ * @returns {Map<string, string[]>|undefined} - Dependency graph where keys are file paths and values are arrays of dependency paths. Returns undefined if buildGraph is false.
200
+ */
201
+ function depGraph(filePath, options = {}) {
202
+ const { buildGraph = true, verifyGraph = true, throwOnFirstError = false } = options
203
+ const errors = []
204
+ const graph = buildGraph ? new Map() : null
205
+
206
+ buildGraphRecursively(filePath, errors, throwOnFirstError, verifyGraph, graph)
207
+
208
+ if (errors.length > 0) {
209
+ const errorMessage = errors.map((err, idx) => `Error ${idx + 1}:\n${err.message}`).join('\n\n')
210
+ throw new Error(`Found ${errors.length} validation error${errors.length === 1 ? '' : 's'}:\n\n${errorMessage}`)
211
+ }
212
+
213
+ if (buildGraph) {
214
+ return graph
215
+ }
216
+ }
217
+
218
+
219
+ /**
220
+ * Get all dependency file paths in build order (dependencies first), deduplicated
221
+ * @param {string} filePath - Entry file path
222
+ * @param {object} options - Options to pass to depGraph
223
+ * @returns {string[]} - Array of unique dependency file paths in topological order
224
+ */
225
+ function resolveDepPaths(filePath, options = {}) {
226
+ const graph = depGraph(filePath, options)
227
+
228
+ // Calculate in-degree (number of dependencies) for each file
229
+ const inDegree = new Map()
230
+ for (const [file, deps] of graph) {
231
+ inDegree.set(file, deps.length)
232
+ }
233
+
234
+ // Queue of files with no dependencies (can be processed first)
235
+ const queue = []
236
+ for (const [file, degree] of inDegree) {
237
+ if (degree === 0) {
238
+ queue.push(file)
239
+ }
240
+ }
241
+
242
+ const buildOrder = []
243
+
244
+ while (queue.length > 0) {
245
+ const file = queue.shift()
246
+ buildOrder.push(file)
247
+
248
+ // Find all files that depend on this file and decrement their in-degree
249
+ for (const [dependent, deps] of graph) {
250
+ if (deps.includes(file)) {
251
+ const newDegree = inDegree.get(dependent) - 1
252
+ inDegree.set(dependent, newDegree)
253
+ if (newDegree === 0) {
254
+ queue.push(dependent)
255
+ }
256
+ }
257
+ }
258
+ }
259
+
260
+ return buildOrder
261
+ }
262
+
263
+
264
+ if (require.main === module) {
265
+ const entry = path.resolve(__dirname, '../tests/fixtures/cjs-deep-example/index.js')
266
+ const graph = depGraph(entry)
267
+ console.log('graph', graph)
268
+ const depPaths = Array.from(graph.values()).flat()
269
+ console.log('depPaths', depPaths)
270
+ const depPathsProper = resolveDepPaths(entry)
271
+ console.log('depPathsProper', depPathsProper)
272
+ }
273
+
274
+ module.exports = {
275
+ depGraph,
276
+ resolveDepPaths
277
+ }
@@ -0,0 +1,213 @@
1
+ // Build and verify dependency graph
2
+ const { test } = require('uvu')
3
+ const assert = require('uvu/assert')
4
+ const path = require('path')
5
+ const { depGraph, resolveDepPaths } = require('../src/dep-graph.js')
6
+
7
+ const CJS_FIXTURE_PATH = path.resolve(__dirname, './fixtures/cjs-example/index.js')
8
+ const ESM_FIXTURE_PATH = path.resolve(__dirname, './fixtures/esm-fixture/index.js')
9
+ const CJS_DEEP_FIXTURE_PATH = path.resolve(__dirname, './fixtures/cjs-deep-example/index.js')
10
+
11
+ test('should build graph by default', () => {
12
+ const graph = depGraph(CJS_FIXTURE_PATH)
13
+ assert.ok(graph instanceof Map, 'Should return a Map by default')
14
+ assert.ok(graph.size > 0, 'Graph should not be empty')
15
+ })
16
+
17
+ test('should verify by default', () => {
18
+ assert.not.throws(() => {
19
+ depGraph(CJS_FIXTURE_PATH)
20
+ }, 'Should verify imports by default')
21
+ })
22
+
23
+ test('should build graph for valid CJS fixture', () => {
24
+ const graph = depGraph(CJS_FIXTURE_PATH)
25
+
26
+ assert.ok(graph instanceof Map, 'Should return a Map')
27
+ assert.ok(graph.size > 0, 'Graph should not be empty')
28
+
29
+ const entries = Array.from(graph.keys())
30
+ const hasIndexFile = entries.some(key => key.includes('cjs-example/index.js'))
31
+ assert.ok(hasIndexFile, 'Graph should include the index.js file')
32
+ })
33
+
34
+ test('should build graph for valid ESM fixture', () => {
35
+ const graph = depGraph(ESM_FIXTURE_PATH)
36
+
37
+ assert.ok(graph instanceof Map, 'Should return a Map')
38
+ assert.ok(graph.size > 0, 'Graph should not be empty')
39
+
40
+ const entries = Array.from(graph.keys())
41
+ const hasIndexFile = entries.some(key => key.includes('esm-fixture/index.js'))
42
+ assert.ok(hasIndexFile, 'Graph should include the index.js file')
43
+ })
44
+
45
+ test('should return undefined when buildGraph is false', () => {
46
+ const result = depGraph(CJS_FIXTURE_PATH, { buildGraph: false })
47
+ assert.is(result, undefined, 'Should return undefined when buildGraph is false')
48
+ })
49
+
50
+ test('should build correct dependency graph for CJS fixture', () => {
51
+ const graph = depGraph(CJS_FIXTURE_PATH)
52
+
53
+ const indexPath = Array.from(graph.keys()).find(key => key.includes('cjs-example/index.js'))
54
+ assert.ok(indexPath, 'Should have index.js in graph')
55
+
56
+ const indexDeps = graph.get(indexPath)
57
+ assert.ok(Array.isArray(indexDeps), 'Dependencies should be an array')
58
+ assert.is(indexDeps.length, 1, 'index.js should have 1 dependency')
59
+
60
+ const hasOneDep = indexDeps.some(dep => dep.includes('one.js'))
61
+ assert.ok(hasOneDep, 'index.js should depend on one.js')
62
+ })
63
+
64
+ test('should build correct dependency graph for ESM fixture', () => {
65
+ const graph = depGraph(ESM_FIXTURE_PATH)
66
+
67
+ const indexPath = Array.from(graph.keys()).find(key => key.includes('esm-fixture/index.js'))
68
+ assert.ok(indexPath, 'Should have index.js in graph')
69
+
70
+ const indexDeps = graph.get(indexPath)
71
+ assert.ok(Array.isArray(indexDeps), 'Dependencies should be an array')
72
+ assert.is(indexDeps.length, 1, 'index.js should have 1 dependency')
73
+
74
+ const hasOneDep = indexDeps.some(dep => dep.includes('one.js'))
75
+ assert.ok(hasOneDep, 'index.js should depend on one.js')
76
+ })
77
+
78
+ test('should include all files in graph', () => {
79
+ const graph = depGraph(CJS_FIXTURE_PATH)
80
+
81
+ const filePaths = Array.from(graph.keys())
82
+
83
+ // Should have index, one, two, three
84
+ assert.ok(filePaths.some(p => p.includes('index.js')), 'Should include index.js')
85
+ assert.ok(filePaths.some(p => p.includes('one.js')), 'Should include one.js')
86
+ assert.ok(filePaths.some(p => p.includes('two.js')), 'Should include two.js')
87
+ assert.ok(filePaths.some(p => p.includes('three.js')), 'Should include three.js')
88
+ })
89
+
90
+ test('should handle files with no dependencies', () => {
91
+ const graph = depGraph(CJS_FIXTURE_PATH)
92
+
93
+ const threePath = Array.from(graph.keys()).find(key => key.includes('three.js'))
94
+ assert.ok(threePath, 'Should have three.js in graph')
95
+
96
+ const threeDeps = graph.get(threePath)
97
+ assert.ok(Array.isArray(threeDeps), 'Dependencies should be an array')
98
+ assert.is(threeDeps.length, 0, 'three.js should have no dependencies')
99
+ })
100
+
101
+ test('should skip verification when verifyGraph is false', () => {
102
+ const graph = depGraph(CJS_FIXTURE_PATH, { verifyGraph: false })
103
+
104
+ assert.ok(graph instanceof Map, 'Should return a Map')
105
+ assert.ok(graph.size > 0, 'Graph should not be empty')
106
+ })
107
+
108
+ test('should work with all options combined', () => {
109
+ const graph = depGraph(CJS_FIXTURE_PATH, {
110
+ buildGraph: true,
111
+ verifyGraph: false,
112
+ throwOnFirstError: false
113
+ })
114
+
115
+ assert.ok(graph instanceof Map, 'Should return a Map')
116
+ assert.ok(graph.size > 0, 'Graph should not be empty')
117
+ })
118
+
119
+ // resolveDepPaths tests
120
+ test('resolveDepPaths should return an array', () => {
121
+ const deps = resolveDepPaths(CJS_FIXTURE_PATH)
122
+ assert.ok(Array.isArray(deps), 'Should return an array')
123
+ })
124
+
125
+ test('resolveDepPaths should return deduplicated paths', () => {
126
+ const deps = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
127
+ const uniqueDeps = [...new Set(deps)]
128
+
129
+ assert.is(deps.length, uniqueDeps.length, 'Should not have duplicate paths')
130
+ })
131
+
132
+ test('resolveDepPaths should include all files from graph', () => {
133
+ const graph = depGraph(CJS_FIXTURE_PATH)
134
+ const deps = resolveDepPaths(CJS_FIXTURE_PATH)
135
+
136
+ assert.is(deps.length, graph.size, 'Should have same number of files as graph')
137
+
138
+ // All graph keys should be in deps
139
+ for (const key of graph.keys()) {
140
+ assert.ok(deps.includes(key), `Should include ${path.basename(key)}`)
141
+ }
142
+ })
143
+
144
+ test('resolveDepPaths should return paths in topological order (dependencies first)', () => {
145
+ const deps = resolveDepPaths(CJS_FIXTURE_PATH)
146
+
147
+ // Find indices
148
+ const threeIdx = deps.findIndex(p => p.includes('three.js'))
149
+ const twoIdx = deps.findIndex(p => p.includes('two.js'))
150
+ const oneIdx = deps.findIndex(p => p.includes('one.js'))
151
+ const indexIdx = deps.findIndex(p => p.includes('index.js'))
152
+
153
+ // three.js has no dependencies, should come first
154
+ assert.ok(threeIdx < twoIdx, 'three.js should come before two.js')
155
+ assert.ok(twoIdx < oneIdx, 'two.js should come before one.js')
156
+ assert.ok(oneIdx < indexIdx, 'one.js should come before index.js')
157
+ })
158
+
159
+ test('resolveDepPaths should work with ESM fixtures', () => {
160
+ const deps = resolveDepPaths(ESM_FIXTURE_PATH)
161
+
162
+ assert.ok(Array.isArray(deps), 'Should return an array')
163
+ assert.ok(deps.length > 0, 'Should have dependencies')
164
+
165
+ // Check files are included
166
+ assert.ok(deps.some(p => p.includes('index.js')), 'Should include index.js')
167
+ assert.ok(deps.some(p => p.includes('one.js')), 'Should include one.js')
168
+ assert.ok(deps.some(p => p.includes('two.js')), 'Should include two.js')
169
+ assert.ok(deps.some(p => p.includes('three.js')), 'Should include three.js')
170
+ })
171
+
172
+ test('resolveDepPaths should have entry point last', () => {
173
+ const deps = resolveDepPaths(CJS_FIXTURE_PATH)
174
+ const lastFile = deps[deps.length - 1]
175
+
176
+ assert.ok(lastFile.includes('index.js'), 'Entry point (index.js) should be last')
177
+ })
178
+
179
+ test('resolveDepPaths should have leaf nodes first', () => {
180
+ const deps = resolveDepPaths(CJS_FIXTURE_PATH)
181
+ const firstFile = deps[0]
182
+
183
+ // three.js has no dependencies - it's a leaf node
184
+ assert.ok(firstFile.includes('three.js'), 'Leaf node (three.js) should be first')
185
+ })
186
+
187
+ test('resolveDepPaths should handle complex graphs with shared dependencies', () => {
188
+ const deps = resolveDepPaths(CJS_DEEP_FIXTURE_PATH)
189
+
190
+ // Should be deduplicated
191
+ const uniqueDeps = [...new Set(deps)]
192
+ assert.is(deps.length, uniqueDeps.length, 'Should deduplicate shared dependencies')
193
+
194
+ // Find d-three.js which is shared by d-two.js, d-two-a.js, d-two-b.js
195
+ const threeIdx = deps.findIndex(p => p.includes('d-three.js'))
196
+ const twoIdx = deps.findIndex(p => p.includes('d-two.js'))
197
+ const twoAIdx = deps.findIndex(p => p.includes('d-two-a.js'))
198
+ const twoBIdx = deps.findIndex(p => p.includes('d-two-b.js'))
199
+
200
+ // d-three.js should come before all files that depend on it
201
+ assert.ok(threeIdx < twoIdx, 'd-three.js should come before d-two.js')
202
+ assert.ok(threeIdx < twoAIdx, 'd-three.js should come before d-two-a.js')
203
+ assert.ok(threeIdx < twoBIdx, 'd-three.js should come before d-two-b.js')
204
+ })
205
+
206
+ test('resolveDepPaths should pass options to depGraph', () => {
207
+ const deps = resolveDepPaths(CJS_FIXTURE_PATH, { verifyGraph: false })
208
+
209
+ assert.ok(Array.isArray(deps), 'Should work with options')
210
+ assert.ok(deps.length > 0, 'Should return dependencies')
211
+ })
212
+
213
+ test.run()
@@ -0,0 +1,10 @@
1
+ const { two, three } = require('./d-sub-folder/d-two')
2
+ const { twoA } = require('./d-sub-folder/d-two-a')
3
+ const { twoB } = require('./d-sub-folder/d-two-b')
4
+ const one = 'one'
5
+
6
+ module.exports = {
7
+ one,
8
+ two,
9
+ three
10
+ }
@@ -0,0 +1,7 @@
1
+ const { parent } = require('../../../cjs-parent')
2
+
3
+ const three = 'three'
4
+
5
+ module.exports = {
6
+ three
7
+ }
@@ -0,0 +1,8 @@
1
+ const { three } = require('./d-sub-sub-folder/d-three')
2
+
3
+ const twoA = 'twoA'
4
+
5
+ module.exports = {
6
+ twoA,
7
+ three
8
+ }
@@ -0,0 +1,8 @@
1
+ const { three } = require('./d-sub-sub-folder/d-three')
2
+
3
+ const twoB = 'twoB'
4
+
5
+ module.exports = {
6
+ twoB,
7
+ three
8
+ }
@@ -0,0 +1,8 @@
1
+ const { three } = require('./d-sub-sub-folder/d-three')
2
+
3
+ const two = 'twoB'
4
+
5
+ module.exports = {
6
+ two,
7
+ three
8
+ }
@@ -0,0 +1,8 @@
1
+ const lodash = require('lodash')
2
+ const { one, two, three } = require('./d-one')
3
+
4
+ module.exports = {
5
+ one,
6
+ two,
7
+ three
8
+ }
@@ -0,0 +1,8 @@
1
+ const lodash = require('lodash')
2
+ const { one, two, three } = require('./one')
3
+
4
+ module.exports = {
5
+ one,
6
+ two,
7
+ three
8
+ }
@@ -0,0 +1,9 @@
1
+ const { two, three } = require('./sub-folder/two')
2
+
3
+ const one = 'one'
4
+
5
+ module.exports = {
6
+ one,
7
+ two,
8
+ three
9
+ }
@@ -0,0 +1,6 @@
1
+
2
+ const three = 'three'
3
+
4
+ module.exports = {
5
+ three
6
+ }
@@ -0,0 +1,8 @@
1
+ const { three } = require('./sub-sub-folder/three')
2
+
3
+ const two = 'two'
4
+
5
+ module.exports = {
6
+ two,
7
+ three
8
+ }
@@ -0,0 +1,5 @@
1
+ const parent = 'parent'
2
+
3
+ module.exports = {
4
+ parent
5
+ }
@@ -0,0 +1,8 @@
1
+ import lodash from 'lodash'
2
+ import { one, two, three } from './one.js'
3
+
4
+ export {
5
+ one,
6
+ two,
7
+ three
8
+ }
@@ -0,0 +1,9 @@
1
+ import { two, three } from './sub-folder/two.js'
2
+
3
+ const one = 'one'
4
+
5
+ export {
6
+ one,
7
+ two,
8
+ three
9
+ }
@@ -0,0 +1,6 @@
1
+
2
+ const three = 'three'
3
+
4
+ export {
5
+ three
6
+ }
@@ -0,0 +1,8 @@
1
+ import { three } from './sub-sub-folder/three.js'
2
+
3
+ const two = 'two'
4
+
5
+ export {
6
+ two,
7
+ three
8
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Build dependency graph for a file and its dependencies
3
+ * @param {string} filePath - File to analyze
4
+ * @param {object} options - Options
5
+ * @param {boolean} [options.buildGraph] - If true, build and return dependency graph. Default: true
6
+ * @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
7
+ * @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
8
+ * @returns {Map<string, string[]>|undefined} - Dependency graph where keys are file paths and values are arrays of dependency paths. Returns undefined if buildGraph is false.
9
+ */
10
+ export function depGraph(filePath: string, options?: {
11
+ buildGraph?: boolean;
12
+ verifyGraph?: boolean;
13
+ throwOnFirstError?: boolean;
14
+ }): Map<string, string[]> | undefined;
15
+ /**
16
+ * Get all dependency file paths in build order (dependencies first), deduplicated
17
+ * @param {string} filePath - Entry file path
18
+ * @param {object} options - Options to pass to depGraph
19
+ * @returns {string[]} - Array of unique dependency file paths in topological order
20
+ */
21
+ export function resolveDepPaths(filePath: string, options?: object): string[];
22
+ //# sourceMappingURL=dep-graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dep-graph.d.ts","sourceRoot":"","sources":["../src/dep-graph.js"],"names":[],"mappings":"AA+LA;;;;;;;;GAQG;AACH,mCAPW,MAAM;IAEY,UAAU,GAA5B,OAAO;IACW,WAAW,GAA7B,OAAO;IACW,iBAAiB,GAAnC,OAAO;IACL,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC,GAAC,SAAS,CAiB3C;AAGD;;;;;GAKG;AACH,0CAJW,MAAM,YACN,MAAM,GACJ,MAAM,EAAE,CAsCpB"}
@@ -0,0 +1,35 @@
1
+ export function getCjsExports(code: any): any[];
2
+ export function getModuleExportsAssignment(originalText?: string, sanitizedText?: string): {
3
+ line: string;
4
+ exportType: string;
5
+ exportName: string;
6
+ exportDefinitionName: any;
7
+ exportValue: string;
8
+ index: number;
9
+ isExport: boolean;
10
+ }[];
11
+ export function getModuleExportsProperty(originalText?: string, sanitizedText?: string): {
12
+ line: string;
13
+ exportType: string;
14
+ exportName: string;
15
+ exportValue: string;
16
+ index: number;
17
+ isExport: boolean;
18
+ }[];
19
+ export function getExportsProperty(originalText?: string, sanitizedText?: string): {
20
+ line: string;
21
+ exportType: string;
22
+ exportName: string;
23
+ exportValue: string;
24
+ index: number;
25
+ isExport: boolean;
26
+ }[];
27
+ export function getObjectAssignExports(originalText?: string, sanitizedText?: string): {
28
+ line: string;
29
+ exportType: string;
30
+ exportName: string;
31
+ exportValue: string;
32
+ index: number;
33
+ isExport: boolean;
34
+ }[];
35
+ //# sourceMappingURL=get-cjs-exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-cjs-exports.d.ts","sourceRoot":"","sources":["../src/get-cjs-exports.js"],"names":[],"mappings":"AA+BA,gDAuBC;AA+BD;;;;;;;;IAqGC;AAED;;;;;;;IAqBC;AAED;;;;;;;IAqBC;AAED;;;;;;;IAiDC"}
@@ -2,7 +2,8 @@ export function getExports(code: any, options?: {}): any[];
2
2
  export function getDefaultExports(targetText?: string): {
3
3
  line: string;
4
4
  exportType: string;
5
- exportName: any;
5
+ exportName: string;
6
+ exportDefinitionName: any;
6
7
  exportValue: string;
7
8
  index: number;
8
9
  isExport: boolean;
@@ -42,6 +43,7 @@ export function getAssertionExports(targetText?: string): {
42
43
  exportType: string;
43
44
  exportName: string;
44
45
  definitions: any;
46
+ keys: any;
45
47
  from: string;
46
48
  assertion: string;
47
49
  assertionType: string;
@@ -1 +1 @@
1
- {"version":3,"file":"get-exports.d.ts","sourceRoot":"","sources":["../src/get-exports.js"],"names":[],"mappings":"AAiBA,2DAsBC;AAED;;;;;;;IA4BC;AAED;;;;;;IAeC;AAED,uEAmBC;AAED;;;;;;IAeC;AAED;;;;;;;IAgBC;AAED;;;;;;IAeC;AAED;;;;;;;;;;;IAuBC"}
1
+ {"version":3,"file":"get-exports.d.ts","sourceRoot":"","sources":["../src/get-exports.js"],"names":[],"mappings":"AAiBA,2DA+BC;AAED;;;;;;;;IAqDC;AAED;;;;;;IAeC;AAED,uEAuBC;AAED;;;;;;IAeC;AAED;;;;;;;IAgBC;AAED;;;;;;IAeC;AAED;;;;;;;;;;;;IA0BC"}
package/types/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export function extractDeps(code: any): {
1
+ export function extractDeps(code: any, filePath?: string): {
2
2
  imports: {
3
3
  line: string;
4
4
  varType: string;
@@ -9,6 +9,7 @@ export function extractDeps(code: any): {
9
9
  isImport: boolean;
10
10
  isRelative: boolean;
11
11
  }[];
12
+ exports: any[];
12
13
  requires: {
13
14
  line: string;
14
15
  varType: string;
@@ -20,8 +21,11 @@ export function extractDeps(code: any): {
20
21
  isRelative: boolean;
21
22
  isDynamic: boolean;
22
23
  }[];
23
- exports: any[];
24
+ moduleExports: any[];
24
25
  };
26
+ import { hasESMSyntax } from "./detect-syntax";
27
+ import { hasCJSSyntax } from "./detect-syntax";
28
+ import { detectSyntax } from "./detect-syntax";
25
29
  import { getRequires } from "./get-requires";
26
30
  import { getDynamicRequires } from "./get-requires";
27
31
  import { getStaticRequires } from "./get-requires";
@@ -35,5 +39,5 @@ import { getNamedDeclarationExports } from "./get-exports";
35
39
  import { getAllExports } from "./get-exports";
36
40
  import { getNamespaceExports } from "./get-exports";
37
41
  import { getTypeExports } from "./get-exports";
38
- export { getRequires, getDynamicRequires, getStaticRequires, getImports, getStaticImports, getDynamicImports, getExports, getDefaultExports, getNamedExports, getNamedDeclarationExports, getAllExports, getNamespaceExports, getTypeExports };
42
+ export { hasESMSyntax, hasCJSSyntax, detectSyntax, getRequires, getDynamicRequires, getStaticRequires, getImports, getStaticImports, getDynamicImports, getExports, getDefaultExports, getNamedExports, getNamedDeclarationExports, getAllExports, getNamespaceExports, getTypeExports };
39
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;;;;;;;;EAQC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;;;;;;;;;EAgBC"}
package/types/utils.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export function isRelativeImport(importLocation: any): boolean;
2
2
  export function isRelativeImportWithQuotes(importLocation: any): boolean;
3
- export function getNames(names: any): any;
3
+ export function getNames(names: any, aliasKey?: string): any;
4
+ export function extractExportName(exportValue: any): any;
4
5
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAEA,+DAEC;AAED,yEAKC;AAED,0CA2CC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AAEA,+DAEC;AAED,yEAKC;AAgFD,6DA+DC;AAGD,yDAqCC"}