@ttt-productions/repo-guards 0.1.15 → 0.1.16

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 (502) hide show
  1. package/dist/guard.d.ts +0 -23
  2. package/dist/guard.d.ts.map +1 -1
  3. package/dist/guard.js +0 -3
  4. package/dist/guard.js.map +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +0 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/modules/backend/audit.d.ts +0 -30
  9. package/dist/modules/backend/audit.d.ts.map +1 -1
  10. package/dist/modules/backend/audit.js +0 -17
  11. package/dist/modules/backend/audit.js.map +1 -1
  12. package/dist/modules/backend/auth.d.ts +0 -13
  13. package/dist/modules/backend/auth.d.ts.map +1 -1
  14. package/dist/modules/backend/auth.js +1 -14
  15. package/dist/modules/backend/auth.js.map +1 -1
  16. package/dist/modules/backend/failure-handling.d.ts +0 -19
  17. package/dist/modules/backend/failure-handling.d.ts.map +1 -1
  18. package/dist/modules/backend/failure-handling.js +0 -14
  19. package/dist/modules/backend/failure-handling.js.map +1 -1
  20. package/dist/modules/backend/functions-build.d.ts +0 -40
  21. package/dist/modules/backend/functions-build.d.ts.map +1 -1
  22. package/dist/modules/backend/functions-build.js +0 -23
  23. package/dist/modules/backend/functions-build.js.map +1 -1
  24. package/dist/modules/backend/guards.d.ts +0 -1
  25. package/dist/modules/backend/guards.d.ts.map +1 -1
  26. package/dist/modules/backend/guards.js +0 -2
  27. package/dist/modules/backend/guards.js.map +1 -1
  28. package/dist/modules/backend/monitoring.d.ts +0 -32
  29. package/dist/modules/backend/monitoring.d.ts.map +1 -1
  30. package/dist/modules/backend/monitoring.js +0 -23
  31. package/dist/modules/backend/monitoring.js.map +1 -1
  32. package/dist/modules/backend/shared.d.ts +0 -13
  33. package/dist/modules/backend/shared.d.ts.map +1 -1
  34. package/dist/modules/backend/shared.js +0 -8
  35. package/dist/modules/backend/shared.js.map +1 -1
  36. package/dist/modules/core-definitions/contracts.d.ts +0 -14
  37. package/dist/modules/core-definitions/contracts.d.ts.map +1 -1
  38. package/dist/modules/core-definitions/contracts.js +0 -28
  39. package/dist/modules/core-definitions/contracts.js.map +1 -1
  40. package/dist/modules/core-definitions/document-id-segment.d.ts +0 -9
  41. package/dist/modules/core-definitions/document-id-segment.d.ts.map +1 -1
  42. package/dist/modules/core-definitions/document-id-segment.js +0 -10
  43. package/dist/modules/core-definitions/document-id-segment.js.map +1 -1
  44. package/dist/modules/core-definitions/guards.d.ts +0 -1
  45. package/dist/modules/core-definitions/guards.d.ts.map +1 -1
  46. package/dist/modules/core-definitions/guards.js +0 -2
  47. package/dist/modules/core-definitions/guards.js.map +1 -1
  48. package/dist/modules/core-definitions/redeclaration.d.ts +0 -21
  49. package/dist/modules/core-definitions/redeclaration.d.ts.map +1 -1
  50. package/dist/modules/core-definitions/redeclaration.js +2 -22
  51. package/dist/modules/core-definitions/redeclaration.js.map +1 -1
  52. package/dist/modules/core-definitions/schema-length-literal.d.ts +0 -3
  53. package/dist/modules/core-definitions/schema-length-literal.d.ts.map +1 -1
  54. package/dist/modules/core-definitions/schema-length-literal.js +0 -5
  55. package/dist/modules/core-definitions/schema-length-literal.js.map +1 -1
  56. package/dist/modules/core-definitions/shared.d.ts +0 -11
  57. package/dist/modules/core-definitions/shared.d.ts.map +1 -1
  58. package/dist/modules/core-definitions/shared.js +0 -13
  59. package/dist/modules/core-definitions/shared.js.map +1 -1
  60. package/dist/modules/core-definitions/singleton-bucket-audience.d.ts +0 -4
  61. package/dist/modules/core-definitions/singleton-bucket-audience.d.ts.map +1 -1
  62. package/dist/modules/core-definitions/singleton-bucket-audience.js +0 -4
  63. package/dist/modules/core-definitions/singleton-bucket-audience.js.map +1 -1
  64. package/dist/modules/core-definitions/text-field-declarations.d.ts +0 -10
  65. package/dist/modules/core-definitions/text-field-declarations.d.ts.map +1 -1
  66. package/dist/modules/core-definitions/text-field-declarations.js +0 -14
  67. package/dist/modules/core-definitions/text-field-declarations.js.map +1 -1
  68. package/dist/modules/firestore/analyzer.d.ts +8 -142
  69. package/dist/modules/firestore/analyzer.d.ts.map +1 -1
  70. package/dist/modules/firestore/analyzer.js +45 -1232
  71. package/dist/modules/firestore/analyzer.js.map +1 -1
  72. package/dist/modules/firestore/client-guards.d.ts +0 -10
  73. package/dist/modules/firestore/client-guards.d.ts.map +1 -1
  74. package/dist/modules/firestore/client-guards.js +0 -11
  75. package/dist/modules/firestore/client-guards.js.map +1 -1
  76. package/dist/modules/firestore/guard.d.ts +0 -10
  77. package/dist/modules/firestore/guard.d.ts.map +1 -1
  78. package/dist/modules/firestore/guard.js +1 -7
  79. package/dist/modules/firestore/guard.js.map +1 -1
  80. package/dist/modules/firestore/guards.d.ts +0 -1
  81. package/dist/modules/firestore/guards.d.ts.map +1 -1
  82. package/dist/modules/firestore/guards.js +0 -2
  83. package/dist/modules/firestore/guards.js.map +1 -1
  84. package/dist/modules/firestore/index-guard.d.ts +0 -6
  85. package/dist/modules/firestore/index-guard.d.ts.map +1 -1
  86. package/dist/modules/firestore/index-guard.js +0 -7
  87. package/dist/modules/firestore/index-guard.js.map +1 -1
  88. package/dist/modules/firestore/path-guards.d.ts +0 -12
  89. package/dist/modules/firestore/path-guards.d.ts.map +1 -1
  90. package/dist/modules/firestore/path-guards.js +0 -19
  91. package/dist/modules/firestore/path-guards.js.map +1 -1
  92. package/dist/modules/firestore/rules-claim-guard.d.ts +0 -8
  93. package/dist/modules/firestore/rules-claim-guard.d.ts.map +1 -1
  94. package/dist/modules/firestore/rules-claim-guard.js +0 -11
  95. package/dist/modules/firestore/rules-claim-guard.js.map +1 -1
  96. package/dist/modules/firestore/rules-mirror-guard.d.ts +0 -11
  97. package/dist/modules/firestore/rules-mirror-guard.d.ts.map +1 -1
  98. package/dist/modules/firestore/rules-mirror-guard.js +0 -11
  99. package/dist/modules/firestore/rules-mirror-guard.js.map +1 -1
  100. package/dist/modules/firestore/rules-syntax.d.ts +0 -22
  101. package/dist/modules/firestore/rules-syntax.d.ts.map +1 -1
  102. package/dist/modules/firestore/rules-syntax.js +0 -18
  103. package/dist/modules/firestore/rules-syntax.js.map +1 -1
  104. package/dist/modules/firestore/rules-tokens.d.ts +0 -11
  105. package/dist/modules/firestore/rules-tokens.d.ts.map +1 -1
  106. package/dist/modules/firestore/rules-tokens.js +0 -14
  107. package/dist/modules/firestore/rules-tokens.js.map +1 -1
  108. package/dist/modules/firestore/server-guards.d.ts +0 -4
  109. package/dist/modules/firestore/server-guards.d.ts.map +1 -1
  110. package/dist/modules/firestore/server-guards.js +0 -8
  111. package/dist/modules/firestore/server-guards.js.map +1 -1
  112. package/dist/modules/firestore/storage-guards.d.ts +0 -17
  113. package/dist/modules/firestore/storage-guards.d.ts.map +1 -1
  114. package/dist/modules/firestore/storage-guards.js +0 -11
  115. package/dist/modules/firestore/storage-guards.js.map +1 -1
  116. package/dist/modules/firestore/support.d.ts +0 -11
  117. package/dist/modules/firestore/support.d.ts.map +1 -1
  118. package/dist/modules/firestore/support.js +0 -11
  119. package/dist/modules/firestore/support.js.map +1 -1
  120. package/dist/modules/firestore/test-paths.d.ts +1 -9
  121. package/dist/modules/firestore/test-paths.d.ts.map +1 -1
  122. package/dist/modules/firestore/test-paths.js +1 -16
  123. package/dist/modules/firestore/test-paths.js.map +1 -1
  124. package/dist/modules/frontend-actions/auth.d.ts +0 -25
  125. package/dist/modules/frontend-actions/auth.d.ts.map +1 -1
  126. package/dist/modules/frontend-actions/auth.js +0 -18
  127. package/dist/modules/frontend-actions/auth.js.map +1 -1
  128. package/dist/modules/frontend-actions/callables.d.ts +0 -24
  129. package/dist/modules/frontend-actions/callables.d.ts.map +1 -1
  130. package/dist/modules/frontend-actions/callables.js +0 -23
  131. package/dist/modules/frontend-actions/callables.js.map +1 -1
  132. package/dist/modules/frontend-actions/client.d.ts +0 -21
  133. package/dist/modules/frontend-actions/client.d.ts.map +1 -1
  134. package/dist/modules/frontend-actions/client.js +0 -17
  135. package/dist/modules/frontend-actions/client.js.map +1 -1
  136. package/dist/modules/frontend-actions/declarations.d.ts +0 -13
  137. package/dist/modules/frontend-actions/declarations.d.ts.map +1 -1
  138. package/dist/modules/frontend-actions/declarations.js +0 -10
  139. package/dist/modules/frontend-actions/declarations.js.map +1 -1
  140. package/dist/modules/frontend-actions/guards.d.ts +0 -1
  141. package/dist/modules/frontend-actions/guards.d.ts.map +1 -1
  142. package/dist/modules/frontend-actions/guards.js +0 -2
  143. package/dist/modules/frontend-actions/guards.js.map +1 -1
  144. package/dist/modules/frontend-actions/text.d.ts +0 -12
  145. package/dist/modules/frontend-actions/text.d.ts.map +1 -1
  146. package/dist/modules/frontend-actions/text.js +0 -13
  147. package/dist/modules/frontend-actions/text.js.map +1 -1
  148. package/dist/modules/frontend-reads/cache.d.ts +0 -24
  149. package/dist/modules/frontend-reads/cache.d.ts.map +1 -1
  150. package/dist/modules/frontend-reads/cache.js +1 -26
  151. package/dist/modules/frontend-reads/cache.js.map +1 -1
  152. package/dist/modules/frontend-reads/guards.d.ts +0 -1
  153. package/dist/modules/frontend-reads/guards.d.ts.map +1 -1
  154. package/dist/modules/frontend-reads/guards.js +0 -2
  155. package/dist/modules/frontend-reads/guards.js.map +1 -1
  156. package/dist/modules/frontend-reads/query-keys.d.ts +0 -7
  157. package/dist/modules/frontend-reads/query-keys.d.ts.map +1 -1
  158. package/dist/modules/frontend-reads/query-keys.js +0 -10
  159. package/dist/modules/frontend-reads/query-keys.js.map +1 -1
  160. package/dist/modules/frontend-reads/read-failures.d.ts +0 -32
  161. package/dist/modules/frontend-reads/read-failures.d.ts.map +1 -1
  162. package/dist/modules/frontend-reads/read-failures.js +0 -29
  163. package/dist/modules/frontend-reads/read-failures.js.map +1 -1
  164. package/dist/modules/frontend-reads/shared.d.ts +0 -25
  165. package/dist/modules/frontend-reads/shared.d.ts.map +1 -1
  166. package/dist/modules/frontend-reads/shared.js +0 -34
  167. package/dist/modules/frontend-reads/shared.js.map +1 -1
  168. package/dist/modules/import-paths/analyzer.d.ts +2 -43
  169. package/dist/modules/import-paths/analyzer.d.ts.map +1 -1
  170. package/dist/modules/import-paths/analyzer.js +4 -92
  171. package/dist/modules/import-paths/analyzer.js.map +1 -1
  172. package/dist/modules/import-paths/application-data.d.ts +0 -2
  173. package/dist/modules/import-paths/application-data.d.ts.map +1 -1
  174. package/dist/modules/import-paths/application-data.js +0 -3
  175. package/dist/modules/import-paths/application-data.js.map +1 -1
  176. package/dist/modules/import-paths/entry-purity.d.ts +0 -4
  177. package/dist/modules/import-paths/entry-purity.d.ts.map +1 -1
  178. package/dist/modules/import-paths/entry-purity.js +1 -12
  179. package/dist/modules/import-paths/entry-purity.js.map +1 -1
  180. package/dist/modules/import-paths/guard.d.ts +0 -3
  181. package/dist/modules/import-paths/guard.d.ts.map +1 -1
  182. package/dist/modules/import-paths/guard.js +0 -7
  183. package/dist/modules/import-paths/guard.js.map +1 -1
  184. package/dist/modules/import-paths/guards.d.ts +0 -1
  185. package/dist/modules/import-paths/guards.d.ts.map +1 -1
  186. package/dist/modules/import-paths/guards.js +0 -1
  187. package/dist/modules/import-paths/guards.js.map +1 -1
  188. package/dist/modules/import-paths/package-entries.d.ts +0 -15
  189. package/dist/modules/import-paths/package-entries.d.ts.map +1 -1
  190. package/dist/modules/import-paths/package-entries.js +0 -16
  191. package/dist/modules/import-paths/package-entries.js.map +1 -1
  192. package/dist/modules/import-paths/package-imports.d.ts +0 -1
  193. package/dist/modules/import-paths/package-imports.d.ts.map +1 -1
  194. package/dist/modules/import-paths/package-imports.js +0 -4
  195. package/dist/modules/import-paths/package-imports.js.map +1 -1
  196. package/dist/modules/import-paths/package-wildcard-imports.d.ts +0 -1
  197. package/dist/modules/import-paths/package-wildcard-imports.d.ts.map +1 -1
  198. package/dist/modules/import-paths/package-wildcard-imports.js +0 -4
  199. package/dist/modules/import-paths/package-wildcard-imports.js.map +1 -1
  200. package/dist/modules/repo/ci-parity.d.ts +0 -5
  201. package/dist/modules/repo/ci-parity.d.ts.map +1 -1
  202. package/dist/modules/repo/ci-parity.js +0 -6
  203. package/dist/modules/repo/ci-parity.js.map +1 -1
  204. package/dist/modules/repo/cross-root.d.ts +0 -12
  205. package/dist/modules/repo/cross-root.d.ts.map +1 -1
  206. package/dist/modules/repo/cross-root.js +0 -13
  207. package/dist/modules/repo/cross-root.js.map +1 -1
  208. package/dist/modules/repo/dependency-overrides.d.ts +0 -4
  209. package/dist/modules/repo/dependency-overrides.d.ts.map +1 -1
  210. package/dist/modules/repo/dependency-overrides.js +1 -9
  211. package/dist/modules/repo/dependency-overrides.js.map +1 -1
  212. package/dist/modules/repo/document-drift.d.ts +0 -3
  213. package/dist/modules/repo/document-drift.d.ts.map +1 -1
  214. package/dist/modules/repo/document-drift.js +0 -5
  215. package/dist/modules/repo/document-drift.js.map +1 -1
  216. package/dist/modules/repo/duplicate-exports.d.ts +0 -11
  217. package/dist/modules/repo/duplicate-exports.d.ts.map +1 -1
  218. package/dist/modules/repo/duplicate-exports.js +0 -10
  219. package/dist/modules/repo/duplicate-exports.js.map +1 -1
  220. package/dist/modules/repo/env-public-values.d.ts +0 -4
  221. package/dist/modules/repo/env-public-values.d.ts.map +1 -1
  222. package/dist/modules/repo/env-public-values.js +0 -5
  223. package/dist/modules/repo/env-public-values.js.map +1 -1
  224. package/dist/modules/repo/guards.d.ts +0 -1
  225. package/dist/modules/repo/guards.d.ts.map +1 -1
  226. package/dist/modules/repo/guards.js +0 -2
  227. package/dist/modules/repo/guards.js.map +1 -1
  228. package/dist/modules/repo/installed-packages-agnostic.d.ts +0 -9
  229. package/dist/modules/repo/installed-packages-agnostic.d.ts.map +1 -1
  230. package/dist/modules/repo/installed-packages-agnostic.js +0 -4
  231. package/dist/modules/repo/installed-packages-agnostic.js.map +1 -1
  232. package/dist/modules/repo/jsonc.d.ts.map +1 -1
  233. package/dist/modules/repo/jsonc.js +0 -2
  234. package/dist/modules/repo/jsonc.js.map +1 -1
  235. package/dist/modules/repo/local-only-variables.d.ts +0 -8
  236. package/dist/modules/repo/local-only-variables.d.ts.map +1 -1
  237. package/dist/modules/repo/local-only-variables.js +0 -12
  238. package/dist/modules/repo/local-only-variables.js.map +1 -1
  239. package/dist/modules/repo/project-scripts.d.ts +0 -3
  240. package/dist/modules/repo/project-scripts.d.ts.map +1 -1
  241. package/dist/modules/repo/project-scripts.js +0 -6
  242. package/dist/modules/repo/project-scripts.js.map +1 -1
  243. package/dist/modules/repo/secret-bindings.d.ts +0 -17
  244. package/dist/modules/repo/secret-bindings.d.ts.map +1 -1
  245. package/dist/modules/repo/secret-bindings.js +0 -36
  246. package/dist/modules/repo/secret-bindings.js.map +1 -1
  247. package/dist/modules/repo/shared-fakes.d.ts +0 -8
  248. package/dist/modules/repo/shared-fakes.d.ts.map +1 -1
  249. package/dist/modules/repo/shared-fakes.js +0 -17
  250. package/dist/modules/repo/shared-fakes.js.map +1 -1
  251. package/dist/modules/repo/shell-safe.d.ts +0 -6
  252. package/dist/modules/repo/shell-safe.d.ts.map +1 -1
  253. package/dist/modules/repo/shell-safe.js +0 -14
  254. package/dist/modules/repo/shell-safe.js.map +1 -1
  255. package/dist/modules/repo/specifiers.d.ts +0 -2
  256. package/dist/modules/repo/specifiers.d.ts.map +1 -1
  257. package/dist/modules/repo/specifiers.js +0 -3
  258. package/dist/modules/repo/specifiers.js.map +1 -1
  259. package/dist/modules/repo/test-case-module-loads.d.ts +0 -12
  260. package/dist/modules/repo/test-case-module-loads.d.ts.map +1 -1
  261. package/dist/modules/repo/test-case-module-loads.js +0 -19
  262. package/dist/modules/repo/test-case-module-loads.js.map +1 -1
  263. package/dist/modules/repo/test-source-root.d.ts +0 -2
  264. package/dist/modules/repo/test-source-root.d.ts.map +1 -1
  265. package/dist/modules/repo/test-source-root.js +0 -4
  266. package/dist/modules/repo/test-source-root.js.map +1 -1
  267. package/dist/modules/repo/test-timeouts.d.ts +0 -13
  268. package/dist/modules/repo/test-timeouts.d.ts.map +1 -1
  269. package/dist/modules/repo/test-timeouts.js +0 -24
  270. package/dist/modules/repo/test-timeouts.js.map +1 -1
  271. package/dist/modules/repo/walker-read-failure.d.ts +0 -5
  272. package/dist/modules/repo/walker-read-failure.d.ts.map +1 -1
  273. package/dist/modules/repo/walker-read-failure.js +0 -8
  274. package/dist/modules/repo/walker-read-failure.js.map +1 -1
  275. package/dist/modules/repo/worker-bounded-body.d.ts +0 -7
  276. package/dist/modules/repo/worker-bounded-body.d.ts.map +1 -1
  277. package/dist/modules/repo/worker-bounded-body.js +0 -6
  278. package/dist/modules/repo/worker-bounded-body.js.map +1 -1
  279. package/dist/modules/repo/worker-config.d.ts +0 -7
  280. package/dist/modules/repo/worker-config.d.ts.map +1 -1
  281. package/dist/modules/repo/worker-config.js +0 -8
  282. package/dist/modules/repo/worker-config.js.map +1 -1
  283. package/dist/modules/repo/wrangler-toml.d.ts +0 -11
  284. package/dist/modules/repo/wrangler-toml.d.ts.map +1 -1
  285. package/dist/modules/repo/wrangler-toml.js +2 -25
  286. package/dist/modules/repo/wrangler-toml.js.map +1 -1
  287. package/dist/modules/ui/accessibility.d.ts +0 -9
  288. package/dist/modules/ui/accessibility.d.ts.map +1 -1
  289. package/dist/modules/ui/accessibility.js +0 -22
  290. package/dist/modules/ui/accessibility.js.map +1 -1
  291. package/dist/modules/ui/cascade.d.ts +0 -11
  292. package/dist/modules/ui/cascade.d.ts.map +1 -1
  293. package/dist/modules/ui/cascade.js +0 -14
  294. package/dist/modules/ui/cascade.js.map +1 -1
  295. package/dist/modules/ui/css.d.ts +0 -18
  296. package/dist/modules/ui/css.d.ts.map +1 -1
  297. package/dist/modules/ui/css.js +0 -12
  298. package/dist/modules/ui/css.js.map +1 -1
  299. package/dist/modules/ui/definitions.d.ts +0 -6
  300. package/dist/modules/ui/definitions.d.ts.map +1 -1
  301. package/dist/modules/ui/definitions.js +0 -7
  302. package/dist/modules/ui/definitions.js.map +1 -1
  303. package/dist/modules/ui/facts.d.ts +0 -1
  304. package/dist/modules/ui/facts.d.ts.map +1 -1
  305. package/dist/modules/ui/facts.js +0 -3
  306. package/dist/modules/ui/facts.js.map +1 -1
  307. package/dist/modules/ui/fonts.d.ts.map +1 -1
  308. package/dist/modules/ui/fonts.js +0 -4
  309. package/dist/modules/ui/fonts.js.map +1 -1
  310. package/dist/modules/ui/guards.d.ts +0 -1
  311. package/dist/modules/ui/guards.d.ts.map +1 -1
  312. package/dist/modules/ui/guards.js +0 -2
  313. package/dist/modules/ui/guards.js.map +1 -1
  314. package/dist/modules/ui/interaction.d.ts +0 -15
  315. package/dist/modules/ui/interaction.d.ts.map +1 -1
  316. package/dist/modules/ui/interaction.js +0 -12
  317. package/dist/modules/ui/interaction.js.map +1 -1
  318. package/dist/modules/ui/motion.d.ts +0 -7
  319. package/dist/modules/ui/motion.d.ts.map +1 -1
  320. package/dist/modules/ui/motion.js +0 -3
  321. package/dist/modules/ui/motion.js.map +1 -1
  322. package/dist/modules/ui/source.d.ts +0 -6
  323. package/dist/modules/ui/source.d.ts.map +1 -1
  324. package/dist/modules/ui/source.js +0 -5
  325. package/dist/modules/ui/source.js.map +1 -1
  326. package/dist/modules/ui/stylesheets.d.ts +0 -10
  327. package/dist/modules/ui/stylesheets.d.ts.map +1 -1
  328. package/dist/modules/ui/stylesheets.js +0 -11
  329. package/dist/modules/ui/stylesheets.js.map +1 -1
  330. package/dist/modules/ui/styling.d.ts +0 -7
  331. package/dist/modules/ui/styling.d.ts.map +1 -1
  332. package/dist/modules/ui/styling.js +0 -16
  333. package/dist/modules/ui/styling.js.map +1 -1
  334. package/dist/node/index.d.ts.map +1 -1
  335. package/dist/node/index.js +0 -2
  336. package/dist/node/index.js.map +1 -1
  337. package/dist/node/layout.d.ts +0 -36
  338. package/dist/node/layout.d.ts.map +1 -1
  339. package/dist/node/layout.js +0 -18
  340. package/dist/node/layout.js.map +1 -1
  341. package/dist/node/reader.d.ts +0 -21
  342. package/dist/node/reader.d.ts.map +1 -1
  343. package/dist/node/reader.js +0 -18
  344. package/dist/node/reader.js.map +1 -1
  345. package/dist/node/reports/reports.d.ts +0 -19
  346. package/dist/node/reports/reports.d.ts.map +1 -1
  347. package/dist/node/reports/reports.js +0 -20
  348. package/dist/node/reports/reports.js.map +1 -1
  349. package/dist/node/suite/config.d.ts +0 -10
  350. package/dist/node/suite/config.d.ts.map +1 -1
  351. package/dist/node/suite/config.js +0 -5
  352. package/dist/node/suite/config.js.map +1 -1
  353. package/dist/node/suite/index.d.ts +0 -4
  354. package/dist/node/suite/index.d.ts.map +1 -1
  355. package/dist/node/suite/index.js +0 -4
  356. package/dist/node/suite/index.js.map +1 -1
  357. package/dist/node/suite/register.d.ts +0 -2
  358. package/dist/node/suite/register.d.ts.map +1 -1
  359. package/dist/node/suite/register.js +0 -5
  360. package/dist/node/suite/register.js.map +1 -1
  361. package/dist/node/suite/registry.d.ts +0 -1
  362. package/dist/node/suite/registry.d.ts.map +1 -1
  363. package/dist/node/suite/registry.js +0 -2
  364. package/dist/node/suite/registry.js.map +1 -1
  365. package/dist/node/suite/run.d.ts +0 -2
  366. package/dist/node/suite/run.d.ts.map +1 -1
  367. package/dist/node/suite/run.js +0 -8
  368. package/dist/node/suite/run.js.map +1 -1
  369. package/dist/node/tooling/apphosting-build.d.ts.map +1 -1
  370. package/dist/node/tooling/apphosting-build.js +0 -4
  371. package/dist/node/tooling/apphosting-build.js.map +1 -1
  372. package/dist/node/tooling/apphosting-env.d.ts +0 -13
  373. package/dist/node/tooling/apphosting-env.d.ts.map +1 -1
  374. package/dist/node/tooling/apphosting-env.js +2 -22
  375. package/dist/node/tooling/apphosting-env.js.map +1 -1
  376. package/dist/node/tooling/callable-invokers.d.ts +0 -7
  377. package/dist/node/tooling/callable-invokers.d.ts.map +1 -1
  378. package/dist/node/tooling/callable-invokers.js +0 -12
  379. package/dist/node/tooling/callable-invokers.js.map +1 -1
  380. package/dist/node/tooling/cleanup.d.ts.map +1 -1
  381. package/dist/node/tooling/cleanup.js +0 -3
  382. package/dist/node/tooling/cleanup.js.map +1 -1
  383. package/dist/node/tooling/cloud-checks.d.ts +0 -14
  384. package/dist/node/tooling/cloud-checks.d.ts.map +1 -1
  385. package/dist/node/tooling/cloud-checks.js +0 -16
  386. package/dist/node/tooling/cloud-checks.js.map +1 -1
  387. package/dist/node/tooling/deployed-functions.d.ts +0 -15
  388. package/dist/node/tooling/deployed-functions.d.ts.map +1 -1
  389. package/dist/node/tooling/deployed-functions.js +1 -19
  390. package/dist/node/tooling/deployed-functions.js.map +1 -1
  391. package/dist/node/tooling/dev-login.d.ts +0 -13
  392. package/dist/node/tooling/dev-login.d.ts.map +1 -1
  393. package/dist/node/tooling/dev-login.js +3 -24
  394. package/dist/node/tooling/dev-login.js.map +1 -1
  395. package/dist/node/tooling/dev-stack.d.ts +0 -13
  396. package/dist/node/tooling/dev-stack.d.ts.map +1 -1
  397. package/dist/node/tooling/dev-stack.js +0 -9
  398. package/dist/node/tooling/dev-stack.js.map +1 -1
  399. package/dist/node/tooling/emulator-seed.d.ts +0 -1
  400. package/dist/node/tooling/emulator-seed.d.ts.map +1 -1
  401. package/dist/node/tooling/emulator-seed.js +0 -3
  402. package/dist/node/tooling/emulator-seed.js.map +1 -1
  403. package/dist/node/tooling/field-lineage.d.ts +0 -6
  404. package/dist/node/tooling/field-lineage.d.ts.map +1 -1
  405. package/dist/node/tooling/field-lineage.js +0 -6
  406. package/dist/node/tooling/field-lineage.js.map +1 -1
  407. package/dist/node/tooling/firebase-projects-file.d.ts +0 -1
  408. package/dist/node/tooling/firebase-projects-file.d.ts.map +1 -1
  409. package/dist/node/tooling/firebase-projects-file.js +0 -1
  410. package/dist/node/tooling/firebase-projects-file.js.map +1 -1
  411. package/dist/node/tooling/firebase-projects.d.ts +0 -6
  412. package/dist/node/tooling/firebase-projects.d.ts.map +1 -1
  413. package/dist/node/tooling/firebase-projects.js +0 -8
  414. package/dist/node/tooling/firebase-projects.js.map +1 -1
  415. package/dist/node/tooling/index.d.ts.map +1 -1
  416. package/dist/node/tooling/index.js +0 -2
  417. package/dist/node/tooling/index.js.map +1 -1
  418. package/dist/node/tooling/playbook-refs.d.ts +17 -9
  419. package/dist/node/tooling/playbook-refs.d.ts.map +1 -1
  420. package/dist/node/tooling/playbook-refs.js +68 -30
  421. package/dist/node/tooling/playbook-refs.js.map +1 -1
  422. package/dist/node/tooling/playwright-report.d.ts +0 -2
  423. package/dist/node/tooling/playwright-report.d.ts.map +1 -1
  424. package/dist/node/tooling/playwright-report.js +0 -5
  425. package/dist/node/tooling/playwright-report.js.map +1 -1
  426. package/dist/node/tooling/quiet-gate.d.ts +0 -16
  427. package/dist/node/tooling/quiet-gate.d.ts.map +1 -1
  428. package/dist/node/tooling/quiet-gate.js +1 -18
  429. package/dist/node/tooling/quiet-gate.js.map +1 -1
  430. package/dist/node/tooling/release-scope.d.ts +0 -33
  431. package/dist/node/tooling/release-scope.d.ts.map +1 -1
  432. package/dist/node/tooling/release-scope.js +4 -55
  433. package/dist/node/tooling/release-scope.js.map +1 -1
  434. package/dist/node/tooling/release-verdict.d.ts +0 -16
  435. package/dist/node/tooling/release-verdict.d.ts.map +1 -1
  436. package/dist/node/tooling/release-verdict.js +1 -23
  437. package/dist/node/tooling/release-verdict.js.map +1 -1
  438. package/dist/node/tooling/release.d.ts +0 -8
  439. package/dist/node/tooling/release.d.ts.map +1 -1
  440. package/dist/node/tooling/release.js +0 -12
  441. package/dist/node/tooling/release.js.map +1 -1
  442. package/dist/node/tooling/shell.d.ts +0 -3
  443. package/dist/node/tooling/shell.d.ts.map +1 -1
  444. package/dist/node/tooling/shell.js +2 -7
  445. package/dist/node/tooling/shell.js.map +1 -1
  446. package/dist/node/tooling/storage-cors.d.ts +0 -6
  447. package/dist/node/tooling/storage-cors.d.ts.map +1 -1
  448. package/dist/node/tooling/storage-cors.js +1 -9
  449. package/dist/node/tooling/storage-cors.js.map +1 -1
  450. package/dist/node/tooling/vitest-report.d.ts +0 -16
  451. package/dist/node/tooling/vitest-report.d.ts.map +1 -1
  452. package/dist/node/tooling/vitest-report.js +3 -20
  453. package/dist/node/tooling/vitest-report.js.map +1 -1
  454. package/dist/node/tooling/vitest-unhandled-errors.d.ts +0 -6
  455. package/dist/node/tooling/vitest-unhandled-errors.d.ts.map +1 -1
  456. package/dist/node/tooling/vitest-unhandled-errors.js +2 -11
  457. package/dist/node/tooling/vitest-unhandled-errors.js.map +1 -1
  458. package/dist/reader/strip-comments.d.ts +0 -10
  459. package/dist/reader/strip-comments.d.ts.map +1 -1
  460. package/dist/reader/strip-comments.js +2 -12
  461. package/dist/reader/strip-comments.js.map +1 -1
  462. package/dist/reader/view.d.ts +0 -21
  463. package/dist/reader/view.d.ts.map +1 -1
  464. package/dist/reader/view.js +0 -7
  465. package/dist/reader/view.js.map +1 -1
  466. package/dist/seed/seed-writer.d.ts +2 -10
  467. package/dist/seed/seed-writer.d.ts.map +1 -1
  468. package/dist/seed/seed-writer.js +2 -25
  469. package/dist/seed/seed-writer.js.map +1 -1
  470. package/dist/shapes/shapes.d.ts +0 -22
  471. package/dist/shapes/shapes.d.ts.map +1 -1
  472. package/dist/shapes/shapes.js +0 -25
  473. package/dist/shapes/shapes.js.map +1 -1
  474. package/dist/support/ast.d.ts +0 -5
  475. package/dist/support/ast.d.ts.map +1 -1
  476. package/dist/support/ast.js +0 -7
  477. package/dist/support/ast.js.map +1 -1
  478. package/dist/support/facts.d.ts +0 -24
  479. package/dist/support/facts.d.ts.map +1 -1
  480. package/dist/support/facts.js +0 -22
  481. package/dist/support/facts.js.map +1 -1
  482. package/dist/support/imports.d.ts +0 -20
  483. package/dist/support/imports.d.ts.map +1 -1
  484. package/dist/support/imports.js +0 -8
  485. package/dist/support/imports.js.map +1 -1
  486. package/dist/support/paths.d.ts +0 -6
  487. package/dist/support/paths.d.ts.map +1 -1
  488. package/dist/support/paths.js +0 -5
  489. package/dist/support/paths.js.map +1 -1
  490. package/dist/support/resolve-specifier.d.ts +0 -6
  491. package/dist/support/resolve-specifier.d.ts.map +1 -1
  492. package/dist/support/resolve-specifier.js +1 -8
  493. package/dist/support/resolve-specifier.js.map +1 -1
  494. package/dist/support/text.d.ts +0 -2
  495. package/dist/support/text.d.ts.map +1 -1
  496. package/dist/support/text.js +0 -3
  497. package/dist/support/text.js.map +1 -1
  498. package/dist/zod-shape/zod-shape.d.ts +0 -14
  499. package/dist/zod-shape/zod-shape.d.ts.map +1 -1
  500. package/dist/zod-shape/zod-shape.js +3 -18
  501. package/dist/zod-shape/zod-shape.js.map +1 -1
  502. package/package.json +4 -4
package/dist/guard.d.ts CHANGED
@@ -1,56 +1,33 @@
1
1
  import type { RulesService } from './node/layout.js';
2
2
  import type { RepoReader, Scope } from './node/reader.js';
3
3
  import type { FileView } from './reader/view.js';
4
- /** One place a guard failed. */
5
4
  export interface Finding {
6
- /** Repo-relative path, or the config entry the finding is about. */
7
5
  file: string;
8
6
  line?: number;
9
7
  detail: string;
10
8
  }
11
- /**
12
- * What a guard run reads through. Every scope a guard reads is counted on its own, so a run whose
13
- * scope reached no file fails as vacuous even when it also read a named file.
14
- */
15
9
  export interface GuardContext {
16
10
  readonly reader: RepoReader;
17
11
  files(scope: Scope): FileView[];
18
12
  file(relPath: string): FileView;
19
- /** Every rules file the layout lists, or those written for one service: a scope like any other. */
20
13
  rulesFiles(service?: RulesService): FileView[];
21
14
  }
22
- /** A must-fail or must-pass input for a guard's matcher. A bare string is the text of `sample.ts`. */
23
15
  export type Sample = string | {
24
16
  path: string;
25
17
  text: string;
26
18
  };
27
19
  export interface Guard {
28
- /** The behavior the guard proves, in words; it names the guard's test. */
29
20
  readonly title: string;
30
- /** What the check requires and how a failure is fixed, in words. Printed with every failure. */
31
21
  readonly description: string;
32
- /** Loads what the guard needs before its samples or its run (an app's declared values). */
33
22
  prepare?(): Promise<void>;
34
23
  run(context: GuardContext): Finding[] | Promise<Finding[]>;
35
- /**
36
- * The guard's own proof that it still catches what it exists to catch: every `flags` sample must
37
- * produce a hit and every `passes` sample none. Generic guards prove themselves in the package's
38
- * own tests; a business guard carries its samples here.
39
- */
40
24
  readonly samples?: {
41
25
  flags: readonly Sample[];
42
26
  passes: readonly Sample[];
43
27
  probe(sample: FileView): readonly unknown[];
44
28
  };
45
- /** A whole-repository sweep can take longer than a unit test's default. */
46
29
  readonly timeoutMs?: number;
47
- /**
48
- * Why this guard cannot run here, or null when it can. Only a guard whose input lies outside the
49
- * checkout (a sibling repository CI never checks out) has one; the suite shows the guard SKIPPED
50
- * with this reason, never passed.
51
- */
52
30
  skipReason?(reader: RepoReader): string | null;
53
31
  }
54
- /** A printable failure report for one guard. */
55
32
  export declare function formatFindings(guard: Pick<Guard, 'title' | 'description'>, findings: readonly Finding[]): string;
56
33
  //# sourceMappingURL=guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,gCAAgC;AAChC,MAAM,WAAW,OAAO;IACtB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IAChC,mGAAmG;IACnG,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED,sGAAsG;AACtG,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,WAAW,KAAK;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2FAA2F;IAC3F,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE;QACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,OAAO,EAAE,CAAC;KAC7C,CAAC;IACF,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,gDAAgD;AAChD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAAC,EAC3C,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,MAAM,CAIR"}
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IAChC,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE;QACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,OAAO,EAAE,CAAC;KAC7C,CAAC;IACF,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAAC,EAC3C,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,MAAM,CAIR"}
package/dist/guard.js CHANGED
@@ -1,6 +1,3 @@
1
- // What a guard is: a named check over the files the reader hands it. Generic guards and an app's
2
- // business guards are the same thing to the suite.
3
- /** A printable failure report for one guard. */
4
1
  export function formatFindings(guard, findings) {
5
2
  const lines = [`${guard.title}: ${findings.length} finding(s)`, '', guard.description, ''];
6
3
  for (const f of findings)
package/dist/guard.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,mDAAmD;AAyDnD,gDAAgD;AAChD,MAAM,UAAU,cAAc,CAC5B,KAA2C,EAC3C,QAA4B;IAE5B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["// What a guard is: a named check over the files the reader hands it. Generic guards and an app's\n// business guards are the same thing to the suite.\n\nimport type { RulesService } from './node/layout.js';\nimport type { RepoReader, Scope } from './node/reader.js';\nimport type { FileView } from './reader/view.js';\n\n/** One place a guard failed. */\nexport interface Finding {\n /** Repo-relative path, or the config entry the finding is about. */\n file: string;\n line?: number;\n detail: string;\n}\n\n/**\n * What a guard run reads through. Every scope a guard reads is counted on its own, so a run whose\n * scope reached no file fails as vacuous even when it also read a named file.\n */\nexport interface GuardContext {\n readonly reader: RepoReader;\n files(scope: Scope): FileView[];\n file(relPath: string): FileView;\n /** Every rules file the layout lists, or those written for one service: a scope like any other. */\n rulesFiles(service?: RulesService): FileView[];\n}\n\n/** A must-fail or must-pass input for a guard's matcher. A bare string is the text of `sample.ts`. */\nexport type Sample = string | { path: string; text: string };\n\nexport interface Guard {\n /** The behavior the guard proves, in words; it names the guard's test. */\n readonly title: string;\n /** What the check requires and how a failure is fixed, in words. Printed with every failure. */\n readonly description: string;\n /** Loads what the guard needs before its samples or its run (an app's declared values). */\n prepare?(): Promise<void>;\n run(context: GuardContext): Finding[] | Promise<Finding[]>;\n /**\n * The guard's own proof that it still catches what it exists to catch: every `flags` sample must\n * produce a hit and every `passes` sample none. Generic guards prove themselves in the package's\n * own tests; a business guard carries its samples here.\n */\n readonly samples?: {\n flags: readonly Sample[];\n passes: readonly Sample[];\n probe(sample: FileView): readonly unknown[];\n };\n /** A whole-repository sweep can take longer than a unit test's default. */\n readonly timeoutMs?: number;\n /**\n * Why this guard cannot run here, or null when it can. Only a guard whose input lies outside the\n * checkout (a sibling repository CI never checks out) has one; the suite shows the guard SKIPPED\n * with this reason, never passed.\n */\n skipReason?(reader: RepoReader): string | null;\n}\n\n/** A printable failure report for one guard. */\nexport function formatFindings(\n guard: Pick<Guard, 'title' | 'description'>,\n findings: readonly Finding[],\n): string {\n const lines = [`${guard.title}: ${findings.length} finding(s)`, '', guard.description, ''];\n for (const f of findings) lines.push(` ${f.file}${f.line ? `:${f.line}` : ''} — ${f.detail}`);\n return lines.join('\\n');\n}\n"]}
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAiCA,MAAM,UAAU,cAAc,CAC5B,KAA2C,EAC3C,QAA4B;IAE5B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["import type { RulesService } from './node/layout.js';\nimport type { RepoReader, Scope } from './node/reader.js';\nimport type { FileView } from './reader/view.js';\n\nexport interface Finding {\n file: string;\n line?: number;\n detail: string;\n}\n\nexport interface GuardContext {\n readonly reader: RepoReader;\n files(scope: Scope): FileView[];\n file(relPath: string): FileView;\n rulesFiles(service?: RulesService): FileView[];\n}\n\nexport type Sample = string | { path: string; text: string };\n\nexport interface Guard {\n readonly title: string;\n readonly description: string;\n prepare?(): Promise<void>;\n run(context: GuardContext): Finding[] | Promise<Finding[]>;\n readonly samples?: {\n flags: readonly Sample[];\n passes: readonly Sample[];\n probe(sample: FileView): readonly unknown[];\n };\n readonly timeoutMs?: number;\n skipReason?(reader: RepoReader): string | null;\n}\n\nexport function formatFindings(\n guard: Pick<Guard, 'title' | 'description'>,\n findings: readonly Finding[],\n): string {\n const lines = [`${guard.title}: ${findings.length} finding(s)`, '', guard.description, ''];\n for (const f of findings) lines.push(` ${f.file}${f.line ? `:${f.line}` : ''} — ${f.detail}`);\n return lines.join('\\n');\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,OAAO,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,MAAM,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,OAAO,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,MAAM,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,3 @@
1
- // The pure entry: the three shapes an app builds its business guards on, and the guard contract.
2
- // Reading the repository is the `./node` entry's job; running the suite is `./suite`'s.
3
1
  export { declaredLiteral, matchPattern, ownerOnly, reviewedAllowlist, sampleHits, } from './shapes/shapes.js';
4
2
  export { formatFindings, } from './guard.js';
5
3
  export { viewOfText } from './reader/view.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,wFAAwF;AAExF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,GAKX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,GAKf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,YAAY,GAIb,MAAM,sBAAsB,CAAC","sourcesContent":["// The pure entry: the three shapes an app builds its business guards on, and the guard contract.\n// Reading the repository is the `./node` entry's job; running the suite is `./suite`'s.\n\nexport {\n declaredLiteral,\n matchPattern,\n ownerOnly,\n reviewedAllowlist,\n sampleHits,\n type AllowlistEntry,\n type Hit,\n type Literal,\n type Matcher,\n} from './shapes/shapes.js';\nexport {\n formatFindings,\n type Finding,\n type Guard,\n type GuardContext,\n type Sample,\n} from './guard.js';\nexport { viewOfText, type FileView } from './reader/view.js';\nexport {\n MODULE_LOADS,\n type ImportedName,\n type ImportKind,\n type ModuleImport,\n} from './support/imports.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,GAKX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,GAKf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,YAAY,GAIb,MAAM,sBAAsB,CAAC","sourcesContent":["export {\n declaredLiteral,\n matchPattern,\n ownerOnly,\n reviewedAllowlist,\n sampleHits,\n type AllowlistEntry,\n type Hit,\n type Literal,\n type Matcher,\n} from './shapes/shapes.js';\nexport {\n formatFindings,\n type Finding,\n type Guard,\n type GuardContext,\n type Sample,\n} from './guard.js';\nexport { viewOfText, type FileView } from './reader/view.js';\nexport {\n MODULE_LOADS,\n type ImportedName,\n type ImportKind,\n type ModuleImport,\n} from './support/imports.js';\n"]}
@@ -5,54 +5,38 @@ import type { Reviewed } from '../../node/layout.js';
5
5
  import { type Matcher } from '../../shapes/shapes.js';
6
6
  import { type ServerZone } from './shared.js';
7
7
  export interface AuditWriterFacts {
8
- /** The one module that writes audit documents. */
9
8
  writer: string;
10
- /** The audit collection's name as stored (`auditEvents`). */
11
9
  collectionName: string;
12
- /** The core's handles on the collection, as `OWNER.member` (`COLLECTIONS.AUDIT_EVENTS`). */
13
10
  collectionHandles: readonly string[];
14
- /** Packages that write audit documents themselves; only the writer imports them. */
15
11
  writerPackages: readonly string[];
16
- /** Modules that name the collection to READ it, never to write; a stale entry fails. */
17
12
  readers: readonly Reviewed[];
18
- /** The one module that builds a person-actor, the field that says an actor's mode, and the person modes. */
19
13
  personActor: {
20
14
  constructors: string;
21
15
  modeField: string;
22
16
  modes: readonly string[];
23
17
  };
24
- /** Server code in the app root, held to the same rules as the Functions tree. */
25
18
  appServerZone: ServerZone;
26
19
  }
27
- /** Every place a file names the audit collection or imports a package that writes it. */
28
20
  export declare function auditCollectionMatcher(facts: Pick<AuditWriterFacts, 'collectionName' | 'collectionHandles' | 'writerPackages'>): Matcher;
29
- /** Every object literal that builds a person-actor by hand: its mode field set to a person mode. */
30
21
  export declare function personActorMatcher(facts: AuditWriterFacts['personActor']): Matcher;
31
22
  export declare const auditWriterGuard: GenericGuardDefinition<AuditWriterFacts>;
32
23
  export interface AuditPayloadFacts {
33
- /** The audit writer's entry points (`writeAuditEventAs`, the failure entry points). */
34
24
  entryPoints: readonly string[];
35
- /** The key under which an entry point takes its payload (`payload`). */
36
25
  payloadKey: string;
37
- /** Keys elsewhere whose object literal is handed to an entry point as its payload (`auditPayload`). */
38
26
  forwardedPayloadKeys: readonly string[];
39
- /** Prose-named keys an operator (never a member) writes, as `file#key`, each with its why. */
40
27
  operatorCopy: ReadonlyArray<{
41
28
  site: string;
42
29
  why: string;
43
30
  }>;
44
31
  }
45
- /** Every prose-named key, at any depth, of the payload literals a file hands to an audit entry point. */
46
32
  export declare function proseKeysInAuditPayloads(file: FileView, facts: AuditPayloadFacts): Array<{
47
33
  key: string;
48
34
  node: ts.Node;
49
35
  }>;
50
36
  export declare const auditPayloadGuard: GenericGuardDefinition<AuditPayloadFacts>;
51
37
  export interface FailureAuditFacts {
52
- /** The audit writer's best-effort failure entry points, which log and capture and never throw. */
53
38
  failureEntryPoints: readonly string[];
54
39
  }
55
- /** Each aliased import of a failure entry point, and each call with a handler chained onto it. */
56
40
  export declare function chainedFailureAudits(file: FileView, names: ReadonlySet<string>): Array<{
57
41
  node: ts.Node;
58
42
  detail: string;
@@ -60,26 +44,15 @@ export declare function chainedFailureAudits(file: FileView, names: ReadonlySet<
60
44
  }>;
61
45
  export declare const failureAuditGuard: GenericGuardDefinition<FailureAuditFacts>;
62
46
  export interface RefusalAuditFacts {
63
- /** The audit writer's plain entry point, which throws when its write fails (`writeAuditEventAs`). */
64
47
  plainWriter: string;
65
- /** The audit writer's best-effort failure entry points, which never throw. */
66
48
  failureEntryPoints: readonly string[];
67
- /** The calls that build a system actor (`systemActor`). */
68
49
  systemActorBuilders: readonly string[];
69
- /** The field and value that mark an actor literal as the system (`mode: 'system'`). */
70
50
  systemActorMode: {
71
51
  field: string;
72
52
  value: string;
73
53
  };
74
- /** The calls that define a callable (`onCall`). */
75
54
  callableFactories: readonly string[];
76
55
  }
77
- /**
78
- * In a module that defines a callable: each plain-writer failure event written outside a
79
- * transaction, and each failure event or failure entry point handed a system actor. Calls inside a
80
- * failure entry point's own body are the owner's and are not read. `called` names every declared
81
- * plain writer, builder, and factory the file calls.
82
- */
83
56
  export declare function refusalAuditShapes(file: FileView, facts: RefusalAuditFacts): {
84
57
  hits: Array<{
85
58
  node: ts.Node;
@@ -89,12 +62,9 @@ export declare function refusalAuditShapes(file: FileView, facts: RefusalAuditFa
89
62
  };
90
63
  export declare const refusalAuditGuard: GenericGuardDefinition<RefusalAuditFacts>;
91
64
  export interface FireAndForgetFacts {
92
- /** The audit writer's success entry points, whose failure is never swallowed by a `.catch`. */
93
65
  auditWrites: readonly string[];
94
- /** Files whose `void`-ed calls are reviewed, each with its why; a file that no longer has one is stale. */
95
66
  voidSites: readonly Reviewed[];
96
67
  }
97
- /** Every `void`-ed call, every `.catch` chained onto an audit write, and every audit write call. */
98
68
  export declare function fireAndForgetShapes(file: FileView, auditWrites: ReadonlySet<string>): {
99
69
  voided: ts.Node[];
100
70
  swallowed: {
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,3 @@
1
- // The audit guards: one writer of the audit collection, one builder of person-actors, no
2
- // member-written text in an audit payload, no handler wrapped around an audit write, and a
3
- // refusal recorded through the failure entry points as the caller.
4
1
  import ts from 'typescript';
5
2
  import { ownerOnly, reviewedAllowlist } from '../../shapes/shapes.js';
6
3
  import { calleeName, forEachNode, isPlainString, lineOfNode, unwrap } from '../../support/ast.js';
@@ -14,7 +11,6 @@ const AUDIT_WRITER_SCOPE = {
14
11
  kinds: ['code'],
15
12
  tests: false,
16
13
  };
17
- /** Every place a file names the audit collection or imports a package that writes it. */
18
14
  export function auditCollectionMatcher(facts) {
19
15
  const handles = new Set(facts.collectionHandles);
20
16
  const namesCollection = (text) => text === facts.collectionName || text.startsWith(`${facts.collectionName}/`);
@@ -44,7 +40,6 @@ export function auditCollectionMatcher(facts) {
44
40
  return hits;
45
41
  };
46
42
  }
47
- /** Every object literal that builds a person-actor by hand: its mode field set to a person mode. */
48
43
  export function personActorMatcher(facts) {
49
44
  const modes = new Set(facts.modes);
50
45
  return (file) => {
@@ -138,11 +133,8 @@ export const auditWriterGuard = {
138
133
  return [inZone(collection), inZone(actors)];
139
134
  },
140
135
  };
141
- /** A key named like prose: a title, a name, a body of text. */
142
136
  const PROSE_KEY = /(title|name|description|subject|body|text|message|content|caption|narrative|comment|bio|words)$/i;
143
- /** A map whose keys NAME fields rather than carry their text (`changedFieldLengths`). */
144
137
  const NAMES_NOT_TEXT = /(Lengths|Fields)$/;
145
- /** Every prose-named key, at any depth, of the payload literals a file hands to an audit entry point. */
146
138
  export function proseKeysInAuditPayloads(file, facts) {
147
139
  const sf = file.sourceFile;
148
140
  const entryPoints = new Set(facts.entryPoints);
@@ -240,7 +232,6 @@ export const auditPayloadGuard = {
240
232
  ];
241
233
  },
242
234
  };
243
- /** Each aliased import of a failure entry point, and each call with a handler chained onto it. */
244
235
  export function chainedFailureAudits(file, names) {
245
236
  const sf = file.sourceFile;
246
237
  const hits = [];
@@ -309,7 +300,6 @@ export const failureAuditGuard = {
309
300
  ];
310
301
  },
311
302
  };
312
- /** The name a function declaration or a `const f = …` function carries, if any. */
313
303
  function functionName(node) {
314
304
  if (ts.isFunctionDeclaration(node))
315
305
  return node.name?.text;
@@ -319,12 +309,6 @@ function functionName(node) {
319
309
  return node.parent.name.text;
320
310
  return undefined;
321
311
  }
322
- /**
323
- * In a module that defines a callable: each plain-writer failure event written outside a
324
- * transaction, and each failure event or failure entry point handed a system actor. Calls inside a
325
- * failure entry point's own body are the owner's and are not read. `called` names every declared
326
- * plain writer, builder, and factory the file calls.
327
- */
328
312
  export function refusalAuditShapes(file, facts) {
329
313
  const sf = file.sourceFile;
330
314
  const failureNames = new Set(facts.failureEntryPoints);
@@ -457,7 +441,6 @@ export const refusalAuditGuard = {
457
441
  ];
458
442
  },
459
443
  };
460
- /** Every `void`-ed call, every `.catch` chained onto an audit write, and every audit write call. */
461
444
  export function fireAndForgetShapes(file, auditWrites) {
462
445
  const sf = file.sourceFile;
463
446
  const voided = [];
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"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","sourcesContent":["// The audit guards: one writer of the audit collection, one builder of person-actors, no\n// member-written text in an audit payload, no handler wrapped around an audit write, and a\n// refusal recorded through the failure entry points as the caller.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { Finding, Guard, GuardContext } from '../../guard.js';\nimport type { Scope } from '../../node/reader.js';\nimport type { FileView } from '../../reader/view.js';\nimport type { Reviewed } from '../../node/layout.js';\nimport { ownerOnly, reviewedAllowlist, type Hit, type Matcher } from '../../shapes/shapes.js';\nimport { calleeName, forEachNode, isPlainString, lineOfNode, unwrap } from '../../support/ast.js';\nimport { namesProblem, reviewedProblems, textProblem } from '../../support/facts.js';\nimport { MODULE_LOADS, moduleImports, namesModule } from '../../support/imports.js';\nimport {\n serverZoneContext,\n serverZoneProblems,\n staleServerFolders,\n type ServerZone,\n} from './shared.js';\n\nconst FUNCTIONS_CODE: Scope = { roots: ['functions'], kinds: ['code'], tests: false };\n\n// ---------------------------------------------------------------------------------------------\n// One audit writer.\n\nexport interface AuditWriterFacts {\n /** The one module that writes audit documents. */\n writer: string;\n /** The audit collection's name as stored (`auditEvents`). */\n collectionName: string;\n /** The core's handles on the collection, as `OWNER.member` (`COLLECTIONS.AUDIT_EVENTS`). */\n collectionHandles: readonly string[];\n /** Packages that write audit documents themselves; only the writer imports them. */\n writerPackages: readonly string[];\n /** Modules that name the collection to READ it, never to write; a stale entry fails. */\n readers: readonly Reviewed[];\n /** The one module that builds a person-actor, the field that says an actor's mode, and the person modes. */\n personActor: { constructors: string; modeField: string; modes: readonly string[] };\n /** Server code in the app root, held to the same rules as the Functions tree. */\n appServerZone: ServerZone;\n}\n\nconst AUDIT_WRITER_SCOPE: Scope = {\n roots: ['functions', 'scripts', 'app'],\n optionalRoots: ['scripts'],\n kinds: ['code'],\n tests: false,\n};\n\n/** Every place a file names the audit collection or imports a package that writes it. */\nexport function auditCollectionMatcher(\n facts: Pick<AuditWriterFacts, 'collectionName' | 'collectionHandles' | 'writerPackages'>,\n): Matcher {\n const handles = new Set(facts.collectionHandles);\n const namesCollection = (text: string) =>\n text === facts.collectionName || text.startsWith(`${facts.collectionName}/`);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n const loads = new Map(moduleImports(sf, MODULE_LOADS).map((site) => [site.node, site.spec]));\n forEachNode(sf, (node) => {\n if (\n ts.isPropertyAccessExpression(node) &&\n handles.has(`${node.expression.getText(sf)}.${node.name.text}`)\n ) {\n hits.push({ index: node.getStart(sf), detail: node.getText(sf) });\n }\n const specifier = loads.get(node);\n if (specifier !== undefined && facts.writerPackages.some((p) => namesModule(specifier, p))) {\n hits.push({ index: node.getStart(sf), detail: `imports ${specifier}` });\n return;\n }\n const isSpecifier =\n !!node.parent &&\n (ts.isImportDeclaration(node.parent) || ts.isExportDeclaration(node.parent));\n if (isPlainString(node) && !isSpecifier && namesCollection(node.text)) {\n hits.push({ index: node.getStart(sf), detail: `'${node.text}'` });\n }\n if (ts.isTemplateExpression(node) && namesCollection(node.head.text)) {\n hits.push({ index: node.getStart(sf), detail: `${facts.collectionName} template path` });\n }\n });\n return hits;\n };\n}\n\n/** Every object literal that builds a person-actor by hand: its mode field set to a person mode. */\nexport function personActorMatcher(facts: AuditWriterFacts['personActor']): Matcher {\n const modes = new Set(facts.modes);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n forEachNode(sf, (node) => {\n if (!ts.isObjectLiteralExpression(node)) return;\n for (const prop of node.properties) {\n if (\n !ts.isPropertyAssignment(prop) ||\n prop.name.getText(sf).replace(/^['\"]|['\"]$/g, '') !== facts.modeField\n )\n continue;\n const init = unwrap(prop.initializer);\n if (ts.isStringLiteralLike(init) && modes.has(init.text)) {\n hits.push({ index: prop.getStart(sf), detail: `${facts.modeField}: '${init.text}'` });\n }\n }\n });\n return hits;\n };\n}\n\nexport const auditWriterGuard: GenericGuardDefinition<AuditWriterFacts> = {\n id: 'auditWriter',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.writer, 'writer', problems);\n textProblem(facts?.collectionName, 'collectionName', problems);\n namesProblem(facts?.collectionHandles, 'collectionHandles', problems);\n for (const handle of facts?.collectionHandles ?? []) {\n if (typeof handle === 'string' && !/^[\\w$]+\\.[\\w$]+$/.test(handle))\n problems.push(`collection handle ${handle} is not OWNER.member`);\n }\n namesProblem(facts?.writerPackages, 'writerPackages', problems, { nonEmpty: false });\n reviewedProblems(facts?.readers, 'readers', problems);\n if (facts?.readers?.some((r) => r?.path === facts.writer))\n problems.push('the writer is listed as a reader');\n textProblem(facts?.personActor?.constructors, 'personActor.constructors', problems);\n textProblem(facts?.personActor?.modeField, 'personActor.modeField', problems);\n namesProblem(facts?.personActor?.modes, 'personActor.modes', problems);\n serverZoneProblems(facts?.appServerZone, 'appServerZone', problems);\n return problems;\n },\n build(facts) {\n const collection = reviewedAllowlist({\n title: 'audit documents are written by the one audit writer',\n description:\n `Only ${facts.writer} names the audit collection (${facts.collectionName}, ${facts.collectionHandles.join(', ')}) ` +\n 'or imports a package that writes it; a second writer would skip the attribution, the request origin, and the ' +\n 'append-only rules the writer owns. Write audit events through the writer. A module that only READS the ' +\n 'collection is a reviewed reader with its why; a reader that stops naming the collection is stale.',\n scope: AUDIT_WRITER_SCOPE,\n match: auditCollectionMatcher(facts),\n allowlist: [{ path: facts.writer, why: 'the one audit writer' }, ...facts.readers],\n samples: {\n flags: [\n `db.collection('${facts.collectionName}').add(event);`,\n `db.doc(\\`${facts.collectionName}/\\${id}\\`).set(event);`,\n `db.collection(${facts.collectionHandles[0]}).doc(id).set(event);`,\n ],\n passes: [\n `// writes ${facts.collectionName} through ${facts.collectionHandles[0]}\\nconst label = '${facts.collectionName}Count';`,\n ],\n },\n });\n const actors = ownerOnly({\n title: 'person-actors are built only by the actor constructors',\n description:\n `Only ${facts.personActor.constructors} writes an object whose ${facts.personActor.modeField} is a person mode ` +\n `(${facts.personActor.modes.join(', ')}). A person-actor carries the origin of the request it acted through; ` +\n 'built by hand it can carry none, or a forged one. Build it with the actor constructors.',\n scope: AUDIT_WRITER_SCOPE,\n match: personActorMatcher(facts.personActor),\n owners: [facts.personActor.constructors],\n samples: {\n flags: [\n `const actor = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' as const, uid };`,\n ],\n passes: [\n `type A = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };\\nconst b = { other${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };`,\n ],\n },\n });\n const inZone = (guard: Guard): Guard => ({\n ...guard,\n async run(context: GuardContext) {\n return [\n ...staleServerFolders(context, facts.appServerZone),\n ...(await guard.run(serverZoneContext(context, facts.appServerZone))),\n ];\n },\n });\n return [inZone(collection), inZone(actors)];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No member-written text in an audit payload.\n\nexport interface AuditPayloadFacts {\n /** The audit writer's entry points (`writeAuditEventAs`, the failure entry points). */\n entryPoints: readonly string[];\n /** The key under which an entry point takes its payload (`payload`). */\n payloadKey: string;\n /** Keys elsewhere whose object literal is handed to an entry point as its payload (`auditPayload`). */\n forwardedPayloadKeys: readonly string[];\n /** Prose-named keys an operator (never a member) writes, as `file#key`, each with its why. */\n operatorCopy: ReadonlyArray<{ site: string; why: string }>;\n}\n\n/** A key named like prose: a title, a name, a body of text. */\nconst PROSE_KEY =\n /(title|name|description|subject|body|text|message|content|caption|narrative|comment|bio|words)$/i;\n/** A map whose keys NAME fields rather than carry their text (`changedFieldLengths`). */\nconst NAMES_NOT_TEXT = /(Lengths|Fields)$/;\n\n/** Every prose-named key, at any depth, of the payload literals a file hands to an audit entry point. */\nexport function proseKeysInAuditPayloads(\n file: FileView,\n facts: AuditPayloadFacts,\n): Array<{ key: string; node: ts.Node }> {\n const sf = file.sourceFile;\n const entryPoints = new Set(facts.entryPoints);\n const forwarded = new Set(facts.forwardedPayloadKeys);\n const hits: Array<{ key: string; node: ts.Node }> = [];\n const keyOf = (prop: ts.ObjectLiteralElementLike) =>\n prop.name?.getText(sf).replace(/^['\"`]|['\"`]$/g, '') ?? '';\n const walkPayload = (obj: ts.ObjectLiteralExpression) => {\n for (const prop of obj.properties) {\n if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop)) continue;\n const key = keyOf(prop);\n if (PROSE_KEY.test(key)) hits.push({ key, node: prop });\n if (ts.isPropertyAssignment(prop) && !NAMES_NOT_TEXT.test(key)) {\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n }\n };\n const payloadOf = (details: ts.ObjectLiteralExpression, keys: ReadonlySet<string>) => {\n for (const prop of details.properties) {\n if (!ts.isPropertyAssignment(prop) || !keys.has(keyOf(prop))) continue;\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n };\n const payloadKeys = new Set([facts.payloadKey]);\n forEachNode(sf, (node) => {\n if (ts.isCallExpression(node) && entryPoints.has(calleeName(node) ?? '')) {\n for (const arg of node.arguments) {\n const value = unwrap(arg);\n if (ts.isObjectLiteralExpression(value)) payloadOf(value, payloadKeys);\n }\n }\n if (ts.isObjectLiteralExpression(node)) payloadOf(node, forwarded);\n });\n return hits;\n}\n\nexport const auditPayloadGuard: GenericGuardDefinition<AuditPayloadFacts> = {\n id: 'auditPayload',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.entryPoints, 'entryPoints', problems);\n textProblem(facts?.payloadKey, 'payloadKey', problems);\n namesProblem(facts?.forwardedPayloadKeys, 'forwardedPayloadKeys', problems, {\n nonEmpty: false,\n });\n reviewedProblems(facts?.operatorCopy, 'operatorCopy', problems, { key: 'site' });\n for (const entry of facts?.operatorCopy ?? []) {\n if (typeof entry?.site === 'string' && !/^[^#]+#[^#]+$/.test(entry.site))\n problems.push(`operatorCopy site ${entry.site} is not file#key`);\n }\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no member-written text is copied into an audit payload',\n description:\n 'An audit payload records identifiers, field names, lengths, and decisions — never member-written text. An audit ' +\n 'event outlives every edit and every erasure, so a title, name, description, subject, body, or message copied ' +\n \"into one survives the member's own change and their account's deletion. Record the changed field names and \" +\n 'their lengths instead. A key under a `…Lengths` or `…Fields` map names fields and is exempt; text an operator ' +\n 'writes is a reviewed `file#key` entry with its why, and an entry that no longer occurs is stale.',\n run(context) {\n const findings: Finding[] = [];\n const reviewed = new Set(facts.operatorCopy.map((e) => e.site));\n const seen = new Set<string>();\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const { key, node } of proseKeysInAuditPayloads(file, facts)) {\n const site = `${file.path}#${key}`;\n seen.add(site);\n if (!reviewed.has(site))\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `prose-named payload key ${key}`,\n });\n }\n }\n for (const site of reviewed)\n if (!seen.has(site))\n findings.push({\n file: site,\n detail: 'stale operator-copy entry: the key no longer occurs',\n });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No handler chained onto a failure-audit entry point.\n\nexport interface FailureAuditFacts {\n /** The audit writer's best-effort failure entry points, which log and capture and never throw. */\n failureEntryPoints: readonly string[];\n}\n\n/** Each aliased import of a failure entry point, and each call with a handler chained onto it. */\nexport function chainedFailureAudits(\n file: FileView,\n names: ReadonlySet<string>,\n): Array<{ node: ts.Node; detail: string; name?: string }> {\n const sf = file.sourceFile;\n const hits: Array<{ node: ts.Node; detail: string; name?: string }> = [];\n forEachNode(sf, (node) => {\n if (\n ts.isImportSpecifier(node) &&\n node.propertyName &&\n names.has(node.propertyName.text) &&\n node.propertyName.text !== node.name.text\n ) {\n hits.push({ node, detail: `imports ${node.propertyName.text} under another name` });\n }\n const name = ts.isCallExpression(node) ? calleeName(node) : undefined;\n if (ts.isCallExpression(node) && name && names.has(name)) {\n const parent = node.parent;\n const chained =\n ts.isPropertyAccessExpression(parent) &&\n parent.expression === node &&\n ['catch', 'then', 'finally'].includes(parent.name.text);\n hits.push({\n node,\n name,\n detail: chained\n ? `chains .${(parent as ts.PropertyAccessExpression).name.text} onto ${name}`\n : '',\n });\n }\n });\n return hits;\n}\n\nexport const failureAuditGuard: GenericGuardDefinition<FailureAuditFacts> = {\n id: 'failureAuditChain',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.failureEntryPoints, 'failureEntryPoints', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no handler is chained onto a failure-audit entry point',\n description:\n `The failure-audit entry points (${facts.failureEntryPoints.join(', ')}) never throw — each logs and captures a ` +\n 'write that failed — so a `.catch`, `.then`, or `.finally` chained onto one is dead code that hides the contract, ' +\n 'and an aliased import hides the call from this check. Import each under its own name and call it bare. Every ' +\n 'declared entry point must still be called somewhere: one renamed away would pass unchecked.',\n run(context) {\n const names = new Set(facts.failureEntryPoints);\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const hit of chainedFailureAudits(file, names)) {\n if (hit.name) called.add(hit.name);\n if (hit.detail)\n findings.push({\n file: file.path,\n line: lineOfNode(file, hit.node),\n detail: hit.detail,\n });\n }\n }\n for (const name of names)\n if (!called.has(name))\n findings.push({ file: '(failureEntryPoints)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// A refusal's failure event goes through the failure entry points, attributed to the caller.\n\nexport interface RefusalAuditFacts {\n /** The audit writer's plain entry point, which throws when its write fails (`writeAuditEventAs`). */\n plainWriter: string;\n /** The audit writer's best-effort failure entry points, which never throw. */\n failureEntryPoints: readonly string[];\n /** The calls that build a system actor (`systemActor`). */\n systemActorBuilders: readonly string[];\n /** The field and value that mark an actor literal as the system (`mode: 'system'`). */\n systemActorMode: { field: string; value: string };\n /** The calls that define a callable (`onCall`). */\n callableFactories: readonly string[];\n}\n\n/** The name a function declaration or a `const f = …` function carries, if any. */\nfunction functionName(node: ts.Node): string | undefined {\n if (ts.isFunctionDeclaration(node)) return node.name?.text;\n if (\n (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&\n ts.isVariableDeclaration(node.parent) &&\n ts.isIdentifier(node.parent.name)\n )\n return node.parent.name.text;\n return undefined;\n}\n\n/**\n * In a module that defines a callable: each plain-writer failure event written outside a\n * transaction, and each failure event or failure entry point handed a system actor. Calls inside a\n * failure entry point's own body are the owner's and are not read. `called` names every declared\n * plain writer, builder, and factory the file calls.\n */\nexport function refusalAuditShapes(\n file: FileView,\n facts: RefusalAuditFacts,\n): { hits: Array<{ node: ts.Node; detail: string }>; called: Set<string> } {\n const sf = file.sourceFile;\n const failureNames = new Set(facts.failureEntryPoints);\n const builders = new Set(facts.systemActorBuilders);\n const factories = new Set(facts.callableFactories);\n const keyOf = (prop: ts.ObjectLiteralElementLike) =>\n prop.name?.getText(sf).replace(/^['\"`]|['\"`]$/g, '') ?? '';\n const called = new Set<string>();\n const systemLocals = new Set<string>();\n const isSystemActor = (expression: ts.Expression | undefined): boolean => {\n if (!expression) return false;\n const e = unwrap(expression);\n if (ts.isCallExpression(e)) return builders.has(calleeName(e) ?? '');\n if (ts.isIdentifier(e)) return systemLocals.has(e.text);\n if (!ts.isObjectLiteralExpression(e)) return false;\n return e.properties.some((prop) => {\n if (!ts.isPropertyAssignment(prop) || keyOf(prop) !== facts.systemActorMode.field)\n return false;\n const value = unwrap(prop.initializer);\n return ts.isStringLiteralLike(value) && value.text === facts.systemActorMode.value;\n });\n };\n let definesCallable = false;\n forEachNode(sf, (node) => {\n if (ts.isCallExpression(node)) {\n const name = calleeName(node) ?? '';\n if (factories.has(name)) definesCallable = true;\n if (name === facts.plainWriter || builders.has(name) || factories.has(name)) called.add(name);\n }\n if (\n ts.isVariableDeclaration(node) &&\n ts.isIdentifier(node.name) &&\n node.initializer &&\n isSystemActor(node.initializer)\n )\n systemLocals.add(node.name.text);\n });\n const hits: Array<{ node: ts.Node; detail: string }> = [];\n if (!definesCallable) return { hits, called };\n const failureEvent = (call: ts.CallExpression) => {\n for (const arg of call.arguments) {\n const details = unwrap(arg);\n if (!ts.isObjectLiteralExpression(details)) continue;\n const result = details.properties.find(\n (prop): prop is ts.PropertyAssignment =>\n ts.isPropertyAssignment(prop) && keyOf(prop) === 'result',\n );\n const value = result && unwrap(result.initializer);\n if (value && ts.isStringLiteralLike(value) && value.text === 'failure')\n return { inTransaction: details.properties.some((prop) => keyOf(prop) === 'transaction') };\n }\n return undefined;\n };\n const walk = (node: ts.Node): void => {\n if (failureNames.has(functionName(node) ?? '')) return;\n if (ts.isCallExpression(node)) {\n const name = calleeName(node) ?? '';\n if (name === facts.plainWriter) {\n const event = failureEvent(node);\n if (event && !event.inTransaction)\n hits.push({\n node,\n detail: `${name} writes a failure event outside a transaction`,\n });\n if (event && isSystemActor(node.arguments[0]))\n hits.push({ node, detail: `${name} records a failure as the system` });\n }\n if (failureNames.has(name) && isSystemActor(node.arguments[0]))\n hits.push({ node, detail: `${name} records a refusal as the system` });\n }\n ts.forEachChild(node, walk);\n };\n walk(sf);\n return { hits, called };\n}\n\nexport const refusalAuditGuard: GenericGuardDefinition<RefusalAuditFacts> = {\n id: 'refusalAudit',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.plainWriter, 'plainWriter', problems);\n namesProblem(facts?.failureEntryPoints, 'failureEntryPoints', problems);\n namesProblem(facts?.systemActorBuilders, 'systemActorBuilders', problems);\n textProblem(facts?.systemActorMode?.field, 'systemActorMode.field', problems);\n textProblem(facts?.systemActorMode?.value, 'systemActorMode.value', problems);\n namesProblem(facts?.callableFactories, 'callableFactories', problems);\n if (facts?.failureEntryPoints?.includes(facts?.plainWriter))\n problems.push('the plain writer is listed as a failure entry point');\n return problems;\n },\n build(facts) {\n return [\n {\n title: \"a refusal's failure event goes through the failure entry points, as the caller\",\n description:\n `In a module that defines a callable (${facts.callableFactories.join(', ')}), a failure event the plain writer ` +\n `${facts.plainWriter} writes outside a transaction is a refusal's record, and the plain writer throws when that ` +\n `write fails, so a failed record masks the refusal itself. Record it through a failure entry point ` +\n `(${facts.failureEntryPoints.join(', ')}), which never throws; only a failure event committed with the state it ` +\n 'explains, in that transaction, uses the plain writer. A refusal is attributed to the person who was refused, ' +\n `with the request's origin, never to the system (${facts.systemActorBuilders.join(', ')}, or an actor whose ` +\n `${facts.systemActorMode.field} is '${facts.systemActorMode.value}'): use the operator's actor once they are ` +\n 'authorized and the request-bound entry point before. Every declared writer, builder, and factory must still ' +\n 'be called somewhere: one renamed away would pass unchecked.',\n run(context) {\n const findings: Finding[] = [];\n const called = new Set<string>();\n for (const file of context.files(FUNCTIONS_CODE)) {\n const shapes = refusalAuditShapes(file, facts);\n shapes.called.forEach((name) => called.add(name));\n for (const hit of shapes.hits)\n findings.push({\n file: file.path,\n line: lineOfNode(file, hit.node),\n detail: hit.detail,\n });\n }\n for (const name of [\n facts.plainWriter,\n ...facts.systemActorBuilders,\n ...facts.callableFactories,\n ])\n if (!called.has(name))\n findings.push({ file: '(refusalAudit)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No fire-and-forget work and no swallowed audit write.\n\nexport interface FireAndForgetFacts {\n /** The audit writer's success entry points, whose failure is never swallowed by a `.catch`. */\n auditWrites: readonly string[];\n /** Files whose `void`-ed calls are reviewed, each with its why; a file that no longer has one is stale. */\n voidSites: readonly Reviewed[];\n}\n\n/** Every `void`-ed call, every `.catch` chained onto an audit write, and every audit write call. */\nexport function fireAndForgetShapes(file: FileView, auditWrites: ReadonlySet<string>) {\n const sf = file.sourceFile;\n const voided: ts.Node[] = [];\n const swallowed: Array<{ node: ts.Node; name: string }> = [];\n const writes: string[] = [];\n forEachNode(sf, (node) => {\n if (ts.isVoidExpression(node) && ts.isCallExpression(unwrap(node.expression)))\n voided.push(node);\n if (!ts.isCallExpression(node)) return;\n const name = calleeName(node);\n if (name && auditWrites.has(name)) writes.push(name);\n if (\n name === 'catch' &&\n ts.isPropertyAccessExpression(node.expression) &&\n ts.isCallExpression(node.expression.expression)\n ) {\n const inner = calleeName(node.expression.expression);\n if (inner && auditWrites.has(inner)) swallowed.push({ node, name: inner });\n }\n });\n return { voided, swallowed, writes };\n}\n\nexport const fireAndForgetGuard: GenericGuardDefinition<FireAndForgetFacts> = {\n id: 'fireAndForget',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.auditWrites, 'auditWrites', problems, { nonEmpty: false });\n reviewedProblems(facts?.voidSites, 'voidSites', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no backend work is fired and forgotten, and no audit write is swallowed',\n description:\n 'A `void`-ed call in a callable, trigger, or worker is never awaited and never has its failure captured, and the ' +\n 'runtime throttles the instance once it has answered, so the work may never run. Await it inside its own ' +\n 'try/catch with a capture, commit it in the primary transaction, or enqueue it to a durable outbox — a write ' +\n \"composed into a caller's transaction is awaited like any other. A `.catch` chained onto an audit write is a \" +\n 'second, silent owner of a failure the best-effort failure-audit entry points already own. A reviewed `void` ' +\n 'site is a file with its why; one with no `void`-ed call left is stale, and each declared audit write must still ' +\n 'be called somewhere.',\n run(context) {\n const auditWrites = new Set(facts.auditWrites);\n const reviewed = new Set(facts.voidSites.map((s) => s.path));\n const voidFiles = new Set<string>();\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n const { voided, swallowed, writes } = fireAndForgetShapes(file, auditWrites);\n writes.forEach((w) => called.add(w));\n if (voided.length) voidFiles.add(file.path);\n if (!reviewed.has(file.path)) {\n for (const node of voided)\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `fire-and-forget: ${node.getText(file.sourceFile).slice(0, 80)}`,\n });\n }\n for (const { node, name } of swallowed)\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `${name}(…).catch(…) swallows an audit write`,\n });\n }\n for (const path of reviewed)\n if (!voidFiles.has(path))\n findings.push({\n file: path,\n detail: 'stale void site: the file has no void-ed call',\n });\n for (const name of auditWrites)\n if (!called.has(name))\n findings.push({ file: '(auditWrites)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n"]}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { Finding, Guard, GuardContext } from '../../guard.js';\nimport type { Scope } from '../../node/reader.js';\nimport type { FileView } from '../../reader/view.js';\nimport type { Reviewed } from '../../node/layout.js';\nimport { ownerOnly, reviewedAllowlist, type Hit, type Matcher } from '../../shapes/shapes.js';\nimport { calleeName, forEachNode, isPlainString, lineOfNode, unwrap } from '../../support/ast.js';\nimport { namesProblem, reviewedProblems, textProblem } from '../../support/facts.js';\nimport { MODULE_LOADS, moduleImports, namesModule } from '../../support/imports.js';\nimport {\n serverZoneContext,\n serverZoneProblems,\n staleServerFolders,\n type ServerZone,\n} from './shared.js';\n\nconst FUNCTIONS_CODE: Scope = { roots: ['functions'], kinds: ['code'], tests: false };\n\nexport interface AuditWriterFacts {\n writer: string;\n collectionName: string;\n collectionHandles: readonly string[];\n writerPackages: readonly string[];\n readers: readonly Reviewed[];\n personActor: { constructors: string; modeField: string; modes: readonly string[] };\n appServerZone: ServerZone;\n}\n\nconst AUDIT_WRITER_SCOPE: Scope = {\n roots: ['functions', 'scripts', 'app'],\n optionalRoots: ['scripts'],\n kinds: ['code'],\n tests: false,\n};\n\nexport function auditCollectionMatcher(\n facts: Pick<AuditWriterFacts, 'collectionName' | 'collectionHandles' | 'writerPackages'>,\n): Matcher {\n const handles = new Set(facts.collectionHandles);\n const namesCollection = (text: string) =>\n text === facts.collectionName || text.startsWith(`${facts.collectionName}/`);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n const loads = new Map(moduleImports(sf, MODULE_LOADS).map((site) => [site.node, site.spec]));\n forEachNode(sf, (node) => {\n if (\n ts.isPropertyAccessExpression(node) &&\n handles.has(`${node.expression.getText(sf)}.${node.name.text}`)\n ) {\n hits.push({ index: node.getStart(sf), detail: node.getText(sf) });\n }\n const specifier = loads.get(node);\n if (specifier !== undefined && facts.writerPackages.some((p) => namesModule(specifier, p))) {\n hits.push({ index: node.getStart(sf), detail: `imports ${specifier}` });\n return;\n }\n const isSpecifier =\n !!node.parent &&\n (ts.isImportDeclaration(node.parent) || ts.isExportDeclaration(node.parent));\n if (isPlainString(node) && !isSpecifier && namesCollection(node.text)) {\n hits.push({ index: node.getStart(sf), detail: `'${node.text}'` });\n }\n if (ts.isTemplateExpression(node) && namesCollection(node.head.text)) {\n hits.push({ index: node.getStart(sf), detail: `${facts.collectionName} template path` });\n }\n });\n return hits;\n };\n}\n\nexport function personActorMatcher(facts: AuditWriterFacts['personActor']): Matcher {\n const modes = new Set(facts.modes);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n forEachNode(sf, (node) => {\n if (!ts.isObjectLiteralExpression(node)) return;\n for (const prop of node.properties) {\n if (\n !ts.isPropertyAssignment(prop) ||\n prop.name.getText(sf).replace(/^['\"]|['\"]$/g, '') !== facts.modeField\n )\n continue;\n const init = unwrap(prop.initializer);\n if (ts.isStringLiteralLike(init) && modes.has(init.text)) {\n hits.push({ index: prop.getStart(sf), detail: `${facts.modeField}: '${init.text}'` });\n }\n }\n });\n return hits;\n };\n}\n\nexport const auditWriterGuard: GenericGuardDefinition<AuditWriterFacts> = {\n id: 'auditWriter',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.writer, 'writer', problems);\n textProblem(facts?.collectionName, 'collectionName', problems);\n namesProblem(facts?.collectionHandles, 'collectionHandles', problems);\n for (const handle of facts?.collectionHandles ?? []) {\n if (typeof handle === 'string' && !/^[\\w$]+\\.[\\w$]+$/.test(handle))\n problems.push(`collection handle ${handle} is not OWNER.member`);\n }\n namesProblem(facts?.writerPackages, 'writerPackages', problems, { nonEmpty: false });\n reviewedProblems(facts?.readers, 'readers', problems);\n if (facts?.readers?.some((r) => r?.path === facts.writer))\n problems.push('the writer is listed as a reader');\n textProblem(facts?.personActor?.constructors, 'personActor.constructors', problems);\n textProblem(facts?.personActor?.modeField, 'personActor.modeField', problems);\n namesProblem(facts?.personActor?.modes, 'personActor.modes', problems);\n serverZoneProblems(facts?.appServerZone, 'appServerZone', problems);\n return problems;\n },\n build(facts) {\n const collection = reviewedAllowlist({\n title: 'audit documents are written by the one audit writer',\n description:\n `Only ${facts.writer} names the audit collection (${facts.collectionName}, ${facts.collectionHandles.join(', ')}) ` +\n 'or imports a package that writes it; a second writer would skip the attribution, the request origin, and the ' +\n 'append-only rules the writer owns. Write audit events through the writer. A module that only READS the ' +\n 'collection is a reviewed reader with its why; a reader that stops naming the collection is stale.',\n scope: AUDIT_WRITER_SCOPE,\n match: auditCollectionMatcher(facts),\n allowlist: [{ path: facts.writer, why: 'the one audit writer' }, ...facts.readers],\n samples: {\n flags: [\n `db.collection('${facts.collectionName}').add(event);`,\n `db.doc(\\`${facts.collectionName}/\\${id}\\`).set(event);`,\n `db.collection(${facts.collectionHandles[0]}).doc(id).set(event);`,\n ],\n passes: [\n `// writes ${facts.collectionName} through ${facts.collectionHandles[0]}\\nconst label = '${facts.collectionName}Count';`,\n ],\n },\n });\n const actors = ownerOnly({\n title: 'person-actors are built only by the actor constructors',\n description:\n `Only ${facts.personActor.constructors} writes an object whose ${facts.personActor.modeField} is a person mode ` +\n `(${facts.personActor.modes.join(', ')}). A person-actor carries the origin of the request it acted through; ` +\n 'built by hand it can carry none, or a forged one. Build it with the actor constructors.',\n scope: AUDIT_WRITER_SCOPE,\n match: personActorMatcher(facts.personActor),\n owners: [facts.personActor.constructors],\n samples: {\n flags: [\n `const actor = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' as const, uid };`,\n ],\n passes: [\n `type A = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };\\nconst b = { other${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };`,\n ],\n },\n });\n const inZone = (guard: Guard): Guard => ({\n ...guard,\n async run(context: GuardContext) {\n return [\n ...staleServerFolders(context, facts.appServerZone),\n ...(await guard.run(serverZoneContext(context, facts.appServerZone))),\n ];\n },\n });\n return [inZone(collection), inZone(actors)];\n },\n};\n\nexport interface AuditPayloadFacts {\n entryPoints: readonly string[];\n payloadKey: string;\n forwardedPayloadKeys: readonly string[];\n operatorCopy: ReadonlyArray<{ site: string; why: string }>;\n}\n\nconst PROSE_KEY =\n /(title|name|description|subject|body|text|message|content|caption|narrative|comment|bio|words)$/i;\nconst NAMES_NOT_TEXT = /(Lengths|Fields)$/;\n\nexport function proseKeysInAuditPayloads(\n file: FileView,\n facts: AuditPayloadFacts,\n): Array<{ key: string; node: ts.Node }> {\n const sf = file.sourceFile;\n const entryPoints = new Set(facts.entryPoints);\n const forwarded = new Set(facts.forwardedPayloadKeys);\n const hits: Array<{ key: string; node: ts.Node }> = [];\n const keyOf = (prop: ts.ObjectLiteralElementLike) =>\n prop.name?.getText(sf).replace(/^['\"`]|['\"`]$/g, '') ?? '';\n const walkPayload = (obj: ts.ObjectLiteralExpression) => {\n for (const prop of obj.properties) {\n if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop)) continue;\n const key = keyOf(prop);\n if (PROSE_KEY.test(key)) hits.push({ key, node: prop });\n if (ts.isPropertyAssignment(prop) && !NAMES_NOT_TEXT.test(key)) {\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n }\n };\n const payloadOf = (details: ts.ObjectLiteralExpression, keys: ReadonlySet<string>) => {\n for (const prop of details.properties) {\n if (!ts.isPropertyAssignment(prop) || !keys.has(keyOf(prop))) continue;\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n };\n const payloadKeys = new Set([facts.payloadKey]);\n forEachNode(sf, (node) => {\n if (ts.isCallExpression(node) && entryPoints.has(calleeName(node) ?? '')) {\n for (const arg of node.arguments) {\n const value = unwrap(arg);\n if (ts.isObjectLiteralExpression(value)) payloadOf(value, payloadKeys);\n }\n }\n if (ts.isObjectLiteralExpression(node)) payloadOf(node, forwarded);\n });\n return hits;\n}\n\nexport const auditPayloadGuard: GenericGuardDefinition<AuditPayloadFacts> = {\n id: 'auditPayload',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.entryPoints, 'entryPoints', problems);\n textProblem(facts?.payloadKey, 'payloadKey', problems);\n namesProblem(facts?.forwardedPayloadKeys, 'forwardedPayloadKeys', problems, {\n nonEmpty: false,\n });\n reviewedProblems(facts?.operatorCopy, 'operatorCopy', problems, { key: 'site' });\n for (const entry of facts?.operatorCopy ?? []) {\n if (typeof entry?.site === 'string' && !/^[^#]+#[^#]+$/.test(entry.site))\n problems.push(`operatorCopy site ${entry.site} is not file#key`);\n }\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no member-written text is copied into an audit payload',\n description:\n 'An audit payload records identifiers, field names, lengths, and decisions — never member-written text. An audit ' +\n 'event outlives every edit and every erasure, so a title, name, description, subject, body, or message copied ' +\n \"into one survives the member's own change and their account's deletion. Record the changed field names and \" +\n 'their lengths instead. A key under a `…Lengths` or `…Fields` map names fields and is exempt; text an operator ' +\n 'writes is a reviewed `file#key` entry with its why, and an entry that no longer occurs is stale.',\n run(context) {\n const findings: Finding[] = [];\n const reviewed = new Set(facts.operatorCopy.map((e) => e.site));\n const seen = new Set<string>();\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const { key, node } of proseKeysInAuditPayloads(file, facts)) {\n const site = `${file.path}#${key}`;\n seen.add(site);\n if (!reviewed.has(site))\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `prose-named payload key ${key}`,\n });\n }\n }\n for (const site of reviewed)\n if (!seen.has(site))\n findings.push({\n file: site,\n detail: 'stale operator-copy entry: the key no longer occurs',\n });\n return findings;\n },\n },\n ];\n },\n};\n\nexport interface FailureAuditFacts {\n failureEntryPoints: readonly string[];\n}\n\nexport function chainedFailureAudits(\n file: FileView,\n names: ReadonlySet<string>,\n): Array<{ node: ts.Node; detail: string; name?: string }> {\n const sf = file.sourceFile;\n const hits: Array<{ node: ts.Node; detail: string; name?: string }> = [];\n forEachNode(sf, (node) => {\n if (\n ts.isImportSpecifier(node) &&\n node.propertyName &&\n names.has(node.propertyName.text) &&\n node.propertyName.text !== node.name.text\n ) {\n hits.push({ node, detail: `imports ${node.propertyName.text} under another name` });\n }\n const name = ts.isCallExpression(node) ? calleeName(node) : undefined;\n if (ts.isCallExpression(node) && name && names.has(name)) {\n const parent = node.parent;\n const chained =\n ts.isPropertyAccessExpression(parent) &&\n parent.expression === node &&\n ['catch', 'then', 'finally'].includes(parent.name.text);\n hits.push({\n node,\n name,\n detail: chained\n ? `chains .${(parent as ts.PropertyAccessExpression).name.text} onto ${name}`\n : '',\n });\n }\n });\n return hits;\n}\n\nexport const failureAuditGuard: GenericGuardDefinition<FailureAuditFacts> = {\n id: 'failureAuditChain',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.failureEntryPoints, 'failureEntryPoints', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no handler is chained onto a failure-audit entry point',\n description:\n `The failure-audit entry points (${facts.failureEntryPoints.join(', ')}) never throw — each logs and captures a ` +\n 'write that failed — so a `.catch`, `.then`, or `.finally` chained onto one is dead code that hides the contract, ' +\n 'and an aliased import hides the call from this check. Import each under its own name and call it bare. Every ' +\n 'declared entry point must still be called somewhere: one renamed away would pass unchecked.',\n run(context) {\n const names = new Set(facts.failureEntryPoints);\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const hit of chainedFailureAudits(file, names)) {\n if (hit.name) called.add(hit.name);\n if (hit.detail)\n findings.push({\n file: file.path,\n line: lineOfNode(file, hit.node),\n detail: hit.detail,\n });\n }\n }\n for (const name of names)\n if (!called.has(name))\n findings.push({ file: '(failureEntryPoints)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n\nexport interface RefusalAuditFacts {\n plainWriter: string;\n failureEntryPoints: readonly string[];\n systemActorBuilders: readonly string[];\n systemActorMode: { field: string; value: string };\n callableFactories: readonly string[];\n}\n\nfunction functionName(node: ts.Node): string | undefined {\n if (ts.isFunctionDeclaration(node)) return node.name?.text;\n if (\n (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&\n ts.isVariableDeclaration(node.parent) &&\n ts.isIdentifier(node.parent.name)\n )\n return node.parent.name.text;\n return undefined;\n}\n\nexport function refusalAuditShapes(\n file: FileView,\n facts: RefusalAuditFacts,\n): { hits: Array<{ node: ts.Node; detail: string }>; called: Set<string> } {\n const sf = file.sourceFile;\n const failureNames = new Set(facts.failureEntryPoints);\n const builders = new Set(facts.systemActorBuilders);\n const factories = new Set(facts.callableFactories);\n const keyOf = (prop: ts.ObjectLiteralElementLike) =>\n prop.name?.getText(sf).replace(/^['\"`]|['\"`]$/g, '') ?? '';\n const called = new Set<string>();\n const systemLocals = new Set<string>();\n const isSystemActor = (expression: ts.Expression | undefined): boolean => {\n if (!expression) return false;\n const e = unwrap(expression);\n if (ts.isCallExpression(e)) return builders.has(calleeName(e) ?? '');\n if (ts.isIdentifier(e)) return systemLocals.has(e.text);\n if (!ts.isObjectLiteralExpression(e)) return false;\n return e.properties.some((prop) => {\n if (!ts.isPropertyAssignment(prop) || keyOf(prop) !== facts.systemActorMode.field)\n return false;\n const value = unwrap(prop.initializer);\n return ts.isStringLiteralLike(value) && value.text === facts.systemActorMode.value;\n });\n };\n let definesCallable = false;\n forEachNode(sf, (node) => {\n if (ts.isCallExpression(node)) {\n const name = calleeName(node) ?? '';\n if (factories.has(name)) definesCallable = true;\n if (name === facts.plainWriter || builders.has(name) || factories.has(name)) called.add(name);\n }\n if (\n ts.isVariableDeclaration(node) &&\n ts.isIdentifier(node.name) &&\n node.initializer &&\n isSystemActor(node.initializer)\n )\n systemLocals.add(node.name.text);\n });\n const hits: Array<{ node: ts.Node; detail: string }> = [];\n if (!definesCallable) return { hits, called };\n const failureEvent = (call: ts.CallExpression) => {\n for (const arg of call.arguments) {\n const details = unwrap(arg);\n if (!ts.isObjectLiteralExpression(details)) continue;\n const result = details.properties.find(\n (prop): prop is ts.PropertyAssignment =>\n ts.isPropertyAssignment(prop) && keyOf(prop) === 'result',\n );\n const value = result && unwrap(result.initializer);\n if (value && ts.isStringLiteralLike(value) && value.text === 'failure')\n return { inTransaction: details.properties.some((prop) => keyOf(prop) === 'transaction') };\n }\n return undefined;\n };\n const walk = (node: ts.Node): void => {\n if (failureNames.has(functionName(node) ?? '')) return;\n if (ts.isCallExpression(node)) {\n const name = calleeName(node) ?? '';\n if (name === facts.plainWriter) {\n const event = failureEvent(node);\n if (event && !event.inTransaction)\n hits.push({\n node,\n detail: `${name} writes a failure event outside a transaction`,\n });\n if (event && isSystemActor(node.arguments[0]))\n hits.push({ node, detail: `${name} records a failure as the system` });\n }\n if (failureNames.has(name) && isSystemActor(node.arguments[0]))\n hits.push({ node, detail: `${name} records a refusal as the system` });\n }\n ts.forEachChild(node, walk);\n };\n walk(sf);\n return { hits, called };\n}\n\nexport const refusalAuditGuard: GenericGuardDefinition<RefusalAuditFacts> = {\n id: 'refusalAudit',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.plainWriter, 'plainWriter', problems);\n namesProblem(facts?.failureEntryPoints, 'failureEntryPoints', problems);\n namesProblem(facts?.systemActorBuilders, 'systemActorBuilders', problems);\n textProblem(facts?.systemActorMode?.field, 'systemActorMode.field', problems);\n textProblem(facts?.systemActorMode?.value, 'systemActorMode.value', problems);\n namesProblem(facts?.callableFactories, 'callableFactories', problems);\n if (facts?.failureEntryPoints?.includes(facts?.plainWriter))\n problems.push('the plain writer is listed as a failure entry point');\n return problems;\n },\n build(facts) {\n return [\n {\n title: \"a refusal's failure event goes through the failure entry points, as the caller\",\n description:\n `In a module that defines a callable (${facts.callableFactories.join(', ')}), a failure event the plain writer ` +\n `${facts.plainWriter} writes outside a transaction is a refusal's record, and the plain writer throws when that ` +\n `write fails, so a failed record masks the refusal itself. Record it through a failure entry point ` +\n `(${facts.failureEntryPoints.join(', ')}), which never throws; only a failure event committed with the state it ` +\n 'explains, in that transaction, uses the plain writer. A refusal is attributed to the person who was refused, ' +\n `with the request's origin, never to the system (${facts.systemActorBuilders.join(', ')}, or an actor whose ` +\n `${facts.systemActorMode.field} is '${facts.systemActorMode.value}'): use the operator's actor once they are ` +\n 'authorized and the request-bound entry point before. Every declared writer, builder, and factory must still ' +\n 'be called somewhere: one renamed away would pass unchecked.',\n run(context) {\n const findings: Finding[] = [];\n const called = new Set<string>();\n for (const file of context.files(FUNCTIONS_CODE)) {\n const shapes = refusalAuditShapes(file, facts);\n shapes.called.forEach((name) => called.add(name));\n for (const hit of shapes.hits)\n findings.push({\n file: file.path,\n line: lineOfNode(file, hit.node),\n detail: hit.detail,\n });\n }\n for (const name of [\n facts.plainWriter,\n ...facts.systemActorBuilders,\n ...facts.callableFactories,\n ])\n if (!called.has(name))\n findings.push({ file: '(refusalAudit)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n\nexport interface FireAndForgetFacts {\n auditWrites: readonly string[];\n voidSites: readonly Reviewed[];\n}\n\nexport function fireAndForgetShapes(file: FileView, auditWrites: ReadonlySet<string>) {\n const sf = file.sourceFile;\n const voided: ts.Node[] = [];\n const swallowed: Array<{ node: ts.Node; name: string }> = [];\n const writes: string[] = [];\n forEachNode(sf, (node) => {\n if (ts.isVoidExpression(node) && ts.isCallExpression(unwrap(node.expression)))\n voided.push(node);\n if (!ts.isCallExpression(node)) return;\n const name = calleeName(node);\n if (name && auditWrites.has(name)) writes.push(name);\n if (\n name === 'catch' &&\n ts.isPropertyAccessExpression(node.expression) &&\n ts.isCallExpression(node.expression.expression)\n ) {\n const inner = calleeName(node.expression.expression);\n if (inner && auditWrites.has(inner)) swallowed.push({ node, name: inner });\n }\n });\n return { voided, swallowed, writes };\n}\n\nexport const fireAndForgetGuard: GenericGuardDefinition<FireAndForgetFacts> = {\n id: 'fireAndForget',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.auditWrites, 'auditWrites', problems, { nonEmpty: false });\n reviewedProblems(facts?.voidSites, 'voidSites', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no backend work is fired and forgotten, and no audit write is swallowed',\n description:\n 'A `void`-ed call in a callable, trigger, or worker is never awaited and never has its failure captured, and the ' +\n 'runtime throttles the instance once it has answered, so the work may never run. Await it inside its own ' +\n 'try/catch with a capture, commit it in the primary transaction, or enqueue it to a durable outbox — a write ' +\n \"composed into a caller's transaction is awaited like any other. A `.catch` chained onto an audit write is a \" +\n 'second, silent owner of a failure the best-effort failure-audit entry points already own. A reviewed `void` ' +\n 'site is a file with its why; one with no `void`-ed call left is stale, and each declared audit write must still ' +\n 'be called somewhere.',\n run(context) {\n const auditWrites = new Set(facts.auditWrites);\n const reviewed = new Set(facts.voidSites.map((s) => s.path));\n const voidFiles = new Set<string>();\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n const { voided, swallowed, writes } = fireAndForgetShapes(file, auditWrites);\n writes.forEach((w) => called.add(w));\n if (voided.length) voidFiles.add(file.path);\n if (!reviewed.has(file.path)) {\n for (const node of voided)\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `fire-and-forget: ${node.getText(file.sourceFile).slice(0, 80)}`,\n });\n }\n for (const { node, name } of swallowed)\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `${name}(…).catch(…) swallows an audit write`,\n });\n }\n for (const path of reviewed)\n if (!voidFiles.has(path))\n findings.push({\n file: path,\n detail: 'stale void site: the file has no void-ed call',\n });\n for (const name of auditWrites)\n if (!called.has(name))\n findings.push({ file: '(auditWrites)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n"]}
@@ -6,44 +6,33 @@ import { type Matcher } from '../../shapes/shapes.js';
6
6
  import { type CallableDeclarationFacts } from '../frontend-actions/declarations.js';
7
7
  import { type ServerZone } from './shared.js';
8
8
  export interface AdminClaimFacts {
9
- /** The token claims that say a caller is an admin (`isAdmin`). */
10
9
  claimKeys: readonly string[];
11
- /** The modules that may read the claim — the resolver, and metadata-only copies — each with its why. */
12
10
  readers: readonly Reviewed[];
13
- /** Server code in the app root, held to the same rule as the Functions tree. */
14
11
  appServerZone: ServerZone;
15
12
  }
16
- /** Every read of an admin claim off a token: member access, bracket access, or destructuring. */
17
13
  export declare function adminClaimMatcher(claimKeys: readonly string[]): Matcher;
18
14
  export declare const adminClaimGuard: GenericGuardDefinition<AdminClaimFacts>;
19
15
  export interface RequestOriginFacts {
20
- /** The one module that derives where a request came from. */
21
16
  reader: string;
22
17
  }
23
18
  export declare const requestOriginGuard: GenericGuardDefinition<RequestOriginFacts>;
24
19
  export type NoBlockingFunctionFacts = Record<string, never>;
25
- /** Every registration of a sign-up, sign-in, email, or SMS blocking function. */
26
20
  export declare function blockingFunctionSites(file: FileView): Array<{
27
21
  node: ts.Node;
28
22
  detail: string;
29
23
  }>;
30
24
  export declare const noBlockingFunctionGuard: GenericGuardDefinition<NoBlockingFunctionFacts>;
31
25
  export interface AppCheckFacts {
32
- /** Functions folders whose every callable spends its App Check token (money, safety, operator commands). */
33
26
  consumingFolders: readonly string[];
34
- /** The auth call whose option marks an admin callable (`{ call: 'assertAuth', option: 'admin' }`). */
35
27
  adminAuth: {
36
28
  call: string;
37
29
  option: string;
38
30
  };
39
- /** Callables that keep the cached token although they would consume, by exported name, each with its why. */
40
31
  consumptionExempt: ReadonlyArray<{
41
32
  callable: string;
42
33
  why: string;
43
34
  }>;
44
- /** The app's callable declarations, which present the token the server consumes. */
45
35
  clientDeclarations: CallableDeclarationFacts;
46
- /** Consuming callables no client declaration names (no client calls them), each with its why. */
47
36
  noClientDeclaration: ReadonlyArray<{
48
37
  callable: string;
49
38
  why: string;
@@ -54,9 +43,7 @@ interface Callable {
54
43
  node: ts.Node;
55
44
  options: ts.ObjectLiteralExpression | null;
56
45
  }
57
- /** Every callable a file defines: exported directly, or made by a module function that returns an `onCall`. */
58
46
  export declare function callablesOf(file: FileView): Callable[];
59
- /** True when a file asks its auth call for the admin option. */
60
47
  export declare function asksForAdmin(file: FileView, adminAuth: AppCheckFacts['adminAuth']): boolean;
61
48
  export declare const appCheckGuard: GenericGuardDefinition<AppCheckFacts>;
62
49
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/auth.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAA0C,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAK9F,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,wGAAwG;IACxG,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,gFAAgF;IAChF,aAAa,EAAE,UAAU,CAAC;CAC3B;AAKD,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAmBvE;AAED,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAAC,eAAe,CAkDnE,CAAC;AAKF,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,eAAO,MAAM,kBAAkB,EAAE,sBAAsB,CAAC,kBAAkB,CAsCzE,CAAC;AAKF,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAK5D,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAc9F;AAED,eAAO,MAAM,uBAAuB,EAAE,sBAAsB,CAAC,uBAAuB,CAyBnF,CAAC;AAKF,MAAM,WAAW,aAAa;IAC5B,4GAA4G;IAC5G,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,sGAAsG;IACtG,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,6GAA6G;IAC7G,iBAAiB,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,oFAAoF;IACpF,kBAAkB,EAAE,wBAAwB,CAAC;IAC7C,iGAAiG;IACjG,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,OAAO,EAAE,EAAE,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAC5C;AAgBD,+GAA+G;AAC/G,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CA0CtD;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAa3F;AAED,eAAO,MAAM,aAAa,EAAE,sBAAsB,CAAC,aAAa,CAqL/D,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAA0C,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAK9F,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,aAAa,EAAE,UAAU,CAAC;CAC3B;AAID,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAmBvE;AAED,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAAC,eAAe,CAkDnE,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,eAAO,MAAM,kBAAkB,EAAE,sBAAsB,CAAC,kBAAkB,CAkCzE,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAK5D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAc9F;AAED,eAAO,MAAM,uBAAuB,EAAE,sBAAsB,CAAC,uBAAuB,CAyBnF,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,iBAAiB,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,kBAAkB,EAAE,wBAAwB,CAAC;IAC7C,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,OAAO,EAAE,EAAE,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAC5C;AAeD,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CA0CtD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAa3F;AAED,eAAO,MAAM,aAAa,EAAE,sBAAsB,CAAC,aAAa,CAqL/D,CAAC"}