@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 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/report/github.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAoC,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAW5F,+FAA+F;AAC/F,wBAAgB,MAAM,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,CAsBrG"}
@@ -0,0 +1,31 @@
1
+ import { denialMessage, describeUse, text } from "./text.js";
2
+ /** Escape a message per the workflow-command rules: % first, then newlines. */
3
+ function escapeData(s) {
4
+ return s.replace(/%/g, "%25").replace(/\r/g, "%0D").replace(/\n/g, "%0A");
5
+ }
6
+ /** Escape a property value: as a message, plus colons and commas. */
7
+ function escapeProperty(s) {
8
+ return escapeData(s).replace(/:/g, "%3A").replace(/,/g, "%2C");
9
+ }
10
+ /** `--format github`: one workflow command per denial or unknown use, then the text report. */
11
+ export function github(decisions, totals, opts = {}) {
12
+ const lines = [];
13
+ for (const d of decisions) {
14
+ if (d.verdict !== "denied" && d.verdict !== "unknown")
15
+ continue;
16
+ const { use } = d;
17
+ const subject = describeUse(use.capability, use.target);
18
+ const kind = d.verdict === "denied" ? "error" : "warning";
19
+ const title = d.verdict === "denied" ? `frostjs: ${use.capability} denied` : `frostjs: ${use.capability} ${use.confidence}`;
20
+ const message = d.verdict === "denied"
21
+ ? denialMessage(d)
22
+ : `${subject} ${use.confidence} (not failing the build): ${use.expression}`;
23
+ lines.push(`::${kind} file=${escapeProperty(use.file)},line=${use.line},col=${use.column},title=${escapeProperty(title)}::${escapeData(message)}`);
24
+ }
25
+ for (const w of opts.warnings ?? []) {
26
+ lines.push(`::warning title=${escapeProperty("frostjs: grant expiring")}::${escapeData(w)}`);
27
+ }
28
+ const body = lines.length ? lines.join("\n") + "\n" : "";
29
+ return body + text(decisions, totals, opts);
30
+ }
31
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/report/github.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,EAAiC,MAAM,WAAW,CAAC;AAE5F,+EAA+E;AAC/E,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5E,CAAC;AACD,qEAAqE;AACrE,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,MAAM,CAAC,SAA8B,EAAE,MAAc,EAAE,OAAoB,EAAE;IAC3F,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;YAAE,SAAS;QAChE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAClB,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1D,MAAM,KAAK,GACT,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,UAAU,SAAS,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QAChH,MAAM,OAAO,GACX,CAAC,CAAC,OAAO,KAAK,QAAQ;YACpB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,GAAG,OAAO,IAAI,GAAG,CAAC,UAAU,6BAA6B,GAAG,CAAC,UAAU,EAAE,CAAC;QAChF,KAAK,CAAC,IAAI,CACR,KAAK,IAAI,SAAS,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC,MAAM,UAAU,cAAc,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,EAAE,CACvI,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,mBAAmB,cAAc,CAAC,yBAAyB,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,OAAO,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * JSON output. The schema is versioned; bump SCHEMA_VERSION on any
3
+ * incompatible change and say so in the changelog.
4
+ */
5
+ import type { Decision, Policy, Verdict } from "../policy/index.js";
6
+ /** Bumped on any incompatible change to JsonReport. */
7
+ export declare const SCHEMA_VERSION = 1;
8
+ export interface JsonRule {
9
+ line: number;
10
+ text: string;
11
+ hint: string;
12
+ }
13
+ export interface JsonDecision {
14
+ file: string;
15
+ line: number;
16
+ column: number;
17
+ capability: string;
18
+ target: string | null;
19
+ expression: string;
20
+ confidence: string;
21
+ verdict: string;
22
+ reason: string | null;
23
+ rule: JsonRule | null;
24
+ }
25
+ /** The document `--format json` prints. `schema` is SCHEMA_VERSION; `frostjs` is the tool version. */
26
+ export interface JsonReport {
27
+ schema: number;
28
+ frostjs: string;
29
+ policy: {
30
+ file: string;
31
+ name: string;
32
+ };
33
+ /** Files analyzed. */
34
+ files: number;
35
+ /** Count of decisions by verdict. */
36
+ summary: Record<Verdict, number>;
37
+ /** Expiry warnings from the policy. */
38
+ warnings: string[];
39
+ /** Every use, including allowed ones. */
40
+ decisions: JsonDecision[];
41
+ }
42
+ /** `--format json`: the JsonReport, pretty-printed. */
43
+ export declare function json(decisions: readonly Decision[], files: number, policy: Policy): string;
44
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGpE,uDAAuD;AACvD,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvB;AAED,sGAAsG;AACtG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACjC,uCAAuC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yCAAyC;IACzC,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAkCD,uDAAuD;AACvD,wBAAgB,IAAI,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1F"}
@@ -0,0 +1,40 @@
1
+ import { VERSION } from "../version.js";
2
+ /** Bumped on any incompatible change to JsonReport. */
3
+ export const SCHEMA_VERSION = 1;
4
+ function buildJson(decisions, files, policy) {
5
+ const summary = {
6
+ allowed: 0,
7
+ denied: 0,
8
+ unknown: 0,
9
+ suppressed: 0,
10
+ baselined: 0,
11
+ unchanged: 0,
12
+ };
13
+ for (const d of decisions)
14
+ summary[d.verdict]++;
15
+ return {
16
+ schema: SCHEMA_VERSION,
17
+ frostjs: VERSION,
18
+ policy: { file: policy.file, name: policy.name },
19
+ files,
20
+ summary,
21
+ warnings: [...policy.warnings],
22
+ decisions: decisions.map((d) => ({
23
+ file: d.use.file,
24
+ line: d.use.line,
25
+ column: d.use.column,
26
+ capability: d.use.capability,
27
+ target: d.use.target,
28
+ expression: d.use.expression,
29
+ confidence: d.use.confidence,
30
+ verdict: d.verdict,
31
+ reason: d.reason,
32
+ rule: d.rule ? { line: d.rule.line, text: d.rule.text, hint: d.rule.hint } : null,
33
+ })),
34
+ };
35
+ }
36
+ /** `--format json`: the JsonReport, pretty-printed. */
37
+ export function json(decisions, files, policy) {
38
+ return JSON.stringify(buildJson(decisions, files, policy), null, 2) + "\n";
39
+ }
40
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/report/json.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,uDAAuD;AACvD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAoChC,SAAS,SAAS,CAAC,SAA8B,EAAE,KAAa,EAAE,MAAc;IAC9E,MAAM,OAAO,GAA4B;QACvC,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,CAAC;KACb,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAChD,OAAO;QACL,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,OAAO;QAChB,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;QAChD,KAAK;QACL,OAAO;QACP,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC9B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;YAChB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI;YAChB,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;YACpB,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU;YAC5B,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;YACpB,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU;YAC5B,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU;YAC5B,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;SAClF,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,IAAI,CAAC,SAA8B,EAAE,KAAa,EAAE,MAAc;IAChF,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * SARIF 2.1.0 for code scanning. One rule per capability code seen. Denied
3
+ * uses are errors, unknown uses are warnings, baselined uses are errors
4
+ * marked baselineState "unchanged", suppressed uses carry an in-source
5
+ * suppression. Uses the policy did not flag are not results.
6
+ */
7
+ import type { Decision } from "../policy/index.js";
8
+ /** `--format sarif`: a SARIF 2.1.0 log with one rule per capability code seen. */
9
+ export declare function sarif(decisions: readonly Decision[]): string;
10
+ //# sourceMappingURL=sarif.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/report/sarif.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,oBAAoB,CAAC;AAY5D,kFAAkF;AAClF,wBAAgB,KAAK,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAmD5D"}
@@ -0,0 +1,64 @@
1
+ import { denialMessage, describeUse } from "./text.js";
2
+ import { VERSION } from "../version.js";
3
+ const LEVEL = {
4
+ denied: "error",
5
+ unknown: "warning",
6
+ baselined: "error",
7
+ unchanged: "note",
8
+ suppressed: "note",
9
+ };
10
+ /** `--format sarif`: a SARIF 2.1.0 log with one rule per capability code seen. */
11
+ export function sarif(decisions) {
12
+ const reported = decisions.filter((d) => d.verdict !== "allowed");
13
+ const ruleIds = [...new Set(reported.map((d) => d.use.capability))].sort();
14
+ const rules = ruleIds.map((id) => ({
15
+ id,
16
+ name: id.replace(/[.-](\w)/g, (_, c) => c.toUpperCase()).replace(/^\w/, (c) => c.toUpperCase()),
17
+ shortDescription: { text: `Use of the ${id} capability` },
18
+ helpUri: "https://github.com/keithadler/frostjs#capabilities-recognized-so-far",
19
+ }));
20
+ const results = reported.map((d) => {
21
+ const carried = d.verdict === "baselined" || d.verdict === "unchanged";
22
+ const subject = describeUse(d.use.capability, d.use.target);
23
+ const message = d.verdict === "denied" || carried ? denialMessage(d) : `${subject} ${d.use.confidence}: ${d.use.expression}`;
24
+ const r = {
25
+ ruleId: d.use.capability,
26
+ ruleIndex: ruleIds.indexOf(d.use.capability),
27
+ level: LEVEL[d.verdict],
28
+ message: { text: message },
29
+ locations: [
30
+ {
31
+ physicalLocation: {
32
+ artifactLocation: { uri: d.use.file.replace(/\\/g, "/"), uriBaseId: "%SRCROOT%" },
33
+ region: { startLine: d.use.line, startColumn: d.use.column },
34
+ },
35
+ },
36
+ ],
37
+ properties: { confidence: d.use.confidence, target: d.use.target, verdict: d.verdict },
38
+ };
39
+ if (carried)
40
+ r["baselineState"] = "unchanged";
41
+ if (d.verdict === "suppressed")
42
+ r["suppressions"] = [{ kind: "inSource" }];
43
+ return r;
44
+ });
45
+ const log = {
46
+ $schema: "https://json.schemastore.org/sarif-2.1.0.json",
47
+ version: "2.1.0",
48
+ runs: [
49
+ {
50
+ tool: {
51
+ driver: {
52
+ name: "frostjs",
53
+ version: VERSION,
54
+ informationUri: "https://github.com/keithadler/frostjs",
55
+ rules,
56
+ },
57
+ },
58
+ results,
59
+ },
60
+ ],
61
+ };
62
+ return JSON.stringify(log, null, 2) + "\n";
63
+ }
64
+ //# sourceMappingURL=sarif.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/report/sarif.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,KAAK,GAAsE;IAC/E,MAAM,EAAE,OAAO;IACf,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,MAAM;IACjB,UAAU,EAAE,MAAM;CACnB,CAAC;AAEF,kFAAkF;AAClF,MAAM,UAAU,KAAK,CAAC,SAA8B;IAClD,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACjC,EAAE;QACF,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACvG,gBAAgB,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,aAAa,EAAE;QACzD,OAAO,EAAE,sEAAsE;KAChF,CAAC,CAAC,CAAC;IACJ,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC;QACvE,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,OAAO,GACX,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QAC/G,MAAM,CAAC,GAA4B;YACjC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU;YACxB,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;YAC5C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAsC,CAAC;YACtD,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;YAC1B,SAAS,EAAE;gBACT;oBACE,gBAAgB,EAAE;wBAChB,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE;wBACjF,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE;qBAC7D;iBACF;aACF;YACD,UAAU,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;SACvF,CAAC;QACF,IAAI,OAAO;YAAE,CAAC,CAAC,eAAe,CAAC,GAAG,WAAW,CAAC;QAC9C,IAAI,CAAC,CAAC,OAAO,KAAK,YAAY;YAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IACH,MAAM,GAAG,GAAG;QACV,OAAO,EAAE,+CAA+C;QACxD,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ;gBACE,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,OAAO;wBAChB,cAAc,EAAE,uCAAuC;wBACvD,KAAK;qBACN;iBACF;gBACD,OAAO;aACR;SACF;KACF,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A plain-English reading of a policy for someone who does not write
3
+ * JavaScript. Says what the code may do, what it may not, and that
4
+ * everything else is denied, which the policy file leaves implicit.
5
+ */
6
+ import { type Policy } from "../policy/index.js";
7
+ /** The plain-English reading of a policy, for the date it was compiled against. */
8
+ export declare function summary(policy: Policy): string;
9
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/report/summary.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAa,KAAK,MAAM,EAAa,MAAM,oBAAoB,CAAC;AAwBvE,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA+B9C"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * A plain-English reading of a policy for someone who does not write
3
+ * JavaScript. Says what the code may do, what it may not, and that
4
+ * everything else is denied, which the policy file leaves implicit.
5
+ */
6
+ import { isExpired } from "../policy/index.js";
7
+ import { CAPABILITY_PHRASES, FAMILIES } from "../policy/vocabulary.js";
8
+ import { SAME_ORIGIN } from "../extract/target.js";
9
+ /** The friendliest phrase for a code: the first vocabulary entry that maps to it. */
10
+ function phraseFor(code) {
11
+ if (code === "*")
12
+ return "everything";
13
+ for (const [phrase, c] of CAPABILITY_PHRASES)
14
+ if (c === code)
15
+ return phrase;
16
+ return code;
17
+ }
18
+ function describe(r, today) {
19
+ const parts = [];
20
+ if (r.hosts.length > 0) {
21
+ parts.push(`reach ${r.hosts.map((h) => (h === SAME_ORIGIN ? "its own origin" : h)).join(", ")}`);
22
+ }
23
+ else
24
+ parts.push(`use ${phraseFor(r.capability)}`);
25
+ if (r.paths.length > 0)
26
+ parts.push(`only in ${r.paths.join(", ")}`);
27
+ if (r.until !== null)
28
+ parts.push(isExpired(r, today) ? `expired ${r.until}` : `until ${r.until}`);
29
+ let s = parts.join(", ");
30
+ s += ` (line ${r.line})`;
31
+ if (r.hint)
32
+ s += ` - ${r.hint}`;
33
+ return s;
34
+ }
35
+ /** The plain-English reading of a policy, for the date it was compiled against. */
36
+ export function summary(policy) {
37
+ const { today } = policy;
38
+ const lines = [];
39
+ lines.push(`Policy "${policy.name}" (${policy.file})`);
40
+ lines.push("");
41
+ const may = policy.rules.filter((r) => r.verb === "may");
42
+ const forbid = policy.rules.filter((r) => r.verb === "forbid" && r.capability !== "*");
43
+ lines.push("This code may:");
44
+ if (may.length === 0)
45
+ lines.push(" - nothing; every capability is denied");
46
+ for (const r of may)
47
+ lines.push(` - ${describe(r, today)}`);
48
+ lines.push("");
49
+ if (forbid.length > 0) {
50
+ lines.push("It may not, even where a broader grant would allow it:");
51
+ for (const r of forbid)
52
+ lines.push(` - ${describe(r, today)}`);
53
+ lines.push("");
54
+ }
55
+ const granted = new Set(may.map((r) => (r.capability === "*" ? "*" : r.capability.split(".")[0])));
56
+ const untouched = granted.has("*") ? [] : FAMILIES.filter((f) => !granted.has(f));
57
+ if (untouched.length > 0) {
58
+ lines.push(`Everything else is denied. In particular this code may not use: ${untouched.map(phraseFor).join(", ")}.`);
59
+ }
60
+ else {
61
+ lines.push("Everything not listed above is denied.");
62
+ }
63
+ for (const w of policy.warnings)
64
+ lines.push(`Warning: ${w}`);
65
+ return lines.join("\n") + "\n";
66
+ }
67
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/report/summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The default, human-readable report, and the wording of a denial that
3
+ * every other format reuses so the same use reads the same everywhere.
4
+ */
5
+ import type { Decision } from "../policy/index.js";
6
+ export interface Totals {
7
+ /** Files analyzed, for the summary line. */
8
+ files: number;
9
+ }
10
+ export interface TextOptions {
11
+ /** Expiry warnings from the compiled policy, printed before the summary. */
12
+ warnings?: readonly string[];
13
+ }
14
+ /** A capability plus its destination when one is known: `network.fetch to api.example.com`. */
15
+ export declare function describeUse(capability: string, target: string | null): string;
16
+ /**
17
+ * Why a use was denied, in the words of the policy line that did it:
18
+ *
19
+ * denied by default (no rule grants it)
20
+ * denied by "forbid cookies" (line 4): consent banner owns these
21
+ * denied (grant expired 2026-08-30) by "may use the cache until 2026-08-30" (line 5)
22
+ * denied (destination cannot be read) by "may reach "api.example.com"" (line 2), which names hosts
23
+ *
24
+ * An unregistered vendored file has no capability or expression to show,
25
+ * so its whole message is the sentence `vendored file is not in the
26
+ * registry; review it with: frostjs vendor add lib/x.js`; see denialMessage.
27
+ */
28
+ export declare function denialText(d: Decision): string;
29
+ /** The message for a denied (or baselined, or unchanged) use, without the position: subject, reason, expression. */
30
+ export declare function denialMessage(d: Decision): string;
31
+ /** One report line for a denied (or baselined, or unchanged) use. */
32
+ export declare function denialLine(d: Decision): string;
33
+ /** One report line for a use below the confidence floor. */
34
+ export declare function unknownLine(d: Decision): string;
35
+ /** One line per denial, unknowns in their own section, warnings, then a summary. */
36
+ export declare function text(decisions: readonly Decision[], totals: Totals, opts?: TextOptions): string;
37
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/report/text.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,MAAM,WAAW,MAAM;IACrB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAID,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAe9C;AAED,oHAAoH;AACpH,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAIjD;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAG9C;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAG/C;AAED,oFAAoF;AACpF,wBAAgB,IAAI,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,CAwBnG"}
@@ -0,0 +1,81 @@
1
+ import { SAME_ORIGIN } from "../extract/target.js";
2
+ const plural = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
3
+ /** A capability plus its destination when one is known: `network.fetch to api.example.com`. */
4
+ export function describeUse(capability, target) {
5
+ return target !== null && target !== SAME_ORIGIN ? `${capability} to ${target}` : capability;
6
+ }
7
+ /**
8
+ * Why a use was denied, in the words of the policy line that did it:
9
+ *
10
+ * denied by default (no rule grants it)
11
+ * denied by "forbid cookies" (line 4): consent banner owns these
12
+ * denied (grant expired 2026-08-30) by "may use the cache until 2026-08-30" (line 5)
13
+ * denied (destination cannot be read) by "may reach "api.example.com"" (line 2), which names hosts
14
+ *
15
+ * An unregistered vendored file has no capability or expression to show,
16
+ * so its whole message is the sentence `vendored file is not in the
17
+ * registry; review it with: frostjs vendor add lib/x.js`; see denialMessage.
18
+ */
19
+ export function denialText(d) {
20
+ const { rule, reason, use } = d;
21
+ if (reason === "unregistered")
22
+ return `vendored file is not in the registry; review it with: frostjs vendor add ${use.file}`;
23
+ if (rule === null)
24
+ return "denied by default (no rule grants it)";
25
+ const where = `"${rule.text}" (line ${rule.line})`;
26
+ const hint = rule.hint ? `: ${rule.hint}` : "";
27
+ switch (reason) {
28
+ case "expired":
29
+ return `denied (grant expired ${rule.until}) by ${where}${hint}`;
30
+ case "unknown destination":
31
+ return `denied (destination cannot be read) by ${where}, which names hosts${hint}`;
32
+ default:
33
+ return `denied by ${where}${hint}`;
34
+ }
35
+ }
36
+ /** The message for a denied (or baselined, or unchanged) use, without the position: subject, reason, expression. */
37
+ export function denialMessage(d) {
38
+ const { use } = d;
39
+ if (d.reason === "unregistered")
40
+ return denialText(d);
41
+ return `${describeUse(use.capability, use.target)} ${denialText(d)}: ${use.expression}`;
42
+ }
43
+ /** One report line for a denied (or baselined, or unchanged) use. */
44
+ export function denialLine(d) {
45
+ const { use } = d;
46
+ return `${use.file}:${use.line}:${use.column}: ${denialMessage(d)}`;
47
+ }
48
+ /** One report line for a use below the confidence floor. */
49
+ export function unknownLine(d) {
50
+ const { use } = d;
51
+ return `${use.file}:${use.line}:${use.column}: ${describeUse(use.capability, use.target)} ${use.confidence}: ${use.expression}`;
52
+ }
53
+ /** One line per denial, unknowns in their own section, warnings, then a summary. */
54
+ export function text(decisions, totals, opts = {}) {
55
+ const denied = decisions.filter((d) => d.verdict === "denied");
56
+ const unknown = decisions.filter((d) => d.verdict === "unknown");
57
+ const count = (verdict) => decisions.filter((d) => d.verdict === verdict).length;
58
+ const warnings = opts.warnings ?? [];
59
+ const lines = denied.map(denialLine);
60
+ if (unknown.length > 0) {
61
+ if (lines.length > 0)
62
+ lines.push("");
63
+ lines.push("unknown (not failing the build):", ...unknown.map(unknownLine));
64
+ }
65
+ if (warnings.length > 0) {
66
+ if (lines.length > 0)
67
+ lines.push("");
68
+ lines.push(...warnings.map((w) => `warning: ${w}`));
69
+ }
70
+ if (lines.length > 0)
71
+ lines.push("");
72
+ let summary = `${plural(totals.files, "file")}, ${denied.length} denied, ${unknown.length} unknown`;
73
+ for (const verdict of ["suppressed", "baselined", "unchanged"]) {
74
+ const n = count(verdict);
75
+ if (n > 0)
76
+ summary += `, ${n} ${verdict}`;
77
+ }
78
+ lines.push(summary);
79
+ return lines.join("\n") + "\n";
80
+ }
81
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/report/text.ts"],"names":[],"mappings":"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"}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { type ParsedFile } from "./extract/ast.js";
2
+ import { type Registry, type RegistryUse } from "./registry.js";
3
+ export interface SyncResult {
4
+ /** The reconciled registry. `sync` does not write it; the caller does. */
5
+ registry: Registry;
6
+ /** What happened, one printable line each, in order. */
7
+ lines: string[];
8
+ /** Conditions worth a person's attention that are not findings (no lockfile). */
9
+ warnings: string[];
10
+ /** True when something needs a person: a new package, or a bump with new capabilities. */
11
+ needsReview: boolean;
12
+ }
13
+ /** Directory names a vendored glob reaches into that discovery would otherwise skip. */
14
+ export declare function includesFor(vendored: readonly string[]): string[];
15
+ /** Distinct (capability, target) pairs of at least probable confidence, sorted. */
16
+ export declare function usesOf(parsed: ParsedFile): RegistryUse[];
17
+ /** Reconcile the registry with the vendored files under `policyDir`. See the module comment. */
18
+ export declare function sync(registry: Registry, policyDir: string, vendored: readonly string[], today: string): SyncResult;
19
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAeA,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9D,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,QAAQ,EAAE,QAAQ,CAAC;IACnB,wDAAwD;IACxD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iFAAiF;IACjF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0FAA0F;IAC1F,WAAW,EAAE,OAAO,CAAC;CACtB;AAWD,wFAAwF;AACxF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAOjE;AAED,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,EAAE,CAWxD;AAID,gGAAgG;AAChG,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CA6ElH"}
package/dist/sync.js ADDED
@@ -0,0 +1,131 @@
1
+ /**
2
+ * `frostjs registry sync`: keep the vendored-code registry in step with the
3
+ * tree after a dependency bump.
4
+ *
5
+ * For every vendored file whose hash is unknown, find the previous entry
6
+ * for the same package. If the new version uses exactly the capability set
7
+ * the old one did, re-admit it automatically and note the bump. If it uses
8
+ * anything new, refuse, print the difference, and point at vendor add: a
9
+ * bump that quietly adds a network destination is the threat this tool
10
+ * exists to catch. Entries whose file is gone are pruned. The lockfile's
11
+ * hash is recorded so the next run can say whether anything moved.
12
+ */
13
+ import fs from "node:fs";
14
+ import path from "node:path";
15
+ import { discover } from "./discover/index.js";
16
+ import { parseFile } from "./extract/ast.js";
17
+ import { extract } from "./extract/index.js";
18
+ import { matchesGlob } from "./policy/index.js";
19
+ import { describeUse } from "./report/text.js";
20
+ import { guessPackage, integrityOfFile, lookup, } from "./registry.js";
21
+ const LOCKFILES = ["package-lock.json", "npm-shrinkwrap.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb"];
22
+ /** The first lockfile found in `dir`, or null. */
23
+ function findLockfile(dir) {
24
+ for (const name of LOCKFILES) {
25
+ const p = path.join(dir, name);
26
+ if (fs.existsSync(p))
27
+ return p;
28
+ }
29
+ return null;
30
+ }
31
+ /** Directory names a vendored glob reaches into that discovery would otherwise skip. */
32
+ export function includesFor(vendored) {
33
+ const out = new Set();
34
+ for (const g of vendored) {
35
+ const first = g.replace(/^\.\//, "").split("/")[0];
36
+ if (first && !/[*?]/.test(first))
37
+ out.add(first);
38
+ }
39
+ return [...out];
40
+ }
41
+ /** Distinct (capability, target) pairs of at least probable confidence, sorted. */
42
+ export function usesOf(parsed) {
43
+ const seen = new Map();
44
+ for (const u of extract(parsed)) {
45
+ if (u.confidence === "possible")
46
+ continue;
47
+ seen.set(`${u.capability}\0${u.target ?? ""}`, { capability: u.capability, target: u.target });
48
+ }
49
+ return [...seen.values()].sort((a, b) => a.capability === b.capability
50
+ ? (a.target ?? "").localeCompare(b.target ?? "")
51
+ : a.capability.localeCompare(b.capability));
52
+ }
53
+ const key = (u) => describeUse(u.capability, u.target);
54
+ /** Reconcile the registry with the vendored files under `policyDir`. See the module comment. */
55
+ export function sync(registry, policyDir, vendored, today) {
56
+ const lines = [];
57
+ const warnings = [];
58
+ let needsReview = false;
59
+ let entries = [...registry.entries];
60
+ const lockfile = findLockfile(policyDir);
61
+ let lock;
62
+ if (lockfile === null) {
63
+ warnings.push("no lockfile found beside the policy; there is nothing to pin dependency versions to");
64
+ }
65
+ else {
66
+ lock = { path: path.basename(lockfile), integrity: integrityOfFile(lockfile) };
67
+ if (registry.lockfile && registry.lockfile.integrity === lock.integrity)
68
+ lines.push(`${lock.path} unchanged since last sync`);
69
+ else if (registry.lockfile)
70
+ lines.push(`${lock.path} changed since last sync`);
71
+ }
72
+ const files = discover([policyDir], { include: includesFor(vendored) });
73
+ const present = new Set();
74
+ for (const file of files) {
75
+ const rel = path.relative(policyDir, file).split(path.sep).join("/");
76
+ if (!vendored.some((g) => matchesGlob(g, rel)))
77
+ continue;
78
+ const integrity = integrityOfFile(file);
79
+ present.add(integrity);
80
+ if (lookup({ version: 1, entries }, integrity) !== null)
81
+ continue;
82
+ const pkg = guessPackage(file, policyDir);
83
+ const previous = entries.filter((e) => e.package === pkg.package).sort((a, b) => b.added.localeCompare(a.added))[0];
84
+ const parsed = parseFile(file);
85
+ if (parsed.errors.length > 0) {
86
+ lines.push(`${rel}: does not parse; not added`);
87
+ needsReview = true;
88
+ continue;
89
+ }
90
+ const uses = usesOf(parsed);
91
+ if (!previous) {
92
+ lines.push(`${rel} (${pkg.package}@${pkg.version}): new package, not in the registry; review it with: frostjs vendor add ${rel}`);
93
+ needsReview = true;
94
+ continue;
95
+ }
96
+ const before = new Set(previous.uses.map(key));
97
+ const after = new Set(uses.map(key));
98
+ const added = [...after].filter((k) => !before.has(k));
99
+ const removed = [...before].filter((k) => !after.has(k));
100
+ if (added.length === 0) {
101
+ const entry = {
102
+ integrity,
103
+ package: pkg.package,
104
+ version: pkg.version,
105
+ file: rel,
106
+ uses,
107
+ added: today,
108
+ };
109
+ entries.push(entry);
110
+ const note = removed.length ? `; no longer uses ${removed.join(", ")}` : "";
111
+ lines.push(`${rel}: ${pkg.package} ${previous.version} -> ${pkg.version}, capabilities unchanged, re-admitted${note}`);
112
+ }
113
+ else {
114
+ needsReview = true;
115
+ lines.push(`${rel}: ${pkg.package} ${previous.version} -> ${pkg.version} adds ${added.join(", ")}; NOT admitted`);
116
+ lines.push(` review it with: frostjs vendor add ${rel}`);
117
+ }
118
+ }
119
+ // Prune entries whose file is gone and whose hash is nowhere in the tree.
120
+ const kept = [];
121
+ for (const e of entries) {
122
+ const exists = fs.existsSync(path.join(policyDir, e.file));
123
+ if (exists || present.has(e.integrity))
124
+ kept.push(e);
125
+ else
126
+ lines.push(`${e.file}: gone, ${e.package}@${e.version} removed from the registry`);
127
+ }
128
+ entries = kept;
129
+ return { registry: { version: 1, ...(lock ? { lockfile: lock } : {}), entries }, lines, warnings, needsReview };
130
+ }
131
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { createRequire } from "node:module";
2
+ const require = createRequire(import.meta.url);
3
+ // Read from package.json so there is exactly one place the version lives.
4
+ const pkg = require("../package.json");
5
+ export const VERSION = pkg.version;
6
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,0EAA0E;AAC1E,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAE9D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC"}