vskill 0.5.0 → 0.5.2
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/dist/eval-ui/assets/{index-CcnlpaWS.js → index-CxHCKEhf.js} +2 -2
- package/dist/eval-ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/agents/agents-registry.test.d.ts +0 -1
- package/dist/agents/agents-registry.test.js +0 -248
- package/dist/agents/agents-registry.test.js.map +0 -1
- package/dist/api/client.test.d.ts +0 -1
- package/dist/api/client.test.js +0 -428
- package/dist/api/client.test.js.map +0 -1
- package/dist/audit/audit-integration.test.d.ts +0 -1
- package/dist/audit/audit-integration.test.js +0 -92
- package/dist/audit/audit-integration.test.js.map +0 -1
- package/dist/audit/audit-llm.test.d.ts +0 -1
- package/dist/audit/audit-llm.test.js +0 -110
- package/dist/audit/audit-llm.test.js.map +0 -1
- package/dist/audit/audit-patterns.test.d.ts +0 -1
- package/dist/audit/audit-patterns.test.js +0 -91
- package/dist/audit/audit-patterns.test.js.map +0 -1
- package/dist/audit/audit-scanner.test.d.ts +0 -1
- package/dist/audit/audit-scanner.test.js +0 -112
- package/dist/audit/audit-scanner.test.js.map +0 -1
- package/dist/audit/audit-types.test.d.ts +0 -1
- package/dist/audit/audit-types.test.js +0 -140
- package/dist/audit/audit-types.test.js.map +0 -1
- package/dist/audit/config.test.d.ts +0 -1
- package/dist/audit/config.test.js +0 -44
- package/dist/audit/config.test.js.map +0 -1
- package/dist/audit/file-discovery.test.d.ts +0 -1
- package/dist/audit/file-discovery.test.js +0 -120
- package/dist/audit/file-discovery.test.js.map +0 -1
- package/dist/audit/fix-suggestions.test.d.ts +0 -1
- package/dist/audit/fix-suggestions.test.js +0 -35
- package/dist/audit/fix-suggestions.test.js.map +0 -1
- package/dist/audit/formatters/json-formatter.test.d.ts +0 -1
- package/dist/audit/formatters/json-formatter.test.js +0 -49
- package/dist/audit/formatters/json-formatter.test.js.map +0 -1
- package/dist/audit/formatters/report-formatter.test.d.ts +0 -1
- package/dist/audit/formatters/report-formatter.test.js +0 -51
- package/dist/audit/formatters/report-formatter.test.js.map +0 -1
- package/dist/audit/formatters/sarif-formatter.test.d.ts +0 -1
- package/dist/audit/formatters/sarif-formatter.test.js +0 -71
- package/dist/audit/formatters/sarif-formatter.test.js.map +0 -1
- package/dist/audit/formatters/terminal-formatter.test.d.ts +0 -1
- package/dist/audit/formatters/terminal-formatter.test.js +0 -51
- package/dist/audit/formatters/terminal-formatter.test.js.map +0 -1
- package/dist/blocklist/blocklist-e2e.test.d.ts +0 -1
- package/dist/blocklist/blocklist-e2e.test.js +0 -346
- package/dist/blocklist/blocklist-e2e.test.js.map +0 -1
- package/dist/blocklist/blocklist.test.d.ts +0 -1
- package/dist/blocklist/blocklist.test.js +0 -259
- package/dist/blocklist/blocklist.test.js.map +0 -1
- package/dist/commands/__tests__/eval-router.test.d.ts +0 -1
- package/dist/commands/__tests__/eval-router.test.js +0 -60
- package/dist/commands/__tests__/eval-router.test.js.map +0 -1
- package/dist/commands/__tests__/eval-serve.test.d.ts +0 -1
- package/dist/commands/__tests__/eval-serve.test.js +0 -23
- package/dist/commands/__tests__/eval-serve.test.js.map +0 -1
- package/dist/commands/add-blocklist-e2e.test.d.ts +0 -1
- package/dist/commands/add-blocklist-e2e.test.js +0 -397
- package/dist/commands/add-blocklist-e2e.test.js.map +0 -1
- package/dist/commands/add-wizard.test.d.ts +0 -1
- package/dist/commands/add-wizard.test.js +0 -392
- package/dist/commands/add-wizard.test.js.map +0 -1
- package/dist/commands/add.test.d.ts +0 -1
- package/dist/commands/add.test.js +0 -2365
- package/dist/commands/add.test.js.map +0 -1
- package/dist/commands/audit.test.d.ts +0 -1
- package/dist/commands/audit.test.js +0 -79
- package/dist/commands/audit.test.js.map +0 -1
- package/dist/commands/blocklist.test.d.ts +0 -1
- package/dist/commands/blocklist.test.js +0 -158
- package/dist/commands/blocklist.test.js.map +0 -1
- package/dist/commands/eval/__tests__/coverage.test.d.ts +0 -1
- package/dist/commands/eval/__tests__/coverage.test.js +0 -122
- package/dist/commands/eval/__tests__/coverage.test.js.map +0 -1
- package/dist/commands/eval/__tests__/generate-all.test.d.ts +0 -1
- package/dist/commands/eval/__tests__/generate-all.test.js +0 -133
- package/dist/commands/eval/__tests__/generate-all.test.js.map +0 -1
- package/dist/commands/eval/__tests__/init.test.d.ts +0 -1
- package/dist/commands/eval/__tests__/init.test.js +0 -116
- package/dist/commands/eval/__tests__/init.test.js.map +0 -1
- package/dist/commands/eval/__tests__/run.test.d.ts +0 -1
- package/dist/commands/eval/__tests__/run.test.js +0 -186
- package/dist/commands/eval/__tests__/run.test.js.map +0 -1
- package/dist/commands/find.test.d.ts +0 -1
- package/dist/commands/find.test.js +0 -481
- package/dist/commands/find.test.js.map +0 -1
- package/dist/commands/marketplace.test.d.ts +0 -1
- package/dist/commands/marketplace.test.js +0 -129
- package/dist/commands/marketplace.test.js.map +0 -1
- package/dist/commands/remove.test.d.ts +0 -1
- package/dist/commands/remove.test.js +0 -164
- package/dist/commands/remove.test.js.map +0 -1
- package/dist/commands/should-skip.test.d.ts +0 -1
- package/dist/commands/should-skip.test.js +0 -56
- package/dist/commands/should-skip.test.js.map +0 -1
- package/dist/commands/submit.test.d.ts +0 -1
- package/dist/commands/submit.test.js +0 -83
- package/dist/commands/submit.test.js.map +0 -1
- package/dist/commands/update.test.d.ts +0 -1
- package/dist/commands/update.test.js +0 -250
- package/dist/commands/update.test.js.map +0 -1
- package/dist/discovery/github-tree.test.d.ts +0 -1
- package/dist/discovery/github-tree.test.js +0 -372
- package/dist/discovery/github-tree.test.js.map +0 -1
- package/dist/eval/__tests__/activation-tester.test.d.ts +0 -1
- package/dist/eval/__tests__/activation-tester.test.js +0 -203
- package/dist/eval/__tests__/activation-tester.test.js.map +0 -1
- package/dist/eval/__tests__/benchmark-history.test.d.ts +0 -1
- package/dist/eval/__tests__/benchmark-history.test.js +0 -422
- package/dist/eval/__tests__/benchmark-history.test.js.map +0 -1
- package/dist/eval/__tests__/benchmark.test.d.ts +0 -1
- package/dist/eval/__tests__/benchmark.test.js +0 -94
- package/dist/eval/__tests__/benchmark.test.js.map +0 -1
- package/dist/eval/__tests__/comparator.test.d.ts +0 -1
- package/dist/eval/__tests__/comparator.test.js +0 -282
- package/dist/eval/__tests__/comparator.test.js.map +0 -1
- package/dist/eval/__tests__/judge.test.d.ts +0 -1
- package/dist/eval/__tests__/judge.test.js +0 -122
- package/dist/eval/__tests__/judge.test.js.map +0 -1
- package/dist/eval/__tests__/llm.test.d.ts +0 -1
- package/dist/eval/__tests__/llm.test.js +0 -543
- package/dist/eval/__tests__/llm.test.js.map +0 -1
- package/dist/eval/__tests__/mcp-detector.test.d.ts +0 -1
- package/dist/eval/__tests__/mcp-detector.test.js +0 -180
- package/dist/eval/__tests__/mcp-detector.test.js.map +0 -1
- package/dist/eval/__tests__/prompt-builder.test.d.ts +0 -1
- package/dist/eval/__tests__/prompt-builder.test.js +0 -142
- package/dist/eval/__tests__/prompt-builder.test.js.map +0 -1
- package/dist/eval/__tests__/schema.test.d.ts +0 -1
- package/dist/eval/__tests__/schema.test.js +0 -247
- package/dist/eval/__tests__/schema.test.js.map +0 -1
- package/dist/eval/__tests__/skill-scanner.test.d.ts +0 -1
- package/dist/eval/__tests__/skill-scanner.test.js +0 -228
- package/dist/eval/__tests__/skill-scanner.test.js.map +0 -1
- package/dist/eval/__tests__/verdict.test.d.ts +0 -1
- package/dist/eval/__tests__/verdict.test.js +0 -47
- package/dist/eval/__tests__/verdict.test.js.map +0 -1
- package/dist/eval-server/__tests__/benchmark-runner.test.d.ts +0 -1
- package/dist/eval-server/__tests__/benchmark-runner.test.js +0 -301
- package/dist/eval-server/__tests__/benchmark-runner.test.js.map +0 -1
- package/dist/eval-server/__tests__/comparison-sse-events.test.d.ts +0 -1
- package/dist/eval-server/__tests__/comparison-sse-events.test.js +0 -278
- package/dist/eval-server/__tests__/comparison-sse-events.test.js.map +0 -1
- package/dist/eval-server/__tests__/sse-helpers.test.d.ts +0 -1
- package/dist/eval-server/__tests__/sse-helpers.test.js +0 -128
- package/dist/eval-server/__tests__/sse-helpers.test.js.map +0 -1
- package/dist/installer/canonical.test.d.ts +0 -1
- package/dist/installer/canonical.test.js +0 -264
- package/dist/installer/canonical.test.js.map +0 -1
- package/dist/lockfile/lockfile.test.d.ts +0 -1
- package/dist/lockfile/lockfile.test.js +0 -204
- package/dist/lockfile/lockfile.test.js.map +0 -1
- package/dist/lockfile/project-root.test.d.ts +0 -1
- package/dist/lockfile/project-root.test.js +0 -49
- package/dist/lockfile/project-root.test.js.map +0 -1
- package/dist/marketplace/marketplace.test.d.ts +0 -1
- package/dist/marketplace/marketplace.test.js +0 -312
- package/dist/marketplace/marketplace.test.js.map +0 -1
- package/dist/resolvers/source-resolver.test.d.ts +0 -1
- package/dist/resolvers/source-resolver.test.js +0 -104
- package/dist/resolvers/source-resolver.test.js.map +0 -1
- package/dist/resolvers/url-resolver.test.d.ts +0 -1
- package/dist/resolvers/url-resolver.test.js +0 -49
- package/dist/resolvers/url-resolver.test.js.map +0 -1
- package/dist/scanner/dci-integration.test.d.ts +0 -1
- package/dist/scanner/dci-integration.test.js +0 -83
- package/dist/scanner/dci-integration.test.js.map +0 -1
- package/dist/scanner/patterns.test.d.ts +0 -1
- package/dist/scanner/patterns.test.js +0 -832
- package/dist/scanner/patterns.test.js.map +0 -1
- package/dist/scanner/tier1.test.d.ts +0 -1
- package/dist/scanner/tier1.test.js +0 -305
- package/dist/scanner/tier1.test.js.map +0 -1
- package/dist/security/platform-security.test.d.ts +0 -1
- package/dist/security/platform-security.test.js +0 -92
- package/dist/security/platform-security.test.js.map +0 -1
- package/dist/settings/settings.test.d.ts +0 -1
- package/dist/settings/settings.test.js +0 -103
- package/dist/settings/settings.test.js.map +0 -1
- package/dist/updater/source-fetcher.test.d.ts +0 -1
- package/dist/updater/source-fetcher.test.js +0 -192
- package/dist/updater/source-fetcher.test.js.map +0 -1
- package/dist/utils/__tests__/paths.test.d.ts +0 -1
- package/dist/utils/__tests__/paths.test.js +0 -22
- package/dist/utils/__tests__/paths.test.js.map +0 -1
- package/dist/utils/__tests__/resolve-binary.integration.test.d.ts +0 -1
- package/dist/utils/__tests__/resolve-binary.integration.test.js +0 -138
- package/dist/utils/__tests__/resolve-binary.integration.test.js.map +0 -1
- package/dist/utils/__tests__/resolve-binary.test.d.ts +0 -1
- package/dist/utils/__tests__/resolve-binary.test.js +0 -175
- package/dist/utils/__tests__/resolve-binary.test.js.map +0 -1
- package/dist/utils/__tests__/validation.test.d.ts +0 -1
- package/dist/utils/__tests__/validation.test.js +0 -107
- package/dist/utils/__tests__/validation.test.js.map +0 -1
- package/dist/utils/agent-filter.test.d.ts +0 -1
- package/dist/utils/agent-filter.test.js +0 -75
- package/dist/utils/agent-filter.test.js.map +0 -1
- package/dist/utils/output.test.d.ts +0 -1
- package/dist/utils/output.test.js +0 -28
- package/dist/utils/output.test.js.map +0 -1
- package/dist/utils/project-root.test.d.ts +0 -1
- package/dist/utils/project-root.test.js +0 -74
- package/dist/utils/project-root.test.js.map +0 -1
- package/dist/utils/prompts.test.d.ts +0 -1
- package/dist/utils/prompts.test.js +0 -285
- package/dist/utils/prompts.test.js.map +0 -1
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { buildLlmPrompt, parseLlmResponse, runLlmAnalysis } from "./audit-llm.js";
|
|
3
|
-
import { createDefaultAuditConfig } from "./audit-types.js";
|
|
4
|
-
describe("audit-llm", () => {
|
|
5
|
-
describe("buildLlmPrompt", () => {
|
|
6
|
-
it("TC-040: builds correct prompt with file content and Tier 1 findings", () => {
|
|
7
|
-
const file = {
|
|
8
|
-
path: "src/handler.ts",
|
|
9
|
-
content: 'const msg = req.body.message;\nexec(`echo ${msg}`);',
|
|
10
|
-
sizeBytes: 50,
|
|
11
|
-
};
|
|
12
|
-
const findings = [
|
|
13
|
-
{
|
|
14
|
-
id: "AF-001", ruleId: "CI-001", severity: "critical", confidence: "high",
|
|
15
|
-
category: "command-injection", message: "exec() call detected",
|
|
16
|
-
filePath: "src/handler.ts", line: 2, snippet: "exec(`echo ${msg}`);",
|
|
17
|
-
source: "tier1",
|
|
18
|
-
},
|
|
19
|
-
];
|
|
20
|
-
const prompt = buildLlmPrompt(file, findings);
|
|
21
|
-
expect(prompt).toContain("src/handler.ts");
|
|
22
|
-
expect(prompt).toContain("exec(`echo ${msg}`)");
|
|
23
|
-
expect(prompt).toContain("CI-001");
|
|
24
|
-
expect(prompt).toContain("command-injection");
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
describe("parseLlmResponse", () => {
|
|
28
|
-
it("TC-041: parses valid LLM JSON response", () => {
|
|
29
|
-
const response = JSON.stringify({
|
|
30
|
-
findings: [
|
|
31
|
-
{
|
|
32
|
-
ruleId: "LLM-CI-001",
|
|
33
|
-
severity: "critical",
|
|
34
|
-
confidence: "high",
|
|
35
|
-
category: "command-injection",
|
|
36
|
-
message: "Command injection via webhook payload",
|
|
37
|
-
line: 2,
|
|
38
|
-
dataFlow: {
|
|
39
|
-
steps: [
|
|
40
|
-
{ file: "src/handler.ts", line: 1, description: "User input", code: "const msg = req.body.message;" },
|
|
41
|
-
{ file: "src/handler.ts", line: 2, description: "Shell exec", code: "exec(`echo ${msg}`);" },
|
|
42
|
-
],
|
|
43
|
-
},
|
|
44
|
-
suggestedFix: "Use execFile with array args instead of exec with template",
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
});
|
|
48
|
-
const parsed = parseLlmResponse(response, "src/handler.ts");
|
|
49
|
-
expect(parsed).toHaveLength(1);
|
|
50
|
-
expect(parsed[0].ruleId).toBe("LLM-CI-001");
|
|
51
|
-
expect(parsed[0].source).toBe("llm");
|
|
52
|
-
expect(parsed[0].filePath).toBe("src/handler.ts");
|
|
53
|
-
});
|
|
54
|
-
it("TC-042: returns empty array on invalid JSON", () => {
|
|
55
|
-
const parsed = parseLlmResponse("not json at all", "src/file.ts");
|
|
56
|
-
expect(parsed).toHaveLength(0);
|
|
57
|
-
});
|
|
58
|
-
it("TC-045: data flow trace is parsed from LLM response", () => {
|
|
59
|
-
const response = JSON.stringify({
|
|
60
|
-
findings: [{
|
|
61
|
-
ruleId: "LLM-SSRF-001",
|
|
62
|
-
severity: "high",
|
|
63
|
-
confidence: "high",
|
|
64
|
-
category: "ssrf",
|
|
65
|
-
message: "SSRF via user URL",
|
|
66
|
-
line: 10,
|
|
67
|
-
dataFlow: {
|
|
68
|
-
steps: [
|
|
69
|
-
{ file: "src/api.ts", line: 5, description: "Input received", code: "const url = req.query.url;" },
|
|
70
|
-
{ file: "src/api.ts", line: 10, description: "Fetch called", code: "fetch(url);" },
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
}],
|
|
74
|
-
});
|
|
75
|
-
const parsed = parseLlmResponse(response, "src/api.ts");
|
|
76
|
-
expect(parsed[0].dataFlow).toBeDefined();
|
|
77
|
-
expect(parsed[0].dataFlow.steps).toHaveLength(2);
|
|
78
|
-
expect(parsed[0].dataFlow.steps[0].file).toBe("src/api.ts");
|
|
79
|
-
expect(parsed[0].dataFlow.steps[1].line).toBe(10);
|
|
80
|
-
});
|
|
81
|
-
it("TC-046: missing data flow is handled gracefully", () => {
|
|
82
|
-
const response = JSON.stringify({
|
|
83
|
-
findings: [{
|
|
84
|
-
ruleId: "LLM-XSS-001",
|
|
85
|
-
severity: "high",
|
|
86
|
-
confidence: "medium",
|
|
87
|
-
category: "xss",
|
|
88
|
-
message: "Potential XSS",
|
|
89
|
-
line: 5,
|
|
90
|
-
}],
|
|
91
|
-
});
|
|
92
|
-
const parsed = parseLlmResponse(response, "src/page.ts");
|
|
93
|
-
expect(parsed[0].dataFlow).toBeUndefined();
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
describe("runLlmAnalysis", () => {
|
|
97
|
-
it("TC-043: skips LLM when tier1Only is true", async () => {
|
|
98
|
-
const config = createDefaultAuditConfig();
|
|
99
|
-
config.tier1Only = true;
|
|
100
|
-
const result = await runLlmAnalysis([], [], config);
|
|
101
|
-
expect(result).toHaveLength(0);
|
|
102
|
-
});
|
|
103
|
-
it("TC-044: returns empty when no flagged files", async () => {
|
|
104
|
-
const config = createDefaultAuditConfig();
|
|
105
|
-
const result = await runLlmAnalysis([], [], config);
|
|
106
|
-
expect(result).toHaveLength(0);
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
//# sourceMappingURL=audit-llm.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audit-llm.test.js","sourceRoot":"","sources":["../../src/audit/audit-llm.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { AUDIT_PATTERNS, PROJECT_PATTERNS } from "./audit-patterns.js";
|
|
3
|
-
import { SCAN_PATTERNS } from "../scanner/patterns.js";
|
|
4
|
-
describe("audit-patterns", () => {
|
|
5
|
-
it("TC-009: AUDIT_PATTERNS includes all 37 original SCAN_PATTERNS", () => {
|
|
6
|
-
const auditIds = new Set(AUDIT_PATTERNS.map((p) => p.id));
|
|
7
|
-
for (const original of SCAN_PATTERNS) {
|
|
8
|
-
expect(auditIds.has(original.id)).toBe(true);
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
it("TC-010: AUDIT_PATTERNS adds at least 15 new project-specific patterns", () => {
|
|
12
|
-
const originalIds = new Set(SCAN_PATTERNS.map((p) => p.id));
|
|
13
|
-
const newPatterns = AUDIT_PATTERNS.filter((p) => !originalIds.has(p.id));
|
|
14
|
-
expect(newPatterns.length).toBeGreaterThanOrEqual(15);
|
|
15
|
-
});
|
|
16
|
-
it("TC-011: SQL injection pattern detects string concatenation in queries", () => {
|
|
17
|
-
const sqliPatterns = PROJECT_PATTERNS.filter((p) => p.category === "sql-injection");
|
|
18
|
-
expect(sqliPatterns.length).toBeGreaterThan(0);
|
|
19
|
-
const testLine = `"SELECT * FROM users WHERE id = '" + userId + "'"`;
|
|
20
|
-
const matched = sqliPatterns.some((p) => {
|
|
21
|
-
const regex = new RegExp(p.pattern.source, p.pattern.flags);
|
|
22
|
-
return regex.test(testLine);
|
|
23
|
-
});
|
|
24
|
-
expect(matched).toBe(true);
|
|
25
|
-
});
|
|
26
|
-
it("TC-012: SSRF pattern detects URL construction from variables", () => {
|
|
27
|
-
const ssrfPatterns = PROJECT_PATTERNS.filter((p) => p.category === "ssrf");
|
|
28
|
-
expect(ssrfPatterns.length).toBeGreaterThan(0);
|
|
29
|
-
const testLine = `fetch(userProvidedUrl)`;
|
|
30
|
-
const matched = ssrfPatterns.some((p) => {
|
|
31
|
-
const regex = new RegExp(p.pattern.source, p.pattern.flags);
|
|
32
|
-
return regex.test(testLine);
|
|
33
|
-
});
|
|
34
|
-
expect(matched).toBe(true);
|
|
35
|
-
});
|
|
36
|
-
it("TC-013: Hardcoded secret pattern detects API key assignments", () => {
|
|
37
|
-
const secretPatterns = PROJECT_PATTERNS.filter((p) => p.category === "hardcoded-secrets");
|
|
38
|
-
expect(secretPatterns.length).toBeGreaterThan(0);
|
|
39
|
-
const testLine = `const API_KEY = "sk-1234567890abcdef"`;
|
|
40
|
-
const matched = secretPatterns.some((p) => {
|
|
41
|
-
const regex = new RegExp(p.pattern.source, p.pattern.flags);
|
|
42
|
-
return regex.test(testLine);
|
|
43
|
-
});
|
|
44
|
-
expect(matched).toBe(true);
|
|
45
|
-
});
|
|
46
|
-
it("TC-014: XSS pattern detects innerHTML assignment", () => {
|
|
47
|
-
const xssPatterns = PROJECT_PATTERNS.filter((p) => p.category === "xss");
|
|
48
|
-
expect(xssPatterns.length).toBeGreaterThan(0);
|
|
49
|
-
const testLine = `element.innerHTML = userInput`;
|
|
50
|
-
const matched = xssPatterns.some((p) => {
|
|
51
|
-
const regex = new RegExp(p.pattern.source, p.pattern.flags);
|
|
52
|
-
return regex.test(testLine);
|
|
53
|
-
});
|
|
54
|
-
expect(matched).toBe(true);
|
|
55
|
-
});
|
|
56
|
-
it("TC-015: safe contexts suppress false positives", () => {
|
|
57
|
-
const patternsWithSafe = PROJECT_PATTERNS.filter((p) => p.safeContexts && p.safeContexts.length > 0);
|
|
58
|
-
expect(patternsWithSafe.length).toBeGreaterThan(0);
|
|
59
|
-
// For each pattern with safeContexts, at least one safe context regex exists
|
|
60
|
-
for (const pattern of patternsWithSafe) {
|
|
61
|
-
expect(pattern.safeContexts.length).toBeGreaterThan(0);
|
|
62
|
-
expect(pattern.safeContexts[0]).toBeInstanceOf(RegExp);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
it("TC-016: all pattern IDs are unique across combined set", () => {
|
|
66
|
-
const ids = AUDIT_PATTERNS.map((p) => p.id);
|
|
67
|
-
const uniqueIds = new Set(ids);
|
|
68
|
-
expect(uniqueIds.size).toBe(ids.length);
|
|
69
|
-
});
|
|
70
|
-
it("detects open redirect pattern", () => {
|
|
71
|
-
const redirectPatterns = PROJECT_PATTERNS.filter((p) => p.category === "open-redirect");
|
|
72
|
-
expect(redirectPatterns.length).toBeGreaterThan(0);
|
|
73
|
-
const testLine = `res.redirect(req.query.url)`;
|
|
74
|
-
const matched = redirectPatterns.some((p) => {
|
|
75
|
-
const regex = new RegExp(p.pattern.source, p.pattern.flags);
|
|
76
|
-
return regex.test(testLine);
|
|
77
|
-
});
|
|
78
|
-
expect(matched).toBe(true);
|
|
79
|
-
});
|
|
80
|
-
it("detects insecure deserialization", () => {
|
|
81
|
-
const deserPatterns = PROJECT_PATTERNS.filter((p) => p.category === "insecure-deserialization");
|
|
82
|
-
expect(deserPatterns.length).toBeGreaterThan(0);
|
|
83
|
-
const testLine = `yaml.load(userInput)`;
|
|
84
|
-
const matched = deserPatterns.some((p) => {
|
|
85
|
-
const regex = new RegExp(p.pattern.source, p.pattern.flags);
|
|
86
|
-
return regex.test(testLine);
|
|
87
|
-
});
|
|
88
|
-
expect(matched).toBe(true);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
//# sourceMappingURL=audit-patterns.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audit-patterns.test.js","sourceRoot":"","sources":["../../src/audit/audit-patterns.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { runAuditScan } from "./audit-scanner.js";
|
|
3
|
-
import { createDefaultAuditConfig } from "./audit-types.js";
|
|
4
|
-
function makeFile(path, content) {
|
|
5
|
-
return { path, content, sizeBytes: Buffer.byteLength(content) };
|
|
6
|
-
}
|
|
7
|
-
describe("audit-scanner", () => {
|
|
8
|
-
it("TC-017: returns empty findings for clean files", () => {
|
|
9
|
-
const files = [
|
|
10
|
-
makeFile("src/clean.ts", "const x = 1;\nconst y = 2;\nexport { x, y };"),
|
|
11
|
-
makeFile("src/utils.ts", "export function add(a: number, b: number) { return a + b; }"),
|
|
12
|
-
];
|
|
13
|
-
const config = createDefaultAuditConfig();
|
|
14
|
-
const result = runAuditScan(files, config);
|
|
15
|
-
expect(result.findings).toHaveLength(0);
|
|
16
|
-
expect(result.summary.verdict).toBe("PASS");
|
|
17
|
-
expect(result.summary.total).toBe(0);
|
|
18
|
-
expect(result.summary.score).toBe(100);
|
|
19
|
-
});
|
|
20
|
-
it("TC-018: detects findings across multiple files", () => {
|
|
21
|
-
const files = [
|
|
22
|
-
makeFile("src/cmd.ts", 'exec("rm -rf /");'),
|
|
23
|
-
makeFile("src/xss.ts", 'element.innerHTML = userInput;'),
|
|
24
|
-
makeFile("src/sql.ts", '`SELECT * FROM users WHERE id = ${userId}`'),
|
|
25
|
-
];
|
|
26
|
-
const config = createDefaultAuditConfig();
|
|
27
|
-
const result = runAuditScan(files, config);
|
|
28
|
-
expect(result.findings.length).toBeGreaterThanOrEqual(3);
|
|
29
|
-
const filePaths = new Set(result.findings.map((f) => f.filePath));
|
|
30
|
-
expect(filePaths.has("src/cmd.ts")).toBe(true);
|
|
31
|
-
expect(filePaths.has("src/xss.ts")).toBe(true);
|
|
32
|
-
expect(filePaths.has("src/sql.ts")).toBe(true);
|
|
33
|
-
});
|
|
34
|
-
it("TC-019: findings are sorted by severity then file path", () => {
|
|
35
|
-
const files = [
|
|
36
|
-
makeFile("z-file.ts", "element.innerHTML = x;"), // high
|
|
37
|
-
makeFile("a-file.ts", 'eval("code");'), // critical
|
|
38
|
-
];
|
|
39
|
-
const config = createDefaultAuditConfig();
|
|
40
|
-
const result = runAuditScan(files, config);
|
|
41
|
-
// Critical should come before high
|
|
42
|
-
const severities = result.findings.map((f) => f.severity);
|
|
43
|
-
const criticalIndex = severities.indexOf("critical");
|
|
44
|
-
const highIndex = severities.indexOf("high");
|
|
45
|
-
if (criticalIndex !== -1 && highIndex !== -1) {
|
|
46
|
-
expect(criticalIndex).toBeLessThan(highIndex);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
it("TC-020: summary statistics are accurate", () => {
|
|
50
|
-
const files = [
|
|
51
|
-
makeFile("src/a.ts", 'eval("x");'), // critical (CE-001)
|
|
52
|
-
makeFile("src/b.ts", "element.innerHTML = y;"), // high (XSS-001)
|
|
53
|
-
];
|
|
54
|
-
const config = createDefaultAuditConfig();
|
|
55
|
-
const result = runAuditScan(files, config);
|
|
56
|
-
expect(result.summary.total).toBe(result.findings.length);
|
|
57
|
-
expect(result.summary.critical + result.summary.high + result.summary.medium +
|
|
58
|
-
result.summary.low + result.summary.info).toBe(result.summary.total);
|
|
59
|
-
});
|
|
60
|
-
it("TC-021: score and verdict are calculated correctly", () => {
|
|
61
|
-
// Clean project -> score 100, PASS
|
|
62
|
-
const cleanFiles = [
|
|
63
|
-
makeFile("src/clean.ts", "const x = 1;"),
|
|
64
|
-
];
|
|
65
|
-
const config = createDefaultAuditConfig();
|
|
66
|
-
const cleanResult = runAuditScan(cleanFiles, config);
|
|
67
|
-
expect(cleanResult.summary.score).toBe(100);
|
|
68
|
-
expect(cleanResult.summary.verdict).toBe("PASS");
|
|
69
|
-
// Many critical findings -> score < 50, FAIL
|
|
70
|
-
const badFiles = [
|
|
71
|
-
makeFile("src/bad.ts", [
|
|
72
|
-
'eval("a");',
|
|
73
|
-
'eval("b");',
|
|
74
|
-
'eval("c");',
|
|
75
|
-
'eval("d");',
|
|
76
|
-
'eval("e");',
|
|
77
|
-
].join("\n")),
|
|
78
|
-
];
|
|
79
|
-
const badResult = runAuditScan(badFiles, config);
|
|
80
|
-
expect(badResult.summary.score).toBeLessThan(50);
|
|
81
|
-
expect(badResult.summary.verdict).toBe("FAIL");
|
|
82
|
-
});
|
|
83
|
-
it("TC-022: duration is tracked", () => {
|
|
84
|
-
const files = [makeFile("src/a.ts", "const x = 1;")];
|
|
85
|
-
const config = createDefaultAuditConfig();
|
|
86
|
-
const result = runAuditScan(files, config);
|
|
87
|
-
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
88
|
-
expect(typeof result.durationMs).toBe("number");
|
|
89
|
-
});
|
|
90
|
-
it("populates filesScanned and filesWithFindings", () => {
|
|
91
|
-
const files = [
|
|
92
|
-
makeFile("src/clean.ts", "const x = 1;"),
|
|
93
|
-
makeFile("src/bad.ts", 'eval("x");'),
|
|
94
|
-
makeFile("src/also-clean.ts", "const y = 2;"),
|
|
95
|
-
];
|
|
96
|
-
const config = createDefaultAuditConfig();
|
|
97
|
-
const result = runAuditScan(files, config);
|
|
98
|
-
expect(result.filesScanned).toBe(3);
|
|
99
|
-
expect(result.filesWithFindings).toBe(1);
|
|
100
|
-
});
|
|
101
|
-
it("applies safeContexts to suppress false positives", () => {
|
|
102
|
-
// innerHTML in a line with DOMPurify should be suppressed
|
|
103
|
-
const files = [
|
|
104
|
-
makeFile("src/safe.ts", "element.innerHTML = DOMPurify.sanitize(input);"),
|
|
105
|
-
];
|
|
106
|
-
const config = createDefaultAuditConfig();
|
|
107
|
-
const result = runAuditScan(files, config);
|
|
108
|
-
const xssFindings = result.findings.filter((f) => f.ruleId === "XSS-001");
|
|
109
|
-
expect(xssFindings).toHaveLength(0);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
//# sourceMappingURL=audit-scanner.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audit-scanner.test.js","sourceRoot":"","sources":["../../src/audit/audit-scanner.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { createDefaultAuditConfig, } from "./audit-types.js";
|
|
3
|
-
describe("audit-types", () => {
|
|
4
|
-
describe("AuditFinding", () => {
|
|
5
|
-
it("TC-001: is correctly importable and all fields are typed", () => {
|
|
6
|
-
const finding = {
|
|
7
|
-
id: "AF-001",
|
|
8
|
-
ruleId: "CI-001",
|
|
9
|
-
severity: "critical",
|
|
10
|
-
confidence: "high",
|
|
11
|
-
category: "command-injection",
|
|
12
|
-
message: "exec() call detected",
|
|
13
|
-
filePath: "src/index.ts",
|
|
14
|
-
line: 42,
|
|
15
|
-
snippet: " exec(command);",
|
|
16
|
-
source: "tier1",
|
|
17
|
-
};
|
|
18
|
-
expect(finding.id).toBe("AF-001");
|
|
19
|
-
expect(finding.ruleId).toBe("CI-001");
|
|
20
|
-
expect(finding.severity).toBe("critical");
|
|
21
|
-
expect(finding.confidence).toBe("high");
|
|
22
|
-
expect(finding.category).toBe("command-injection");
|
|
23
|
-
expect(finding.message).toBe("exec() call detected");
|
|
24
|
-
expect(finding.filePath).toBe("src/index.ts");
|
|
25
|
-
expect(finding.line).toBe(42);
|
|
26
|
-
expect(finding.snippet).toBe(" exec(command);");
|
|
27
|
-
expect(finding.source).toBe("tier1");
|
|
28
|
-
});
|
|
29
|
-
it("supports optional fields: column, endLine, dataFlow, suggestedFix", () => {
|
|
30
|
-
const finding = {
|
|
31
|
-
id: "AF-002",
|
|
32
|
-
ruleId: "SSRF-001",
|
|
33
|
-
severity: "high",
|
|
34
|
-
confidence: "medium",
|
|
35
|
-
category: "ssrf",
|
|
36
|
-
message: "SSRF via user-controlled URL",
|
|
37
|
-
filePath: "src/api.ts",
|
|
38
|
-
line: 10,
|
|
39
|
-
column: 5,
|
|
40
|
-
endLine: 12,
|
|
41
|
-
snippet: " fetch(url);",
|
|
42
|
-
source: "llm",
|
|
43
|
-
dataFlow: {
|
|
44
|
-
steps: [
|
|
45
|
-
{
|
|
46
|
-
file: "src/api.ts",
|
|
47
|
-
line: 5,
|
|
48
|
-
description: "User input received",
|
|
49
|
-
code: "const url = req.query.url;",
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
},
|
|
53
|
-
suggestedFix: "Validate URL against an allowlist",
|
|
54
|
-
};
|
|
55
|
-
expect(finding.column).toBe(5);
|
|
56
|
-
expect(finding.endLine).toBe(12);
|
|
57
|
-
expect(finding.dataFlow?.steps).toHaveLength(1);
|
|
58
|
-
expect(finding.suggestedFix).toBe("Validate URL against an allowlist");
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
describe("AuditConfig", () => {
|
|
62
|
-
it("TC-002: default values are correct", () => {
|
|
63
|
-
const config = createDefaultAuditConfig();
|
|
64
|
-
expect(config.excludePaths).toEqual([]);
|
|
65
|
-
expect(config.severityThreshold).toBe("low");
|
|
66
|
-
expect(config.maxFiles).toBe(500);
|
|
67
|
-
expect(config.maxFileSize).toBe(100 * 1024);
|
|
68
|
-
expect(config.tier1Only).toBe(false);
|
|
69
|
-
expect(config.llmProvider).toBeNull();
|
|
70
|
-
expect(config.llmTimeout).toBe(30_000);
|
|
71
|
-
expect(config.llmConcurrency).toBe(5);
|
|
72
|
-
expect(config.customPatterns).toEqual([]);
|
|
73
|
-
expect(config.fix).toBe(false);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
describe("AuditResult", () => {
|
|
77
|
-
it("contains all required fields for a complete result", () => {
|
|
78
|
-
const result = {
|
|
79
|
-
rootPath: "/project",
|
|
80
|
-
startedAt: "2026-02-20T18:00:00Z",
|
|
81
|
-
completedAt: "2026-02-20T18:00:05Z",
|
|
82
|
-
durationMs: 5000,
|
|
83
|
-
filesScanned: 100,
|
|
84
|
-
filesWithFindings: 3,
|
|
85
|
-
findings: [],
|
|
86
|
-
summary: {
|
|
87
|
-
critical: 0,
|
|
88
|
-
high: 0,
|
|
89
|
-
medium: 0,
|
|
90
|
-
low: 0,
|
|
91
|
-
info: 0,
|
|
92
|
-
total: 0,
|
|
93
|
-
score: 100,
|
|
94
|
-
verdict: "PASS",
|
|
95
|
-
},
|
|
96
|
-
config: createDefaultAuditConfig(),
|
|
97
|
-
};
|
|
98
|
-
expect(result.rootPath).toBe("/project");
|
|
99
|
-
expect(result.filesScanned).toBe(100);
|
|
100
|
-
expect(result.summary.verdict).toBe("PASS");
|
|
101
|
-
expect(result.summary.score).toBe(100);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
describe("DataFlowTrace", () => {
|
|
105
|
-
it("has steps with file, line, description, code", () => {
|
|
106
|
-
const trace = {
|
|
107
|
-
steps: [
|
|
108
|
-
{
|
|
109
|
-
file: "src/handler.ts",
|
|
110
|
-
line: 10,
|
|
111
|
-
description: "User input received from webhook",
|
|
112
|
-
code: 'const msg = req.body.message;',
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
file: "src/handler.ts",
|
|
116
|
-
line: 15,
|
|
117
|
-
description: "Passed to shell execution",
|
|
118
|
-
code: 'exec(`echo ${msg}`);',
|
|
119
|
-
},
|
|
120
|
-
],
|
|
121
|
-
};
|
|
122
|
-
expect(trace.steps).toHaveLength(2);
|
|
123
|
-
expect(trace.steps[0].file).toBe("src/handler.ts");
|
|
124
|
-
expect(trace.steps[1].line).toBe(15);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
describe("AuditFile", () => {
|
|
128
|
-
it("represents a discovered file with path, content, sizeBytes", () => {
|
|
129
|
-
const file = {
|
|
130
|
-
path: "src/index.ts",
|
|
131
|
-
content: "console.log('hello');",
|
|
132
|
-
sizeBytes: 21,
|
|
133
|
-
};
|
|
134
|
-
expect(file.path).toBe("src/index.ts");
|
|
135
|
-
expect(file.content).toBe("console.log('hello');");
|
|
136
|
-
expect(file.sizeBytes).toBe(21);
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
//# sourceMappingURL=audit-types.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"audit-types.test.js","sourceRoot":"","sources":["../../src/audit/audit-types.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { mkdtemp, writeFile, rm } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
5
|
-
import { loadAuditConfig } from "./config.js";
|
|
6
|
-
describe("config", () => {
|
|
7
|
-
let tmpDir;
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
tmpDir = await mkdtemp(join(tmpdir(), "vskill-config-"));
|
|
10
|
-
});
|
|
11
|
-
afterEach(async () => {
|
|
12
|
-
await rm(tmpDir, { recursive: true, force: true });
|
|
13
|
-
});
|
|
14
|
-
it("TC-050: returns defaults when no config file exists", async () => {
|
|
15
|
-
const config = await loadAuditConfig(tmpDir, {});
|
|
16
|
-
expect(config.excludePaths).toEqual([]);
|
|
17
|
-
expect(config.maxFiles).toBe(500);
|
|
18
|
-
expect(config.severityThreshold).toBe("low");
|
|
19
|
-
expect(config.tier1Only).toBe(false);
|
|
20
|
-
expect(config.fix).toBe(false);
|
|
21
|
-
});
|
|
22
|
-
it("TC-051: loads and merges .vskill-audit.json", async () => {
|
|
23
|
-
await writeFile(join(tmpDir, ".vskill-audit.json"), JSON.stringify({ excludePaths: ["vendor/"], maxFiles: 200 }));
|
|
24
|
-
const config = await loadAuditConfig(tmpDir, {});
|
|
25
|
-
expect(config.excludePaths).toEqual(["vendor/"]);
|
|
26
|
-
expect(config.maxFiles).toBe(200);
|
|
27
|
-
// Other fields remain defaults
|
|
28
|
-
expect(config.severityThreshold).toBe("low");
|
|
29
|
-
});
|
|
30
|
-
it("TC-052: CLI flags override config file values", async () => {
|
|
31
|
-
await writeFile(join(tmpDir, ".vskill-audit.json"), JSON.stringify({ maxFiles: 100 }));
|
|
32
|
-
const config = await loadAuditConfig(tmpDir, { maxFiles: "50" });
|
|
33
|
-
expect(config.maxFiles).toBe(50);
|
|
34
|
-
});
|
|
35
|
-
it("TC-053: invalid severity value throws error", async () => {
|
|
36
|
-
await expect(loadAuditConfig(tmpDir, { severity: "invalid" })).rejects.toThrow();
|
|
37
|
-
});
|
|
38
|
-
it("loads .vskillrc as fallback", async () => {
|
|
39
|
-
await writeFile(join(tmpDir, ".vskillrc"), JSON.stringify({ tier1Only: true }));
|
|
40
|
-
const config = await loadAuditConfig(tmpDir, {});
|
|
41
|
-
expect(config.tier1Only).toBe(true);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
//# sourceMappingURL=config.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/audit/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACtB,IAAI,MAAc,CAAC;IAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAClC,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAC7D,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,+BAA+B;QAC/B,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAClC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAClC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,CACV,eAAe,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CACjD,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,SAAS,CACb,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EACzB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CACpC,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|