@davidwells/extract-deps 0.0.6 → 0.0.8
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/examples/verify-basic.js
CHANGED
package/package.json
CHANGED
package/src/dep-graph.js
CHANGED
|
@@ -14,6 +14,14 @@ function fsExistsSync(path) {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
function isFileSync(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
return fs.statSync(filePath).isFile()
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return false
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
/**
|
|
18
26
|
* Resolve a relative import to an actual file path
|
|
19
27
|
* @param {string} baseDir - Directory containing the importing file
|
|
@@ -23,10 +31,10 @@ function fsExistsSync(path) {
|
|
|
23
31
|
function resolveImportPath(baseDir, importPath) {
|
|
24
32
|
const possibleExtensions = ['.js', '.mjs', '.ts', '.json', '']
|
|
25
33
|
|
|
26
|
-
// Try direct file resolution
|
|
34
|
+
// Try direct file resolution (must be a file, not directory)
|
|
27
35
|
for (const ext of possibleExtensions) {
|
|
28
36
|
const testPath = path.resolve(baseDir, importPath + ext)
|
|
29
|
-
if (
|
|
37
|
+
if (isFileSync(testPath)) {
|
|
30
38
|
return testPath
|
|
31
39
|
}
|
|
32
40
|
}
|
|
@@ -124,16 +132,18 @@ function verifyImportedValuesExist(dep, targetDeps, targetPath, sourcePath, erro
|
|
|
124
132
|
* @param {boolean} throwOnFirstError - Whether to throw immediately on first error
|
|
125
133
|
* @param {boolean} verify - Whether to verify imports/exports
|
|
126
134
|
* @param {boolean} verifyNodeModules - Whether to verify node_modules can be resolved
|
|
135
|
+
* @param {boolean} includeNodeModules - Whether to include node_modules in the graph
|
|
127
136
|
* @param {Map<string, string[]>|null} graph - Optional map to collect dependency graph
|
|
128
137
|
* @param {Set} visited - Set of already-visited file paths to avoid cycles
|
|
129
138
|
*/
|
|
130
139
|
function buildGraphRecursively(
|
|
131
|
-
filePath,
|
|
132
|
-
errors,
|
|
133
|
-
throwOnFirstError,
|
|
134
|
-
verify,
|
|
135
|
-
verifyNodeModules,
|
|
136
|
-
|
|
140
|
+
filePath,
|
|
141
|
+
errors,
|
|
142
|
+
throwOnFirstError,
|
|
143
|
+
verify,
|
|
144
|
+
verifyNodeModules,
|
|
145
|
+
includeNodeModules,
|
|
146
|
+
graph = null,
|
|
137
147
|
visited = new Set(),
|
|
138
148
|
) {
|
|
139
149
|
// Avoid infinite loops
|
|
@@ -163,7 +173,7 @@ function buildGraphRecursively(
|
|
|
163
173
|
|
|
164
174
|
// Collect all non-relative dependencies (node_modules)
|
|
165
175
|
const nodeModuleDeps = []
|
|
166
|
-
if (verifyNodeModules) {
|
|
176
|
+
if (verifyNodeModules || includeNodeModules) {
|
|
167
177
|
if (deps.requires && deps.requires.length > 0) {
|
|
168
178
|
nodeModuleDeps.push(...deps.requires.filter(req => !req.isRelative))
|
|
169
179
|
}
|
|
@@ -209,7 +219,14 @@ function buildGraphRecursively(
|
|
|
209
219
|
}
|
|
210
220
|
|
|
211
221
|
// Recursively process the imported file
|
|
212
|
-
buildGraphRecursively(resolvedPath, errors, throwOnFirstError, verify, verifyNodeModules, graph, visited)
|
|
222
|
+
buildGraphRecursively(resolvedPath, errors, throwOnFirstError, verify, verifyNodeModules, includeNodeModules, graph, visited)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Add node_modules to graph if enabled
|
|
226
|
+
if (includeNodeModules && graph !== null) {
|
|
227
|
+
for (const dep of nodeModuleDeps) {
|
|
228
|
+
graph.get(normalizedPath).push(dep.from)
|
|
229
|
+
}
|
|
213
230
|
}
|
|
214
231
|
|
|
215
232
|
// Verify node_modules dependencies if enabled
|
|
@@ -247,20 +264,22 @@ function buildGraphRecursively(
|
|
|
247
264
|
* @param {boolean} [options.buildGraph] - If true, build and return dependency graph. Default: true
|
|
248
265
|
* @param {boolean} [options.verifyGraph] - If true, verify imports/exports. Default: true
|
|
249
266
|
* @param {boolean} [options.verifyNodeModules] - If true, verify node_modules packages can be resolved. Default: false
|
|
267
|
+
* @param {boolean} [options.includeNodeModules] - If true, include node_modules package names in the graph. Default: false
|
|
250
268
|
* @param {boolean} [options.throwOnFirstError] - If true, throw immediately on first error. Default: false
|
|
251
|
-
* @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.
|
|
269
|
+
* @returns {Map<string, string[]>|undefined} - Dependency graph where keys are file paths and values are arrays of dependency paths (or package names if includeNodeModules). Returns undefined if buildGraph is false.
|
|
252
270
|
*/
|
|
253
271
|
function depGraph(filePath, options = {}) {
|
|
254
|
-
const {
|
|
255
|
-
buildGraph = true,
|
|
256
|
-
verifyGraph = true,
|
|
257
|
-
verifyNodeModules = false,
|
|
272
|
+
const {
|
|
273
|
+
buildGraph = true,
|
|
274
|
+
verifyGraph = true,
|
|
275
|
+
verifyNodeModules = false,
|
|
276
|
+
includeNodeModules = false,
|
|
258
277
|
throwOnFirstError = false,
|
|
259
278
|
} = options
|
|
260
279
|
const errors = []
|
|
261
280
|
const graph = buildGraph ? new Map() : null
|
|
262
281
|
|
|
263
|
-
buildGraphRecursively(filePath, errors, throwOnFirstError, verifyGraph, verifyNodeModules, graph)
|
|
282
|
+
buildGraphRecursively(filePath, errors, throwOnFirstError, verifyGraph, verifyNodeModules, includeNodeModules, graph)
|
|
264
283
|
|
|
265
284
|
if (errors.length > 0) {
|
|
266
285
|
const errorMessage = errors.map((err, idx) => `Dep graph error:\n ${err.message}`).join('\n')
|
|
@@ -323,7 +342,7 @@ function resolveDepPaths(filePath, options = {}) {
|
|
|
323
342
|
if (require.main === module) {
|
|
324
343
|
const entry = path.resolve(__dirname, '../tests/fixtures/cjs-deep-example/index.js')
|
|
325
344
|
const graph = depGraph(entry, {
|
|
326
|
-
|
|
345
|
+
includeNodeModules: true,
|
|
327
346
|
throwOnFirstError: true
|
|
328
347
|
})
|
|
329
348
|
console.log('graph', graph)
|
package/src/index.js
CHANGED
|
@@ -50,6 +50,19 @@ if (require.main === module) {
|
|
|
50
50
|
}
|
|
51
51
|
`
|
|
52
52
|
|
|
53
|
+
const code2 = `
|
|
54
|
+
// Get users Lambda handler
|
|
55
|
+
import _ from 'lodash'
|
|
56
|
+
|
|
57
|
+
export async function handler(event, context) {
|
|
58
|
+
const data = { message: 'get function called' }
|
|
59
|
+
return {
|
|
60
|
+
statusCode: 200,
|
|
61
|
+
body: JSON.stringify(_.omit(data, [])),
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
`
|
|
65
|
+
|
|
53
66
|
const failCase = `
|
|
54
67
|
const { test } = require('uvu')
|
|
55
68
|
const assert = require('uvu/assert')
|
|
@@ -65,7 +78,7 @@ const config = await import('./config.js')
|
|
|
65
78
|
const lerna = require('lerna')
|
|
66
79
|
const { execSync, spawnSync } = require('child_process')
|
|
67
80
|
`
|
|
68
|
-
const result = extractDeps(
|
|
81
|
+
const result = extractDeps(code2)
|
|
69
82
|
|
|
70
83
|
const { imports, requires } = result
|
|
71
84
|
|
package/tests/dep-graph.test.js
CHANGED
|
@@ -355,4 +355,31 @@ module.exports = { missing1, missing2 }
|
|
|
355
355
|
}
|
|
356
356
|
})
|
|
357
357
|
|
|
358
|
+
// Directory to index.js resolution tests
|
|
359
|
+
const DIR_INDEX_FIXTURE_PATH = path.resolve(__dirname, './fixtures/dir-index-example/entry.js')
|
|
360
|
+
|
|
361
|
+
test('should resolve directory import to index.js', () => {
|
|
362
|
+
const graph = depGraph(DIR_INDEX_FIXTURE_PATH)
|
|
363
|
+
|
|
364
|
+
assert.ok(graph instanceof Map, 'Should return a Map')
|
|
365
|
+
assert.ok(graph.size === 2, 'Graph should have 2 files (entry.js and shared-pkg/index.js)')
|
|
366
|
+
|
|
367
|
+
const entries = Array.from(graph.keys())
|
|
368
|
+
const hasEntry = entries.some(key => key.includes('entry.js'))
|
|
369
|
+
const hasIndex = entries.some(key => key.includes('shared-pkg/index.js'))
|
|
370
|
+
|
|
371
|
+
assert.ok(hasEntry, 'Graph should include entry.js')
|
|
372
|
+
assert.ok(hasIndex, 'Graph should resolve directory to index.js')
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
test('resolveDepPaths should work with directory imports', () => {
|
|
376
|
+
const deps = resolveDepPaths(DIR_INDEX_FIXTURE_PATH)
|
|
377
|
+
|
|
378
|
+
assert.ok(Array.isArray(deps), 'Should return an array')
|
|
379
|
+
assert.is(deps.length, 2, 'Should have 2 files')
|
|
380
|
+
|
|
381
|
+
assert.ok(deps.some(p => p.includes('shared-pkg/index.js')), 'Should include resolved index.js')
|
|
382
|
+
assert.ok(deps.some(p => p.includes('entry.js')), 'Should include entry.js')
|
|
383
|
+
})
|
|
384
|
+
|
|
358
385
|
test.run()
|