@safegres/test 0.0.1 → 1.30.7

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 (483) hide show
  1. package/README.md +825 -412
  2. package/adapters.d.ts +8 -0
  3. package/adapters.js +18 -0
  4. package/ast/helpers.d.ts +16 -0
  5. package/ast/helpers.js +40 -0
  6. package/ast/parse.d.ts +31 -0
  7. package/ast/parse.js +87 -0
  8. package/ast/walk.d.ts +27 -0
  9. package/ast/walk.js +79 -0
  10. package/callgraph/baseline.d.ts +28 -0
  11. package/callgraph/baseline.js +55 -0
  12. package/callgraph/extract.d.ts +93 -0
  13. package/callgraph/extract.js +340 -0
  14. package/callgraph/graph.d.ts +82 -0
  15. package/callgraph/graph.js +276 -0
  16. package/checks/anti-patterns.d.ts +53 -0
  17. package/checks/anti-patterns.js +247 -0
  18. package/checks/column-grants.d.ts +20 -0
  19. package/checks/column-grants.js +74 -0
  20. package/checks/coverage.d.ts +43 -0
  21. package/checks/coverage.js +110 -0
  22. package/checks/definer-function.d.ts +91 -0
  23. package/checks/definer-function.js +458 -0
  24. package/checks/definer-view.d.ts +167 -0
  25. package/checks/definer-view.js +392 -0
  26. package/checks/indexes.d.ts +82 -0
  27. package/checks/indexes.js +263 -0
  28. package/checks/lattice.d.ts +179 -0
  29. package/checks/lattice.js +487 -0
  30. package/checks/object-acls.d.ts +32 -0
  31. package/checks/object-acls.js +129 -0
  32. package/checks/policy-index.d.ts +78 -0
  33. package/checks/policy-index.js +349 -0
  34. package/checks/revocable-grants.d.ts +140 -0
  35. package/checks/revocable-grants.js +377 -0
  36. package/checks/rls-flags.d.ts +25 -0
  37. package/checks/rls-flags.js +82 -0
  38. package/checks/role-reach.d.ts +329 -0
  39. package/checks/role-reach.js +277 -0
  40. package/checks/role-trust.d.ts +45 -0
  41. package/checks/role-trust.js +91 -0
  42. package/checks/set-role.d.ts +21 -0
  43. package/checks/set-role.js +66 -0
  44. package/checks/stats.d.ts +52 -0
  45. package/checks/stats.js +192 -0
  46. package/checks/view-exposure.d.ts +68 -0
  47. package/checks/view-exposure.js +236 -0
  48. package/checks/view-writes.d.ts +88 -0
  49. package/checks/view-writes.js +350 -0
  50. package/ci/baseline.d.ts +104 -0
  51. package/ci/baseline.js +111 -0
  52. package/ci/github.d.ts +47 -0
  53. package/ci/github.js +197 -0
  54. package/cli/audit.d.ts +3 -0
  55. package/cli/audit.js +560 -0
  56. package/cli/baseline.d.ts +3 -0
  57. package/cli/baseline.js +104 -0
  58. package/cli/commands.d.ts +2 -0
  59. package/cli/commands.js +60 -0
  60. package/cli/doctor.d.ts +3 -0
  61. package/cli/doctor.js +72 -0
  62. package/cli/eval.d.ts +3 -0
  63. package/cli/eval.js +153 -0
  64. package/cli/print-config.d.ts +3 -0
  65. package/cli/print-config.js +54 -0
  66. package/cli/shared.d.ts +43 -0
  67. package/cli/shared.js +153 -0
  68. package/cli.d.ts +2 -0
  69. package/cli.js +69 -0
  70. package/commands/audit.d.ts +65 -0
  71. package/commands/audit.js +779 -0
  72. package/commands/doctor.d.ts +19 -0
  73. package/commands/doctor.js +181 -0
  74. package/commands/eval.d.ts +67 -0
  75. package/commands/eval.js +93 -0
  76. package/config/fingerprint.d.ts +40 -0
  77. package/config/fingerprint.js +71 -0
  78. package/config/loader.d.ts +44 -0
  79. package/config/loader.js +210 -0
  80. package/config/presets.d.ts +95 -0
  81. package/config/presets.js +327 -0
  82. package/config/resolve.d.ts +47 -0
  83. package/config/resolve.js +192 -0
  84. package/config/schema.d.ts +54 -0
  85. package/config/schema.js +269 -0
  86. package/config/types.d.ts +562 -0
  87. package/config/validate.d.ts +14 -0
  88. package/config/validate.js +125 -0
  89. package/corpus/README.md +83 -0
  90. package/corpus/bootstrap.sql +14 -0
  91. package/corpus/cases/01-anon-write-grant/case.json +26 -0
  92. package/corpus/cases/01-anon-write-grant/schema.sql +19 -0
  93. package/corpus/cases/02-grant-to-public/case.json +25 -0
  94. package/corpus/cases/02-grant-to-public/schema.sql +18 -0
  95. package/corpus/cases/03-rls-off-reachable-by-anon/case.json +30 -0
  96. package/corpus/cases/03-rls-off-reachable-by-anon/schema.sql +13 -0
  97. package/corpus/cases/04-permissive-write-policy/case.json +30 -0
  98. package/corpus/cases/04-permissive-write-policy/schema.sql +21 -0
  99. package/corpus/cases/05-public-read-policy/case.json +25 -0
  100. package/corpus/cases/05-public-read-policy/schema.sql +16 -0
  101. package/corpus/cases/06-update-without-with-check/case.json +25 -0
  102. package/corpus/cases/06-update-without-with-check/schema.sql +19 -0
  103. package/corpus/cases/07-rls-enabled-no-policies/case.json +29 -0
  104. package/corpus/cases/07-rls-enabled-no-policies/schema.sql +14 -0
  105. package/corpus/cases/08-select-grant-no-policy/case.json +25 -0
  106. package/corpus/cases/08-select-grant-no-policy/schema.sql +20 -0
  107. package/corpus/cases/09-write-grant-no-policy/case.json +24 -0
  108. package/corpus/cases/09-write-grant-no-policy/schema.sql +18 -0
  109. package/corpus/cases/10-rls-not-forced/case.json +24 -0
  110. package/corpus/cases/10-rls-not-forced/schema.sql +18 -0
  111. package/corpus/cases/11-session-user-in-policy/case.json +24 -0
  112. package/corpus/cases/11-session-user-in-policy/schema.sql +18 -0
  113. package/corpus/cases/12-volatile-function-in-policy/case.json +24 -0
  114. package/corpus/cases/12-volatile-function-in-policy/schema.sql +21 -0
  115. package/corpus/cases/13-security-definer-policy-wrapper/case.json +24 -0
  116. package/corpus/cases/13-security-definer-policy-wrapper/schema.sql +21 -0
  117. package/corpus/cases/14-dead-policy/case.json +24 -0
  118. package/corpus/cases/14-dead-policy/schema.sql +18 -0
  119. package/corpus/cases/15-unreachable-grant/case.json +24 -0
  120. package/corpus/cases/15-unreachable-grant/schema.sql +18 -0
  121. package/corpus/cases/16-anon-permissive-write-policy/case.json +34 -0
  122. package/corpus/cases/16-anon-permissive-write-policy/schema.sql +17 -0
  123. package/corpus/cases/17-foreign-key-without-index/case.json +24 -0
  124. package/corpus/cases/17-foreign-key-without-index/schema.sql +18 -0
  125. package/corpus/cases/18-policy-column-unindexed/case.json +24 -0
  126. package/corpus/cases/18-policy-column-unindexed/schema.sql +23 -0
  127. package/corpus/cases/19-policy-column-cast/case.json +24 -0
  128. package/corpus/cases/19-policy-column-cast/schema.sql +19 -0
  129. package/corpus/cases/20-stable-function-per-row/case.json +24 -0
  130. package/corpus/cases/20-stable-function-per-row/schema.sql +25 -0
  131. package/corpus/cases/21-table-without-primary-key/case.json +24 -0
  132. package/corpus/cases/21-table-without-primary-key/schema.sql +14 -0
  133. package/corpus/cases/22-redundant-index/case.json +24 -0
  134. package/corpus/cases/22-redundant-index/schema.sql +16 -0
  135. package/corpus/cases/23-tsvector-without-index/case.json +24 -0
  136. package/corpus/cases/23-tsvector-without-index/schema.sql +13 -0
  137. package/corpus/cases/24-anon-set-role-escalation/case.json +29 -0
  138. package/corpus/cases/24-anon-set-role-escalation/schema.sql +30 -0
  139. package/corpus/cases/25-definer-view-bypass/case.json +31 -0
  140. package/corpus/cases/25-definer-view-bypass/schema.sql +36 -0
  141. package/corpus/cases/26-invoker-view-no-bypass/case.json +31 -0
  142. package/corpus/cases/26-invoker-view-no-bypass/schema.sql +44 -0
  143. package/corpus/cases/27-definer-view-write/case.json +36 -0
  144. package/corpus/cases/27-definer-view-write/schema.sql +40 -0
  145. package/corpus/cases/28-invoker-view-no-write/case.json +31 -0
  146. package/corpus/cases/28-invoker-view-no-write/schema.sql +37 -0
  147. package/corpus/cases/29-rewrite-rule-bypass/case.json +36 -0
  148. package/corpus/cases/29-rewrite-rule-bypass/schema.sql +52 -0
  149. package/corpus/cases/30-instead-nothing-rule/case.json +31 -0
  150. package/corpus/cases/30-instead-nothing-rule/schema.sql +44 -0
  151. package/corpus/cases/31-matview-snapshot/case.json +32 -0
  152. package/corpus/cases/31-matview-snapshot/schema.sql +36 -0
  153. package/corpus/cases/32-matview-no-rls-no-bypass/case.json +30 -0
  154. package/corpus/cases/32-matview-no-rls-no-bypass/schema.sql +18 -0
  155. package/corpus/cases/33-leaky-filter-view/case.json +36 -0
  156. package/corpus/cases/33-leaky-filter-view/schema.sql +29 -0
  157. package/corpus/cases/34-barrier-view-no-leak/case.json +32 -0
  158. package/corpus/cases/34-barrier-view-no-leak/schema.sql +29 -0
  159. package/corpus/cases/35-column-grant-projection/case.json +27 -0
  160. package/corpus/cases/35-column-grant-projection/schema.sql +21 -0
  161. package/corpus/cases/35-policy-function-not-leakproof/case.json +24 -0
  162. package/corpus/cases/35-policy-function-not-leakproof/schema.sql +27 -0
  163. package/corpus/cases/36-column-grant-rls-mediated/case.json +27 -0
  164. package/corpus/cases/36-column-grant-rls-mediated/schema.sql +32 -0
  165. package/corpus/cases/36-policy-function-leakproof/case.json +24 -0
  166. package/corpus/cases/36-policy-function-leakproof/schema.sql +22 -0
  167. package/corpus/cases/37-sort-column-unindexed/case.json +24 -0
  168. package/corpus/cases/37-sort-column-unindexed/schema.sql +14 -0
  169. package/corpus/cases/37-unaudited-base-relation/case.json +30 -0
  170. package/corpus/cases/37-unaudited-base-relation/schema.sql +45 -0
  171. package/corpus/cases/38-foreign-key-with-index/case.json +22 -0
  172. package/corpus/cases/38-foreign-key-with-index/schema.sql +17 -0
  173. package/corpus/cases/38-invoker-view-unaudited-base/case.json +30 -0
  174. package/corpus/cases/38-invoker-view-unaudited-base/schema.sql +39 -0
  175. package/corpus/cases/39-definer-view-column-subset/case.json +30 -0
  176. package/corpus/cases/39-definer-view-column-subset/schema.sql +29 -0
  177. package/corpus/cases/39-policy-cast-with-expression-index/case.json +23 -0
  178. package/corpus/cases/39-policy-cast-with-expression-index/schema.sql +19 -0
  179. package/corpus/cases/40-definer-view-column-overreach/case.json +27 -0
  180. package/corpus/cases/40-definer-view-column-overreach/schema.sql +29 -0
  181. package/corpus/cases/40-stable-function-hoisted/case.json +23 -0
  182. package/corpus/cases/40-stable-function-hoisted/schema.sql +25 -0
  183. package/corpus/cases/41-index-prefix-not-redundant/case.json +21 -0
  184. package/corpus/cases/41-index-prefix-not-redundant/schema.sql +15 -0
  185. package/corpus/cases/41-unreadable-view-body/case.json +33 -0
  186. package/corpus/cases/41-unreadable-view-body/schema.sql +28 -0
  187. package/corpus/cases/42-invoker-view-unreadable-body/case.json +30 -0
  188. package/corpus/cases/42-invoker-view-unreadable-body/schema.sql +27 -0
  189. package/corpus/cases/42-search-column-indexed/case.json +21 -0
  190. package/corpus/cases/42-search-column-indexed/schema.sql +12 -0
  191. package/corpus/cases/43-anon-sequence-grant/case.json +27 -0
  192. package/corpus/cases/43-anon-sequence-grant/schema.sql +23 -0
  193. package/corpus/cases/44-serial-sequence-usage/case.json +27 -0
  194. package/corpus/cases/44-serial-sequence-usage/schema.sql +25 -0
  195. package/corpus/cases/45-anon-foreign-table/case.json +27 -0
  196. package/corpus/cases/45-anon-foreign-table/schema.sql +23 -0
  197. package/corpus/cases/46-unchecked-writable-view/case.json +41 -0
  198. package/corpus/cases/46-unchecked-writable-view/schema.sql +37 -0
  199. package/corpus/cases/47-checked-writable-view/case.json +37 -0
  200. package/corpus/cases/47-checked-writable-view/schema.sql +38 -0
  201. package/corpus/cases/48-definer-function-reach/case.json +38 -0
  202. package/corpus/cases/48-definer-function-reach/schema.sql +41 -0
  203. package/corpus/cases/49-invoker-function-no-reach/case.json +32 -0
  204. package/corpus/cases/49-invoker-function-no-reach/schema.sql +38 -0
  205. package/corpus/cases/50-instead-of-trigger-write/case.json +38 -0
  206. package/corpus/cases/50-instead-of-trigger-write/schema.sql +58 -0
  207. package/corpus/cases/51-invoker-trigger-no-write/case.json +33 -0
  208. package/corpus/cases/51-invoker-trigger-no-write/schema.sql +54 -0
  209. package/corpus/cases/52-revocable-execute-grant/case.json +30 -0
  210. package/corpus/cases/52-revocable-execute-grant/schema.sql +45 -0
  211. package/corpus/cases/53-policy-predicate-retains-execute/case.json +23 -0
  212. package/corpus/cases/53-policy-predicate-retains-execute/schema.sql +49 -0
  213. package/corpus/index.d.ts +79 -0
  214. package/corpus/index.js +125 -0
  215. package/esm/adapters.d.ts +8 -0
  216. package/esm/adapters.js +6 -0
  217. package/esm/ast/helpers.d.ts +16 -0
  218. package/esm/ast/helpers.js +36 -0
  219. package/esm/ast/parse.d.ts +31 -0
  220. package/esm/ast/parse.js +82 -0
  221. package/esm/ast/walk.d.ts +27 -0
  222. package/esm/ast/walk.js +72 -0
  223. package/esm/callgraph/baseline.d.ts +28 -0
  224. package/esm/callgraph/baseline.js +48 -0
  225. package/esm/callgraph/extract.d.ts +93 -0
  226. package/esm/callgraph/extract.js +333 -0
  227. package/esm/callgraph/graph.d.ts +82 -0
  228. package/esm/callgraph/graph.js +273 -0
  229. package/esm/checks/anti-patterns.d.ts +53 -0
  230. package/esm/checks/anti-patterns.js +240 -0
  231. package/esm/checks/column-grants.d.ts +20 -0
  232. package/esm/checks/column-grants.js +71 -0
  233. package/esm/checks/coverage.d.ts +43 -0
  234. package/esm/checks/coverage.js +104 -0
  235. package/esm/checks/definer-function.d.ts +91 -0
  236. package/esm/checks/definer-function.js +452 -0
  237. package/esm/checks/definer-view.d.ts +167 -0
  238. package/esm/checks/definer-view.js +382 -0
  239. package/esm/checks/indexes.d.ts +82 -0
  240. package/esm/checks/indexes.js +256 -0
  241. package/esm/checks/lattice.d.ts +179 -0
  242. package/esm/checks/lattice.js +475 -0
  243. package/esm/checks/object-acls.d.ts +32 -0
  244. package/esm/checks/object-acls.js +125 -0
  245. package/esm/checks/policy-index.d.ts +78 -0
  246. package/esm/checks/policy-index.js +342 -0
  247. package/esm/checks/revocable-grants.d.ts +140 -0
  248. package/esm/checks/revocable-grants.js +373 -0
  249. package/esm/checks/rls-flags.d.ts +25 -0
  250. package/esm/checks/rls-flags.js +77 -0
  251. package/esm/checks/role-reach.d.ts +329 -0
  252. package/esm/checks/role-reach.js +270 -0
  253. package/esm/checks/role-trust.d.ts +45 -0
  254. package/esm/checks/role-trust.js +86 -0
  255. package/esm/checks/set-role.d.ts +21 -0
  256. package/esm/checks/set-role.js +63 -0
  257. package/esm/checks/stats.d.ts +52 -0
  258. package/esm/checks/stats.js +184 -0
  259. package/esm/checks/view-exposure.d.ts +68 -0
  260. package/esm/checks/view-exposure.js +231 -0
  261. package/esm/checks/view-writes.d.ts +88 -0
  262. package/esm/checks/view-writes.js +344 -0
  263. package/esm/ci/baseline.d.ts +104 -0
  264. package/esm/ci/baseline.js +107 -0
  265. package/esm/ci/github.d.ts +47 -0
  266. package/esm/ci/github.js +161 -0
  267. package/esm/cli/audit.d.ts +3 -0
  268. package/esm/cli/audit.js +525 -0
  269. package/esm/cli/baseline.d.ts +3 -0
  270. package/esm/cli/baseline.js +102 -0
  271. package/esm/cli/commands.d.ts +2 -0
  272. package/esm/cli/commands.js +53 -0
  273. package/esm/cli/doctor.d.ts +3 -0
  274. package/esm/cli/doctor.js +67 -0
  275. package/esm/cli/eval.d.ts +3 -0
  276. package/esm/cli/eval.js +115 -0
  277. package/esm/cli/print-config.d.ts +3 -0
  278. package/esm/cli/print-config.js +52 -0
  279. package/esm/cli/shared.d.ts +43 -0
  280. package/esm/cli/shared.js +112 -0
  281. package/esm/cli.d.ts +2 -0
  282. package/esm/cli.js +67 -0
  283. package/esm/commands/audit.d.ts +65 -0
  284. package/esm/commands/audit.js +776 -0
  285. package/esm/commands/doctor.d.ts +19 -0
  286. package/esm/commands/doctor.js +178 -0
  287. package/esm/commands/eval.d.ts +67 -0
  288. package/esm/commands/eval.js +90 -0
  289. package/esm/config/fingerprint.d.ts +40 -0
  290. package/esm/config/fingerprint.js +68 -0
  291. package/esm/config/loader.d.ts +44 -0
  292. package/esm/config/loader.js +172 -0
  293. package/esm/config/presets.d.ts +95 -0
  294. package/esm/config/presets.js +324 -0
  295. package/esm/config/resolve.d.ts +47 -0
  296. package/esm/config/resolve.js +180 -0
  297. package/esm/config/schema.d.ts +54 -0
  298. package/esm/config/schema.js +265 -0
  299. package/esm/config/types.d.ts +562 -0
  300. package/esm/config/validate.d.ts +14 -0
  301. package/esm/config/validate.js +122 -0
  302. package/esm/corpus/index.d.ts +79 -0
  303. package/esm/corpus/index.js +85 -0
  304. package/esm/exposure/adapters.d.ts +152 -0
  305. package/esm/exposure/adapters.js +463 -0
  306. package/esm/exposure/planes.d.ts +59 -0
  307. package/esm/exposure/planes.js +144 -0
  308. package/esm/exposure/reach.d.ts +78 -0
  309. package/esm/exposure/reach.js +105 -0
  310. package/esm/exposure/routines.d.ts +36 -0
  311. package/esm/exposure/routines.js +54 -0
  312. package/esm/index.d.ts +96 -0
  313. package/esm/index.js +57 -6
  314. package/esm/lint/index.d.ts +11 -0
  315. package/esm/lint/index.js +10 -0
  316. package/esm/perf/baseline.d.ts +40 -0
  317. package/esm/perf/baseline.js +83 -0
  318. package/esm/perf/explain.d.ts +46 -0
  319. package/esm/perf/explain.js +201 -0
  320. package/esm/pg/acl.d.ts +72 -0
  321. package/esm/pg/acl.js +186 -0
  322. package/esm/pg/behaviors.d.ts +114 -0
  323. package/esm/pg/behaviors.js +206 -0
  324. package/esm/pg/exposure.d.ts +74 -0
  325. package/esm/pg/exposure.js +198 -0
  326. package/esm/pg/functions.d.ts +52 -0
  327. package/esm/pg/functions.js +128 -0
  328. package/esm/pg/indexes.d.ts +192 -0
  329. package/esm/pg/indexes.js +395 -0
  330. package/esm/pg/introspect.d.ts +134 -0
  331. package/esm/pg/introspect.js +274 -0
  332. package/esm/pg/objects.d.ts +37 -0
  333. package/esm/pg/objects.js +108 -0
  334. package/esm/pg/paths.d.ts +114 -0
  335. package/esm/pg/paths.js +159 -0
  336. package/esm/pg/proc.d.ts +23 -0
  337. package/esm/pg/proc.js +55 -0
  338. package/esm/pg/reach-inputs.d.ts +47 -0
  339. package/esm/pg/reach-inputs.js +133 -0
  340. package/esm/pg/roles.d.ts +28 -0
  341. package/esm/pg/roles.js +50 -0
  342. package/esm/pg/stats.d.ts +65 -0
  343. package/esm/pg/stats.js +129 -0
  344. package/esm/pgpm-test.d.ts +22 -0
  345. package/esm/pgpm-test.js +39 -0
  346. package/esm/report/callgraph.d.ts +9 -0
  347. package/esm/report/callgraph.js +74 -0
  348. package/esm/report/compare.d.ts +143 -0
  349. package/esm/report/compare.js +195 -0
  350. package/esm/report/github.d.ts +74 -0
  351. package/esm/report/github.js +290 -0
  352. package/esm/report/json.d.ts +4 -0
  353. package/esm/report/json.js +3 -0
  354. package/esm/report/markdown.d.ts +25 -0
  355. package/esm/report/markdown.js +352 -0
  356. package/esm/report/pretty.d.ts +14 -0
  357. package/esm/report/pretty.js +318 -0
  358. package/esm/report/sarif.d.ts +40 -0
  359. package/esm/report/sarif.js +189 -0
  360. package/esm/report/view.d.ts +82 -0
  361. package/esm/report/view.js +126 -0
  362. package/esm/rules/registry.d.ts +66 -0
  363. package/esm/rules/registry.js +562 -0
  364. package/esm/score/score.d.ts +84 -0
  365. package/esm/score/score.js +233 -0
  366. package/esm/score/scorecards.d.ts +68 -0
  367. package/esm/score/scorecards.js +157 -0
  368. package/esm/types.d.ts +292 -0
  369. package/esm/types.js +26 -0
  370. package/esm/version.d.ts +8 -0
  371. package/esm/version.js +9 -0
  372. package/exposure/adapters.d.ts +152 -0
  373. package/exposure/adapters.js +468 -0
  374. package/exposure/planes.d.ts +59 -0
  375. package/exposure/planes.js +151 -0
  376. package/exposure/reach.d.ts +78 -0
  377. package/exposure/reach.js +109 -0
  378. package/exposure/routines.d.ts +36 -0
  379. package/exposure/routines.js +57 -0
  380. package/index.d.ts +96 -6
  381. package/index.js +229 -6
  382. package/lint/index.d.ts +11 -0
  383. package/lint/index.js +19 -0
  384. package/package.json +54 -48
  385. package/perf/baseline.d.ts +40 -0
  386. package/perf/baseline.js +92 -0
  387. package/perf/explain.d.ts +46 -0
  388. package/perf/explain.js +204 -0
  389. package/pg/acl.d.ts +72 -0
  390. package/pg/acl.js +191 -0
  391. package/pg/behaviors.d.ts +114 -0
  392. package/pg/behaviors.js +217 -0
  393. package/pg/exposure.d.ts +74 -0
  394. package/pg/exposure.js +205 -0
  395. package/pg/functions.d.ts +52 -0
  396. package/pg/functions.js +131 -0
  397. package/pg/indexes.d.ts +192 -0
  398. package/pg/indexes.js +400 -0
  399. package/pg/introspect.d.ts +134 -0
  400. package/pg/introspect.js +280 -0
  401. package/pg/objects.d.ts +37 -0
  402. package/pg/objects.js +111 -0
  403. package/pg/paths.d.ts +114 -0
  404. package/pg/paths.js +166 -0
  405. package/pg/proc.d.ts +23 -0
  406. package/pg/proc.js +58 -0
  407. package/pg/reach-inputs.d.ts +47 -0
  408. package/pg/reach-inputs.js +136 -0
  409. package/pg/roles.d.ts +28 -0
  410. package/pg/roles.js +54 -0
  411. package/pg/stats.d.ts +65 -0
  412. package/pg/stats.js +133 -0
  413. package/pgpm-test.d.ts +22 -0
  414. package/pgpm-test.js +42 -0
  415. package/report/callgraph.d.ts +9 -0
  416. package/report/callgraph.js +81 -0
  417. package/report/compare.d.ts +143 -0
  418. package/report/compare.js +205 -0
  419. package/report/github.d.ts +74 -0
  420. package/report/github.js +333 -0
  421. package/report/json.d.ts +4 -0
  422. package/report/json.js +6 -0
  423. package/report/markdown.d.ts +25 -0
  424. package/report/markdown.js +355 -0
  425. package/report/pretty.d.ts +14 -0
  426. package/report/pretty.js +324 -0
  427. package/report/sarif.d.ts +40 -0
  428. package/report/sarif.js +193 -0
  429. package/report/view.d.ts +82 -0
  430. package/report/view.js +132 -0
  431. package/rules/registry.d.ts +66 -0
  432. package/rules/registry.js +569 -0
  433. package/schema/safegres.schema.json +1119 -0
  434. package/score/score.d.ts +84 -0
  435. package/score/score.js +238 -0
  436. package/score/scorecards.d.ts +68 -0
  437. package/score/scorecards.js +162 -0
  438. package/types.d.ts +292 -0
  439. package/types.js +32 -0
  440. package/version.d.ts +8 -0
  441. package/version.js +12 -0
  442. package/LICENSE +0 -23
  443. package/admin.d.ts +0 -26
  444. package/admin.js +0 -182
  445. package/connect.d.ts +0 -19
  446. package/connect.js +0 -83
  447. package/dist/README.md +0 -557
  448. package/dist/package.json +0 -72
  449. package/esm/admin.js +0 -178
  450. package/esm/connect.js +0 -78
  451. package/esm/manager.js +0 -136
  452. package/esm/roles.js +0 -32
  453. package/esm/seed/adapters.js +0 -23
  454. package/esm/seed/csv.js +0 -44
  455. package/esm/seed/index.js +0 -16
  456. package/esm/seed/json.js +0 -18
  457. package/esm/seed/launchql.js +0 -19
  458. package/esm/seed/sqitch.js +0 -17
  459. package/esm/stream.js +0 -43
  460. package/esm/test-client.js +0 -150
  461. package/manager.d.ts +0 -25
  462. package/manager.js +0 -140
  463. package/roles.d.ts +0 -17
  464. package/roles.js +0 -38
  465. package/seed/adapters.d.ts +0 -4
  466. package/seed/adapters.js +0 -28
  467. package/seed/csv.d.ts +0 -9
  468. package/seed/csv.js +0 -49
  469. package/seed/index.d.ts +0 -16
  470. package/seed/index.js +0 -33
  471. package/seed/json.d.ts +0 -6
  472. package/seed/json.js +0 -21
  473. package/seed/launchql.d.ts +0 -2
  474. package/seed/launchql.js +0 -22
  475. package/seed/sqitch.d.ts +0 -2
  476. package/seed/sqitch.js +0 -20
  477. package/seed/types.d.ts +0 -13
  478. package/stream.d.ts +0 -2
  479. package/stream.js +0 -46
  480. package/test-client.d.ts +0 -49
  481. package/test-client.js +0 -154
  482. /package/{seed → config}/types.js +0 -0
  483. /package/esm/{seed → config}/types.js +0 -0
@@ -0,0 +1,562 @@
1
+ import type { ExposureAdapter } from '../exposure/adapters';
2
+ import type { Dimension, Direction, Severity } from '../types';
3
+ /**
4
+ * `'off'` disables a rule; a severity retunes it; `[severity, options]`
5
+ * reserves room for rule-specific options (forward-compatible).
6
+ */
7
+ export type RuleSetting = 'off' | Severity | [Severity, Record<string, unknown>];
8
+ /**
9
+ * Rule settings keyed by rule code or prefix wildcard (`A*`, `P*`, `*`).
10
+ * Exact codes always win over wildcards.
11
+ */
12
+ export type RulesConfig = Record<string, RuleSetting>;
13
+ /** Per-scope retuning, ESLint `overrides`-style. */
14
+ export interface OverrideEntry {
15
+ /**
16
+ * Glob patterns matched against the qualified `schema.table` name
17
+ * (`*` matches any run of characters), e.g. `public.audit_log`, `metrics.*`.
18
+ */
19
+ tables: string[];
20
+ rules: RulesConfig;
21
+ }
22
+ export type Grade = 'A+' | 'A' | 'B' | 'C' | 'D' | 'F';
23
+ /**
24
+ * The exposure surface: what is actually reachable through the exposed APIs.
25
+ * Findings on non-exposed schemas contribute nothing to the score — they are
26
+ * reported as internal advisories. When no surface is configured or
27
+ * resolvable, the whole database is assumed reachable, a W1 warning is
28
+ * emitted, and the score is capped.
29
+ */
30
+ export interface ExposureConfig {
31
+ /**
32
+ * How to resolve the surface:
33
+ * - `static` (default): use `schemas` / `roles` as given.
34
+ * - `constructive`: introspect the Constructive routing plane
35
+ * (`routing_public.apis` → `api_schemas` → `metaschema_public.schema`,
36
+ * plus the platform plane) to discover exposed schemas and API roles.
37
+ *
38
+ * - `postgraphile`: contribute no planes, but read behavior tags so the
39
+ * planes another resolver or `schemas` establishes are narrowed from
40
+ * "every relation in the schema" to the relations the generated API can
41
+ * address. Pair it with `schemas`, or use it alone for the reach only.
42
+ *
43
+ * Equivalent to listing the corresponding built-in in `adapters`.
44
+ */
45
+ resolver?: 'static' | 'constructive' | 'postgraphile';
46
+ /**
47
+ * Exposure adapters: objects implementing `ExposureAdapter`, or the name of
48
+ * a built-in (`'constructive'`, `'postgraphile'`). An adapter whose `detect()` succeeds
49
+ * contributes planes; static `schemas`/`roles` extend, never replace, what
50
+ * it found. Adapters are values, not module names — a custom one is an
51
+ * object you construct, and nothing is resolved by package name.
52
+ */
53
+ adapters?: Array<string | ExposureAdapter>;
54
+ /** Schemas reachable from the exposed APIs (static resolver). */
55
+ schemas?: string[];
56
+ /** Roles reachable from the API edge (static resolver). */
57
+ roles?: string[];
58
+ /**
59
+ * The subset of `roles` an unauthenticated caller arrives as. Adapters
60
+ * resolve this themselves (`apis.anon_role`, `pgrst.db_anon_role`, ...);
61
+ * set it only for a surface you are declaring statically.
62
+ */
63
+ anonRoles?: string[];
64
+ /** Name of the primary plane. Default `api`. */
65
+ name?: string;
66
+ /**
67
+ * Let adapters narrow a plane's reach from its schemas to the relations the
68
+ * generated API can actually address (`postgraphile` reads behavior tags for
69
+ * this). Default `true`; an adapter that cannot answer changes nothing.
70
+ *
71
+ * Set `false` to grade every relation in an exposed schema as exposed, which
72
+ * is the safer reading if you do not trust your behavior declarations.
73
+ */
74
+ reach?: boolean;
75
+ /**
76
+ * Additional access planes to grade: the ways into the database that are
77
+ * not the declared API. Each is scored on the security axis with the same
78
+ * model, reported alongside the primary plane, and — unless `failOn.planes`
79
+ * says otherwise — gates nothing.
80
+ */
81
+ planes?: PlaneConfig[];
82
+ }
83
+ /** What kind of access path a plane describes. */
84
+ export type PlaneKind = 'api' | 'role' | 'schema';
85
+ /**
86
+ * One graded access plane. `api`/`schema` planes are a set of schemas; a
87
+ * `role` plane is whatever its roles can effectively reach (direct grants,
88
+ * grants TO PUBLIC, and role inheritance), so it never has to be kept in
89
+ * sync with a schema list by hand.
90
+ */
91
+ export interface PlaneConfig {
92
+ /** Plane identifier, e.g. `api`, `direct:app`, `internal`. */
93
+ name: string;
94
+ /** Default: `role` when `roles` is set and `schemas` is not, else `schema`. */
95
+ kind?: PlaneKind;
96
+ /**
97
+ * Make this plane the headline score (`report.score`). At most one plane
98
+ * may claim it; declaring two is a configuration error rather than a
99
+ * silent pick. Default: the declared API surface is primary.
100
+ */
101
+ primary?: boolean;
102
+ schemas?: string[];
103
+ roles?: string[];
104
+ /** The subset of `roles` reachable without authenticating. */
105
+ anonRoles?: string[];
106
+ }
107
+ /**
108
+ * Declared-public surface: intent, stated in config. Open reads on declared
109
+ * tables are acknowledged — reported as info and excluded from the score.
110
+ * Open reads anywhere else stay findings, even in `*_public`-named schemas;
111
+ * naming is never treated as intent.
112
+ */
113
+ export interface PublicConfig {
114
+ /**
115
+ * Glob patterns matched against the qualified `schema.table` name
116
+ * (`*` matches any run of characters) for tables whose open SELECT
117
+ * (`USING (true)`) policies are by design, e.g. reference/pricing tables
118
+ * or a deliberate public directory.
119
+ */
120
+ read?: string[];
121
+ }
122
+ export interface ScoringConfig {
123
+ /**
124
+ * Scoring model:
125
+ * - `density` (default): severity-weighted findings per exposed table with
126
+ * exponential falloff — does not saturate on large schemas.
127
+ * - `weighted`: legacy flat deductions with a per-rule cap.
128
+ */
129
+ model?: 'density' | 'weighted';
130
+ /** Points deducted per finding of each severity. */
131
+ weights?: Partial<Record<Severity, number>>;
132
+ /** Per-rule weight override — beats the severity weight. */
133
+ perRuleWeights?: Record<string, number>;
134
+ /** Cap on total deduction any single rule can contribute (weighted model). */
135
+ maxDeductionPerRule?: number;
136
+ /**
137
+ * Cap on any single rule's contribution (density model), as a fraction of
138
+ * the points that would take the score to F on their own. Default 0.5 — one
139
+ * rule at its cap costs two grade bands, and an F still takes breadth.
140
+ *
141
+ * The density curve has no natural ceiling, so before this a rule's weight
142
+ * and its *fan-out* were indistinguishable: L19 emitting one finding per
143
+ * (relation × function) pair took a real audit from A+ to F on one severity
144
+ * notch. `false` removes the cap.
145
+ */
146
+ maxRuleDensity?: number | false;
147
+ /**
148
+ * Multiplier applied to fail-closed findings' weights (density model).
149
+ * Default 0 — denied-at-runtime hygiene findings don't reduce the score.
150
+ */
151
+ failClosedWeight?: number;
152
+ /** Density falloff constant (density model). Default 0.17. */
153
+ densityK?: number;
154
+ /**
155
+ * Maximum score when no exposure surface is configured/resolvable.
156
+ * Default 80. `false` disables the cap.
157
+ */
158
+ unknownExposureCap?: number | false;
159
+ /** Any finding at/above this severity caps the grade (e.g. 'critical' -> 'C'). */
160
+ floorOnCritical?: Grade | false;
161
+ /** Minimum score for each grade; anything below the lowest is 'F'. */
162
+ gradeBands?: Partial<Record<Exclude<Grade, 'F'>, number>>;
163
+ }
164
+ /**
165
+ * A named score over a slice of the findings: a selector plus the weighting
166
+ * to grade what it selects with. Every scoring key is available per card, so
167
+ * a scorecard is a full `ScoringConfig` with a question attached.
168
+ *
169
+ * The point is that "how secure is this database" is not one question. A
170
+ * platform team gates on what `anonymous` reaches; an application team gates
171
+ * on house style; a compliance reviewer wants the number that no preset
172
+ * softened. Collapsing those into a single grade means at least two of them
173
+ * are reading a number that does not answer their question — and the first
174
+ * time it disagrees with their judgement, they stop reading it at all.
175
+ *
176
+ * ```jsonc
177
+ * "scorecards": {
178
+ * "anon-surface": {
179
+ * "description": "What an unauthenticated caller reaches.",
180
+ * "select": { "roles": ["anonymous"], "direction": "fail-open" },
181
+ * "perRuleWeights": { "L19": 10 },
182
+ * "floorOnCritical": "C"
183
+ * },
184
+ * "sql-conventions": { "select": { "rules": ["C*"], "exposure": "all" } }
185
+ * }
186
+ * ```
187
+ *
188
+ * Findings are never filtered by a scorecard — only *scored* by one. The
189
+ * report always carries every finding, so no configuration of this block can
190
+ * hide anything; it can only decide what a given number is about.
191
+ */
192
+ export interface ScorecardConfig extends ScoringConfig {
193
+ /** Heading for reports. Defaults to the config key. */
194
+ title?: string;
195
+ /** What decision this score informs. Rendered with it. */
196
+ description?: string;
197
+ /** Which findings it grades. An empty selector grades what the headline does. */
198
+ select?: ScorecardSelector;
199
+ }
200
+ /**
201
+ * Which findings a scorecard grades. Every clause narrows; omitting one
202
+ * means "don't care", and an empty selector is the headline's own slice
203
+ * (exposed, non-acknowledged, security-dimension).
204
+ */
205
+ export interface ScorecardSelector {
206
+ /** Rule codes or `C*` prefix wildcards to include. Default: all. */
207
+ rules?: string[];
208
+ /** Rule codes or wildcards to drop after `rules` has selected. */
209
+ exclude?: string[];
210
+ /** `security` (default), `perf`, or `all` — the two axes in one number. */
211
+ dimension?: Dimension | 'all';
212
+ /** Only findings about these roles (the finding's role, grantee, or reach context). */
213
+ roles?: string[];
214
+ /** Only findings reachable on these access planes. */
215
+ planes?: string[];
216
+ /** Only findings in these schemas. */
217
+ schemas?: string[];
218
+ /** `fail-open` leaks, `fail-closed` denials, or `any`. Default: any. */
219
+ direction?: Direction | 'any';
220
+ /** Drop findings below this severity before scoring. */
221
+ minSeverity?: Severity;
222
+ /**
223
+ * `exposed` (default) grades only what the API surface reaches; `all`
224
+ * ignores exposure entirely — the honest, database-to-database number.
225
+ */
226
+ exposure?: 'exposed' | 'all';
227
+ /** `include` grades acknowledged findings too. Default: skip them. */
228
+ acknowledged?: 'skip' | 'include';
229
+ /**
230
+ * `configured` (default) uses the severities this config resolved;
231
+ * `declared` uses each rule's registry default, so a preset that quiets a
232
+ * rule cannot quiet the score that is supposed to catch it.
233
+ */
234
+ severities?: 'configured' | 'declared';
235
+ /**
236
+ * Density denominator: `exposed` relations (default) or `all` of them.
237
+ * A card that ignores exposure should normalize by everything, or it
238
+ * divides a wider numerator by a narrower denominator.
239
+ */
240
+ denominator?: 'exposed' | 'all';
241
+ }
242
+ /**
243
+ * The optional performance dimension: index-hygiene and policy-cost rules
244
+ * (`X*`, plus P1/P1b), scored on their own axis against the same exposure
245
+ * surface. Off by default — `safegres perf` / `--perf` / `enabled: true`.
246
+ */
247
+ export interface PerfConfig {
248
+ /** Collect and score perf findings without passing `--perf`. */
249
+ enabled?: boolean;
250
+ /**
251
+ * Rule settings for perf-dimension codes only. Applied on top of the
252
+ * top-level `rules`; naming a security rule here is a config error.
253
+ */
254
+ rules?: RulesConfig;
255
+ /**
256
+ * Glob patterns matched against the qualified `schema.table` name for
257
+ * tables whose perf findings are intentional (cold audit logs, tiny
258
+ * lookup tables the planner will seq-scan anyway). Acknowledged findings
259
+ * are reported as info and excluded from the perf score.
260
+ */
261
+ ignore?: string[];
262
+ /** Scoring settings for the perf axis (defaults mirror the security score). */
263
+ scoring?: PerfScoringConfig;
264
+ /** Runtime statistics (`--stats`, `S*`). Off unless enabled here or by flag. */
265
+ stats?: PerfStatsConfig;
266
+ /** Planner proof (`--explain`). Off unless enabled here or by flag. */
267
+ explain?: PerfExplainConfig;
268
+ /**
269
+ * Baseline of accepted perf debt. Present → the run diffs against it, the
270
+ * same as `--perf-baseline`. Writing one stays a flag (`--write-perf-baseline`):
271
+ * accepting debt is an act, not a setting.
272
+ */
273
+ baseline?: string;
274
+ /** Exit non-zero on a perf finding that isn't in the baseline. */
275
+ failOnNew?: boolean;
276
+ /** Access-path classification, which decides whether X1 applies to a key. */
277
+ paths?: PerfPathsConfig;
278
+ }
279
+ export interface PerfPathsConfig {
280
+ /**
281
+ * Collect access-path signals for every foreign key. Default true. Signals
282
+ * are reported, and by default change no finding and no score; set false to
283
+ * skip the introspection entirely.
284
+ */
285
+ infer?: boolean;
286
+ /**
287
+ * Write-once pointers a table needs before the `config-record` signal fires.
288
+ * Default 2. Raise it for a narrower signal.
289
+ */
290
+ minPointers?: number;
291
+ /**
292
+ * What X1 does with a key whose only evidence is shape — it looks like a
293
+ * write-once provisioning pointer, but nothing has proven the path is
294
+ * unreachable.
295
+ *
296
+ * - `report` (default) — the finding stands, with the signals attached.
297
+ * - `demote` — the finding drops to `info`, so it is read rather than gated
298
+ * on and contributes nothing to the score.
299
+ * - `suppress` — no finding. Only defensible once you know the generated API
300
+ * does not expose these relations; a shape is not a proof.
301
+ */
302
+ onWriteOncePointer?: 'report' | 'demote' | 'suppress';
303
+ }
304
+ export interface PerfScoringConfig extends ScoringConfig {
305
+ /**
306
+ * Whether runtime-statistics findings (`S*`) count toward the perf score.
307
+ * Default true — asking for `--stats` is the opt-in. Set false to keep the
308
+ * grade purely deterministic and read the `S*` findings as advisories.
309
+ */
310
+ includeStats?: boolean;
311
+ }
312
+ /**
313
+ * Thresholds for the runtime-statistics rules. Every one is a floor: below
314
+ * it the workload hasn't said enough for the finding to mean anything.
315
+ */
316
+ export interface PerfStatsConfig {
317
+ /** Collect and check runtime statistics without passing `--stats`. */
318
+ enabled?: boolean;
319
+ /** Ignore tables with fewer live rows than this. Default 1000. */
320
+ minRows?: number;
321
+ /** S1 fires when sequential scans exceed index scans by this factor. Default 10. */
322
+ seqScanRatio?: number;
323
+ /** S2 ignores indexes smaller than this many bytes. Default 1048576 (1 MiB). */
324
+ minIndexBytes?: number;
325
+ /** S3 fires above this dead/live tuple ratio. Default 0.2. */
326
+ deadTupleRatio?: number;
327
+ /** S4 fires for statements at or above this share of total time. Default 0.05. */
328
+ minTimeShare?: number;
329
+ /** S4 reports at most this many statements. Default 5. */
330
+ topStatements?: number;
331
+ }
332
+ export interface PerfExplainConfig {
333
+ /** Probe findings with EXPLAIN without passing `--explain`. */
334
+ enabled?: boolean;
335
+ /**
336
+ * Below this planner row estimate a sequential scan is the right plan, so a
337
+ * probe can refute a finding but never confirm one. Default 1000.
338
+ */
339
+ minRows?: number;
340
+ }
341
+ /**
342
+ * Extension objects are a database's `node_modules`: they live in the same
343
+ * catalog and scan like anything else, but they are the extension author's
344
+ * to secure and tune, and altering them breaks `pg_dump` and upgrades.
345
+ */
346
+ export interface ExtensionsConfig {
347
+ /**
348
+ * Skip relations an extension owns (`pg_depend.deptype = 'e'`) and their
349
+ * partitions. Default `true`. Set `false` to audit them anyway — useful
350
+ * when auditing an extension itself.
351
+ */
352
+ skipOwned?: boolean;
353
+ /**
354
+ * Extension names whose *schemas* are skipped wholesale, for objects an
355
+ * extension creates at runtime and never registers as dependencies.
356
+ * `pg_partman` is the motivating case: its child partitions and templates
357
+ * carry no dependency on the extension, so ownership alone misses them.
358
+ * Unknown or uninstalled names are ignored.
359
+ */
360
+ ignore?: string[];
361
+ }
362
+ export interface FailOnConfig {
363
+ /** Exit non-zero if any finding is at/above this severity. */
364
+ severity?: Severity;
365
+ /** Exit non-zero if the score is below this value (0-100). */
366
+ score?: number;
367
+ /** Exit non-zero if the grade is below this letter. */
368
+ grade?: Grade;
369
+ /** Exit non-zero if the perf score is below this value (0-100). */
370
+ perfScore?: number;
371
+ /** Exit non-zero if the perf grade is below this letter. */
372
+ perfGrade?: Grade;
373
+ /**
374
+ * Per-plane gates, keyed by plane name. Secondary planes gate nothing by
375
+ * default: an internal role legitimately reaches internal tables, so its
376
+ * plane scores worse than the API's by construction and gating it at parity
377
+ * would only force the plane to be deleted. A floor (`{ grade: 'D' }`) is
378
+ * the useful shape — the direct-connection surface may be a D, but it may
379
+ * not become an F.
380
+ */
381
+ planes?: Record<string, PlaneFailOnConfig>;
382
+ /**
383
+ * Per-scorecard gates, keyed by scorecard name. This is where a team's own
384
+ * question becomes its own build failure — `{ "anon-surface": { "grade": "A" } }`
385
+ * gates on that and nothing else.
386
+ */
387
+ scorecards?: Record<string, PlaneFailOnConfig>;
388
+ }
389
+ export interface PlaneFailOnConfig {
390
+ /** Exit non-zero if the plane's score is below this value (0-100). */
391
+ score?: number;
392
+ /** Exit non-zero if the plane's grade is below this letter. */
393
+ grade?: Grade;
394
+ }
395
+ /** Which scores and sections a rendered report shows. */
396
+ /**
397
+ * The database under audit. A repository that always audits the same thing —
398
+ * a pgpm workspace deployed into an ephemeral database — should say so once,
399
+ * in the file, rather than in every invocation.
400
+ */
401
+ export interface SourceConfig {
402
+ /**
403
+ * Deploy the pgpm workspace or module at this path (relative to the config
404
+ * file) into an ephemeral test database and audit that. Equivalent to
405
+ * `--pgpm <dir>`; requires the optional peer dependency `pgsql-test`.
406
+ * A connection named on the command line (`--connection`, `--database`,
407
+ * `--host`, `--port`) wins: the same config then audits that database.
408
+ */
409
+ pgpm?: string;
410
+ }
411
+ /**
412
+ * Files one run writes. Paths are relative to the config file, and the
413
+ * directories are created as needed: the point is that a CI job is
414
+ * `safegres audit`, with the artifact list versioned alongside the rules.
415
+ */
416
+ export interface OutputsConfig {
417
+ /**
418
+ * Write the whole set into one directory as `safegres.json`, `safegres.md`
419
+ * and `safegres.sarif`. The usual case, and nobody has to remember three
420
+ * paths; the keys below still override an individual file.
421
+ */
422
+ dir?: string;
423
+ json?: string;
424
+ markdown?: string;
425
+ sarif?: string;
426
+ /** Root scanned to resolve SARIF findings to their SQL source lines. */
427
+ sarifSources?: string;
428
+ /** Aggregate-only snapshot, for a later run's `compare`. */
429
+ snapshot?: string;
430
+ /** The rendered sticky PR comment, for a workflow that posts it itself. */
431
+ githubComment?: string;
432
+ }
433
+ export interface CallGraphConfig {
434
+ /** Build the call-graph audit without passing `--call-graph`. */
435
+ enabled?: boolean;
436
+ /** Baseline of accepted trust boundaries; enables the diff. */
437
+ baseline?: string;
438
+ /** Exit non-zero on a boundary that isn't in the baseline. */
439
+ failOnNew?: boolean;
440
+ }
441
+ export interface ReportConfig {
442
+ /**
443
+ * Planes to render, by name or glob (`primary`, `*`, `direct:*`). Default:
444
+ * the primary plane in full, secondaries as a one-line advisory.
445
+ */
446
+ planes?: string[];
447
+ /** Dimensions to render. Default: both. */
448
+ dimensions?: Array<'security' | 'perf'>;
449
+ /** GitHub Actions output (job summary, annotations, PR comment). */
450
+ github?: GithubReportConfig;
451
+ }
452
+ /**
453
+ * What the GitHub integration emits. Defaults render both headline scores,
454
+ * the delta against the compared run, and annotations for gate failures only.
455
+ */
456
+ export interface GithubReportConfig {
457
+ /**
458
+ * Scores in the job summary, in order. `security`, `perf`, and
459
+ * `planes:<glob>` for secondary planes (e.g. `planes:direct:*`).
460
+ * Default `['security', 'perf']`.
461
+ */
462
+ summary?: string[];
463
+ /** Sticky PR comment. */
464
+ comment?: GithubCommentConfig;
465
+ /** Which findings become workflow annotations. Default `gate-failures`. */
466
+ annotations?: 'all' | 'gate-failures' | 'none';
467
+ /**
468
+ * How much of the report goes in the job summary. Default `normal`. Set
469
+ * `summary` on a database with thousands of findings: GitHub truncates a job
470
+ * summary at 1 MB, and a truncated report is worse than a short one.
471
+ */
472
+ detail?: 'summary' | 'normal' | 'verbose';
473
+ /**
474
+ * Render scores as colored shields.io badges. Default `true`; `false` falls
475
+ * back to 🟢/🟡/🔴 text, which needs no network fetch.
476
+ */
477
+ badges?: boolean;
478
+ }
479
+ export interface GithubCommentConfig {
480
+ /** Reuse one comment per PR instead of appending. Default `true`. */
481
+ sticky?: boolean;
482
+ /**
483
+ * Sections to include, in this order: `scores` (badges + exposure), `planes`,
484
+ * `delta`, `new-findings` (the perf ratchet verdict and what it caught), and
485
+ * `report` — the same markdown report the job summary carries, at `detail`.
486
+ * `findings` is the old name for `report`. Default
487
+ * `['scores', 'delta', 'new-findings']`; add `report` to review the audit
488
+ * without leaving the PR.
489
+ */
490
+ sections?: Array<'scores' | 'delta' | 'new-findings' | 'report' | 'findings' | 'planes'>;
491
+ /**
492
+ * How much of the report the `report` section carries. Default `summary` —
493
+ * scores, exposure, counts, the delta and the ratchet verdict, with no
494
+ * per-finding tables, because a comment is read on the way past and GitHub
495
+ * rejects a body over 64 KB. `normal`/`verbose` add the finding tables and
496
+ * degrade back to `summary` when the body would not fit.
497
+ */
498
+ detail?: 'summary' | 'normal' | 'verbose';
499
+ }
500
+ /**
501
+ * The full safegres configuration, loadable from `safegres.config.{ts,js,mjs,cjs}`,
502
+ * `.safegresrc{,.json,.yaml,.yml,.js}`, `safegres.json`, or the `"safegres"`
503
+ * key in package.json.
504
+ */
505
+ export interface SafegresConfig {
506
+ /**
507
+ * Presets (`safegres:recommended`, …), relative paths (`./safegres.base.json`),
508
+ * or npm packages — recursively, lowest precedence first.
509
+ *
510
+ * A path is resolved against the file that declared it, and so is every
511
+ * *path-valued* key inherited from it (`source.pgpm`, `perf.baseline`,
512
+ * `outputs.*`, `eval.corpus`): a baseline written in a shared base file means
513
+ * that file's directory, whichever job inherited it. Objects merge per key
514
+ * and arrays replace, except `overrides`, which is a list of scoped
515
+ * exceptions and so unions across the chain.
516
+ */
517
+ extends?: string | string[];
518
+ /** The exposed API surface — what the score is computed against. */
519
+ exposure?: ExposureConfig;
520
+ /** Tables whose open reads are deliberate (declared public surface). */
521
+ public?: PublicConfig;
522
+ /** How to treat objects belonging to installed extensions. */
523
+ extensions?: ExtensionsConfig;
524
+ /** The optional performance dimension. */
525
+ perf?: PerfConfig;
526
+ schemas?: string[];
527
+ excludeSchemas?: string[];
528
+ roles?: string[];
529
+ excludeRoles?: string[];
530
+ rules?: RulesConfig;
531
+ overrides?: OverrideEntry[];
532
+ scoring?: ScoringConfig;
533
+ /**
534
+ * Named scores over slices of the same findings — see `ScorecardConfig`.
535
+ * Merged with the reserved `default` and `raw` cards, which always run.
536
+ */
537
+ scorecards?: Record<string, ScorecardConfig>;
538
+ failOn?: FailOnConfig;
539
+ /** Where the database to audit comes from, when it isn't a live connection. */
540
+ source?: SourceConfig;
541
+ /** Files a single run writes, so CI doesn't have to spell them as flags. */
542
+ outputs?: OutputsConfig;
543
+ /** The unscored call-graph audit (`--call-graph`) and its baseline. */
544
+ callGraph?: CallGraphConfig;
545
+ /** What a rendered report shows — selection, not analysis. */
546
+ report?: ReportConfig;
547
+ /** Defaults for `safegres eval` — which corpus, graded by which preset. */
548
+ eval?: EvalConfig;
549
+ }
550
+ /**
551
+ * `safegres eval` defaults. Deliberately only says *what* to run: a case is
552
+ * graded by a named preset, never by the rest of this file, so a project can
553
+ * point eval at its own corpus without also being able to move the answers.
554
+ */
555
+ export interface EvalConfig {
556
+ /** Corpus directory of `<id>/{case.json,schema.sql}`. Defaults to the shipped one. */
557
+ corpus?: string;
558
+ /** Preset every case is graded under. Defaults to `recommended`. */
559
+ preset?: string;
560
+ /** Case ids (or id prefixes) to run. Defaults to all of them. */
561
+ cases?: string[];
562
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Check a config against the described shape: unknown keys, and values of the
3
+ * wrong kind.
4
+ *
5
+ * A typo'd key used to be *silently ignored*, which for a file that decides
6
+ * whether CI fails is the worst possible outcome — `failon: { grade: 'B' }`
7
+ * reads as a passing build rather than as a mistake. So this rejects rather
8
+ * than warns, and names the key it thinks you meant.
9
+ *
10
+ * Value checks stay shallow on purpose: rule settings, severities and grades
11
+ * are validated by `resolveRules` and by the gate code, which know the rule
12
+ * registry. This is the shape, not the semantics.
13
+ */
14
+ export declare function validateConfigShape(config: unknown): void;