@quantakrypto/core 0.3.0 → 0.4.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/dist/agent-types.d.ts +48 -0
- package/dist/agent-types.d.ts.map +1 -0
- package/dist/agent-types.js +2 -0
- package/dist/agent-types.js.map +1 -0
- package/dist/cache.d.ts +27 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +93 -0
- package/dist/cache.js.map +1 -0
- package/dist/cbom.d.ts.map +1 -1
- package/dist/cbom.js +26 -1
- package/dist/cbom.js.map +1 -1
- package/dist/changed.d.ts.map +1 -1
- package/dist/changed.js +14 -2
- package/dist/changed.js.map +1 -1
- package/dist/codemods/config-toggle.d.ts +3 -0
- package/dist/codemods/config-toggle.d.ts.map +1 -0
- package/dist/codemods/config-toggle.js +26 -0
- package/dist/codemods/config-toggle.js.map +1 -0
- package/dist/codemods/registry.d.ts +26 -0
- package/dist/codemods/registry.d.ts.map +1 -0
- package/dist/codemods/registry.js +8 -0
- package/dist/codemods/registry.js.map +1 -0
- package/dist/comments.d.ts +45 -0
- package/dist/comments.d.ts.map +1 -0
- package/dist/comments.js +164 -0
- package/dist/comments.js.map +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/dependencies.d.ts +31 -13
- package/dist/dependencies.d.ts.map +1 -1
- package/dist/dependencies.js +460 -40
- package/dist/dependencies.js.map +1 -1
- package/dist/detect-utils.d.ts +44 -1
- package/dist/detect-utils.d.ts.map +1 -1
- package/dist/detect-utils.js +113 -17
- package/dist/detect-utils.js.map +1 -1
- package/dist/detectors/c.d.ts +20 -0
- package/dist/detectors/c.d.ts.map +1 -0
- package/dist/detectors/c.js +104 -0
- package/dist/detectors/c.js.map +1 -0
- package/dist/detectors/csharp.d.ts +15 -0
- package/dist/detectors/csharp.d.ts.map +1 -0
- package/dist/detectors/csharp.js +76 -0
- package/dist/detectors/csharp.js.map +1 -0
- package/dist/detectors/go.d.ts +25 -0
- package/dist/detectors/go.d.ts.map +1 -0
- package/dist/detectors/go.js +132 -0
- package/dist/detectors/go.js.map +1 -0
- package/dist/detectors/java.d.ts +25 -0
- package/dist/detectors/java.d.ts.map +1 -0
- package/dist/detectors/java.js +200 -0
- package/dist/detectors/java.js.map +1 -0
- package/dist/detectors/python.d.ts +26 -0
- package/dist/detectors/python.d.ts.map +1 -0
- package/dist/detectors/python.js +171 -0
- package/dist/detectors/python.js.map +1 -0
- package/dist/detectors/ruby.d.ts +15 -0
- package/dist/detectors/ruby.d.ts.map +1 -0
- package/dist/detectors/ruby.js +75 -0
- package/dist/detectors/ruby.js.map +1 -0
- package/dist/detectors/rust.d.ts +13 -0
- package/dist/detectors/rust.d.ts.map +1 -0
- package/dist/detectors/rust.js +94 -0
- package/dist/detectors/rust.js.map +1 -0
- package/dist/detectors/source.d.ts.map +1 -1
- package/dist/detectors/source.js +70 -22
- package/dist/detectors/source.js.map +1 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/parallel.d.ts +4 -0
- package/dist/parallel.d.ts.map +1 -1
- package/dist/parallel.js +59 -8
- package/dist/parallel.js.map +1 -1
- package/dist/patch-policy.d.ts +22 -0
- package/dist/patch-policy.d.ts.map +1 -0
- package/dist/patch-policy.js +21 -0
- package/dist/patch-policy.js.map +1 -0
- package/dist/redact.d.ts +19 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +77 -0
- package/dist/redact.js.map +1 -0
- package/dist/registry.d.ts +13 -3
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +31 -4
- package/dist/registry.js.map +1 -1
- package/dist/remediate-pipeline.d.ts +41 -0
- package/dist/remediate-pipeline.d.ts.map +1 -0
- package/dist/remediate-pipeline.js +38 -0
- package/dist/remediate-pipeline.js.map +1 -0
- package/dist/remediate-request.d.ts +21 -0
- package/dist/remediate-request.d.ts.map +1 -0
- package/dist/remediate-request.js +28 -0
- package/dist/remediate-request.js.map +1 -0
- package/dist/remediation.d.ts +10 -0
- package/dist/remediation.d.ts.map +1 -1
- package/dist/remediation.js +21 -8
- package/dist/remediation.js.map +1 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +16 -1
- package/dist/report.js.map +1 -1
- package/dist/scan-worker.js +6 -2
- package/dist/scan-worker.js.map +1 -1
- package/dist/scan.d.ts +5 -4
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +52 -29
- package/dist/scan.js.map +1 -1
- package/dist/triage.d.ts +27 -0
- package/dist/triage.d.ts.map +1 -0
- package/dist/triage.js +33 -0
- package/dist/triage.js.map +1 -0
- package/dist/types.d.ts +53 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/verify.d.ts +30 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +65 -0
- package/dist/verify.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/walk.d.ts +7 -0
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +85 -11
- package/dist/walk.js.map +1 -1
- package/dist/worktree.d.ts +6 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +43 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +1 -1
- package/src/agent-types.ts +52 -0
- package/src/cache.ts +120 -0
- package/src/cbom.ts +27 -1
- package/src/changed.ts +13 -4
- package/src/codemods/config-toggle.ts +35 -0
- package/src/codemods/registry.ts +31 -0
- package/src/comments.ts +180 -0
- package/src/config.ts +8 -0
- package/src/dependencies.ts +483 -51
- package/src/detect-utils.ts +123 -15
- package/src/detectors/c.ts +132 -0
- package/src/detectors/csharp.ts +98 -0
- package/src/detectors/go.ts +167 -0
- package/src/detectors/java.ts +235 -0
- package/src/detectors/python.ts +212 -0
- package/src/detectors/ruby.ts +97 -0
- package/src/detectors/rust.ts +112 -0
- package/src/detectors/source.ts +69 -21
- package/src/index.ts +45 -1
- package/src/parallel.ts +63 -6
- package/src/patch-policy.ts +42 -0
- package/src/redact.ts +92 -0
- package/src/registry.ts +32 -4
- package/src/remediate-pipeline.ts +81 -0
- package/src/remediate-request.ts +52 -0
- package/src/remediation.ts +27 -11
- package/src/report.ts +27 -1
- package/src/scan-worker.ts +6 -2
- package/src/scan.ts +62 -31
- package/src/triage.ts +58 -0
- package/src/types.ts +66 -3
- package/src/verify.ts +82 -0
- package/src/version.ts +1 -1
- package/src/walk.ts +81 -12
- package/src/worktree.ts +45 -0
package/src/walk.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { readdir, stat } from "node:fs/promises";
|
|
|
8
8
|
import type { Dirent } from "node:fs";
|
|
9
9
|
import * as path from "node:path";
|
|
10
10
|
|
|
11
|
+
import { isManifestFile } from "./dependencies.js";
|
|
12
|
+
|
|
11
13
|
/** Directories ignored by default (can be disabled with noDefaultIgnores). */
|
|
12
14
|
export const DEFAULT_IGNORES: readonly string[] = [
|
|
13
15
|
"node_modules",
|
|
@@ -116,12 +118,80 @@ export function toPosix(p: string): string {
|
|
|
116
118
|
return p.split(path.sep).join("/");
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
/**
|
|
120
|
-
function
|
|
121
|
+
/** A pattern is treated as a glob when it contains one of these metacharacters. */
|
|
122
|
+
function hasGlobMeta(pattern: string): boolean {
|
|
123
|
+
return /[*?[]/.test(pattern);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Translate a glob into an anchored RegExp: `*` matches within a path segment
|
|
128
|
+
* (not `/`), `**` matches across segments, a leading `**` before a slash is an
|
|
129
|
+
* optional path prefix, `?` matches a single non-`/` char, `[...]` is a
|
|
130
|
+
* character class. Other regex
|
|
131
|
+
* metacharacters are escaped.
|
|
132
|
+
*/
|
|
133
|
+
function globToRegExp(glob: string): RegExp {
|
|
134
|
+
let re = "";
|
|
135
|
+
for (let i = 0; i < glob.length; i++) {
|
|
136
|
+
const c = glob[i];
|
|
137
|
+
if (c === "*") {
|
|
138
|
+
if (glob[i + 1] === "*") {
|
|
139
|
+
i++; // consume the second '*'
|
|
140
|
+
if (glob[i + 1] === "/") {
|
|
141
|
+
i++; // consume the trailing '/'
|
|
142
|
+
re += "(?:.*/)?"; // zero or more path segments
|
|
143
|
+
} else {
|
|
144
|
+
re += ".*"; // '**' spanning segments
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
re += "[^/]*"; // '*' within a segment
|
|
148
|
+
}
|
|
149
|
+
} else if (c === "?") {
|
|
150
|
+
re += "[^/]";
|
|
151
|
+
} else if (c === "[") {
|
|
152
|
+
// Pass a character class through; find its closing ']'.
|
|
153
|
+
const end = glob.indexOf("]", i + 1);
|
|
154
|
+
if (end === -1) {
|
|
155
|
+
re += "\\[";
|
|
156
|
+
} else {
|
|
157
|
+
re += glob.slice(i, end + 1);
|
|
158
|
+
i = end;
|
|
159
|
+
}
|
|
160
|
+
} else if ("\\^$.|+(){}".includes(c)) {
|
|
161
|
+
re += "\\" + c;
|
|
162
|
+
} else {
|
|
163
|
+
re += c;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return new RegExp(`^${re}$`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Memoized glob→RegExp so a pattern is compiled once, not once per file. */
|
|
170
|
+
const GLOB_CACHE = new Map<string, RegExp>();
|
|
171
|
+
function globRegExp(pattern: string): RegExp {
|
|
172
|
+
let re = GLOB_CACHE.get(pattern);
|
|
173
|
+
if (!re) {
|
|
174
|
+
re = globToRegExp(pattern);
|
|
175
|
+
GLOB_CACHE.set(pattern, re);
|
|
176
|
+
}
|
|
177
|
+
return re;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* True if `rel` (a POSIX relative path) matches any pattern. A pattern with a
|
|
182
|
+
* glob metacharacter (`*`, `?`, `[`) is matched as an anchored glob; a plain
|
|
183
|
+
* pattern keeps the historical substring / path-prefix semantics (so `"src"`
|
|
184
|
+
* still matches `src/a.ts` and `"secrets"` matches anywhere).
|
|
185
|
+
*/
|
|
186
|
+
export function matchesAny(rel: string, patterns: readonly string[]): boolean {
|
|
121
187
|
for (const pattern of patterns) {
|
|
122
188
|
if (!pattern) continue;
|
|
123
189
|
const p = toPosix(pattern).replace(/\/+$/, "");
|
|
124
|
-
|
|
190
|
+
if (hasGlobMeta(p)) {
|
|
191
|
+
if (globRegExp(p).test(rel)) return true;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
// Plain pattern: substring match (handles "src/legacy" or "secrets")...
|
|
125
195
|
if (rel.includes(p)) return true;
|
|
126
196
|
// ...and explicit path-prefix match ("foo" should match "foo/bar.ts").
|
|
127
197
|
if (rel === p || rel.startsWith(`${p}/`)) return true;
|
|
@@ -232,16 +302,12 @@ interface WalkContext {
|
|
|
232
302
|
* scanned for vulnerable dependencies instead of being silently dropped.
|
|
233
303
|
*/
|
|
234
304
|
function passesSizeLimit(rel: string, size: number, maxFileSize: number): boolean {
|
|
235
|
-
|
|
305
|
+
// Dependency manifests are always read (they can exceed the size cap but carry
|
|
306
|
+
// the whole dependency tree). Uses the single {@link isManifestFile} definition.
|
|
307
|
+
if (isManifestFile(rel)) return true;
|
|
236
308
|
return size <= maxFileSize;
|
|
237
309
|
}
|
|
238
310
|
|
|
239
|
-
/** True if the path's basename is a dependency manifest we always read. */
|
|
240
|
-
function isManifestPath(rel: string): boolean {
|
|
241
|
-
const base = rel.split("/").pop() ?? rel;
|
|
242
|
-
return base === "package.json" || base === "package-lock.json";
|
|
243
|
-
}
|
|
244
|
-
|
|
245
311
|
/** Internal recursive directory walker. `relDir` is POSIX-relative to the root. */
|
|
246
312
|
async function* walkDir(absDir: string, relDir: string, ctx: WalkContext): AsyncGenerator<string> {
|
|
247
313
|
let entries: Dirent[];
|
|
@@ -274,8 +340,11 @@ async function* walkDir(absDir: string, relDir: string, ctx: WalkContext): Async
|
|
|
274
340
|
if (!entry.isFile()) continue;
|
|
275
341
|
if (isExcluded(rel, ctx.exclude)) continue;
|
|
276
342
|
if (!isIncluded(rel, ctx.include)) continue;
|
|
277
|
-
|
|
278
|
-
|
|
343
|
+
// Dependency manifests (incl. yarn.lock / pnpm-lock.yaml) are always read —
|
|
344
|
+
// they carry the dependency tree and must not be dropped as binary/generated.
|
|
345
|
+
const manifest = isManifestFile(rel);
|
|
346
|
+
if (!manifest && isBinaryPath(rel)) continue;
|
|
347
|
+
if (!manifest && isGeneratedPath(rel)) continue;
|
|
279
348
|
|
|
280
349
|
try {
|
|
281
350
|
const s = await stat(abs);
|
package/src/worktree.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ephemeral git worktree runner. Remediation applies candidate patches inside a
|
|
3
|
+
* throwaway `git worktree` checked out at HEAD, so the user's working tree is
|
|
4
|
+
* never touched while patches are being tried and verified. The worktree is
|
|
5
|
+
* always removed afterwards, even if the callback throws.
|
|
6
|
+
*/
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
|
|
13
|
+
const exec = promisify(execFile);
|
|
14
|
+
|
|
15
|
+
async function git(args: string[], cwd?: string): Promise<void> {
|
|
16
|
+
await exec("git", args, { cwd });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Create a detached worktree of `repoRoot` at HEAD, run `fn` with its path, and
|
|
21
|
+
* always tear it down. Throws if `repoRoot` is not a git repository.
|
|
22
|
+
*/
|
|
23
|
+
export async function withWorktree<T>(
|
|
24
|
+
repoRoot: string,
|
|
25
|
+
fn: (dir: string) => Promise<T>,
|
|
26
|
+
): Promise<T> {
|
|
27
|
+
try {
|
|
28
|
+
await git(["rev-parse", "--is-inside-work-tree"], repoRoot);
|
|
29
|
+
} catch {
|
|
30
|
+
throw new Error(`withWorktree: "${repoRoot}" is not a git repository`);
|
|
31
|
+
}
|
|
32
|
+
const base = await mkdtemp(join(tmpdir(), "quantakrypto-wt-"));
|
|
33
|
+
const dir = join(base, "wt");
|
|
34
|
+
await git(["worktree", "add", "--detach", dir], repoRoot);
|
|
35
|
+
try {
|
|
36
|
+
return await fn(dir);
|
|
37
|
+
} finally {
|
|
38
|
+
try {
|
|
39
|
+
await git(["worktree", "remove", "--force", dir], repoRoot);
|
|
40
|
+
} catch {
|
|
41
|
+
// best effort — the temp dir removal below still reclaims the disk.
|
|
42
|
+
}
|
|
43
|
+
await rm(base, { recursive: true, force: true });
|
|
44
|
+
}
|
|
45
|
+
}
|