|
1 | | -/* eslint-disable max-params */ |
2 | | - |
3 | | -// Node.js |
| 1 | +// Import Node.js Dependencies |
4 | 2 | import fs from "node:fs/promises"; |
5 | 3 | import path from "node:path"; |
6 | 4 |
|
7 | | -// Third-party |
8 | | -import filenamify from "filenamify"; |
9 | | - |
10 | | -// Internal |
11 | | -import { analyzeJavaScriptFile, Utils } from "../index"; |
12 | | - |
13 | | -// CONSTANTS |
14 | | -const kJavaScriptExtensions = new Set([".js", ".mjs", ".cjs"]); |
15 | | -const kJSONSpace = 2; |
16 | | -const kDefaultReplacement = "#"; |
| 5 | +// Import Third-party Dependencies |
| 6 | +import { tarball } from "@nodesecure/scanner"; |
17 | 7 |
|
18 | | -let count = 0; |
| 8 | +// Import Internal Dependencies |
| 9 | +import { IRunOptions } from "../index.js"; |
19 | 10 |
|
20 | | -export async function init() { |
21 | | - const baseDir = path.join(process.cwd(), "results"); |
| 11 | +type Context = { |
| 12 | + outdir: string; |
| 13 | + count: number; |
| 14 | +}; |
22 | 15 |
|
23 | | - const analysisDir = path.join(baseDir, "packages"); |
24 | | - const errorDir = path.join(baseDir, "parsing-errors"); |
25 | | - await fs.mkdir(analysisDir, { recursive: true }); |
26 | | - await fs.mkdir(errorDir, { recursive: true }); |
| 16 | +export async function init(): Promise<Context> { |
| 17 | + const outdir = path.join(process.cwd(), "nsf-results"); |
| 18 | + await fs.mkdir(outdir, { recursive: true }); |
27 | 19 |
|
28 | | - return { analysisDir, errorDir }; |
| 20 | + return { outdir, count: 0 }; |
29 | 21 | } |
30 | 22 |
|
31 | 23 | export async function close() { |
32 | 24 | console.log("close triggered"); |
33 | 25 | } |
34 | 26 |
|
35 | | -type RunOptions = { |
36 | | - name: string; |
37 | | - location: string; |
38 | | - root: string; |
39 | | -}; |
| 27 | +export async function run(ctx: Context, options: IRunOptions) { |
| 28 | + const { name, location } = options; |
40 | 29 |
|
41 | | -export async function run(ctx: Ctx, { name, location, root }: RunOptions) { |
42 | 30 | try { |
43 | | - console.log(`handle package name: ${name}, count: ${count++}`); |
44 | | - const { files } = await Utils.getTarballComposition(location); |
45 | | - const jsFiles = files.filter((name) => kJavaScriptExtensions.has(path.extname(name))); |
46 | | - const toWait: any[] = []; |
47 | | - |
48 | | - for (const file of jsFiles) { |
49 | | - const cleanName = filenamify( |
50 | | - path.relative(root, file).slice(name.length), |
51 | | - { replacement: kDefaultReplacement } |
52 | | - ); |
53 | | - toWait.push(runASTAnalysis(ctx, cleanName, file, name)); |
54 | | - } |
| 31 | + console.log(`handle package name: ${name}, count: ${ctx.count++}`); |
| 32 | + const result = await tarball.scanPackage(location, name); |
55 | 33 |
|
56 | | - const results = (await Promise.allSettled(toWait)) |
57 | | - .filter(({ status }) => status === "fulfilled") |
58 | | - .map((p) => (p as PromiseFulfilledResult<unknown>).value); |
59 | | - |
60 | | - const content = JSON.stringify( |
61 | | - Object.assign({}, ...results), |
62 | | - null, |
63 | | - kJSONSpace |
| 34 | + const fileName = path.join(ctx.outdir, name.replace(/\//g, "__")) + ".json"; |
| 35 | + await fs.writeFile( |
| 36 | + fileName, |
| 37 | + JSON.stringify(result, null, 2) |
64 | 38 | ); |
65 | | - |
66 | | - const fileName = |
67 | | - path.join(ctx.analysisDir, name.replace(/\//g, "__")) + ".json"; |
68 | | - await fs.writeFile(fileName, content); |
69 | 39 | } |
70 | 40 | finally { |
71 | 41 | await fs.rmdir(location, { recursive: true }); |
72 | 42 | } |
73 | 43 | } |
74 | | - |
75 | | -async function dumpParsingError( |
76 | | - ctx: Ctx, |
77 | | - error: { code: string; message: string; stack: string } | string, |
78 | | - cleanName: string, |
79 | | - pkgName: string |
80 | | -) { |
81 | | - try { |
82 | | - const stack = typeof error === "string" ? "" : error.stack.split("\n"); |
83 | | - const dumpStr = JSON.stringify( |
84 | | - { |
85 | | - pkgName, |
86 | | - code: typeof error === "string" ? null : error.code || null, |
87 | | - message: typeof error === "string" ? error : error.message || "", |
88 | | - stack |
89 | | - }, |
90 | | - null, |
91 | | - kJSONSpace |
92 | | - ); |
93 | | - |
94 | | - await fs.writeFile(path.join(ctx.errorDir, `${cleanName}.json`), dumpStr); |
95 | | - } |
96 | | - catch { |
97 | | - // ignore |
98 | | - } |
99 | | -} |
100 | | - |
101 | | -type Ctx = { analysisDir: string; errorDir: string }; |
102 | | - |
103 | | -async function runASTAnalysis( |
104 | | - ctx: Ctx, |
105 | | - cleanName: string, |
106 | | - location: string, |
107 | | - pkgName: string |
108 | | -) { |
109 | | - try { |
110 | | - const ASTAnalysis = await analyzeJavaScriptFile(location); |
111 | | - // @ts-ignore |
112 | | - const deps = [...ASTAnalysis.dependencies]; |
113 | | - const warnings = ASTAnalysis.warnings; |
114 | | - |
115 | | - return { [cleanName]: { warnings, deps } }; |
116 | | - } |
117 | | - catch (error: any) { |
118 | | - if (error.name === "SyntaxError") { |
119 | | - return {}; |
120 | | - } |
121 | | - await dumpParsingError(ctx, error, cleanName, pkgName); |
122 | | - |
123 | | - return {}; |
124 | | - } |
125 | | -} |
0 commit comments