@keithadler/frostjs 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/LICENSE +21 -0
- package/README.md +568 -0
- package/dist/baseline.d.ts +18 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +56 -0
- package/dist/baseline.js.map +1 -0
- package/dist/changed.d.ts +15 -0
- package/dist/changed.d.ts.map +1 -0
- package/dist/changed.js +93 -0
- package/dist/changed.js.map +1 -0
- package/dist/cli/args.d.ts +37 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +200 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +8 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/run.d.ts +9 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +404 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/discover/index.d.ts +15 -0
- package/dist/discover/index.d.ts.map +1 -0
- package/dist/discover/index.js +70 -0
- package/dist/discover/index.js.map +1 -0
- package/dist/eslint.d.ts +103 -0
- package/dist/eslint.d.ts.map +1 -0
- package/dist/eslint.js +111 -0
- package/dist/eslint.js.map +1 -0
- package/dist/extract/annotations.d.ts +5 -0
- package/dist/extract/annotations.d.ts.map +1 -0
- package/dist/extract/annotations.js +5 -0
- package/dist/extract/annotations.js.map +1 -0
- package/dist/extract/ast.d.ts +45 -0
- package/dist/extract/ast.d.ts.map +1 -0
- package/dist/extract/ast.js +60 -0
- package/dist/extract/ast.js.map +1 -0
- package/dist/extract/capability.d.ts +22 -0
- package/dist/extract/capability.d.ts.map +1 -0
- package/dist/extract/capability.js +2 -0
- package/dist/extract/capability.js.map +1 -0
- package/dist/extract/html.d.ts +15 -0
- package/dist/extract/html.d.ts.map +1 -0
- package/dist/extract/html.js +69 -0
- package/dist/extract/html.js.map +1 -0
- package/dist/extract/index.d.ts +9 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +95 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/recognizers/codegen.d.ts +10 -0
- package/dist/extract/recognizers/codegen.d.ts.map +1 -0
- package/dist/extract/recognizers/codegen.js +39 -0
- package/dist/extract/recognizers/codegen.js.map +1 -0
- package/dist/extract/recognizers/dom-escape.d.ts +11 -0
- package/dist/extract/recognizers/dom-escape.d.ts.map +1 -0
- package/dist/extract/recognizers/dom-escape.js +58 -0
- package/dist/extract/recognizers/dom-escape.js.map +1 -0
- package/dist/extract/recognizers/globals.d.ts +9 -0
- package/dist/extract/recognizers/globals.d.ts.map +1 -0
- package/dist/extract/recognizers/globals.js +121 -0
- package/dist/extract/recognizers/globals.js.map +1 -0
- package/dist/extract/recognizers/identity.d.ts +10 -0
- package/dist/extract/recognizers/identity.d.ts.map +1 -0
- package/dist/extract/recognizers/identity.js +79 -0
- package/dist/extract/recognizers/identity.js.map +1 -0
- package/dist/extract/recognizers/navigation.d.ts +12 -0
- package/dist/extract/recognizers/navigation.d.ts.map +1 -0
- package/dist/extract/recognizers/navigation.js +110 -0
- package/dist/extract/recognizers/navigation.js.map +1 -0
- package/dist/extract/recognizers/network.d.ts +11 -0
- package/dist/extract/recognizers/network.d.ts.map +1 -0
- package/dist/extract/recognizers/network.js +41 -0
- package/dist/extract/recognizers/network.js.map +1 -0
- package/dist/extract/recognizers/resolve.d.ts +37 -0
- package/dist/extract/recognizers/resolve.d.ts.map +1 -0
- package/dist/extract/recognizers/resolve.js +72 -0
- package/dist/extract/recognizers/resolve.js.map +1 -0
- package/dist/extract/recognizers/storage.d.ts +9 -0
- package/dist/extract/recognizers/storage.d.ts.map +1 -0
- package/dist/extract/recognizers/storage.js +37 -0
- package/dist/extract/recognizers/storage.js.map +1 -0
- package/dist/extract/recognizers/types.d.ts +38 -0
- package/dist/extract/recognizers/types.d.ts.map +1 -0
- package/dist/extract/recognizers/types.js +25 -0
- package/dist/extract/recognizers/types.js.map +1 -0
- package/dist/extract/recognizers/worker.d.ts +11 -0
- package/dist/extract/recognizers/worker.d.ts.map +1 -0
- package/dist/extract/recognizers/worker.js +41 -0
- package/dist/extract/recognizers/worker.js.map +1 -0
- package/dist/extract/scope.d.ts +23 -0
- package/dist/extract/scope.d.ts.map +1 -0
- package/dist/extract/scope.js +299 -0
- package/dist/extract/scope.js.map +1 -0
- package/dist/extract/suppress.d.ts +21 -0
- package/dist/extract/suppress.d.ts.map +1 -0
- package/dist/extract/suppress.js +42 -0
- package/dist/extract/suppress.js.map +1 -0
- package/dist/extract/target.d.ts +34 -0
- package/dist/extract/target.d.ts.map +1 -0
- package/dist/extract/target.js +81 -0
- package/dist/extract/target.js.map +1 -0
- package/dist/extract/typescript.d.ts +12 -0
- package/dist/extract/typescript.d.ts.map +1 -0
- package/dist/extract/typescript.js +56 -0
- package/dist/extract/typescript.js.map +1 -0
- package/dist/extract/walk.d.ts +14 -0
- package/dist/extract/walk.d.ts.map +1 -0
- package/dist/extract/walk.js +70 -0
- package/dist/extract/walk.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +10 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +79 -0
- package/dist/init.js.map +1 -0
- package/dist/policy/compile.d.ts +56 -0
- package/dist/policy/compile.d.ts.map +1 -0
- package/dist/policy/compile.js +78 -0
- package/dist/policy/compile.js.map +1 -0
- package/dist/policy/config.d.ts +18 -0
- package/dist/policy/config.d.ts.map +1 -0
- package/dist/policy/config.js +70 -0
- package/dist/policy/config.js.map +1 -0
- package/dist/policy/csp.d.ts +19 -0
- package/dist/policy/csp.d.ts.map +1 -0
- package/dist/policy/csp.js +47 -0
- package/dist/policy/csp.js.map +1 -0
- package/dist/policy/glob.d.ts +12 -0
- package/dist/policy/glob.d.ts.map +1 -0
- package/dist/policy/glob.js +63 -0
- package/dist/policy/glob.js.map +1 -0
- package/dist/policy/index.d.ts +47 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +34 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/parse.d.ts +51 -0
- package/dist/policy/parse.d.ts.map +1 -0
- package/dist/policy/parse.js +352 -0
- package/dist/policy/parse.js.map +1 -0
- package/dist/policy/vocabulary.d.ts +15 -0
- package/dist/policy/vocabulary.d.ts.map +1 -0
- package/dist/policy/vocabulary.js +99 -0
- package/dist/policy/vocabulary.js.map +1 -0
- package/dist/registry.d.ts +45 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +85 -0
- package/dist/registry.js.map +1 -0
- package/dist/report/github.d.ts +10 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +31 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/json.d.ts +44 -0
- package/dist/report/json.d.ts.map +1 -0
- package/dist/report/json.js +40 -0
- package/dist/report/json.js.map +1 -0
- package/dist/report/sarif.d.ts +10 -0
- package/dist/report/sarif.d.ts.map +1 -0
- package/dist/report/sarif.js +64 -0
- package/dist/report/sarif.js.map +1 -0
- package/dist/report/summary.d.ts +9 -0
- package/dist/report/summary.d.ts.map +1 -0
- package/dist/report/summary.js +67 -0
- package/dist/report/summary.js.map +1 -0
- package/dist/report/text.d.ts +37 -0
- package/dist/report/text.d.ts.map +1 -0
- package/dist/report/text.js +81 -0
- package/dist/report/text.js.map +1 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +131 -0
- package/dist/sync.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static resolution of a network destination from an argument expression.
|
|
3
|
+
*
|
|
4
|
+
* Frost's rule: a literal that closes the authority fixes the host, and
|
|
5
|
+
* nothing after the slash can move it. `"https://api.example.com/items/" + id`
|
|
6
|
+
* reaches api.example.com. `"https://" + host` reaches nobody we can name,
|
|
7
|
+
* so it resolves to null and the policy treats it as unknown.
|
|
8
|
+
*
|
|
9
|
+
* Relative URLs resolve to "same-origin". `data:` and `blob:` URLs resolve to
|
|
10
|
+
* their scheme.
|
|
11
|
+
*/
|
|
12
|
+
import type { AnyNode } from "./ast.js";
|
|
13
|
+
/** The target of a relative URL: the document's own origin. */
|
|
14
|
+
export declare const SAME_ORIGIN = "same-origin";
|
|
15
|
+
/** The known leading text of an expression, or null if it does not start with a literal. */
|
|
16
|
+
export declare function leadingLiteral(raw: AnyNode): {
|
|
17
|
+
text: string;
|
|
18
|
+
complete: boolean;
|
|
19
|
+
} | null;
|
|
20
|
+
/**
|
|
21
|
+
* How a string is interpreted when it has no scheme. A `url` (fetch,
|
|
22
|
+
* WebSocket...) is relative to the document; a `specifier` (import) is a
|
|
23
|
+
* path only when it starts with `/`, `./` or `../`, and otherwise a bare
|
|
24
|
+
* package name resolved by the bundler or import map.
|
|
25
|
+
*/
|
|
26
|
+
export type TargetKind = "url" | "specifier";
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a URL-ish string, or a known prefix of one, to a host.
|
|
29
|
+
* Returns null when the host cannot be fixed from what is known.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveTarget(text: string, complete?: boolean, kind?: TargetKind): string | null;
|
|
32
|
+
/** Resolve the destination of an argument expression, or null. */
|
|
33
|
+
export declare function resolveTargetOf(arg: AnyNode | undefined, kind?: TargetKind): string | null;
|
|
34
|
+
//# sourceMappingURL=target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/extract/target.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAIxC,+DAA+D;AAC/D,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4BvF;AAKD;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,UAAO,EAAE,IAAI,GAAE,UAAkB,GAAG,MAAM,GAAG,IAAI,CAqBpG;AAED,kEAAkE;AAClE,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,EAAE,IAAI,GAAE,UAAkB,GAAG,MAAM,GAAG,IAAI,CAKjG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { FOLDED } from "./annotations.js";
|
|
2
|
+
import { unwrap } from "./typescript.js";
|
|
3
|
+
/** The target of a relative URL: the document's own origin. */
|
|
4
|
+
export const SAME_ORIGIN = "same-origin";
|
|
5
|
+
/** The known leading text of an expression, or null if it does not start with a literal. */
|
|
6
|
+
export function leadingLiteral(raw) {
|
|
7
|
+
const node = unwrap(raw);
|
|
8
|
+
switch (node.type) {
|
|
9
|
+
case "Literal":
|
|
10
|
+
return typeof node["value"] === "string" ? { text: node["value"], complete: true } : null;
|
|
11
|
+
case "Identifier": {
|
|
12
|
+
// A const bound to a string literal, folded by the scope analysis.
|
|
13
|
+
const v = node[FOLDED];
|
|
14
|
+
return typeof v === "string" ? { text: v, complete: true } : null;
|
|
15
|
+
}
|
|
16
|
+
case "TemplateLiteral": {
|
|
17
|
+
const quasis = node["quasis"];
|
|
18
|
+
const exprs = node["expressions"];
|
|
19
|
+
const first = quasis[0]?.["value"]?.cooked ?? "";
|
|
20
|
+
return { text: first, complete: exprs.length === 0 };
|
|
21
|
+
}
|
|
22
|
+
case "BinaryExpression": {
|
|
23
|
+
if (node["operator"] !== "+")
|
|
24
|
+
return null;
|
|
25
|
+
const left = leadingLiteral(node["left"]);
|
|
26
|
+
if (left === null)
|
|
27
|
+
return null;
|
|
28
|
+
if (!left.complete)
|
|
29
|
+
return left;
|
|
30
|
+
const right = leadingLiteral(node["right"]);
|
|
31
|
+
if (right === null)
|
|
32
|
+
return { text: left.text, complete: false };
|
|
33
|
+
return { text: left.text + right.text, complete: right.complete };
|
|
34
|
+
}
|
|
35
|
+
default:
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const ABSOLUTE = /^([a-z][a-z0-9+.-]*):/i;
|
|
40
|
+
const AUTHORITY = /^(?:[a-z][a-z0-9+.-]*:)?\/\/(?:[^/?#@\s]*@)?([^/?#:\s]+)(?::\d+)?(?=[/?#]|$)/i;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a URL-ish string, or a known prefix of one, to a host.
|
|
43
|
+
* Returns null when the host cannot be fixed from what is known.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveTarget(text, complete = true, kind = "url") {
|
|
46
|
+
const t = text.trim();
|
|
47
|
+
if (t === "")
|
|
48
|
+
return null;
|
|
49
|
+
const m = AUTHORITY.exec(t);
|
|
50
|
+
if (m) {
|
|
51
|
+
// A prefix that ends inside the host cannot be trusted; `"https://api" + rest` might be api.evil.com.
|
|
52
|
+
const host = m[1];
|
|
53
|
+
const closed = complete || t.length > m[0].length;
|
|
54
|
+
return closed ? host.toLowerCase() : null;
|
|
55
|
+
}
|
|
56
|
+
if (t.startsWith("//"))
|
|
57
|
+
return null; // scheme-relative with an unfinished host
|
|
58
|
+
const scheme = ABSOLUTE.exec(t);
|
|
59
|
+
if (scheme) {
|
|
60
|
+
const s = scheme[1].toLowerCase();
|
|
61
|
+
if (s === "data" || s === "blob" || s === "javascript")
|
|
62
|
+
return `${s}:`;
|
|
63
|
+
if (s === "node" || s === "file")
|
|
64
|
+
return "bare"; // local to the runtime, not a network destination
|
|
65
|
+
return null; // some other scheme with no authority we understand
|
|
66
|
+
}
|
|
67
|
+
// No scheme and no authority.
|
|
68
|
+
if (kind === "url")
|
|
69
|
+
return SAME_ORIGIN;
|
|
70
|
+
return t.startsWith("/") || t.startsWith("./") || t.startsWith("../") ? SAME_ORIGIN : "bare";
|
|
71
|
+
}
|
|
72
|
+
/** Resolve the destination of an argument expression, or null. */
|
|
73
|
+
export function resolveTargetOf(arg, kind = "url") {
|
|
74
|
+
if (!arg)
|
|
75
|
+
return null;
|
|
76
|
+
const lit = leadingLiteral(arg);
|
|
77
|
+
if (lit === null)
|
|
78
|
+
return null;
|
|
79
|
+
return resolveTarget(lit.text, lit.complete, kind);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target.js","sourceRoot":"","sources":["../../src/extract/target.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What TypeScript and JSX add to the tree, and how the walkers treat it.
|
|
3
|
+
* Type positions are never references: nothing in a type annotation runs.
|
|
4
|
+
* `declare` statements describe globals rather than create bindings. JSX
|
|
5
|
+
* element and attribute names are not identifiers.
|
|
6
|
+
*/
|
|
7
|
+
import type { AnyNode } from "./ast.js";
|
|
8
|
+
/** True for a subtree that contributes no runtime code: types, signatures, `declare`, `import type`. */
|
|
9
|
+
export declare function isTypeOnly(node: AnyNode): boolean;
|
|
10
|
+
/** Strip `as`, `!`, `satisfies`, parentheses and the like. */
|
|
11
|
+
export declare function unwrap(node: AnyNode): AnyNode;
|
|
12
|
+
//# sourceMappingURL=typescript.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/extract/typescript.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAyBxC,wGAAwG;AACxG,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAgBjD;AAYD,8DAA8D;AAC9D,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAI7C"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const TYPE_LEVEL = new Set([
|
|
2
|
+
"TSTypeAnnotation",
|
|
3
|
+
"TSInterfaceDeclaration",
|
|
4
|
+
"TSTypeAliasDeclaration",
|
|
5
|
+
"TSDeclareFunction",
|
|
6
|
+
"TSImportType",
|
|
7
|
+
"TSIndexSignature",
|
|
8
|
+
"TSPropertySignature",
|
|
9
|
+
"TSMethodSignature",
|
|
10
|
+
"TSCallSignatureDeclaration",
|
|
11
|
+
"TSConstructSignatureDeclaration",
|
|
12
|
+
"TSTypeParameterDeclaration",
|
|
13
|
+
"TSTypeParameterInstantiation",
|
|
14
|
+
"TSAbstractMethodDefinition",
|
|
15
|
+
"TSAbstractPropertyDefinition",
|
|
16
|
+
"TSAbstractAccessorProperty",
|
|
17
|
+
"TSInterfaceBody",
|
|
18
|
+
"TSInterfaceHeritage",
|
|
19
|
+
"TSClassImplements",
|
|
20
|
+
"TSExportAssignment",
|
|
21
|
+
"TSNamespaceExportDeclaration",
|
|
22
|
+
]);
|
|
23
|
+
/** True for a subtree that contributes no runtime code: types, signatures, `declare`, `import type`. */
|
|
24
|
+
export function isTypeOnly(node) {
|
|
25
|
+
const t = node.type;
|
|
26
|
+
if (t.startsWith("TSType") || TYPE_LEVEL.has(t))
|
|
27
|
+
return true;
|
|
28
|
+
if (node["declare"] === true)
|
|
29
|
+
return true;
|
|
30
|
+
if ((t === "ImportDeclaration" || t === "ExportNamedDeclaration" || t === "ExportAllDeclaration") &&
|
|
31
|
+
node["exportKind"] === "type")
|
|
32
|
+
return true;
|
|
33
|
+
if (t === "ImportDeclaration" && node["importKind"] === "type")
|
|
34
|
+
return true;
|
|
35
|
+
if ((t === "ImportSpecifier" || t === "ExportSpecifier") &&
|
|
36
|
+
(node["importKind"] === "type" || node["exportKind"] === "type"))
|
|
37
|
+
return true;
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
/** Expression wrappers TypeScript adds around a value: the value is the `expression` child. */
|
|
41
|
+
const VALUE_WRAPPERS = new Set([
|
|
42
|
+
"TSAsExpression",
|
|
43
|
+
"TSSatisfiesExpression",
|
|
44
|
+
"TSNonNullExpression",
|
|
45
|
+
"TSTypeAssertion",
|
|
46
|
+
"TSInstantiationExpression",
|
|
47
|
+
"ParenthesizedExpression",
|
|
48
|
+
]);
|
|
49
|
+
/** Strip `as`, `!`, `satisfies`, parentheses and the like. */
|
|
50
|
+
export function unwrap(node) {
|
|
51
|
+
let n = node;
|
|
52
|
+
while (VALUE_WRAPPERS.has(n.type))
|
|
53
|
+
n = n["expression"];
|
|
54
|
+
return n;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=typescript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/extract/typescript.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,kBAAkB;IAClB,wBAAwB;IACxB,wBAAwB;IACxB,mBAAmB;IACnB,cAAc;IACd,kBAAkB;IAClB,qBAAqB;IACrB,mBAAmB;IACnB,4BAA4B;IAC5B,iCAAiC;IACjC,4BAA4B;IAC5B,8BAA8B;IAC9B,4BAA4B;IAC5B,8BAA8B;IAC9B,4BAA4B;IAC5B,iBAAiB;IACjB,qBAAqB;IACrB,mBAAmB;IACnB,oBAAoB;IACpB,8BAA8B;CAC/B,CAAC,CAAC;AAEH,wGAAwG;AACxG,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACpB,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC1C,IACE,CAAC,CAAC,KAAK,mBAAmB,IAAI,CAAC,KAAK,wBAAwB,IAAI,CAAC,KAAK,sBAAsB,CAAC;QAC7F,IAAI,CAAC,YAAY,CAAC,KAAK,MAAM;QAE7B,OAAO,IAAI,CAAC;IACd,IAAI,CAAC,KAAK,mBAAmB,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC5E,IACE,CAAC,CAAC,KAAK,iBAAiB,IAAI,CAAC,KAAK,iBAAiB,CAAC;QACpD,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;QAEhE,OAAO,IAAI,CAAC;IACd,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+FAA+F;AAC/F,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IAClD,gBAAgB;IAChB,uBAAuB;IACvB,qBAAqB;IACrB,iBAAiB;IACjB,2BAA2B;IAC3B,yBAAyB;CAC1B,CAAC,CAAC;AAEH,8DAA8D;AAC9D,MAAM,UAAU,MAAM,CAAC,IAAa;IAClC,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,YAAY,CAAY,CAAC;IAClE,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Node } from "./ast.js";
|
|
2
|
+
export interface Visit {
|
|
3
|
+
node: Node;
|
|
4
|
+
/** Nearest ancestor first. */
|
|
5
|
+
ancestors: readonly Node[];
|
|
6
|
+
/** True when this node is (inside) a binding position: a declared name, parameter, pattern, or import. */
|
|
7
|
+
binding: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Pre-order walk of the tree, skipping type-only subtrees. `Visit.ancestors`
|
|
11
|
+
* is a live array (nearest first) that is only valid during the callback.
|
|
12
|
+
*/
|
|
13
|
+
export declare function walk(root: Node, visit: (v: Visit) => void): void;
|
|
14
|
+
//# sourceMappingURL=walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../src/extract/walk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,IAAI,EAAE,MAAM,UAAU,CAAC;AAG3D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,8BAA8B;IAC9B,SAAS,EAAE,SAAS,IAAI,EAAE,CAAC;IAC3B,0GAA0G;IAC1G,OAAO,EAAE,OAAO,CAAC;CAClB;AAoCD;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAyBhE"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { isNode } from "./ast.js";
|
|
2
|
+
import { isTypeOnly } from "./typescript.js";
|
|
3
|
+
/**
|
|
4
|
+
* Child keys that introduce bindings rather than references. An Identifier
|
|
5
|
+
* reached through one of these keys names something; it does not use it.
|
|
6
|
+
*/
|
|
7
|
+
const BINDING_KEYS = {
|
|
8
|
+
VariableDeclarator: new Set(["id"]),
|
|
9
|
+
FunctionDeclaration: new Set(["id", "params"]),
|
|
10
|
+
FunctionExpression: new Set(["id", "params"]),
|
|
11
|
+
ArrowFunctionExpression: new Set(["params"]),
|
|
12
|
+
ClassDeclaration: new Set(["id"]),
|
|
13
|
+
ClassExpression: new Set(["id"]),
|
|
14
|
+
CatchClause: new Set(["param"]),
|
|
15
|
+
ImportSpecifier: new Set(["local", "imported"]),
|
|
16
|
+
ImportDefaultSpecifier: new Set(["local"]),
|
|
17
|
+
ImportNamespaceSpecifier: new Set(["local"]),
|
|
18
|
+
ExportSpecifier: new Set(["exported"]),
|
|
19
|
+
LabeledStatement: new Set(["label"]),
|
|
20
|
+
BreakStatement: new Set(["label"]),
|
|
21
|
+
ContinueStatement: new Set(["label"]),
|
|
22
|
+
TSEnumDeclaration: new Set(["id"]),
|
|
23
|
+
TSEnumMember: new Set(["id"]),
|
|
24
|
+
TSModuleDeclaration: new Set(["id"]),
|
|
25
|
+
TSParameterProperty: new Set(["parameter"]),
|
|
26
|
+
};
|
|
27
|
+
/** Non-computed keys are names, not references, under these parents. */
|
|
28
|
+
const NAME_KEYS = {
|
|
29
|
+
MemberExpression: "property",
|
|
30
|
+
Property: "key",
|
|
31
|
+
MethodDefinition: "key",
|
|
32
|
+
PropertyDefinition: "key",
|
|
33
|
+
AccessorProperty: "key",
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Pre-order walk of the tree, skipping type-only subtrees. `Visit.ancestors`
|
|
37
|
+
* is a live array (nearest first) that is only valid during the callback.
|
|
38
|
+
*/
|
|
39
|
+
export function walk(root, visit) {
|
|
40
|
+
const ancestors = [];
|
|
41
|
+
const go = (node, binding) => {
|
|
42
|
+
if (isTypeOnly(node))
|
|
43
|
+
return;
|
|
44
|
+
visit({ node, ancestors, binding });
|
|
45
|
+
ancestors.unshift(node);
|
|
46
|
+
const bindingKeys = BINDING_KEYS[node.type];
|
|
47
|
+
const nameKey = NAME_KEYS[node.type];
|
|
48
|
+
for (const key of Object.keys(node)) {
|
|
49
|
+
if (key === "type" || key === "start" || key === "end")
|
|
50
|
+
continue;
|
|
51
|
+
const value = node[key];
|
|
52
|
+
const childBinding = binding || (bindingKeys?.has(key) ?? false);
|
|
53
|
+
// A non-computed property name is never a reference; skip it outright.
|
|
54
|
+
if (key === nameKey && node["computed"] !== true && isNode(value) && value.type === "Identifier") {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (Array.isArray(value)) {
|
|
58
|
+
for (const item of value)
|
|
59
|
+
if (isNode(item))
|
|
60
|
+
go(item, childBinding);
|
|
61
|
+
}
|
|
62
|
+
else if (isNode(value)) {
|
|
63
|
+
go(value, childBinding);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
ancestors.shift();
|
|
67
|
+
};
|
|
68
|
+
go(root, false);
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/extract/walk.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,GAAG,EAAW,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CapabilityUse } from "./extract/capability.js";
|
|
2
|
+
/**
|
|
3
|
+
* The text of a starter policy for these uses. `uses` carry paths relative
|
|
4
|
+
* to the directory the policy will live in. Only certain and probable uses
|
|
5
|
+
* count; possible ones never fail a build and are left for the person.
|
|
6
|
+
*/
|
|
7
|
+
export declare function starterPolicy(name: string, uses: readonly CapabilityUse[], today: string): string;
|
|
8
|
+
/** A policy name from the directory it lives in. */
|
|
9
|
+
export declare function policyNameFor(dir: string): string;
|
|
10
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAsB7D;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAyCjG;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `frostjs init`: write a starter policy that grants exactly what the code
|
|
3
|
+
* does today, so the first run passes and every later change is a
|
|
4
|
+
* visible decision. The generated file is meant to be read and pruned:
|
|
5
|
+
* each grant says where it is used, a capability used in only a few files
|
|
6
|
+
* is scoped to them, and an unreadable network destination is called out
|
|
7
|
+
* rather than quietly widened to the whole network.
|
|
8
|
+
*/
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { CAPABILITY_PHRASES } from "./policy/vocabulary.js";
|
|
11
|
+
/** Scope a grant to its files when it is used in no more than this many. */
|
|
12
|
+
const SCOPE_UP_TO = 3;
|
|
13
|
+
/** The friendliest phrase for a code, else the code. */
|
|
14
|
+
function phraseFor(code) {
|
|
15
|
+
for (const [phrase, c] of CAPABILITY_PHRASES)
|
|
16
|
+
if (c === code)
|
|
17
|
+
return phrase;
|
|
18
|
+
return code;
|
|
19
|
+
}
|
|
20
|
+
function where(files) {
|
|
21
|
+
const shown = files.slice(0, SCOPE_UP_TO);
|
|
22
|
+
const more = files.length - shown.length;
|
|
23
|
+
return `used in ${shown.join(", ")}${more > 0 ? ` and ${more} more` : ""}`;
|
|
24
|
+
}
|
|
25
|
+
function scope(files) {
|
|
26
|
+
return files.length <= SCOPE_UP_TO ? ` in ${files.map((f) => `"${f}"`).join(", ")}` : "";
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The text of a starter policy for these uses. `uses` carry paths relative
|
|
30
|
+
* to the directory the policy will live in. Only certain and probable uses
|
|
31
|
+
* count; possible ones never fail a build and are left for the person.
|
|
32
|
+
*/
|
|
33
|
+
export function starterPolicy(name, uses, today) {
|
|
34
|
+
const counted = uses.filter((u) => u.confidence !== "possible" && !u.suppressed);
|
|
35
|
+
const lines = [
|
|
36
|
+
`policy "${name}"`,
|
|
37
|
+
`-- Written by frostjs init on ${today} from what the code does today.`,
|
|
38
|
+
"-- Every line below is a grant. Delete the ones that should not be",
|
|
39
|
+
"-- allowed and the build will start refusing them. Add an expiry",
|
|
40
|
+
"-- (until YYYY-MM-DD) to anything that is meant to go away.",
|
|
41
|
+
"",
|
|
42
|
+
];
|
|
43
|
+
// Network: known destinations become `may reach`; anything unreadable
|
|
44
|
+
// needs `may use the network`, which the hint says how to narrow.
|
|
45
|
+
const net = counted.filter((u) => u.capability.startsWith("network."));
|
|
46
|
+
if (net.length > 0) {
|
|
47
|
+
const hosts = [...new Set(net.map((u) => u.target).filter((t) => t !== null))].sort();
|
|
48
|
+
const unknown = net.filter((u) => u.target === null);
|
|
49
|
+
const netFiles = [...new Set(net.map((u) => u.file))].sort();
|
|
50
|
+
if (unknown.length === 0) {
|
|
51
|
+
lines.push(`may reach ${hosts.map((h) => `"${h}"`).join(", ")}${scope(netFiles)} -- ${where(netFiles)}`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const hint = `${unknown.length} ${unknown.length === 1 ? "use" : "uses"} whose destination cannot be read; narrow this to: may reach ${hosts.length ? hosts.map((h) => `"${h}"`).join(", ") : '"host"'}`;
|
|
55
|
+
lines.push(`may use the network${scope(netFiles)} -- ${hint}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Everything else: one grant per member code, scoped when used in few files.
|
|
59
|
+
const byCode = new Map();
|
|
60
|
+
for (const u of counted) {
|
|
61
|
+
if (u.capability.startsWith("network."))
|
|
62
|
+
continue;
|
|
63
|
+
if (!byCode.has(u.capability))
|
|
64
|
+
byCode.set(u.capability, new Set());
|
|
65
|
+
byCode.get(u.capability).add(u.file);
|
|
66
|
+
}
|
|
67
|
+
for (const [code, fileSet] of [...byCode].sort(([a], [b]) => a.localeCompare(b))) {
|
|
68
|
+
const files = [...fileSet].sort();
|
|
69
|
+
lines.push(`may use ${phraseFor(code)}${scope(files)} -- ${where(files)}`);
|
|
70
|
+
}
|
|
71
|
+
if (lines.length === 6)
|
|
72
|
+
lines.push("-- Nothing found: the code uses no capability frostjs recognizes. Every grant is off.");
|
|
73
|
+
return lines.join("\n") + "\n";
|
|
74
|
+
}
|
|
75
|
+
/** A policy name from the directory it lives in. */
|
|
76
|
+
export function policyNameFor(dir) {
|
|
77
|
+
return path.basename(path.resolve(dir)) || "project";
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile a parsed policy into the ruleset the gate runs. Three rules
|
|
3
|
+
* decide everything:
|
|
4
|
+
*
|
|
5
|
+
* - `forbid` always wins over `may`, whatever the order in the file.
|
|
6
|
+
* - A grant with `until` stops granting the day after its date; inside the
|
|
7
|
+
* warning window it produces a printable warning.
|
|
8
|
+
* - A host list (`may reach`, `forbid reaching`) matches a known
|
|
9
|
+
* destination by pattern. A destination that cannot be read from the
|
|
10
|
+
* code cannot be shown to match, so a forbid does not fire on it and a
|
|
11
|
+
* grant does not cover it: cannot be shown to be allowed is not allowed.
|
|
12
|
+
*/
|
|
13
|
+
import type { CapabilityUse } from "../extract/capability.js";
|
|
14
|
+
import { type ParsedPolicy, type Rule } from "./parse.js";
|
|
15
|
+
/**
|
|
16
|
+
* Why a use was allowed or denied. `unregistered` is produced by
|
|
17
|
+
* `decide()` for vendored files the registry does not know, never by
|
|
18
|
+
* `compile()`.
|
|
19
|
+
*/
|
|
20
|
+
export type Reason = "granted" | "forbidden" | "expired" | "not granted" | "unknown destination" | "unregistered";
|
|
21
|
+
export interface Evaluation {
|
|
22
|
+
verdict: "allowed" | "denied";
|
|
23
|
+
reason: Reason;
|
|
24
|
+
/** The rule that decided it; null when nothing in the policy applied. */
|
|
25
|
+
rule: Rule | null;
|
|
26
|
+
}
|
|
27
|
+
export interface Policy {
|
|
28
|
+
name: string;
|
|
29
|
+
file: string;
|
|
30
|
+
/** The date the policy was compiled against, YYYY-MM-DD; expiry and warnings are relative to it. */
|
|
31
|
+
today: string;
|
|
32
|
+
rules: readonly Rule[];
|
|
33
|
+
/** Globs of vendored files, relative to the policy directory. */
|
|
34
|
+
vendored: readonly string[];
|
|
35
|
+
/** Globs of files not analyzed at all, relative to the policy directory. */
|
|
36
|
+
ignore: readonly string[];
|
|
37
|
+
/** Grants that expire within the warning window, as printable lines. */
|
|
38
|
+
warnings: readonly string[];
|
|
39
|
+
/** `use.file` must be relative to the policy file's directory. */
|
|
40
|
+
evaluate(use: CapabilityUse): Evaluation;
|
|
41
|
+
}
|
|
42
|
+
export interface CompileOptions {
|
|
43
|
+
/** ISO date, YYYY-MM-DD. Injected so runs are reproducible and testable. */
|
|
44
|
+
today: string;
|
|
45
|
+
/** Days before expiry at which a grant starts warning. Default 14. */
|
|
46
|
+
warnDays?: number;
|
|
47
|
+
}
|
|
48
|
+
/** True when a grant's `until` date is before `today`. ISO strings compare correctly. */
|
|
49
|
+
export declare function isExpired(rule: Rule, today: string): boolean;
|
|
50
|
+
/** Compile a parsed policy against a date. See the module comment for the rules. */
|
|
51
|
+
export declare function compile(parsed: ParsedPolicy, opts: CompileOptions): Policy;
|
|
52
|
+
/** "*" matches all; a family matches itself and its members; a code matches exactly. */
|
|
53
|
+
export declare function matchesCapability(pattern: string, capability: string): boolean;
|
|
54
|
+
/** Host patterns: `*` spans any characters including dots; the match is whole-host and case-insensitive. */
|
|
55
|
+
export declare function matchesHost(pattern: string, host: string): boolean;
|
|
56
|
+
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/policy/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAO,KAAK,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,qBAAqB,GAAG,cAAc,CAAC;AAElH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oGAAoG;IACpG,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,iEAAiE;IACjE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,4EAA4E;IAC5E,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,oFAAoF;AACpF,wBAAgB,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAsD1E;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,4GAA4G;AAC5G,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGlE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { escapeRegExp, matchesGlob } from "./glob.js";
|
|
2
|
+
import { ymd } from "./parse.js";
|
|
3
|
+
/** True when a grant's `until` date is before `today`. ISO strings compare correctly. */
|
|
4
|
+
export function isExpired(rule, today) {
|
|
5
|
+
return rule.until !== null && rule.until < today;
|
|
6
|
+
}
|
|
7
|
+
/** Compile a parsed policy against a date. See the module comment for the rules. */
|
|
8
|
+
export function compile(parsed, opts) {
|
|
9
|
+
const { today } = opts;
|
|
10
|
+
const warnDays = opts.warnDays ?? 14;
|
|
11
|
+
const forbids = parsed.rules.filter((r) => r.verb === "forbid" && r.capability !== "*");
|
|
12
|
+
const grants = parsed.rules.filter((r) => r.verb === "may");
|
|
13
|
+
const expired = new Set(grants.filter((r) => isExpired(r, today)));
|
|
14
|
+
const warnings = [];
|
|
15
|
+
for (const r of grants) {
|
|
16
|
+
if (r.until === null)
|
|
17
|
+
continue;
|
|
18
|
+
const days = daysBetween(today, r.until);
|
|
19
|
+
if (days < 0 || days > warnDays)
|
|
20
|
+
continue;
|
|
21
|
+
const when = days === 0 ? "today" : `in ${days} ${days === 1 ? "day" : "days"}`;
|
|
22
|
+
warnings.push(`${parsed.file} line ${r.line}: "${r.text}" expires ${when}`);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
name: parsed.name,
|
|
26
|
+
file: parsed.file,
|
|
27
|
+
today,
|
|
28
|
+
rules: parsed.rules,
|
|
29
|
+
vendored: parsed.vendored,
|
|
30
|
+
ignore: parsed.ignore,
|
|
31
|
+
warnings,
|
|
32
|
+
evaluate(use) {
|
|
33
|
+
const target = use.target;
|
|
34
|
+
const inScope = (r) => matchesCapability(r.capability, use.capability) &&
|
|
35
|
+
(r.paths.length === 0 || r.paths.some((p) => matchesGlob(p, use.file)));
|
|
36
|
+
const hostMatches = (r) => r.hosts.length === 0 || (target !== null && r.hosts.some((h) => matchesHost(h, target)));
|
|
37
|
+
const forbid = forbids.find((r) => inScope(r) && hostMatches(r));
|
|
38
|
+
if (forbid)
|
|
39
|
+
return { verdict: "denied", reason: "forbidden", rule: forbid };
|
|
40
|
+
let expiredGrant = null;
|
|
41
|
+
let hostListed = null;
|
|
42
|
+
for (const g of grants) {
|
|
43
|
+
if (!inScope(g))
|
|
44
|
+
continue;
|
|
45
|
+
if (expired.has(g)) {
|
|
46
|
+
expiredGrant ??= g;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!hostMatches(g)) {
|
|
50
|
+
if (target === null)
|
|
51
|
+
hostListed ??= g;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
return { verdict: "allowed", reason: "granted", rule: g };
|
|
55
|
+
}
|
|
56
|
+
if (hostListed)
|
|
57
|
+
return { verdict: "denied", reason: "unknown destination", rule: hostListed };
|
|
58
|
+
if (expiredGrant)
|
|
59
|
+
return { verdict: "denied", reason: "expired", rule: expiredGrant };
|
|
60
|
+
return { verdict: "denied", reason: "not granted", rule: null };
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** "*" matches all; a family matches itself and its members; a code matches exactly. */
|
|
65
|
+
export function matchesCapability(pattern, capability) {
|
|
66
|
+
return pattern === "*" || pattern === capability || capability.startsWith(pattern + ".");
|
|
67
|
+
}
|
|
68
|
+
/** Host patterns: `*` spans any characters including dots; the match is whole-host and case-insensitive. */
|
|
69
|
+
export function matchesHost(pattern, host) {
|
|
70
|
+
const rx = "^" + pattern.toLowerCase().split("*").map(escapeRegExp).join(".*") + "$";
|
|
71
|
+
return new RegExp(rx).test(host.toLowerCase());
|
|
72
|
+
}
|
|
73
|
+
/** Whole days from `from` to `to`; negative when `to` is in the past. */
|
|
74
|
+
function daysBetween(from, to) {
|
|
75
|
+
const ms = Date.UTC(...ymd(to)) - Date.UTC(...ymd(from));
|
|
76
|
+
return Math.round(ms / 86_400_000);
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/policy/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type Policy } from "./compile.js";
|
|
2
|
+
export declare const POLICY_FILENAME = "frostjs.policy";
|
|
3
|
+
/** The deepest directory containing every input (a file counts as its directory). */
|
|
4
|
+
export declare function commonAncestor(inputs: readonly string[]): string;
|
|
5
|
+
/**
|
|
6
|
+
* Walk up from `start` looking for frostjs.policy. `stopAt`, when given, is the
|
|
7
|
+
* last directory searched. Returns the absolute path or null.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findPolicyFile(start: string, stopAt?: string): string | null;
|
|
10
|
+
/** Today as YYYY-MM-DD, the form every expiry check uses. */
|
|
11
|
+
export declare function isoToday(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Read and compile a policy file. Throws PolicyError when it cannot be
|
|
14
|
+
* read as a policy, or a plain Error when the file cannot be read at all.
|
|
15
|
+
* `shownAs` is the name used in messages, typically relative to the cwd.
|
|
16
|
+
*/
|
|
17
|
+
export declare function compilePolicyFile(policyFile: string, today: string, shownAs?: string): Policy;
|
|
18
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/policy/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAGpD,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAoBhE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW5E;AAED,6DAA6D;AAC7D,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAmB,GAAG,MAAM,CAQzG"}
|