@hookwarden/engine 0.0.1 → 0.1.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/adapters/django.d.ts +4 -0
- package/dist/adapters/django.d.ts.map +1 -0
- package/dist/adapters/django.js +148 -0
- package/dist/adapters/django.js.map +1 -0
- package/dist/adapters/fastapi.d.ts +4 -0
- package/dist/adapters/fastapi.d.ts.map +1 -0
- package/dist/adapters/fastapi.js +118 -0
- package/dist/adapters/fastapi.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +10 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/nextjs.d.ts +4 -0
- package/dist/adapters/nextjs.d.ts.map +1 -0
- package/dist/adapters/nextjs.js +82 -0
- package/dist/adapters/nextjs.js.map +1 -0
- package/dist/evaluate.d.ts +6 -0
- package/dist/evaluate.d.ts.map +1 -0
- package/dist/evaluate.js +108 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/evaluator/index.d.ts +4 -0
- package/dist/evaluator/index.d.ts.map +1 -0
- package/dist/evaluator/index.js +4 -0
- package/dist/evaluator/index.js.map +1 -0
- package/dist/evaluator/matchers.d.ts +13 -0
- package/dist/evaluator/matchers.d.ts.map +1 -0
- package/dist/evaluator/matchers.js +124 -0
- package/dist/evaluator/matchers.js.map +1 -0
- package/dist/evaluator/parse-error.d.ts +4 -0
- package/dist/evaluator/parse-error.d.ts.map +1 -0
- package/dist/evaluator/parse-error.js +46 -0
- package/dist/evaluator/parse-error.js.map +1 -0
- package/dist/evaluator/path-severity-overrides.d.ts +4 -0
- package/dist/evaluator/path-severity-overrides.d.ts.map +1 -0
- package/dist/evaluator/path-severity-overrides.js +29 -0
- package/dist/evaluator/path-severity-overrides.js.map +1 -0
- package/dist/evaluator/visit.d.ts +16 -0
- package/dist/evaluator/visit.d.ts.map +1 -0
- package/dist/evaluator/visit.js +96 -0
- package/dist/evaluator/visit.js.map +1 -0
- package/dist/findings/fingerprint.d.ts +22 -0
- package/dist/findings/fingerprint.d.ts.map +1 -0
- package/dist/findings/fingerprint.js +39 -0
- package/dist/findings/fingerprint.js.map +1 -0
- package/dist/findings/index.d.ts +3 -0
- package/dist/findings/index.d.ts.map +1 -0
- package/dist/findings/index.js +4 -0
- package/dist/findings/index.js.map +1 -0
- package/dist/findings/webcrypto.d.ts +2 -0
- package/dist/findings/webcrypto.d.ts.map +1 -0
- package/dist/findings/webcrypto.js +15 -0
- package/dist/findings/webcrypto.js.map +1 -0
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/model/build.d.ts +12 -0
- package/dist/model/build.d.ts.map +1 -0
- package/dist/model/build.js +154 -0
- package/dist/model/build.js.map +1 -0
- package/dist/model/catalog.d.ts +17 -0
- package/dist/model/catalog.d.ts.map +1 -0
- package/dist/model/catalog.js +303 -0
- package/dist/model/catalog.js.map +1 -0
- package/dist/model/evidence.d.ts +18 -0
- package/dist/model/evidence.d.ts.map +1 -0
- package/dist/model/evidence.js +114 -0
- package/dist/model/evidence.js.map +1 -0
- package/dist/model/index.d.ts +6 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +7 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/middleware.d.ts +10 -0
- package/dist/model/middleware.d.ts.map +1 -0
- package/dist/model/middleware.js +140 -0
- package/dist/model/middleware.js.map +1 -0
- package/dist/model/reachability.d.ts +11 -0
- package/dist/model/reachability.d.ts.map +1 -0
- package/dist/model/reachability.js +260 -0
- package/dist/model/reachability.js.map +1 -0
- package/dist/parsers/babel.d.ts +11 -0
- package/dist/parsers/babel.d.ts.map +1 -0
- package/dist/parsers/babel.js +121 -0
- package/dist/parsers/babel.js.map +1 -0
- package/dist/parsers/index.d.ts +6 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +7 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/literals.d.ts +4 -0
- package/dist/parsers/literals.d.ts.map +1 -0
- package/dist/parsers/literals.js +37 -0
- package/dist/parsers/literals.js.map +1 -0
- package/dist/parsers/python-literals.d.ts +5 -0
- package/dist/parsers/python-literals.d.ts.map +1 -0
- package/dist/parsers/python-literals.js +62 -0
- package/dist/parsers/python-literals.js.map +1 -0
- package/dist/parsers/python-loader.d.ts +9 -0
- package/dist/parsers/python-loader.d.ts.map +1 -0
- package/dist/parsers/python-loader.js +16 -0
- package/dist/parsers/python-loader.js.map +1 -0
- package/dist/parsers/python.d.ts +8 -0
- package/dist/parsers/python.d.ts.map +1 -0
- package/dist/parsers/python.js +125 -0
- package/dist/parsers/python.js.map +1 -0
- package/dist/parsers/walk.d.ts +15 -0
- package/dist/parsers/walk.d.ts.map +1 -0
- package/dist/parsers/walk.js +66 -0
- package/dist/parsers/walk.js.map +1 -0
- package/dist/redaction/index.d.ts +3 -0
- package/dist/redaction/index.d.ts.map +1 -0
- package/dist/redaction/index.js +2 -0
- package/dist/redaction/index.js.map +1 -0
- package/dist/redaction/structural.d.ts +14 -0
- package/dist/redaction/structural.d.ts.map +1 -0
- package/dist/redaction/structural.js +37 -0
- package/dist/redaction/structural.js.map +1 -0
- package/dist/types/config.d.ts +7 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/finding.d.ts +32 -0
- package/dist/types/finding.d.ts.map +1 -0
- package/dist/types/finding.js +12 -0
- package/dist/types/finding.js.map +1 -0
- package/dist/types/handler.d.ts +39 -0
- package/dist/types/handler.d.ts.map +1 -0
- package/dist/types/handler.js +7 -0
- package/dist/types/handler.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/project-model.d.ts +42 -0
- package/dist/types/project-model.d.ts.map +1 -0
- package/dist/types/project-model.js +5 -0
- package/dist/types/project-model.js.map +1 -0
- package/dist/types/rule-set.d.ts +42 -0
- package/dist/types/rule-set.d.ts.map +1 -0
- package/dist/types/rule-set.js +6 -0
- package/dist/types/rule-set.js.map +1 -0
- package/dist/types/scan-result.d.ts +19 -0
- package/dist/types/scan-result.d.ts.map +1 -0
- package/dist/types/scan-result.js +8 -0
- package/dist/types/scan-result.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +12 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parsers/index.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAuD,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAyB,WAAW,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAEL,iBAAiB,GAElB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"literals.d.ts","sourceRoot":"","sources":["../../src/parsers/literals.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAa9D,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,GAAG,aAAa,CAAC,WAAW,CAAC,CA0BjF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Walks a Babel File and extracts every literal span the redactor needs.
|
|
2
|
+
// Pure traversal: depth-first via the shared walkUntypedAst helper. No @babel/traverse dep.
|
|
3
|
+
import { walkUntypedAst } from "./walk.js";
|
|
4
|
+
function pushSpan(out, kind, node, value) {
|
|
5
|
+
if (typeof node.start !== "number" || typeof node.end !== "number")
|
|
6
|
+
return;
|
|
7
|
+
out.push({ kind, start: node.start, end: node.end, value });
|
|
8
|
+
}
|
|
9
|
+
export function extractBabelLiterals(ast) {
|
|
10
|
+
if (ast === null)
|
|
11
|
+
return [];
|
|
12
|
+
const out = [];
|
|
13
|
+
walkUntypedAst(ast, (node) => {
|
|
14
|
+
switch (node.type) {
|
|
15
|
+
case "StringLiteral":
|
|
16
|
+
pushSpan(out, "string", node, node.value);
|
|
17
|
+
return;
|
|
18
|
+
case "NumericLiteral":
|
|
19
|
+
case "BigIntLiteral":
|
|
20
|
+
pushSpan(out, "number", node, String(node.value));
|
|
21
|
+
return;
|
|
22
|
+
case "TemplateLiteral":
|
|
23
|
+
// Whole template captured as one span so substitution values cannot survive redaction.
|
|
24
|
+
pushSpan(out, "template", node, "<TEMPLATE>");
|
|
25
|
+
return;
|
|
26
|
+
case "RegExpLiteral":
|
|
27
|
+
pushSpan(out, "regex", node, node.pattern);
|
|
28
|
+
return;
|
|
29
|
+
default:
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
// Stable order: ascending by start.
|
|
34
|
+
out.sort((a, b) => a.start - b.start);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=literals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"literals.js","sourceRoot":"","sources":["../../src/parsers/literals.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4FAA4F;AAI5F,OAAO,EAAqB,cAAc,EAAE,MAAM,WAAW,CAAC;AAE9D,SAAS,QAAQ,CACf,GAAkB,EAClB,IAAyB,EACzB,IAAkB,EAClB,KAAa;IAEb,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;QAAE,OAAO;IAC3E,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAgB;IACnD,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,cAAc,CAAC,GAA8B,EAAE,CAAC,IAAI,EAAE,EAAE;QACtD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,eAAe;gBAClB,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAG,IAAqC,CAAC,KAAK,CAAC,CAAC;gBAC5E,OAAO;YACT,KAAK,gBAAgB,CAAC;YACtB,KAAK,eAAe;gBAClB,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAE,IAAsC,CAAC,KAAK,CAAC,CAAC,CAAC;gBACrF,OAAO;YACT,KAAK,iBAAiB;gBACpB,uFAAuF;gBACvF,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;gBAC9C,OAAO;YACT,KAAK,eAAe;gBAClB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAG,IAAuC,CAAC,OAAO,CAAC,CAAC;gBAC/E,OAAO;YACT;gBACE,OAAO;QACX,CAAC;IACH,CAAC,CAAC,CAAC;IACH,oCAAoC;IACpC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Node, Tree } from "web-tree-sitter";
|
|
2
|
+
import type { LiteralSpan } from "../redaction/structural.js";
|
|
3
|
+
export declare function extractPythonLiterals(tree: Tree | null): ReadonlyArray<LiteralSpan>;
|
|
4
|
+
export type { Node as TreeSitterNode };
|
|
5
|
+
//# sourceMappingURL=python-literals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-literals.d.ts","sourceRoot":"","sources":["../../src/parsers/python-literals.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAO9D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,aAAa,CAAC,WAAW,CAAC,CAsCnF;AAkBD,YAAY,EAAE,IAAI,IAAI,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Walks a tree-sitter-python tree and emits LiteralSpan[] for the redactor (D-39).
|
|
2
|
+
// Pure: in-memory tree traversal only — engine purity gate (D-01) bans any I/O imports.
|
|
3
|
+
// tree-sitter-python literal node types we care about. (Confirmed against tree-sitter-python's
|
|
4
|
+
// `node-types.json`; if a grammar bump renames any of these, update this list.)
|
|
5
|
+
const STRING_NODES = ["string"];
|
|
6
|
+
const NUMBER_NODES = ["integer", "float"];
|
|
7
|
+
export function extractPythonLiterals(tree) {
|
|
8
|
+
if (tree === null)
|
|
9
|
+
return [];
|
|
10
|
+
const out = [];
|
|
11
|
+
const root = tree.rootNode;
|
|
12
|
+
for (const node of root.descendantsOfType([...STRING_NODES, ...NUMBER_NODES])) {
|
|
13
|
+
if (NUMBER_NODES.includes(node.type)) {
|
|
14
|
+
out.push({
|
|
15
|
+
kind: "number",
|
|
16
|
+
start: node.startIndex,
|
|
17
|
+
end: node.endIndex,
|
|
18
|
+
value: node.text,
|
|
19
|
+
});
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
// String literal. Detect f-string by looking for an `interpolation` named descendant.
|
|
23
|
+
// (Some grammar versions use `string_interpolation`; treat both as template.)
|
|
24
|
+
const isTemplate = node.descendantsOfType(["interpolation", "string_interpolation"]).length > 0;
|
|
25
|
+
if (isTemplate) {
|
|
26
|
+
out.push({
|
|
27
|
+
kind: "template",
|
|
28
|
+
start: node.startIndex,
|
|
29
|
+
end: node.endIndex,
|
|
30
|
+
value: "<TEMPLATE>",
|
|
31
|
+
});
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
// Plain string literal. The `text` field includes the quote characters and any prefix
|
|
35
|
+
// (b, r, u). Strip prefix + quotes to get the inner value for length-aware redaction.
|
|
36
|
+
const innerValue = stripPythonQuotes(node.text);
|
|
37
|
+
out.push({
|
|
38
|
+
kind: "string",
|
|
39
|
+
start: node.startIndex,
|
|
40
|
+
end: node.endIndex,
|
|
41
|
+
value: innerValue,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
out.sort((a, b) => a.start - b.start);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function stripPythonQuotes(raw) {
|
|
48
|
+
// Strip any prefix character (b, r, u, B, R, U, plus combos like rb, fr).
|
|
49
|
+
let i = 0;
|
|
50
|
+
while (i < raw.length && /[bBrRuUfF]/.test(raw[i] ?? ""))
|
|
51
|
+
i++;
|
|
52
|
+
const quoted = raw.slice(i);
|
|
53
|
+
// Triple-quoted ('''x''' or """x""") and single-quoted ('x' or "x").
|
|
54
|
+
if (quoted.startsWith('"""') || quoted.startsWith("'''")) {
|
|
55
|
+
return quoted.slice(3, quoted.length - 3);
|
|
56
|
+
}
|
|
57
|
+
if (quoted.startsWith('"') || quoted.startsWith("'")) {
|
|
58
|
+
return quoted.slice(1, quoted.length - 1);
|
|
59
|
+
}
|
|
60
|
+
return quoted;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=python-literals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-literals.js","sourceRoot":"","sources":["../../src/parsers/python-literals.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,wFAAwF;AAKxF,+FAA+F;AAC/F,gFAAgF;AAChF,MAAM,YAAY,GAAG,CAAC,QAAQ,CAAU,CAAC;AACzC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,OAAO,CAAU,CAAC;AAEnD,MAAM,UAAU,qBAAqB,CAAC,IAAiB;IACrD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC,CAAC,EAAE,CAAC;QAC9E,IAAK,YAAkC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5D,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,IAAI,CAAC,UAAU;gBACtB,GAAG,EAAE,IAAI,CAAC,QAAQ;gBAClB,KAAK,EAAE,IAAI,CAAC,IAAI;aACjB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,sFAAsF;QACtF,8EAA8E;QAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAChG,IAAI,UAAU,EAAE,CAAC;YACf,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,IAAI,CAAC,UAAU;gBACtB,GAAG,EAAE,IAAI,CAAC,QAAQ;gBAClB,KAAK,EAAE,YAAY;aACpB,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,sFAAsF;QACtF,sFAAsF;QACtF,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI,CAAC,UAAU;YACtB,GAAG,EAAE,IAAI,CAAC,QAAQ;YAClB,KAAK,EAAE,UAAU;SAClB,CAAC,CAAC;IACL,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,0EAA0E;IAC1E,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAAE,CAAC,EAAE,CAAC;IAC9D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC5B,qEAAqE;IACrE,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Parser } from "web-tree-sitter";
|
|
2
|
+
export interface PythonRuntime {
|
|
3
|
+
readonly parser: Parser;
|
|
4
|
+
}
|
|
5
|
+
export interface InitPythonRuntimeInput {
|
|
6
|
+
readonly wasmBytes: Uint8Array;
|
|
7
|
+
}
|
|
8
|
+
export declare function initPythonRuntime(input: InitPythonRuntimeInput): Promise<PythonRuntime>;
|
|
9
|
+
//# sourceMappingURL=python-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-loader.d.ts","sourceRoot":"","sources":["../../src/parsers/python-loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAY,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IAErC,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAChC;AAID,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,CAS7F"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Caller-supplied init for the tree-sitter-python WASM runtime.
|
|
2
|
+
// D-01 engine purity: this module never opens the .wasm file. The CLI runner reads
|
|
3
|
+
// it from disk (or fetch in a future browser playground build) and passes the bytes.
|
|
4
|
+
import { Language, Parser } from "web-tree-sitter";
|
|
5
|
+
let parserInited = false;
|
|
6
|
+
export async function initPythonRuntime(input) {
|
|
7
|
+
if (!parserInited) {
|
|
8
|
+
await Parser.init();
|
|
9
|
+
parserInited = true;
|
|
10
|
+
}
|
|
11
|
+
const language = await Language.load(input.wasmBytes);
|
|
12
|
+
const parser = new Parser();
|
|
13
|
+
parser.setLanguage(language);
|
|
14
|
+
return { parser };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=python-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-loader.js","sourceRoot":"","sources":["../../src/parsers/python-loader.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,mFAAmF;AACnF,qFAAqF;AAErF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAWnD,IAAI,YAAY,GAAG,KAAK,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAA6B;IACnE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParsedFile } from "../types/project-model.js";
|
|
2
|
+
import type { PythonRuntime } from "./python-loader.js";
|
|
3
|
+
export interface ParsePythonInput {
|
|
4
|
+
readonly file_path: string;
|
|
5
|
+
readonly source_text: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function parsePython(input: ParsePythonInput, runtime: PythonRuntime): Promise<ParsedFile>;
|
|
8
|
+
//# sourceMappingURL=python.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/parsers/python.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAc,UAAU,EAAoB,MAAM,2BAA2B,CAAC;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,UAAU,CAAC,CA2BrB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Python parser adapter (ENGINE-02). web-tree-sitter (WASM) + tree-sitter-python.
|
|
2
|
+
// D-27 all-or-nothing: any ERROR or MISSING node in the parse output triggers a ParseErrorRecord.
|
|
3
|
+
// PITFALLS #6: tree-sitter-python decorator-grammar gaps surface here as parse errors,
|
|
4
|
+
// NOT as silently-skipped files. The all-or-nothing policy is the user-visible signal.
|
|
5
|
+
export async function parsePython(input, runtime) {
|
|
6
|
+
const { file_path, source_text } = input;
|
|
7
|
+
// tree-sitter never throws on parse — it always returns a tree (possibly null on OOM).
|
|
8
|
+
// Errors surface as ERROR / MISSING nodes inside the tree.
|
|
9
|
+
const tree = runtime.parser.parse(source_text);
|
|
10
|
+
let parseError = null;
|
|
11
|
+
if (tree === null) {
|
|
12
|
+
parseError = {
|
|
13
|
+
message: "tree-sitter-python: parser returned null tree",
|
|
14
|
+
location: { line: 1, col: 1 },
|
|
15
|
+
source: "tree-sitter",
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
parseError = findFirstError(tree.rootNode);
|
|
20
|
+
}
|
|
21
|
+
const cleanTree = parseError === null ? tree : null;
|
|
22
|
+
const imports = cleanTree === null ? [] : extractImports(cleanTree.rootNode, file_path);
|
|
23
|
+
return {
|
|
24
|
+
file_path,
|
|
25
|
+
language: "python",
|
|
26
|
+
dialect: "tree-sitter-python",
|
|
27
|
+
source_text,
|
|
28
|
+
raw_ast: cleanTree, // D-27: null on error
|
|
29
|
+
imports,
|
|
30
|
+
parse_error: parseError,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function findFirstError(root) {
|
|
34
|
+
// DFS from rootNode; stop at first ERROR or MISSING node.
|
|
35
|
+
const stack = [root];
|
|
36
|
+
while (stack.length > 0) {
|
|
37
|
+
const node = stack.pop();
|
|
38
|
+
if (!node)
|
|
39
|
+
break;
|
|
40
|
+
if (node.type === "ERROR" || node.isMissing) {
|
|
41
|
+
return {
|
|
42
|
+
message: node.isMissing
|
|
43
|
+
? `tree-sitter-python: missing token (${node.type})`
|
|
44
|
+
: `tree-sitter-python: ERROR node at ${node.startPosition.row + 1}:${node.startPosition.column + 1}`,
|
|
45
|
+
location: { line: node.startPosition.row + 1, col: node.startPosition.column + 1 },
|
|
46
|
+
source: "tree-sitter",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (!node.hasError)
|
|
50
|
+
continue; // entire subtree is clean; skip
|
|
51
|
+
for (const child of node.namedChildren) {
|
|
52
|
+
if (child !== null)
|
|
53
|
+
stack.push(child);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
function extractImports(root, fromFile) {
|
|
59
|
+
const out = [];
|
|
60
|
+
// tree-sitter-python distinguishes:
|
|
61
|
+
// import_statement → `import a`, `import a as b`, `import a, c`
|
|
62
|
+
// import_from_statement → `from a import b`, `from a import b as c`, `from a import (b, c)`
|
|
63
|
+
for (const node of root.descendantsOfType(["import_statement", "import_from_statement"])) {
|
|
64
|
+
if (node.type === "import_statement") {
|
|
65
|
+
// Children include dotted_name | aliased_import nodes.
|
|
66
|
+
for (const child of node.namedChildren) {
|
|
67
|
+
if (child === null)
|
|
68
|
+
continue;
|
|
69
|
+
if (child.type === "dotted_name") {
|
|
70
|
+
out.push({
|
|
71
|
+
from_file: fromFile,
|
|
72
|
+
to_module: child.text,
|
|
73
|
+
imported_names: [{ local: child.text, source: "default" }],
|
|
74
|
+
is_default: true,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (child.type === "aliased_import") {
|
|
78
|
+
const name = child.childForFieldName("name")?.text ?? "";
|
|
79
|
+
const alias = child.childForFieldName("alias")?.text ?? name;
|
|
80
|
+
out.push({
|
|
81
|
+
from_file: fromFile,
|
|
82
|
+
to_module: name,
|
|
83
|
+
imported_names: [{ local: alias, source: "default" }],
|
|
84
|
+
is_default: true,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// import_from_statement. The module_name field child is itself a dotted_name, so identifying
|
|
91
|
+
// imported-name children requires comparing byte offsets — tree-sitter returns fresh node
|
|
92
|
+
// objects on each accessor, so reference equality is not reliable.
|
|
93
|
+
const moduleNode = node.childForFieldName("module_name");
|
|
94
|
+
const moduleName = moduleNode?.text ?? "";
|
|
95
|
+
const moduleStart = moduleNode?.startIndex ?? -1;
|
|
96
|
+
const moduleEnd = moduleNode?.endIndex ?? -1;
|
|
97
|
+
const names = [];
|
|
98
|
+
for (const child of node.namedChildren) {
|
|
99
|
+
if (child === null)
|
|
100
|
+
continue;
|
|
101
|
+
// Skip the module_name child by byte-offset match.
|
|
102
|
+
if (child.startIndex === moduleStart && child.endIndex === moduleEnd)
|
|
103
|
+
continue;
|
|
104
|
+
if (child.type === "dotted_name") {
|
|
105
|
+
names.push({ local: child.text, source: child.text });
|
|
106
|
+
}
|
|
107
|
+
else if (child.type === "aliased_import") {
|
|
108
|
+
const src = child.childForFieldName("name")?.text ?? "";
|
|
109
|
+
const alias = child.childForFieldName("alias")?.text ?? src;
|
|
110
|
+
names.push({ local: alias, source: src });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (moduleName !== "") {
|
|
114
|
+
out.push({
|
|
115
|
+
from_file: fromFile,
|
|
116
|
+
to_module: moduleName,
|
|
117
|
+
imported_names: names,
|
|
118
|
+
is_default: false,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=python.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.js","sourceRoot":"","sources":["../../src/parsers/python.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Node } from "@babel/types";
|
|
2
|
+
/**
|
|
3
|
+
* Walk a Babel AST depth-first, invoking `visitor` on every node.
|
|
4
|
+
*
|
|
5
|
+
* The visitor cannot stop traversal — call sites that need early-exit semantics
|
|
6
|
+
* collect into an output array and inspect it after the walk completes.
|
|
7
|
+
*/
|
|
8
|
+
export declare function walkBabelAst(root: Node, visitor: (node: Node) => void): void;
|
|
9
|
+
export interface MaybeAstNode {
|
|
10
|
+
readonly type?: string;
|
|
11
|
+
readonly start?: number | null;
|
|
12
|
+
readonly end?: number | null;
|
|
13
|
+
}
|
|
14
|
+
export declare function walkUntypedAst(root: MaybeAstNode | null | undefined, visitor: (node: MaybeAstNode) => void): void;
|
|
15
|
+
//# sourceMappingURL=walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../src/parsers/walk.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMzC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAoB5E;AAMD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,EACrC,OAAO,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GACpC,IAAI,CAqBN"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Canonical iterative AST walkers. Engine has multiple readers (literal extraction, catalog
|
|
2
|
+
// detection, future reachability + middleware extraction in Plan 06b, evaluator dispatch in
|
|
3
|
+
// Plan 02-08) — all use the same depth-first walk.
|
|
4
|
+
//
|
|
5
|
+
// Iterative (not recursive) so deeply-nested ASTs cannot exhaust the JS stack — a real concern
|
|
6
|
+
// for adversarial source. Bounded by the parser's source-size cap (Phase 8 worker concern).
|
|
7
|
+
// Keys we never recurse into. `loc` is metadata; `start`/`end` are byte offsets;
|
|
8
|
+
// `range` is a tuple alias for start/end; `type` is the node discriminator itself.
|
|
9
|
+
const SKIP_KEYS = new Set(["loc", "type", "start", "end", "range"]);
|
|
10
|
+
/**
|
|
11
|
+
* Walk a Babel AST depth-first, invoking `visitor` on every node.
|
|
12
|
+
*
|
|
13
|
+
* The visitor cannot stop traversal — call sites that need early-exit semantics
|
|
14
|
+
* collect into an output array and inspect it after the walk completes.
|
|
15
|
+
*/
|
|
16
|
+
export function walkBabelAst(root, visitor) {
|
|
17
|
+
const stack = [root];
|
|
18
|
+
while (stack.length > 0) {
|
|
19
|
+
const node = stack.pop();
|
|
20
|
+
if (!node)
|
|
21
|
+
break;
|
|
22
|
+
visitor(node);
|
|
23
|
+
for (const key of Object.keys(node)) {
|
|
24
|
+
if (SKIP_KEYS.has(key))
|
|
25
|
+
continue;
|
|
26
|
+
const value = node[key];
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
for (const item of value) {
|
|
29
|
+
if (item && typeof item === "object" && "type" in item) {
|
|
30
|
+
stack.push(item);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (value && typeof value === "object" && "type" in value) {
|
|
35
|
+
stack.push(value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function walkUntypedAst(root, visitor) {
|
|
41
|
+
if (!root || typeof root.type !== "string")
|
|
42
|
+
return;
|
|
43
|
+
const stack = [root];
|
|
44
|
+
while (stack.length > 0) {
|
|
45
|
+
const node = stack.pop();
|
|
46
|
+
if (!node)
|
|
47
|
+
break;
|
|
48
|
+
visitor(node);
|
|
49
|
+
for (const key of Object.keys(node)) {
|
|
50
|
+
if (SKIP_KEYS.has(key))
|
|
51
|
+
continue;
|
|
52
|
+
const value = node[key];
|
|
53
|
+
if (Array.isArray(value)) {
|
|
54
|
+
for (const item of value) {
|
|
55
|
+
if (item && typeof item === "object" && "type" in item) {
|
|
56
|
+
stack.push(item);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (value && typeof value === "object" && "type" in value) {
|
|
61
|
+
stack.push(value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/parsers/walk.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,4FAA4F;AAC5F,mDAAmD;AACnD,EAAE;AACF,+FAA+F;AAC/F,4FAA4F;AAI5F,iFAAiF;AACjF,mFAAmF;AACnF,MAAM,SAAS,GAAwB,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAEzF;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAU,EAAE,OAA6B;IACpE,MAAM,KAAK,GAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,MAAM;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjC,MAAM,KAAK,GAAI,IAA2C,CAAC,GAAG,CAAC,CAAC;YAChE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAK,IAAe,EAAE,CAAC;wBACnE,KAAK,CAAC,IAAI,CAAC,IAAY,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAK,KAAgB,EAAE,CAAC;gBAC7E,KAAK,CAAC,IAAI,CAAC,KAAa,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAYD,MAAM,UAAU,cAAc,CAC5B,IAAqC,EACrC,OAAqC;IAErC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO;IACnD,MAAM,KAAK,GAAmB,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,MAAM;QACjB,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YACjC,MAAM,KAAK,GAAI,IAA2C,CAAC,GAAG,CAAC,CAAC;YAChE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAK,IAAe,EAAE,CAAC;wBACnE,KAAK,CAAC,IAAI,CAAC,IAAoB,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAK,KAAgB,EAAE,CAAC;gBAC7E,KAAK,CAAC,IAAI,CAAC,KAAqB,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redaction/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redaction/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type LiteralKind = "string" | "number" | "template" | "regex" | "secret";
|
|
2
|
+
export interface LiteralSpan {
|
|
3
|
+
readonly kind: LiteralKind;
|
|
4
|
+
readonly start: number;
|
|
5
|
+
readonly end: number;
|
|
6
|
+
readonly value: string;
|
|
7
|
+
}
|
|
8
|
+
export interface RedactionInput {
|
|
9
|
+
readonly source_text: string;
|
|
10
|
+
readonly literals: ReadonlyArray<LiteralSpan>;
|
|
11
|
+
readonly secret_literal_prefixes?: ReadonlyArray<string>;
|
|
12
|
+
}
|
|
13
|
+
export declare function redactSnippet(input: RedactionInput): string;
|
|
14
|
+
//# sourceMappingURL=structural.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural.d.ts","sourceRoot":"","sources":["../../src/redaction/structural.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,OAAO,GACP,QAAQ,CAAC;AAEb,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAG9C,QAAQ,CAAC,uBAAuB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC1D;AAuBD,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAQ3D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// D-39: structural snippet redaction. Literals → typed placeholders; identifiers preserved.
|
|
2
|
+
// Browser-safe: pure string transformation, no Node built-ins.
|
|
3
|
+
// Property-tested: every string literal becomes <STRING:N>; every identifier is unchanged.
|
|
4
|
+
// Sort spans descending by start so we can splice without shifting indices.
|
|
5
|
+
function sortSpans(spans) {
|
|
6
|
+
return [...spans].sort((a, b) => b.start - a.start);
|
|
7
|
+
}
|
|
8
|
+
function placeholderFor(span, secretPrefixes) {
|
|
9
|
+
if (span.kind === "secret")
|
|
10
|
+
return "<SECRET_LITERAL>";
|
|
11
|
+
if (span.kind === "string") {
|
|
12
|
+
for (const prefix of secretPrefixes) {
|
|
13
|
+
if (span.value.startsWith(prefix))
|
|
14
|
+
return "<SECRET_LITERAL>";
|
|
15
|
+
}
|
|
16
|
+
return `<STRING:${span.value.length}>`;
|
|
17
|
+
}
|
|
18
|
+
if (span.kind === "number")
|
|
19
|
+
return "<NUMBER>";
|
|
20
|
+
if (span.kind === "template")
|
|
21
|
+
return "<TEMPLATE>";
|
|
22
|
+
if (span.kind === "regex")
|
|
23
|
+
return "<REGEX>";
|
|
24
|
+
// Exhaustiveness: every LiteralKind covered above.
|
|
25
|
+
const _exhaustive = span.kind;
|
|
26
|
+
return `<UNKNOWN:${_exhaustive}>`;
|
|
27
|
+
}
|
|
28
|
+
export function redactSnippet(input) {
|
|
29
|
+
const secretPrefixes = input.secret_literal_prefixes ?? [];
|
|
30
|
+
let out = input.source_text;
|
|
31
|
+
for (const span of sortSpans(input.literals)) {
|
|
32
|
+
const placeholder = placeholderFor(span, secretPrefixes);
|
|
33
|
+
out = out.slice(0, span.start) + placeholder + out.slice(span.end);
|
|
34
|
+
}
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=structural.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural.js","sourceRoot":"","sources":["../../src/redaction/structural.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,+DAA+D;AAC/D,2FAA2F;AAwB3F,4EAA4E;AAC5E,SAAS,SAAS,CAAC,KAAiC;IAClD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,cAAc,CAAC,IAAiB,EAAE,cAAqC;IAC9E,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,kBAAkB,CAAC;IACtD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,OAAO,kBAAkB,CAAC;QAC/D,CAAC;QACD,OAAO,WAAW,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;IACzC,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC;IAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC;IAClD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAC5C,mDAAmD;IACnD,MAAM,WAAW,GAAU,IAAI,CAAC,IAAI,CAAC;IACrC,OAAO,YAAY,WAAqB,GAAG,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAqB;IACjD,MAAM,cAAc,GAAG,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC;IAC3D,IAAI,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QACzD,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,MAAM;IAErB,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IAExC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// D-01: Engine is pure — caller supplies wall clock and git context, engine never reads them.
|
|
2
|
+
// D-34: reachability_max_depth bounds handler reachability walk (default 3 hops).
|
|
3
|
+
// D-38: engine_commit_sha and total_files_count flow through Config into ScanMetadata.
|
|
4
|
+
// ENGINE-06: bounded reachability depth keeps the 30s/50KLOC perf budget achievable.
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,kFAAkF;AAClF,uFAAuF;AACvF,qFAAqF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type Severity = "critical" | "high" | "medium" | "low" | "info";
|
|
2
|
+
export type SuppressionSource = "inline" | "ignore" | "baseline";
|
|
3
|
+
export interface SuppressedPayload {
|
|
4
|
+
readonly source: SuppressionSource;
|
|
5
|
+
readonly pattern?: string;
|
|
6
|
+
readonly comment?: string;
|
|
7
|
+
readonly baselined_at?: string;
|
|
8
|
+
}
|
|
9
|
+
export type Verdict = "verified" | "not-verified" | "manual-review";
|
|
10
|
+
export type FindingId = string;
|
|
11
|
+
export interface SourceLocation {
|
|
12
|
+
readonly line: number;
|
|
13
|
+
readonly col: number;
|
|
14
|
+
readonly end_line: number;
|
|
15
|
+
readonly end_col: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Finding {
|
|
18
|
+
readonly id: FindingId;
|
|
19
|
+
readonly rule_id: string;
|
|
20
|
+
readonly provider: string;
|
|
21
|
+
readonly severity: Severity;
|
|
22
|
+
readonly state: Verdict;
|
|
23
|
+
readonly file_path: string;
|
|
24
|
+
readonly location: SourceLocation;
|
|
25
|
+
readonly snippet: string;
|
|
26
|
+
readonly handler_id: string | null;
|
|
27
|
+
readonly primary_location_line_hash: string;
|
|
28
|
+
readonly message: string;
|
|
29
|
+
readonly metadata: Readonly<Record<string, string | number | boolean | null>>;
|
|
30
|
+
readonly suppressed?: SuppressedPayload | null;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=finding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding.d.ts","sourceRoot":"","sources":["../../src/types/finding.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAIvE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAGD,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,cAAc,GAAG,eAAe,CAAC;AAGpE,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,0BAA0B,EAAE,MAAM,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAChD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// D-29: Verdict three-state output.
|
|
2
|
+
// D-30: FindingId is a stable composite hash string.
|
|
3
|
+
// D-37: Composite stable id is sha256 hex from WebCrypto.
|
|
4
|
+
// D-39: snippet is the structurally redacted slice.
|
|
5
|
+
// D-63: Suppressed findings stay in findings[] with a payload describing the source.
|
|
6
|
+
// Engine emits suppressed = null/undefined; the CLI Phase 4 suppression annotator
|
|
7
|
+
// populates non-null values. The field is optional so existing engine emit sites
|
|
8
|
+
// compile unchanged.
|
|
9
|
+
// ENGINE-04: Finding carries fingerprint, file path, line:col, severity, provider,
|
|
10
|
+
// three-state state field, and redacted snippet.
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=finding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding.js","sourceRoot":"","sources":["../../src/types/finding.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,qDAAqD;AACrD,0DAA0D;AAC1D,oDAAoD;AACpD,qFAAqF;AACrF,wFAAwF;AACxF,uFAAuF;AACvF,2BAA2B;AAC3B,mFAAmF;AACnF,4DAA4D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { FindingId, SourceLocation, Verdict } from "./finding.ts";
|
|
2
|
+
export type Framework = "express" | "hono" | "fastify" | "nextjs" | "flask" | "fastapi" | "django";
|
|
3
|
+
export type WebhookEvidenceKind = "path_pattern_match" | "signature_header_read" | "sdk_import" | "sdk_verify_call" | "body_as_bytes_or_buffer" | "secret_env_var_reference" | "secret_literal_match";
|
|
4
|
+
export interface WebhookEvidence {
|
|
5
|
+
readonly kind: WebhookEvidenceKind;
|
|
6
|
+
readonly provider: string;
|
|
7
|
+
readonly location: SourceLocation;
|
|
8
|
+
readonly detail: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ResolvedMiddleware {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly import_source: string | null;
|
|
13
|
+
readonly position: number;
|
|
14
|
+
readonly location: SourceLocation;
|
|
15
|
+
}
|
|
16
|
+
export interface ReachableSymbol {
|
|
17
|
+
readonly qualified_name: string;
|
|
18
|
+
readonly import_source: string | null;
|
|
19
|
+
readonly hops: number;
|
|
20
|
+
readonly via: string;
|
|
21
|
+
}
|
|
22
|
+
export interface WebhookHandler {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly framework: Framework;
|
|
25
|
+
readonly framework_version: string | null;
|
|
26
|
+
readonly route_pattern: string;
|
|
27
|
+
readonly http_methods: ReadonlyArray<string>;
|
|
28
|
+
readonly file_path: string;
|
|
29
|
+
readonly location: SourceLocation;
|
|
30
|
+
readonly handler_function_name: string | null;
|
|
31
|
+
readonly provider: string;
|
|
32
|
+
readonly verification_state: Verdict;
|
|
33
|
+
readonly evidence: ReadonlyArray<WebhookEvidence>;
|
|
34
|
+
readonly middleware_chain: ReadonlyArray<ResolvedMiddleware>;
|
|
35
|
+
readonly reachable_symbols: ReadonlyArray<ReachableSymbol>;
|
|
36
|
+
readonly findings_ref: ReadonlyArray<FindingId>;
|
|
37
|
+
readonly redacted_snippet: string;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/types/handler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvE,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAGnG,MAAM,MAAM,mBAAmB,GAC3B,oBAAoB,GACpB,uBAAuB,GACvB,YAAY,GACZ,iBAAiB,GACjB,yBAAyB,GACzB,0BAA0B,GAC1B,sBAAsB,CAAC;AAE3B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC;AAGD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAGD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD,QAAQ,CAAC,gBAAgB,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC7D,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3D,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAChD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// D-32: WebhookEvidence multi-signal model — engine computes, rules query thresholds.
|
|
2
|
+
// D-34: ReachableSymbol bounded-depth reachability set per WebhookHandler.
|
|
3
|
+
// D-36: WebhookHandler shape — every field used by Phase 3 CLI inventory + Phase 8 SaaS dashboard.
|
|
4
|
+
// D-37: WebhookHandler.id derivation locked.
|
|
5
|
+
// D-39: redacted_snippet is structurally redacted.
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=handler.js.map
|