@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.
Files changed (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +568 -0
  3. package/dist/baseline.d.ts +18 -0
  4. package/dist/baseline.d.ts.map +1 -0
  5. package/dist/baseline.js +56 -0
  6. package/dist/baseline.js.map +1 -0
  7. package/dist/changed.d.ts +15 -0
  8. package/dist/changed.d.ts.map +1 -0
  9. package/dist/changed.js +93 -0
  10. package/dist/changed.js.map +1 -0
  11. package/dist/cli/args.d.ts +37 -0
  12. package/dist/cli/args.d.ts.map +1 -0
  13. package/dist/cli/args.js +200 -0
  14. package/dist/cli/args.js.map +1 -0
  15. package/dist/cli/main.d.ts +3 -0
  16. package/dist/cli/main.d.ts.map +1 -0
  17. package/dist/cli/main.js +8 -0
  18. package/dist/cli/main.js.map +1 -0
  19. package/dist/cli/run.d.ts +9 -0
  20. package/dist/cli/run.d.ts.map +1 -0
  21. package/dist/cli/run.js +404 -0
  22. package/dist/cli/run.js.map +1 -0
  23. package/dist/discover/index.d.ts +15 -0
  24. package/dist/discover/index.d.ts.map +1 -0
  25. package/dist/discover/index.js +70 -0
  26. package/dist/discover/index.js.map +1 -0
  27. package/dist/eslint.d.ts +103 -0
  28. package/dist/eslint.d.ts.map +1 -0
  29. package/dist/eslint.js +111 -0
  30. package/dist/eslint.js.map +1 -0
  31. package/dist/extract/annotations.d.ts +5 -0
  32. package/dist/extract/annotations.d.ts.map +1 -0
  33. package/dist/extract/annotations.js +5 -0
  34. package/dist/extract/annotations.js.map +1 -0
  35. package/dist/extract/ast.d.ts +45 -0
  36. package/dist/extract/ast.d.ts.map +1 -0
  37. package/dist/extract/ast.js +60 -0
  38. package/dist/extract/ast.js.map +1 -0
  39. package/dist/extract/capability.d.ts +22 -0
  40. package/dist/extract/capability.d.ts.map +1 -0
  41. package/dist/extract/capability.js +2 -0
  42. package/dist/extract/capability.js.map +1 -0
  43. package/dist/extract/html.d.ts +15 -0
  44. package/dist/extract/html.d.ts.map +1 -0
  45. package/dist/extract/html.js +69 -0
  46. package/dist/extract/html.js.map +1 -0
  47. package/dist/extract/index.d.ts +9 -0
  48. package/dist/extract/index.d.ts.map +1 -0
  49. package/dist/extract/index.js +95 -0
  50. package/dist/extract/index.js.map +1 -0
  51. package/dist/extract/recognizers/codegen.d.ts +10 -0
  52. package/dist/extract/recognizers/codegen.d.ts.map +1 -0
  53. package/dist/extract/recognizers/codegen.js +39 -0
  54. package/dist/extract/recognizers/codegen.js.map +1 -0
  55. package/dist/extract/recognizers/dom-escape.d.ts +11 -0
  56. package/dist/extract/recognizers/dom-escape.d.ts.map +1 -0
  57. package/dist/extract/recognizers/dom-escape.js +58 -0
  58. package/dist/extract/recognizers/dom-escape.js.map +1 -0
  59. package/dist/extract/recognizers/globals.d.ts +9 -0
  60. package/dist/extract/recognizers/globals.d.ts.map +1 -0
  61. package/dist/extract/recognizers/globals.js +121 -0
  62. package/dist/extract/recognizers/globals.js.map +1 -0
  63. package/dist/extract/recognizers/identity.d.ts +10 -0
  64. package/dist/extract/recognizers/identity.d.ts.map +1 -0
  65. package/dist/extract/recognizers/identity.js +79 -0
  66. package/dist/extract/recognizers/identity.js.map +1 -0
  67. package/dist/extract/recognizers/navigation.d.ts +12 -0
  68. package/dist/extract/recognizers/navigation.d.ts.map +1 -0
  69. package/dist/extract/recognizers/navigation.js +110 -0
  70. package/dist/extract/recognizers/navigation.js.map +1 -0
  71. package/dist/extract/recognizers/network.d.ts +11 -0
  72. package/dist/extract/recognizers/network.d.ts.map +1 -0
  73. package/dist/extract/recognizers/network.js +41 -0
  74. package/dist/extract/recognizers/network.js.map +1 -0
  75. package/dist/extract/recognizers/resolve.d.ts +37 -0
  76. package/dist/extract/recognizers/resolve.d.ts.map +1 -0
  77. package/dist/extract/recognizers/resolve.js +72 -0
  78. package/dist/extract/recognizers/resolve.js.map +1 -0
  79. package/dist/extract/recognizers/storage.d.ts +9 -0
  80. package/dist/extract/recognizers/storage.d.ts.map +1 -0
  81. package/dist/extract/recognizers/storage.js +37 -0
  82. package/dist/extract/recognizers/storage.js.map +1 -0
  83. package/dist/extract/recognizers/types.d.ts +38 -0
  84. package/dist/extract/recognizers/types.d.ts.map +1 -0
  85. package/dist/extract/recognizers/types.js +25 -0
  86. package/dist/extract/recognizers/types.js.map +1 -0
  87. package/dist/extract/recognizers/worker.d.ts +11 -0
  88. package/dist/extract/recognizers/worker.d.ts.map +1 -0
  89. package/dist/extract/recognizers/worker.js +41 -0
  90. package/dist/extract/recognizers/worker.js.map +1 -0
  91. package/dist/extract/scope.d.ts +23 -0
  92. package/dist/extract/scope.d.ts.map +1 -0
  93. package/dist/extract/scope.js +299 -0
  94. package/dist/extract/scope.js.map +1 -0
  95. package/dist/extract/suppress.d.ts +21 -0
  96. package/dist/extract/suppress.d.ts.map +1 -0
  97. package/dist/extract/suppress.js +42 -0
  98. package/dist/extract/suppress.js.map +1 -0
  99. package/dist/extract/target.d.ts +34 -0
  100. package/dist/extract/target.d.ts.map +1 -0
  101. package/dist/extract/target.js +81 -0
  102. package/dist/extract/target.js.map +1 -0
  103. package/dist/extract/typescript.d.ts +12 -0
  104. package/dist/extract/typescript.d.ts.map +1 -0
  105. package/dist/extract/typescript.js +56 -0
  106. package/dist/extract/typescript.js.map +1 -0
  107. package/dist/extract/walk.d.ts +14 -0
  108. package/dist/extract/walk.d.ts.map +1 -0
  109. package/dist/extract/walk.js +70 -0
  110. package/dist/extract/walk.js.map +1 -0
  111. package/dist/index.d.ts +4 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +4 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/init.d.ts +10 -0
  116. package/dist/init.d.ts.map +1 -0
  117. package/dist/init.js +79 -0
  118. package/dist/init.js.map +1 -0
  119. package/dist/policy/compile.d.ts +56 -0
  120. package/dist/policy/compile.d.ts.map +1 -0
  121. package/dist/policy/compile.js +78 -0
  122. package/dist/policy/compile.js.map +1 -0
  123. package/dist/policy/config.d.ts +18 -0
  124. package/dist/policy/config.d.ts.map +1 -0
  125. package/dist/policy/config.js +70 -0
  126. package/dist/policy/config.js.map +1 -0
  127. package/dist/policy/csp.d.ts +19 -0
  128. package/dist/policy/csp.d.ts.map +1 -0
  129. package/dist/policy/csp.js +47 -0
  130. package/dist/policy/csp.js.map +1 -0
  131. package/dist/policy/glob.d.ts +12 -0
  132. package/dist/policy/glob.d.ts.map +1 -0
  133. package/dist/policy/glob.js +63 -0
  134. package/dist/policy/glob.js.map +1 -0
  135. package/dist/policy/index.d.ts +47 -0
  136. package/dist/policy/index.d.ts.map +1 -0
  137. package/dist/policy/index.js +34 -0
  138. package/dist/policy/index.js.map +1 -0
  139. package/dist/policy/parse.d.ts +51 -0
  140. package/dist/policy/parse.d.ts.map +1 -0
  141. package/dist/policy/parse.js +352 -0
  142. package/dist/policy/parse.js.map +1 -0
  143. package/dist/policy/vocabulary.d.ts +15 -0
  144. package/dist/policy/vocabulary.d.ts.map +1 -0
  145. package/dist/policy/vocabulary.js +99 -0
  146. package/dist/policy/vocabulary.js.map +1 -0
  147. package/dist/registry.d.ts +45 -0
  148. package/dist/registry.d.ts.map +1 -0
  149. package/dist/registry.js +85 -0
  150. package/dist/registry.js.map +1 -0
  151. package/dist/report/github.d.ts +10 -0
  152. package/dist/report/github.d.ts.map +1 -0
  153. package/dist/report/github.js +31 -0
  154. package/dist/report/github.js.map +1 -0
  155. package/dist/report/json.d.ts +44 -0
  156. package/dist/report/json.d.ts.map +1 -0
  157. package/dist/report/json.js +40 -0
  158. package/dist/report/json.js.map +1 -0
  159. package/dist/report/sarif.d.ts +10 -0
  160. package/dist/report/sarif.d.ts.map +1 -0
  161. package/dist/report/sarif.js +64 -0
  162. package/dist/report/sarif.js.map +1 -0
  163. package/dist/report/summary.d.ts +9 -0
  164. package/dist/report/summary.d.ts.map +1 -0
  165. package/dist/report/summary.js +67 -0
  166. package/dist/report/summary.js.map +1 -0
  167. package/dist/report/text.d.ts +37 -0
  168. package/dist/report/text.d.ts.map +1 -0
  169. package/dist/report/text.js +81 -0
  170. package/dist/report/text.js.map +1 -0
  171. package/dist/sync.d.ts +19 -0
  172. package/dist/sync.d.ts.map +1 -0
  173. package/dist/sync.js +131 -0
  174. package/dist/sync.js.map +1 -0
  175. package/dist/version.d.ts +2 -0
  176. package/dist/version.d.ts.map +1 -0
  177. package/dist/version.js +6 -0
  178. package/dist/version.js.map +1 -0
  179. package/package.json +88 -0
@@ -0,0 +1,352 @@
1
+ /**
2
+ * Parser for frostjs's policy files, written in frost's policy dialect:
3
+ * line-oriented, one rule per line, `--` or `#` comments, case-insensitive
4
+ * keywords, double-quoted strings. A trailing comment on a rule is its hint
5
+ * and is printed when the rule refuses something.
6
+ *
7
+ * policy "checkout-widget"
8
+ * ignore "public/*.min.js"
9
+ * vendored "vendor/**"
10
+ * may reach "api.example.com", "cdn.example.com"
11
+ * may use session storage
12
+ * may use local storage in "src/legacy/*" until 2026-12-01 -- migrating
13
+ * forbid cookies -- consent banner owns these
14
+ * forbid reaching "*.telemetry.example"
15
+ * forbid everything else
16
+ */
17
+ import { resolveCapability, FAMILIES, CAPABILITY_PHRASES } from "./vocabulary.js";
18
+ import { SAME_ORIGIN } from "../extract/target.js";
19
+ /**
20
+ * A policy that cannot be read. The message carries file, line, the source
21
+ * line with a caret under the column, and what to try instead.
22
+ */
23
+ export class PolicyError extends Error {
24
+ file;
25
+ line;
26
+ column;
27
+ detail;
28
+ source;
29
+ tryInstead;
30
+ constructor(file, line,
31
+ /** 1-based. */
32
+ column, detail, source, tryInstead) {
33
+ super(`${file} line ${line}: ${detail}\n ${source}\n ${" ".repeat(Math.max(0, column - 1))}^` +
34
+ (tryInstead ? `\n try: ${tryInstead}` : ""));
35
+ this.file = file;
36
+ this.line = line;
37
+ this.column = column;
38
+ this.detail = detail;
39
+ this.source = source;
40
+ this.tryInstead = tryInstead;
41
+ this.name = "PolicyError";
42
+ }
43
+ }
44
+ /** A position in one line's tokens. */
45
+ class Cursor {
46
+ tokens;
47
+ end;
48
+ fail;
49
+ pos = 0;
50
+ constructor(tokens,
51
+ /** Offset of the end of the code on this line, for errors about something missing. */
52
+ end, fail) {
53
+ this.tokens = tokens;
54
+ this.end = end;
55
+ this.fail = fail;
56
+ }
57
+ tok() {
58
+ return this.tokens[this.pos];
59
+ }
60
+ word(offset = 0) {
61
+ const t = this.tokens[this.pos + offset];
62
+ return t?.kind === "word" ? t.value : null;
63
+ }
64
+ at() {
65
+ return this.tokens[this.pos]?.at ?? this.end;
66
+ }
67
+ done() {
68
+ return this.pos >= this.tokens.length;
69
+ }
70
+ }
71
+ /**
72
+ * Parse a policy file's text. Throws PolicyError at the first line that
73
+ * cannot be read; `file` is used only in messages.
74
+ */
75
+ export function parsePolicy(text, file) {
76
+ const rules = [];
77
+ const vendored = [];
78
+ const ignore = [];
79
+ let name = null;
80
+ const lines = text.split(/\r?\n/);
81
+ for (let i = 0; i < lines.length; i++) {
82
+ const n = i + 1;
83
+ const [code, hint] = splitComment(lines[i]);
84
+ const trimmed = code.trim();
85
+ if (trimmed === "")
86
+ continue;
87
+ const fail = (at, detail, tryInstead) => {
88
+ throw new PolicyError(file, n, at + 1, detail, code.trimEnd(), tryInstead);
89
+ };
90
+ const c = new Cursor(tokenize(code, fail), code.trimEnd().length, fail);
91
+ const first = c.tok();
92
+ if (c.word() === "policy") {
93
+ if (name !== null)
94
+ fail(first.at, "only one policy line is allowed");
95
+ const nameTok = c.tokens[1];
96
+ if (nameTok?.kind !== "string" || c.tokens.length !== 2) {
97
+ fail(nameTok?.at ?? c.end, "'policy' needs a quoted name", `policy "${nameTok?.raw ?? "name"}"`);
98
+ }
99
+ name = nameTok.value;
100
+ continue;
101
+ }
102
+ const pathList = c.word() === "vendored" ? vendored : c.word() === "ignore" ? ignore : null;
103
+ if (pathList !== null) {
104
+ const keyword = c.word();
105
+ const example = keyword === "vendored" ? 'vendored "vendor/**"' : 'ignore "public/*.min.js"';
106
+ c.pos = 1;
107
+ if (c.tok()?.kind !== "string")
108
+ fail(c.at(), `'${keyword}' needs one or more quoted paths`, example);
109
+ pathList.push(...quotedList(c, "path", example, checkPath(example)));
110
+ if (!c.done())
111
+ fail(c.at(), `unexpected '${c.tok().raw}' after the paths`);
112
+ continue;
113
+ }
114
+ rules.push(parseRule(c, trimmed, hint, n));
115
+ }
116
+ return { file, name: name ?? file, rules, vendored, ignore };
117
+ }
118
+ /** The verb forms a rule may start with, longest first so `forbid using` beats `forbid`. */
119
+ const FORMS = [
120
+ { words: ["may", "use"], verb: "may", reach: false, text: "may use" },
121
+ { words: ["may", "reach"], verb: "may", reach: true, text: "may reach" },
122
+ { words: ["forbid", "reaching"], verb: "forbid", reach: true, text: "forbid reaching" },
123
+ { words: ["forbid", "using"], verb: "forbid", reach: false, text: "forbid" },
124
+ { words: ["forbid"], verb: "forbid", reach: false, text: "forbid" },
125
+ ];
126
+ function parseRule(c, text, hint, line) {
127
+ const form = FORMS.find((f) => f.words.every((w, i) => c.word(i) === w));
128
+ if (!form) {
129
+ const rest = c.tokens
130
+ .slice(1)
131
+ .map((t) => t.raw)
132
+ .join(" ");
133
+ c.fail(c.tokens[0].at, `cannot read '${text}'`, resolveCapability(rest) ? `may use ${rest}` : "may use storage");
134
+ }
135
+ c.pos = form.words.length;
136
+ const { verb, text: verbText } = form;
137
+ const { capability, phrase, hosts } = form.reach ? parseHosts(c, verbText) : parseCapability(c, verb, verbText);
138
+ const paths = [];
139
+ let until = null;
140
+ while (!c.done()) {
141
+ const w = c.word();
142
+ if (w === "in") {
143
+ if (paths.length > 0) {
144
+ c.fail(c.at(), "'in' given twice; list every path after one 'in', separated by commas", `${verbText} ${phrase} in "a/*", "b/*"`);
145
+ }
146
+ c.pos++;
147
+ const example = `${verbText} ${phrase} in "src/*"`;
148
+ if (c.tok()?.kind !== "string")
149
+ c.fail(c.at(), "'in' needs one or more quoted paths", example);
150
+ paths.push(...quotedList(c, "path", example, checkPath(example)));
151
+ }
152
+ else if (w === "until") {
153
+ if (verb === "forbid") {
154
+ c.fail(c.at(), "'until' only applies to 'may' rules; a forbid does not expire", `forbid ${phrase}`);
155
+ }
156
+ if (until !== null)
157
+ c.fail(c.at(), "'until' given twice", `${verbText} ${phrase} until 2026-12-01`);
158
+ c.pos++;
159
+ const t = c.tok();
160
+ if (t?.kind !== "word" || !/^\d{4}-\d{2}-\d{2}$/.test(t.value)) {
161
+ c.fail(c.at(), "'until' needs a date like 2026-12-01", `${verbText} ${phrase} until 2026-12-01`);
162
+ }
163
+ if (!isRealDate(t.value))
164
+ c.fail(t.at, `${t.value} is not a real date`);
165
+ until = t.value;
166
+ c.pos++;
167
+ }
168
+ else {
169
+ c.fail(c.at(), `unexpected '${c.tok()?.raw}' after the rule`);
170
+ }
171
+ }
172
+ return { verb, capability, hosts, paths, until, hint, line, text };
173
+ }
174
+ /** `may reach "host", ...` and `forbid reaching "host", ...`. */
175
+ function parseHosts(c, verbText) {
176
+ const example = `${verbText} "api.example.com"`;
177
+ const t0 = c.tok();
178
+ if (t0?.kind !== "string") {
179
+ const guess = t0?.kind === "word" ? t0.raw : "api.example.com";
180
+ c.fail(c.at(), `'${verbText}' needs one or more quoted hosts`, `${verbText} "${guess}"`);
181
+ }
182
+ const hosts = quotedList(c, "host", example, (host, at) => {
183
+ if (/[/:?#]/.test(host)) {
184
+ const m = /^(?:[a-z][a-z0-9+.-]*:)?\/\/(?:[^/@]*@)?([^/:?#]+)/i.exec(host);
185
+ c.fail(at, "name a host, not a URL", `${verbText} "${m?.[1] ?? "api.example.com"}"`);
186
+ }
187
+ return host.toLowerCase();
188
+ });
189
+ return { capability: "network", phrase: hosts.map((h) => `"${h}"`).join(", "), hosts };
190
+ }
191
+ /** `may use <capability>` and `forbid [using] <capability>`: words up to `in`, `until` or the end. */
192
+ function parseCapability(c, verb, verbText) {
193
+ const phraseAt = c.at();
194
+ const words = [];
195
+ for (let w = c.word(); w !== null && w !== "in" && w !== "until"; w = c.word()) {
196
+ words.push(w);
197
+ c.pos++;
198
+ }
199
+ if (words.length === 0)
200
+ c.fail(phraseAt, "name a capability after the verb", `${verbText} storage`);
201
+ const phrase = words.join(" ");
202
+ if (verb === "forbid" && phrase === "everything else")
203
+ return { capability: "*", phrase, hosts: [] };
204
+ const capability = resolveCapability(phrase);
205
+ if (capability === null) {
206
+ const near = nearest(phrase);
207
+ c.fail(phraseAt, `unknown capability '${phrase}'` + (near ? `; did you mean '${near}'?` : ""), near ? `${verbText} ${near}` : `one of ${FAMILIES.join(", ")}, or a phrase such as "local storage" or "cookies"`);
208
+ }
209
+ return { capability, phrase, hosts: [] };
210
+ }
211
+ /** Validator for a path in `in` or `vendored`: relative, never absolute. */
212
+ function checkPath(example) {
213
+ return (value, at, c) => {
214
+ if (value.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(value)) {
215
+ c.fail(at, "paths are relative to the policy file, not absolute", example);
216
+ }
217
+ return value;
218
+ };
219
+ }
220
+ /**
221
+ * A comma-separated list of quoted strings starting at the cursor. The
222
+ * caller has already checked that the first token is a string, so the
223
+ * "needs one or more" message stays the caller's.
224
+ */
225
+ function quotedList(c, what, example, check) {
226
+ const out = [];
227
+ for (;;) {
228
+ const t = c.tok();
229
+ if (t?.kind !== "string")
230
+ c.fail(c.at(), `expected another quoted ${what} after the comma`, example);
231
+ const value = what === "host" ? t.value.trim() : t.value;
232
+ if (value === "")
233
+ c.fail(t.at, what === "host" ? "empty host" : "empty path; name a file or a glob", example);
234
+ out.push(value === SAME_ORIGIN ? value : check(value, t.at, c));
235
+ c.pos++;
236
+ if (c.tok()?.kind === "comma")
237
+ c.pos++;
238
+ else
239
+ break;
240
+ }
241
+ return out;
242
+ }
243
+ /** The closest known phrase or code, or null if nothing is within editing distance. */
244
+ function nearest(phrase) {
245
+ let best = null;
246
+ let bestDist = Infinity;
247
+ const candidates = [...CAPABILITY_PHRASES.keys(), ...new Set(CAPABILITY_PHRASES.values())];
248
+ for (const candidate of candidates) {
249
+ if (candidate === "*")
250
+ continue;
251
+ const d = levenshtein(phrase, candidate);
252
+ if (d < bestDist) {
253
+ bestDist = d;
254
+ best = candidate;
255
+ }
256
+ }
257
+ // Allow roughly a third of the phrase to be wrong, never more than three edits.
258
+ const limit = Math.min(3, Math.max(1, Math.floor(phrase.length / 3)));
259
+ return bestDist <= limit ? best : null;
260
+ }
261
+ function levenshtein(a, b) {
262
+ const prev = Array.from({ length: b.length + 1 }, (_, i) => i);
263
+ for (let i = 1; i <= a.length; i++) {
264
+ let diag = prev[0];
265
+ prev[0] = i;
266
+ for (let j = 1; j <= b.length; j++) {
267
+ const tmp = prev[j];
268
+ prev[j] = Math.min(prev[j] + 1, prev[j - 1] + 1, diag + (a[i - 1] === b[j - 1] ? 0 : 1));
269
+ diag = tmp;
270
+ }
271
+ }
272
+ return prev[b.length];
273
+ }
274
+ /** Year, month (0-based) and day of a validated YYYY-MM-DD string. */
275
+ export function ymd(s) {
276
+ const [y, m, d] = s.split("-").map(Number);
277
+ return [y, m - 1, d];
278
+ }
279
+ function isRealDate(s) {
280
+ const [y, m, d] = ymd(s);
281
+ const dt = new Date(Date.UTC(y, m, d));
282
+ return dt.getUTCFullYear() === y && dt.getUTCMonth() === m && dt.getUTCDate() === d;
283
+ }
284
+ /** Split a line into code and trailing comment; a marker inside quotes is not a comment. */
285
+ function splitComment(raw) {
286
+ let quoted = false;
287
+ for (let i = 0; i < raw.length; i++) {
288
+ const ch = raw[i];
289
+ if (ch === "\\" && quoted) {
290
+ i++;
291
+ continue;
292
+ }
293
+ if (ch === '"')
294
+ quoted = !quoted;
295
+ else if (!quoted && (raw.startsWith("--", i) || ch === "#")) {
296
+ const len = ch === "#" ? 1 : 2;
297
+ return [raw.slice(0, i), raw.slice(i + len).trim()];
298
+ }
299
+ }
300
+ return [raw, ""];
301
+ }
302
+ const ESCAPES = { n: "\n", t: "\t", '"': '"', "\\": "\\" };
303
+ function tokenize(line, fail) {
304
+ const out = [];
305
+ let i = 0;
306
+ while (i < line.length) {
307
+ const ch = line[i];
308
+ if (/\s/.test(ch)) {
309
+ i++;
310
+ }
311
+ else if (ch === ",") {
312
+ out.push({ kind: "comma", raw: ",", at: i });
313
+ i++;
314
+ }
315
+ else if (ch === '"') {
316
+ let j = i + 1;
317
+ let value = "";
318
+ let closed = false;
319
+ while (j < line.length) {
320
+ const inner = line[j];
321
+ if (inner === "\\") {
322
+ const e = line[j + 1];
323
+ if (e !== undefined && ESCAPES[e] !== undefined) {
324
+ value += ESCAPES[e];
325
+ j += 2;
326
+ continue;
327
+ }
328
+ }
329
+ if (inner === '"') {
330
+ closed = true;
331
+ break;
332
+ }
333
+ value += inner;
334
+ j++;
335
+ }
336
+ if (!closed)
337
+ fail(i, "unterminated string", `${line.trim()}"`);
338
+ out.push({ kind: "string", value, raw: line.slice(i, j + 1), at: i });
339
+ i = j + 1;
340
+ }
341
+ else {
342
+ let j = i;
343
+ while (j < line.length && !/[\s,"]/.test(line[j]))
344
+ j++;
345
+ const raw = line.slice(i, j);
346
+ out.push({ kind: "word", value: raw.toLowerCase(), raw, at: i });
347
+ i = j;
348
+ }
349
+ }
350
+ return out;
351
+ }
352
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/policy/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The words a policy author may use for a capability, mapped to the stable
3
+ * code the extractor emits. Phrases are matched after lowercasing and
4
+ * whitespace collapsing. A capability code is always accepted as-is.
5
+ */
6
+ export declare const CAPABILITY_PHRASES: ReadonlyMap<string, string>;
7
+ /** Every capability family code, for validating a bare code and for hints. */
8
+ export declare const FAMILIES: readonly string[];
9
+ /** Every member code the extractor can emit. Keep in step with src/extract/recognizers. */
10
+ export declare const MEMBER_CODES: readonly string[];
11
+ /** Every code a policy may name directly: the families and each member the extractor can emit. */
12
+ export declare const KNOWN_CODES: ReadonlySet<string>;
13
+ /** Resolve a phrase or code to a capability code, or null. */
14
+ export declare function resolveCapability(words: string): string | null;
15
+ //# sourceMappingURL=vocabulary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../../src/policy/vocabulary.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CA+BzD,CAAC;AAEH,8EAA8E;AAC9E,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EASrC,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAoCzC,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,MAAM,CAA2C,CAAC;AAExF,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9D"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * The words a policy author may use for a capability, mapped to the stable
3
+ * code the extractor emits. Phrases are matched after lowercasing and
4
+ * whitespace collapsing. A capability code is always accepted as-is.
5
+ */
6
+ export const CAPABILITY_PHRASES = new Map([
7
+ ["everything", "*"],
8
+ // storage
9
+ ["storage", "storage"],
10
+ ["local storage", "storage.local"],
11
+ ["session storage", "storage.session"],
12
+ ["cookies", "storage.cookie"],
13
+ ["the cookie", "storage.cookie"],
14
+ ["indexeddb", "storage.indexeddb"],
15
+ ["the cache", "storage.cache"],
16
+ ["caches", "storage.cache"],
17
+ ["cache storage", "storage.cache"],
18
+ ["navigator storage", "storage.navigator"],
19
+ // network
20
+ ["the network", "network"],
21
+ ["network", "network"],
22
+ // codegen
23
+ ["code generation", "codegen"],
24
+ ["eval", "codegen"],
25
+ // dom-escape
26
+ ["html injection", "dom-escape"],
27
+ // identity
28
+ ["identity", "identity"],
29
+ ["fingerprinting", "identity"],
30
+ // navigation
31
+ ["navigation", "navigation"],
32
+ // globals
33
+ ["globals", "globals"],
34
+ // worker
35
+ ["workers", "worker"],
36
+ ["service workers", "worker"],
37
+ ]);
38
+ /** Every capability family code, for validating a bare code and for hints. */
39
+ export const FAMILIES = [
40
+ "storage",
41
+ "network",
42
+ "codegen",
43
+ "dom-escape",
44
+ "identity",
45
+ "navigation",
46
+ "globals",
47
+ "worker",
48
+ ];
49
+ /** Every member code the extractor can emit. Keep in step with src/extract/recognizers. */
50
+ export const MEMBER_CODES = [
51
+ "storage.local",
52
+ "storage.session",
53
+ "storage.indexeddb",
54
+ "storage.cache",
55
+ "storage.cookie",
56
+ "storage.navigator",
57
+ "network.fetch",
58
+ "network.xhr",
59
+ "network.websocket",
60
+ "network.eventsource",
61
+ "network.beacon",
62
+ "network.import",
63
+ "codegen.eval",
64
+ "codegen.function",
65
+ "codegen.timer",
66
+ "codegen.write",
67
+ "dom-escape.html",
68
+ "dom-escape.script",
69
+ "dom-escape.iframe",
70
+ "identity.device",
71
+ "identity.geolocation",
72
+ "identity.media",
73
+ "identity.clipboard",
74
+ "identity.credentials",
75
+ "identity.permissions",
76
+ "navigation.location",
77
+ "navigation.open",
78
+ "navigation.history",
79
+ "navigation.postmessage",
80
+ "globals.window",
81
+ "globals.prototype",
82
+ "worker.dedicated",
83
+ "worker.shared",
84
+ "worker.service",
85
+ "worker.worklet",
86
+ ];
87
+ /** Every code a policy may name directly: the families and each member the extractor can emit. */
88
+ export const KNOWN_CODES = new Set([...FAMILIES, ...MEMBER_CODES]);
89
+ /** Resolve a phrase or code to a capability code, or null. */
90
+ export function resolveCapability(words) {
91
+ const key = words.trim().toLowerCase().replace(/\s+/g, " ");
92
+ const phrase = CAPABILITY_PHRASES.get(key);
93
+ if (phrase !== undefined)
94
+ return phrase;
95
+ if (KNOWN_CODES.has(key))
96
+ return key;
97
+ return null;
98
+ }
99
+ //# sourceMappingURL=vocabulary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/policy/vocabulary.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAgC,IAAI,GAAG,CAAC;IACrE,CAAC,YAAY,EAAE,GAAG,CAAC;IACnB,UAAU;IACV,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,CAAC,eAAe,EAAE,eAAe,CAAC;IAClC,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IACtC,CAAC,SAAS,EAAE,gBAAgB,CAAC;IAC7B,CAAC,YAAY,EAAE,gBAAgB,CAAC;IAChC,CAAC,WAAW,EAAE,mBAAmB,CAAC;IAClC,CAAC,WAAW,EAAE,eAAe,CAAC;IAC9B,CAAC,QAAQ,EAAE,eAAe,CAAC;IAC3B,CAAC,eAAe,EAAE,eAAe,CAAC;IAClC,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAC1C,UAAU;IACV,CAAC,aAAa,EAAE,SAAS,CAAC;IAC1B,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,UAAU;IACV,CAAC,iBAAiB,EAAE,SAAS,CAAC;IAC9B,CAAC,MAAM,EAAE,SAAS,CAAC;IACnB,aAAa;IACb,CAAC,gBAAgB,EAAE,YAAY,CAAC;IAChC,WAAW;IACX,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,gBAAgB,EAAE,UAAU,CAAC;IAC9B,aAAa;IACb,CAAC,YAAY,EAAE,YAAY,CAAC;IAC5B,UAAU;IACV,CAAC,SAAS,EAAE,SAAS,CAAC;IACtB,SAAS;IACT,CAAC,SAAS,EAAE,QAAQ,CAAC;IACrB,CAAC,iBAAiB,EAAE,QAAQ,CAAC;CAC9B,CAAC,CAAC;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,QAAQ,GAAsB;IACzC,SAAS;IACT,SAAS;IACT,SAAS;IACT,YAAY;IACZ,UAAU;IACV,YAAY;IACZ,SAAS;IACT,QAAQ;CACT,CAAC;AAEF,2FAA2F;AAC3F,MAAM,CAAC,MAAM,YAAY,GAAsB;IAC7C,eAAe;IACf,iBAAiB;IACjB,mBAAmB;IACnB,eAAe;IACf,gBAAgB;IAChB,mBAAmB;IACnB,eAAe;IACf,aAAa;IACb,mBAAmB;IACnB,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,eAAe;IACf,eAAe;IACf,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,iBAAiB;IACjB,sBAAsB;IACtB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;IACtB,sBAAsB;IACtB,qBAAqB;IACrB,iBAAiB;IACjB,oBAAoB;IACpB,wBAAwB;IACxB,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;IAClB,eAAe;IACf,gBAAgB;IAChB,gBAAgB;CACjB,CAAC;AAEF,kGAAkG;AAClG,MAAM,CAAC,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;AAExF,8DAA8D;AAC9D,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACrC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,45 @@
1
+ export interface RegistryUse {
2
+ capability: string;
3
+ target: string | null;
4
+ }
5
+ export interface RegistryEntry {
6
+ /** "sha384-<base64>", the same form as an SRI integrity value. */
7
+ integrity: string;
8
+ package: string;
9
+ version: string;
10
+ /** Path relative to the policy directory when the entry was added. */
11
+ file: string;
12
+ /** Distinct (capability, target) pairs with at least probable confidence. */
13
+ uses: RegistryUse[];
14
+ added: string;
15
+ }
16
+ export interface Registry {
17
+ version: 1;
18
+ /** Lockfile this registry was last synced against, if any. */
19
+ lockfile?: {
20
+ path: string;
21
+ integrity: string;
22
+ };
23
+ entries: RegistryEntry[];
24
+ }
25
+ /** The SRI-form SHA-384 of a file's contents. */
26
+ export declare function integrityOfFile(file: string): string;
27
+ /** Where the registry lives for a policy: .frostjs/registry.json beside it. */
28
+ export declare function registryPath(policyDir: string): string;
29
+ /** Read a registry. A missing file is an empty registry; malformed JSON or an unknown version throws. */
30
+ export declare function readRegistry(file: string): Registry;
31
+ /** Write the registry with entries sorted by package, version and file, creating .frostjs/ if needed. */
32
+ export declare function writeRegistry(file: string, registry: Registry): void;
33
+ /** Replace any entry with the same integrity, then add. */
34
+ export declare function upsert(registry: Registry, entry: RegistryEntry): Registry;
35
+ /** The entry for a hash, or null. */
36
+ export declare function lookup(registry: Registry, integrity: string): RegistryEntry | null;
37
+ /**
38
+ * Guess the package and version a vendored file belongs to: the nearest
39
+ * package.json between the file and `stopAt`, else the file's base name.
40
+ */
41
+ export declare function guessPackage(file: string, stopAt: string): {
42
+ package: string;
43
+ version: string;
44
+ };
45
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,8DAA8D;IAC9D,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAOD,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,yGAAyG;AACzG,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAWnD;AAED,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAUpE;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAEzE;AAED,qCAAqC;AACrC,wBAAgB,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAElF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAoB/F"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * The fingerprint registry for vendored code (REQUIREMENTS section 8).
3
+ * Lives at .frostjs/registry.json beside the policy. Maps a SHA-384 of a
4
+ * file's bytes to the package it came from and the capability set it was
5
+ * found to use when somebody reviewed it with `frostjs vendor add`.
6
+ */
7
+ import { createHash } from "node:crypto";
8
+ import fs from "node:fs";
9
+ import path from "node:path";
10
+ const REGISTRY_RELATIVE = path.join(".frostjs", "registry.json");
11
+ /** The SRI-form SHA-384 of some bytes. */
12
+ function integrityOf(bytes) {
13
+ return "sha384-" + createHash("sha384").update(bytes).digest("base64");
14
+ }
15
+ /** The SRI-form SHA-384 of a file's contents. */
16
+ export function integrityOfFile(file) {
17
+ return integrityOf(fs.readFileSync(file));
18
+ }
19
+ /** Where the registry lives for a policy: .frostjs/registry.json beside it. */
20
+ export function registryPath(policyDir) {
21
+ return path.join(policyDir, REGISTRY_RELATIVE);
22
+ }
23
+ /** Read a registry. A missing file is an empty registry; malformed JSON or an unknown version throws. */
24
+ export function readRegistry(file) {
25
+ if (!fs.existsSync(file))
26
+ return { version: 1, entries: [] };
27
+ let raw;
28
+ try {
29
+ raw = JSON.parse(fs.readFileSync(file, "utf8"));
30
+ }
31
+ catch (e) {
32
+ throw new Error(`registry ${file} is not valid JSON: ${e.message}`);
33
+ }
34
+ const r = raw;
35
+ if (r.version !== 1 || !Array.isArray(r.entries))
36
+ throw new Error(`registry ${file} has an unknown format`);
37
+ return { version: 1, ...(r.lockfile ? { lockfile: r.lockfile } : {}), entries: r.entries };
38
+ }
39
+ /** Write the registry with entries sorted by package, version and file, creating .frostjs/ if needed. */
40
+ export function writeRegistry(file, registry) {
41
+ const sorted = [...registry.entries].sort((a, b) => a.package === b.package
42
+ ? a.version === b.version
43
+ ? a.file.localeCompare(b.file)
44
+ : a.version.localeCompare(b.version)
45
+ : a.package.localeCompare(b.package));
46
+ fs.mkdirSync(path.dirname(file), { recursive: true });
47
+ fs.writeFileSync(file, JSON.stringify({ ...registry, entries: sorted }, null, 2) + "\n");
48
+ }
49
+ /** Replace any entry with the same integrity, then add. */
50
+ export function upsert(registry, entry) {
51
+ return { ...registry, entries: [...registry.entries.filter((e) => e.integrity !== entry.integrity), entry] };
52
+ }
53
+ /** The entry for a hash, or null. */
54
+ export function lookup(registry, integrity) {
55
+ return registry.entries.find((e) => e.integrity === integrity) ?? null;
56
+ }
57
+ /**
58
+ * Guess the package and version a vendored file belongs to: the nearest
59
+ * package.json between the file and `stopAt`, else the file's base name.
60
+ */
61
+ export function guessPackage(file, stopAt) {
62
+ let dir = path.dirname(path.resolve(file));
63
+ const stop = path.resolve(stopAt);
64
+ for (;;) {
65
+ const pj = path.join(dir, "package.json");
66
+ if (fs.existsSync(pj)) {
67
+ try {
68
+ const p = JSON.parse(fs.readFileSync(pj, "utf8"));
69
+ if (typeof p.name === "string")
70
+ return { package: p.name, version: typeof p.version === "string" ? p.version : "unknown" };
71
+ }
72
+ catch {
73
+ // fall through to the next directory
74
+ }
75
+ }
76
+ if (dir === stop)
77
+ break;
78
+ const parent = path.dirname(dir);
79
+ if (parent === dir)
80
+ break;
81
+ dir = parent;
82
+ }
83
+ return { package: path.basename(file), version: "unknown" };
84
+ }
85
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * GitHub Actions workflow commands. Each denial becomes an inline
3
+ * annotation on the pull request; unknown uses become warnings. The text
4
+ * summary follows so the job log still reads on its own.
5
+ */
6
+ import type { Decision } from "../policy/index.js";
7
+ import { type Totals, type TextOptions } from "./text.js";
8
+ /** `--format github`: one workflow command per denial or unknown use, then the text report. */
9
+ export declare function github(decisions: readonly Decision[], totals: Totals, opts?: TextOptions): string;
10
+ //# sourceMappingURL=github.d.ts.map