ai-trust 0.1.2 → 0.2.0
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 +25 -2
- package/dist/api/client.d.ts +30 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +20 -0
- package/dist/api/client.js.map +1 -1
- package/dist/commands/audit.d.ts +2 -1
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +101 -4
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/batch.d.ts.map +1 -1
- package/dist/commands/batch.js +17 -2
- package/dist/commands/batch.js.map +1 -1
- package/dist/commands/check.d.ts +4 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +154 -10
- package/dist/commands/check.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/output/formatter.d.ts +2 -0
- package/dist/output/formatter.d.ts.map +1 -1
- package/dist/output/formatter.js +41 -3
- package/dist/output/formatter.js.map +1 -1
- package/dist/scanner/downloader.d.ts +15 -0
- package/dist/scanner/downloader.d.ts.map +1 -0
- package/dist/scanner/downloader.js +63 -0
- package/dist/scanner/downloader.js.map +1 -0
- package/dist/scanner/hma.d.ts +37 -0
- package/dist/scanner/hma.d.ts.map +1 -0
- package/dist/scanner/hma.js +90 -0
- package/dist/scanner/hma.js.map +1 -0
- package/dist/scanner/index.d.ts +24 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +55 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/utils/parser.d.ts.map +1 -1
- package/dist/utils/parser.js +11 -3
- package/dist/utils/parser.js.map +1 -1
- package/dist/utils/prompt.d.ts +9 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +31 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/resolve.d.ts +22 -0
- package/dist/utils/resolve.d.ts.map +1 -0
- package/dist/utils/resolve.js +50 -0
- package/dist/utils/resolve.js.map +1 -0
- package/package.json +1 -1
package/dist/output/formatter.js
CHANGED
|
@@ -41,7 +41,6 @@ function trustLevelColor(level) {
|
|
|
41
41
|
export function formatCheckResult(answer) {
|
|
42
42
|
if (!answer.found) {
|
|
43
43
|
return [
|
|
44
|
-
"",
|
|
45
44
|
chalk.bold(` ${answer.name}`),
|
|
46
45
|
chalk.gray(` Type: ${answer.packageType || "unknown"}`),
|
|
47
46
|
chalk.gray(" Status: Not found in registry"),
|
|
@@ -51,7 +50,6 @@ export function formatCheckResult(answer) {
|
|
|
51
50
|
const colorVerdict = verdictColor(answer.verdict);
|
|
52
51
|
const colorTrust = trustLevelColor(answer.trustLevel);
|
|
53
52
|
const lines = [
|
|
54
|
-
"",
|
|
55
53
|
chalk.bold(` ${answer.name}`),
|
|
56
54
|
` Type: ${answer.packageType || "unknown"}`,
|
|
57
55
|
` Verdict: ${colorVerdict(answer.verdict.toUpperCase())}`,
|
|
@@ -72,7 +70,6 @@ export function formatCheckResult(answer) {
|
|
|
72
70
|
}
|
|
73
71
|
export function formatBatchResults(response, minTrust) {
|
|
74
72
|
const lines = [];
|
|
75
|
-
lines.push("");
|
|
76
73
|
lines.push(chalk.bold(` Trust Audit: ${response.meta.total} packages queried, ${response.meta.found} found, ${response.meta.notFound} not found`));
|
|
77
74
|
lines.push("");
|
|
78
75
|
// Table header
|
|
@@ -126,6 +123,47 @@ export function formatBatchResults(response, minTrust) {
|
|
|
126
123
|
lines.push("");
|
|
127
124
|
return lines.join("\n");
|
|
128
125
|
}
|
|
126
|
+
export function formatScanResult(result) {
|
|
127
|
+
const colorVerdict = verdictColor(result.verdict);
|
|
128
|
+
const colorTrust = trustLevelColor(result.trustLevel);
|
|
129
|
+
const lines = [
|
|
130
|
+
chalk.bold(` ${result.packageName}`) +
|
|
131
|
+
chalk.gray(" (local scan)"),
|
|
132
|
+
` Verdict: ${colorVerdict(result.verdict.toUpperCase())}`,
|
|
133
|
+
` Trust Level: ${colorTrust(trustLevelLabel(result.trustLevel))} (${result.trustLevel}/4)`,
|
|
134
|
+
` Trust Score: ${result.trustScore.toFixed(2)}`,
|
|
135
|
+
` HMA Score: ${result.scan.score}/${result.scan.maxScore}`,
|
|
136
|
+
];
|
|
137
|
+
const failed = result.scan.findings.filter((f) => !f.passed);
|
|
138
|
+
if (failed.length > 0) {
|
|
139
|
+
lines.push("");
|
|
140
|
+
lines.push(chalk.bold(" Findings"));
|
|
141
|
+
const bySeverity = {
|
|
142
|
+
critical: failed.filter((f) => f.severity === "critical"),
|
|
143
|
+
high: failed.filter((f) => f.severity === "high"),
|
|
144
|
+
medium: failed.filter((f) => f.severity === "medium"),
|
|
145
|
+
low: failed.filter((f) => f.severity === "low"),
|
|
146
|
+
};
|
|
147
|
+
for (const [sev, items] of Object.entries(bySeverity)) {
|
|
148
|
+
if (items.length === 0)
|
|
149
|
+
continue;
|
|
150
|
+
const colorFn = sev === "critical"
|
|
151
|
+
? chalk.red
|
|
152
|
+
: sev === "high"
|
|
153
|
+
? chalk.yellow
|
|
154
|
+
: chalk.gray;
|
|
155
|
+
for (const item of items) {
|
|
156
|
+
lines.push(` ${colorFn(`[${sev.toUpperCase()}]`)} ${item.name}: ${item.message}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
lines.push("");
|
|
162
|
+
lines.push(chalk.green(" No security findings."));
|
|
163
|
+
}
|
|
164
|
+
lines.push("");
|
|
165
|
+
return lines.join("\n");
|
|
166
|
+
}
|
|
129
167
|
export function formatJson(data) {
|
|
130
168
|
return JSON.stringify(data, null, 2);
|
|
131
169
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/output/formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/output/formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package downloader - fetch npm tarballs and extract to temp directories.
|
|
3
|
+
*/
|
|
4
|
+
export interface DownloadResult {
|
|
5
|
+
/** Temporary directory containing the extracted package */
|
|
6
|
+
dir: string;
|
|
7
|
+
/** Cleanup function to remove the temp directory */
|
|
8
|
+
cleanup: () => Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Download an npm package tarball and extract it to a temp directory.
|
|
12
|
+
* Uses `npm pack --pack-destination` to fetch the tarball, then extracts it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function downloadPackage(name: string): Promise<DownloadResult>;
|
|
15
|
+
//# sourceMappingURL=downloader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"downloader.d.ts","sourceRoot":"","sources":["../../src/scanner/downloader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,CAAC,CAyDzB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package downloader - fetch npm tarballs and extract to temp directories.
|
|
3
|
+
*/
|
|
4
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
/**
|
|
11
|
+
* Download an npm package tarball and extract it to a temp directory.
|
|
12
|
+
* Uses `npm pack --pack-destination` to fetch the tarball, then extracts it.
|
|
13
|
+
*/
|
|
14
|
+
export async function downloadPackage(name) {
|
|
15
|
+
const tempDir = await mkdtemp(join(tmpdir(), "ai-trust-scan-"));
|
|
16
|
+
try {
|
|
17
|
+
// Use npm pack to download the tarball
|
|
18
|
+
const { stdout } = await execFileAsync("npm", ["pack", name, "--pack-destination", tempDir], { timeout: 60_000 });
|
|
19
|
+
const tarball = stdout.trim().split("\n").pop();
|
|
20
|
+
const tarballPath = join(tempDir, tarball);
|
|
21
|
+
// Extract the tarball
|
|
22
|
+
const extractDir = join(tempDir, "package");
|
|
23
|
+
await execFileAsync("tar", ["xzf", tarballPath, "-C", tempDir], {
|
|
24
|
+
timeout: 30_000,
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
dir: extractDir,
|
|
28
|
+
cleanup: async () => {
|
|
29
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
// Clean up on failure
|
|
35
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
36
|
+
// Extract a clean error message from npm's verbose stderr
|
|
37
|
+
let message;
|
|
38
|
+
if (err &&
|
|
39
|
+
typeof err === "object" &&
|
|
40
|
+
"stderr" in err &&
|
|
41
|
+
typeof err.stderr === "string") {
|
|
42
|
+
const stderr = err.stderr;
|
|
43
|
+
const notFound = stderr.includes("404") || stderr.includes("Not Found");
|
|
44
|
+
if (notFound) {
|
|
45
|
+
message = `Package "${name}" not found on npm. Verify the package name and try again.`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Extract the first meaningful npm error line
|
|
49
|
+
const errorLine = stderr
|
|
50
|
+
.split("\n")
|
|
51
|
+
.find((l) => l.startsWith("npm error") && !l.includes("A complete log"));
|
|
52
|
+
message = errorLine
|
|
53
|
+
? errorLine.replace(/^npm error\s*/, "")
|
|
54
|
+
: (err instanceof Error ? err.message : String(err));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
message = err instanceof Error ? err.message : String(err);
|
|
59
|
+
}
|
|
60
|
+
throw new Error(`Failed to download "${name}": ${message}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=downloader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/scanner/downloader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMA (HackMyAgent) subprocess runner.
|
|
3
|
+
* Detects availability and runs security scans against downloaded packages.
|
|
4
|
+
*/
|
|
5
|
+
export interface HmaScanResult {
|
|
6
|
+
score: number;
|
|
7
|
+
maxScore: number;
|
|
8
|
+
findings: HmaFinding[];
|
|
9
|
+
projectType: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
}
|
|
12
|
+
export interface HmaFinding {
|
|
13
|
+
checkId: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
category: string;
|
|
17
|
+
severity: "critical" | "high" | "medium" | "low";
|
|
18
|
+
passed: boolean;
|
|
19
|
+
message: string;
|
|
20
|
+
file?: string;
|
|
21
|
+
line?: number;
|
|
22
|
+
fix?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if HMA (hackmyagent) is available on the system.
|
|
26
|
+
* Tries npx first, then checks for global install.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isHmaAvailable(): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Run HMA security scan against a directory.
|
|
31
|
+
* Uses `npx hackmyagent secure --format json <dir>`.
|
|
32
|
+
*
|
|
33
|
+
* @returns Parsed scan results
|
|
34
|
+
* @throws If HMA is not available or scan fails to produce valid output
|
|
35
|
+
*/
|
|
36
|
+
export declare function runHmaScan(targetDir: string): Promise<HmaScanResult>;
|
|
37
|
+
//# sourceMappingURL=hma.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hma.d.ts","sourceRoot":"","sources":["../../src/scanner/hma.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CASvD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CA8BxB"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMA (HackMyAgent) subprocess runner.
|
|
3
|
+
* Detects availability and runs security scans against downloaded packages.
|
|
4
|
+
*/
|
|
5
|
+
import { execFile } from "node:child_process";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
/**
|
|
9
|
+
* Check if HMA (hackmyagent) is available on the system.
|
|
10
|
+
* Tries npx first, then checks for global install.
|
|
11
|
+
*/
|
|
12
|
+
export async function isHmaAvailable() {
|
|
13
|
+
try {
|
|
14
|
+
await execFileAsync("npx", ["hackmyagent", "--version"], {
|
|
15
|
+
timeout: 15_000,
|
|
16
|
+
});
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run HMA security scan against a directory.
|
|
25
|
+
* Uses `npx hackmyagent secure --format json <dir>`.
|
|
26
|
+
*
|
|
27
|
+
* @returns Parsed scan results
|
|
28
|
+
* @throws If HMA is not available or scan fails to produce valid output
|
|
29
|
+
*/
|
|
30
|
+
export async function runHmaScan(targetDir) {
|
|
31
|
+
try {
|
|
32
|
+
// HMA may exit non-zero when findings exist, so we handle that
|
|
33
|
+
const { stdout } = await execFileAsync("npx", ["hackmyagent", "secure", "--format", "json", targetDir], { timeout: 120_000 });
|
|
34
|
+
return parseHmaOutput(stdout);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
// HMA exits with code 1 when it finds issues but still outputs JSON
|
|
38
|
+
if (err &&
|
|
39
|
+
typeof err === "object" &&
|
|
40
|
+
"stdout" in err &&
|
|
41
|
+
typeof err.stdout === "string") {
|
|
42
|
+
const stdout = err.stdout;
|
|
43
|
+
if (stdout.trim()) {
|
|
44
|
+
try {
|
|
45
|
+
return parseHmaOutput(stdout);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Fall through to throw
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
53
|
+
throw new Error(`HMA scan failed: ${message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function parseHmaOutput(stdout) {
|
|
57
|
+
// HMA may output non-JSON lines before the JSON; find the JSON object
|
|
58
|
+
const lines = stdout.split("\n");
|
|
59
|
+
let jsonStr = "";
|
|
60
|
+
for (let i = 0; i < lines.length; i++) {
|
|
61
|
+
const line = lines[i].trim();
|
|
62
|
+
if (line.startsWith("{")) {
|
|
63
|
+
jsonStr = lines.slice(i).join("\n");
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!jsonStr) {
|
|
68
|
+
throw new Error("No JSON output found from HMA scan");
|
|
69
|
+
}
|
|
70
|
+
const raw = JSON.parse(jsonStr);
|
|
71
|
+
return {
|
|
72
|
+
score: raw.score ?? 0,
|
|
73
|
+
maxScore: raw.maxScore ?? 100,
|
|
74
|
+
findings: (raw.findings ?? []).map((f) => ({
|
|
75
|
+
checkId: f.checkId ?? "",
|
|
76
|
+
name: f.name ?? "",
|
|
77
|
+
description: f.description ?? "",
|
|
78
|
+
category: f.category ?? "",
|
|
79
|
+
severity: f.severity ?? "low",
|
|
80
|
+
passed: f.passed ?? true,
|
|
81
|
+
message: f.message ?? "",
|
|
82
|
+
file: f.file,
|
|
83
|
+
line: f.line,
|
|
84
|
+
fix: f.fix,
|
|
85
|
+
})),
|
|
86
|
+
projectType: raw.projectType ?? "unknown",
|
|
87
|
+
timestamp: raw.timestamp ?? new Date().toISOString(),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=hma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hma.js","sourceRoot":"","sources":["../../src/scanner/hma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scanner module - orchestrates package download, HMA scan, and cleanup.
|
|
3
|
+
*/
|
|
4
|
+
export { downloadPackage } from "./downloader.js";
|
|
5
|
+
export type { DownloadResult } from "./downloader.js";
|
|
6
|
+
export { isHmaAvailable, runHmaScan } from "./hma.js";
|
|
7
|
+
export type { HmaScanResult, HmaFinding } from "./hma.js";
|
|
8
|
+
import type { HmaScanResult } from "./hma.js";
|
|
9
|
+
export interface ScanResult {
|
|
10
|
+
packageName: string;
|
|
11
|
+
scan: HmaScanResult;
|
|
12
|
+
/** Trust score derived from HMA score (0.0-1.0) */
|
|
13
|
+
trustScore: number;
|
|
14
|
+
/** Trust level derived from scan (0-4) */
|
|
15
|
+
trustLevel: number;
|
|
16
|
+
/** Verdict derived from scan results */
|
|
17
|
+
verdict: "safe" | "warning" | "blocked";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Download a package, scan it with HMA, and return results.
|
|
21
|
+
* Cleans up the temp directory after scanning.
|
|
22
|
+
*/
|
|
23
|
+
export declare function scanPackage(name: string): Promise<ScanResult>;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,aAAa,CAAC;IACpB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,CAmBrB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scanner module - orchestrates package download, HMA scan, and cleanup.
|
|
3
|
+
*/
|
|
4
|
+
export { downloadPackage } from "./downloader.js";
|
|
5
|
+
export { isHmaAvailable, runHmaScan } from "./hma.js";
|
|
6
|
+
import { downloadPackage } from "./downloader.js";
|
|
7
|
+
import { runHmaScan } from "./hma.js";
|
|
8
|
+
/**
|
|
9
|
+
* Download a package, scan it with HMA, and return results.
|
|
10
|
+
* Cleans up the temp directory after scanning.
|
|
11
|
+
*/
|
|
12
|
+
export async function scanPackage(name) {
|
|
13
|
+
const download = await downloadPackage(name);
|
|
14
|
+
try {
|
|
15
|
+
const scan = await runHmaScan(download.dir);
|
|
16
|
+
const trustScore = scan.score / scan.maxScore;
|
|
17
|
+
const trustLevel = deriveTrustLevel(scan);
|
|
18
|
+
const verdict = deriveVerdict(scan);
|
|
19
|
+
return {
|
|
20
|
+
packageName: name,
|
|
21
|
+
scan,
|
|
22
|
+
trustScore,
|
|
23
|
+
trustLevel,
|
|
24
|
+
verdict,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
await download.cleanup();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function deriveTrustLevel(scan) {
|
|
32
|
+
const ratio = scan.score / scan.maxScore;
|
|
33
|
+
if (ratio >= 0.9)
|
|
34
|
+
return 3; // Scanned, high trust
|
|
35
|
+
if (ratio >= 0.7)
|
|
36
|
+
return 2; // Listed, moderate trust
|
|
37
|
+
if (ratio >= 0.4)
|
|
38
|
+
return 1; // Warning
|
|
39
|
+
return 0; // Blocked
|
|
40
|
+
}
|
|
41
|
+
function deriveVerdict(scan) {
|
|
42
|
+
const hasCritical = scan.findings.some((f) => !f.passed && f.severity === "critical");
|
|
43
|
+
const hasHigh = scan.findings.some((f) => !f.passed && f.severity === "high");
|
|
44
|
+
if (hasCritical)
|
|
45
|
+
return "blocked";
|
|
46
|
+
if (hasHigh)
|
|
47
|
+
return "warning";
|
|
48
|
+
const ratio = scan.score / scan.maxScore;
|
|
49
|
+
if (ratio >= 0.7)
|
|
50
|
+
return "safe";
|
|
51
|
+
if (ratio >= 0.4)
|
|
52
|
+
return "warning";
|
|
53
|
+
return "blocked";
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AActC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAY;IAEZ,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAE7C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEpC,OAAO;YACL,WAAW,EAAE,IAAI;YACjB,IAAI;YACJ,UAAU;YACV,UAAU;YACV,OAAO;SACR,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAmB;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;IACzC,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC,CAAC,sBAAsB;IAClD,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC,CAAC,yBAAyB;IACrD,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC,CAAC,UAAU;IACtC,OAAO,CAAC,CAAC,CAAC,UAAU;AACtB,CAAC;AAED,SAAS,aAAa,CAAC,IAAmB;IACxC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CACpC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,CAC9C,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,MAAM,CAC1C,CAAC;IAEF,IAAI,WAAW;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,OAAO;QAAE,OAAO,SAAS,CAAC;IAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;IACzC,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,SAAS,CAAC;IACnC,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/utils/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/utils/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,EAAE,CAAC,CAoBzB"}
|
package/dist/utils/parser.js
CHANGED
|
@@ -6,13 +6,21 @@ import { basename } from "node:path";
|
|
|
6
6
|
export async function parseDependencyFile(filePath) {
|
|
7
7
|
const fileName = basename(filePath);
|
|
8
8
|
const content = await readFile(filePath, "utf-8");
|
|
9
|
-
|
|
9
|
+
// Detect format by filename or extension
|
|
10
|
+
if (fileName.endsWith(".json")) {
|
|
10
11
|
return parsePackageJson(content);
|
|
11
12
|
}
|
|
12
|
-
if (fileName === "requirements
|
|
13
|
+
if (fileName.endsWith(".txt") || fileName === "requirements") {
|
|
14
|
+
return parseRequirementsTxt(content);
|
|
15
|
+
}
|
|
16
|
+
// Try JSON first, fall back to requirements.txt format
|
|
17
|
+
try {
|
|
18
|
+
JSON.parse(content);
|
|
19
|
+
return parsePackageJson(content);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
13
22
|
return parseRequirementsTxt(content);
|
|
14
23
|
}
|
|
15
|
-
throw new Error(`Unsupported dependency file: ${fileName}. Supported: package.json, requirements.txt`);
|
|
16
24
|
}
|
|
17
25
|
function parsePackageJson(content) {
|
|
18
26
|
const pkg = JSON.parse(content);
|
package/dist/utils/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/utils/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB;IAEhB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElD,IAAI,QAAQ,
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/utils/parser.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAgB;IAEhB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElD,yCAAyC;IACzC,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAC7D,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAG7B,CAAC;IAEF,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe;IAC3C,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAE5B,gCAAgC;QAChC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1D,SAAS;QACX,CAAC;QAED,mDAAmD;QACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACtE,IAAI,KAAK,EAAE,CAAC;YACV,uDAAuD;YACvD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACf,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive prompt utility for terminal input.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Ask a yes/no question. Returns true for yes (default), false for no.
|
|
6
|
+
* In non-interactive mode (no TTY), returns the default value.
|
|
7
|
+
*/
|
|
8
|
+
export declare function confirm(question: string, defaultYes?: boolean): Promise<boolean>;
|
|
9
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,UAAO,GAChB,OAAO,CAAC,OAAO,CAAC,CAsBlB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive prompt utility for terminal input.
|
|
3
|
+
*/
|
|
4
|
+
import { createInterface } from "node:readline";
|
|
5
|
+
/**
|
|
6
|
+
* Ask a yes/no question. Returns true for yes (default), false for no.
|
|
7
|
+
* In non-interactive mode (no TTY), returns the default value.
|
|
8
|
+
*/
|
|
9
|
+
export async function confirm(question, defaultYes = true) {
|
|
10
|
+
if (!process.stdin.isTTY) {
|
|
11
|
+
return defaultYes;
|
|
12
|
+
}
|
|
13
|
+
const suffix = defaultYes ? "[Y/n]" : "[y/N]";
|
|
14
|
+
const rl = createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stderr, // Use stderr so stdout stays clean for JSON/piping
|
|
17
|
+
});
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
rl.question(`${question} ${suffix} `, (answer) => {
|
|
20
|
+
rl.close();
|
|
21
|
+
const trimmed = answer.trim().toLowerCase();
|
|
22
|
+
if (trimmed === "") {
|
|
23
|
+
resolve(defaultYes);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
resolve(trimmed === "y" || trimmed === "yes");
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,QAAgB,EAChB,UAAU,GAAG,IAAI;IAEjB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9C,MAAM,EAAE,GAAG,eAAe,CAAC;QACzB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,mDAAmD;KAC5E,CAAC,CAAC;IAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,IAAI,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;gBACnB,OAAO,CAAC,UAAU,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,KAAK,CAAC,CAAC;YAChD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP package name shorthand resolution.
|
|
3
|
+
*
|
|
4
|
+
* Converts short forms like "server-filesystem" or "mcp-server-fetch"
|
|
5
|
+
* into the full scoped name "@modelcontextprotocol/server-*".
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a package name, expanding MCP shorthand if applicable.
|
|
9
|
+
*
|
|
10
|
+
* Rules (applied in order):
|
|
11
|
+
* 1. Starts with `@` -- use as-is (already scoped).
|
|
12
|
+
* 2. Starts with `server-` -- prefix with @modelcontextprotocol/.
|
|
13
|
+
* 3. Starts with `mcp/server-` or `mcp-server-` -- convert to @modelcontextprotocol/server-*.
|
|
14
|
+
* 4. Otherwise -- use as-is (regular npm package).
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolvePackageName(name: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a package name and log a note if resolution changed it.
|
|
19
|
+
* Returns the resolved name.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveAndLog(name: string): string;
|
|
22
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/utils/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBvD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP package name shorthand resolution.
|
|
3
|
+
*
|
|
4
|
+
* Converts short forms like "server-filesystem" or "mcp-server-fetch"
|
|
5
|
+
* into the full scoped name "@modelcontextprotocol/server-*".
|
|
6
|
+
*/
|
|
7
|
+
const MCP_SCOPE = "@modelcontextprotocol";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a package name, expanding MCP shorthand if applicable.
|
|
10
|
+
*
|
|
11
|
+
* Rules (applied in order):
|
|
12
|
+
* 1. Starts with `@` -- use as-is (already scoped).
|
|
13
|
+
* 2. Starts with `server-` -- prefix with @modelcontextprotocol/.
|
|
14
|
+
* 3. Starts with `mcp/server-` or `mcp-server-` -- convert to @modelcontextprotocol/server-*.
|
|
15
|
+
* 4. Otherwise -- use as-is (regular npm package).
|
|
16
|
+
*/
|
|
17
|
+
export function resolvePackageName(name) {
|
|
18
|
+
// Rule 1: already scoped
|
|
19
|
+
if (name.startsWith("@")) {
|
|
20
|
+
return name;
|
|
21
|
+
}
|
|
22
|
+
// Rule 2: server-* shorthand (must have at least one char after "server-")
|
|
23
|
+
if (name.startsWith("server-") && name.length > "server-".length) {
|
|
24
|
+
return `${MCP_SCOPE}/${name}`;
|
|
25
|
+
}
|
|
26
|
+
// Rule 3a: mcp/server-* notation (must have at least one char after "mcp/server-")
|
|
27
|
+
if (name.startsWith("mcp/server-") && name.length > "mcp/server-".length) {
|
|
28
|
+
const serverPart = name.slice("mcp/".length);
|
|
29
|
+
return `${MCP_SCOPE}/${serverPart}`;
|
|
30
|
+
}
|
|
31
|
+
// Rule 3b: mcp-server-* notation (must have at least one char after "mcp-server-")
|
|
32
|
+
if (name.startsWith("mcp-server-") && name.length > "mcp-server-".length) {
|
|
33
|
+
const serverPart = name.slice("mcp-".length);
|
|
34
|
+
return `${MCP_SCOPE}/${serverPart}`;
|
|
35
|
+
}
|
|
36
|
+
// Rule 4: regular package
|
|
37
|
+
return name;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a package name and log a note if resolution changed it.
|
|
41
|
+
* Returns the resolved name.
|
|
42
|
+
*/
|
|
43
|
+
export function resolveAndLog(name) {
|
|
44
|
+
const resolved = resolvePackageName(name);
|
|
45
|
+
if (resolved !== name) {
|
|
46
|
+
console.error(`Resolved: ${name} -> ${resolved}`);
|
|
47
|
+
}
|
|
48
|
+
return resolved;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/utils/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,yBAAyB;IACzB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;QACjE,OAAO,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,mFAAmF;IACnF,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;QACzE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,OAAO,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;IACtC,CAAC;IAED,mFAAmF;IACnF,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;QACzE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,OAAO,GAAG,SAAS,IAAI,UAAU,EAAE,CAAC;IACtC,CAAC;IAED,0BAA0B;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,OAAO,QAAQ,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|