@fuzdev/fuz_app 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/actions/action_bridge.d.ts +65 -0
  4. package/dist/actions/action_bridge.d.ts.map +1 -0
  5. package/dist/actions/action_bridge.js +76 -0
  6. package/dist/actions/action_codegen.d.ts +97 -0
  7. package/dist/actions/action_codegen.d.ts.map +1 -0
  8. package/dist/actions/action_codegen.js +280 -0
  9. package/dist/actions/action_registry.d.ts +35 -0
  10. package/dist/actions/action_registry.d.ts.map +1 -0
  11. package/dist/actions/action_registry.js +83 -0
  12. package/dist/actions/action_spec.d.ts +169 -0
  13. package/dist/actions/action_spec.d.ts.map +1 -0
  14. package/dist/actions/action_spec.js +76 -0
  15. package/dist/auth/account_queries.d.ts +96 -0
  16. package/dist/auth/account_queries.d.ts.map +1 -0
  17. package/dist/auth/account_queries.js +172 -0
  18. package/dist/auth/account_routes.d.ts +86 -0
  19. package/dist/auth/account_routes.d.ts.map +1 -0
  20. package/dist/auth/account_routes.js +406 -0
  21. package/dist/auth/account_schema.d.ts +192 -0
  22. package/dist/auth/account_schema.d.ts.map +1 -0
  23. package/dist/auth/account_schema.js +105 -0
  24. package/dist/auth/admin_routes.d.ts +29 -0
  25. package/dist/auth/admin_routes.d.ts.map +1 -0
  26. package/dist/auth/admin_routes.js +193 -0
  27. package/dist/auth/api_token.d.ts +33 -0
  28. package/dist/auth/api_token.d.ts.map +1 -0
  29. package/dist/auth/api_token.js +36 -0
  30. package/dist/auth/api_token_queries.d.ts +80 -0
  31. package/dist/auth/api_token_queries.d.ts.map +1 -0
  32. package/dist/auth/api_token_queries.js +116 -0
  33. package/dist/auth/app_settings_queries.d.ts +33 -0
  34. package/dist/auth/app_settings_queries.d.ts.map +1 -0
  35. package/dist/auth/app_settings_queries.js +51 -0
  36. package/dist/auth/app_settings_routes.d.ts +27 -0
  37. package/dist/auth/app_settings_routes.d.ts.map +1 -0
  38. package/dist/auth/app_settings_routes.js +66 -0
  39. package/dist/auth/app_settings_schema.d.ts +35 -0
  40. package/dist/auth/app_settings_schema.d.ts.map +1 -0
  41. package/dist/auth/app_settings_schema.js +22 -0
  42. package/dist/auth/audit_log_queries.d.ts +90 -0
  43. package/dist/auth/audit_log_queries.d.ts.map +1 -0
  44. package/dist/auth/audit_log_queries.js +205 -0
  45. package/dist/auth/audit_log_routes.d.ts +33 -0
  46. package/dist/auth/audit_log_routes.d.ts.map +1 -0
  47. package/dist/auth/audit_log_routes.js +106 -0
  48. package/dist/auth/audit_log_schema.d.ts +259 -0
  49. package/dist/auth/audit_log_schema.d.ts.map +1 -0
  50. package/dist/auth/audit_log_schema.js +123 -0
  51. package/dist/auth/bearer_auth.d.ts +32 -0
  52. package/dist/auth/bearer_auth.d.ts.map +1 -0
  53. package/dist/auth/bearer_auth.js +90 -0
  54. package/dist/auth/bootstrap_account.d.ts +82 -0
  55. package/dist/auth/bootstrap_account.d.ts.map +1 -0
  56. package/dist/auth/bootstrap_account.js +97 -0
  57. package/dist/auth/bootstrap_routes.d.ts +74 -0
  58. package/dist/auth/bootstrap_routes.d.ts.map +1 -0
  59. package/dist/auth/bootstrap_routes.js +154 -0
  60. package/dist/auth/daemon_token.d.ts +49 -0
  61. package/dist/auth/daemon_token.d.ts.map +1 -0
  62. package/dist/auth/daemon_token.js +49 -0
  63. package/dist/auth/daemon_token_middleware.d.ts +93 -0
  64. package/dist/auth/daemon_token_middleware.d.ts.map +1 -0
  65. package/dist/auth/daemon_token_middleware.js +167 -0
  66. package/dist/auth/ddl.d.ts +27 -0
  67. package/dist/auth/ddl.d.ts.map +1 -0
  68. package/dist/auth/ddl.js +111 -0
  69. package/dist/auth/deps.d.ts +52 -0
  70. package/dist/auth/deps.d.ts.map +1 -0
  71. package/dist/auth/deps.js +10 -0
  72. package/dist/auth/invite_queries.d.ts +68 -0
  73. package/dist/auth/invite_queries.d.ts.map +1 -0
  74. package/dist/auth/invite_queries.js +105 -0
  75. package/dist/auth/invite_routes.d.ts +18 -0
  76. package/dist/auth/invite_routes.d.ts.map +1 -0
  77. package/dist/auth/invite_routes.js +129 -0
  78. package/dist/auth/invite_schema.d.ts +51 -0
  79. package/dist/auth/invite_schema.d.ts.map +1 -0
  80. package/dist/auth/invite_schema.js +25 -0
  81. package/dist/auth/keyring.d.ts +87 -0
  82. package/dist/auth/keyring.d.ts.map +1 -0
  83. package/dist/auth/keyring.js +142 -0
  84. package/dist/auth/middleware.d.ts +40 -0
  85. package/dist/auth/middleware.d.ts.map +1 -0
  86. package/dist/auth/middleware.js +64 -0
  87. package/dist/auth/migrations.d.ts +42 -0
  88. package/dist/auth/migrations.d.ts.map +1 -0
  89. package/dist/auth/migrations.js +79 -0
  90. package/dist/auth/password.d.ts +39 -0
  91. package/dist/auth/password.d.ts.map +1 -0
  92. package/dist/auth/password.js +25 -0
  93. package/dist/auth/password_argon2.d.ts +43 -0
  94. package/dist/auth/password_argon2.d.ts.map +1 -0
  95. package/dist/auth/password_argon2.js +76 -0
  96. package/dist/auth/permit_queries.d.ts +72 -0
  97. package/dist/auth/permit_queries.d.ts.map +1 -0
  98. package/dist/auth/permit_queries.js +116 -0
  99. package/dist/auth/request_context.d.ts +114 -0
  100. package/dist/auth/request_context.d.ts.map +1 -0
  101. package/dist/auth/request_context.js +176 -0
  102. package/dist/auth/require_keeper.d.ts +20 -0
  103. package/dist/auth/require_keeper.d.ts.map +1 -0
  104. package/dist/auth/require_keeper.js +35 -0
  105. package/dist/auth/role_schema.d.ts +69 -0
  106. package/dist/auth/role_schema.d.ts.map +1 -0
  107. package/dist/auth/role_schema.js +70 -0
  108. package/dist/auth/route_guards.d.ts +21 -0
  109. package/dist/auth/route_guards.d.ts.map +1 -0
  110. package/dist/auth/route_guards.js +32 -0
  111. package/dist/auth/session_cookie.d.ts +158 -0
  112. package/dist/auth/session_cookie.d.ts.map +1 -0
  113. package/dist/auth/session_cookie.js +135 -0
  114. package/dist/auth/session_lifecycle.d.ts +35 -0
  115. package/dist/auth/session_lifecycle.d.ts.map +1 -0
  116. package/dist/auth/session_lifecycle.js +27 -0
  117. package/dist/auth/session_middleware.d.ts +33 -0
  118. package/dist/auth/session_middleware.d.ts.map +1 -0
  119. package/dist/auth/session_middleware.js +62 -0
  120. package/dist/auth/session_queries.d.ts +135 -0
  121. package/dist/auth/session_queries.d.ts.map +1 -0
  122. package/dist/auth/session_queries.js +186 -0
  123. package/dist/auth/signup_routes.d.ts +32 -0
  124. package/dist/auth/signup_routes.d.ts.map +1 -0
  125. package/dist/auth/signup_routes.js +150 -0
  126. package/dist/cli/args.d.ts +48 -0
  127. package/dist/cli/args.d.ts.map +1 -0
  128. package/dist/cli/args.js +76 -0
  129. package/dist/cli/config.d.ts +48 -0
  130. package/dist/cli/config.d.ts.map +1 -0
  131. package/dist/cli/config.js +77 -0
  132. package/dist/cli/daemon.d.ts +82 -0
  133. package/dist/cli/daemon.d.ts.map +1 -0
  134. package/dist/cli/daemon.js +149 -0
  135. package/dist/cli/help.d.ts +85 -0
  136. package/dist/cli/help.d.ts.map +1 -0
  137. package/dist/cli/help.js +138 -0
  138. package/dist/cli/logger.d.ts +46 -0
  139. package/dist/cli/logger.d.ts.map +1 -0
  140. package/dist/cli/logger.js +48 -0
  141. package/dist/cli/util.d.ts +36 -0
  142. package/dist/cli/util.d.ts.map +1 -0
  143. package/dist/cli/util.js +50 -0
  144. package/dist/crypto.d.ts +13 -0
  145. package/dist/crypto.d.ts.map +1 -0
  146. package/dist/crypto.js +19 -0
  147. package/dist/db/assert_row.d.ts +18 -0
  148. package/dist/db/assert_row.d.ts.map +1 -0
  149. package/dist/db/assert_row.js +24 -0
  150. package/dist/db/create_db.d.ts +38 -0
  151. package/dist/db/create_db.d.ts.map +1 -0
  152. package/dist/db/create_db.js +57 -0
  153. package/dist/db/db.d.ts +97 -0
  154. package/dist/db/db.d.ts.map +1 -0
  155. package/dist/db/db.js +76 -0
  156. package/dist/db/db_pg.d.ts +21 -0
  157. package/dist/db/db_pg.d.ts.map +1 -0
  158. package/dist/db/db_pg.js +45 -0
  159. package/dist/db/db_pglite.d.ts +21 -0
  160. package/dist/db/db_pglite.d.ts.map +1 -0
  161. package/dist/db/db_pglite.js +28 -0
  162. package/dist/db/migrate.d.ts +67 -0
  163. package/dist/db/migrate.d.ts.map +1 -0
  164. package/dist/db/migrate.js +118 -0
  165. package/dist/db/pg_error.d.ts +16 -0
  166. package/dist/db/pg_error.d.ts.map +1 -0
  167. package/dist/db/pg_error.js +15 -0
  168. package/dist/db/query_deps.d.ts +14 -0
  169. package/dist/db/query_deps.d.ts.map +1 -0
  170. package/dist/db/query_deps.js +9 -0
  171. package/dist/db/sql_identifier.d.ts +27 -0
  172. package/dist/db/sql_identifier.d.ts.map +1 -0
  173. package/dist/db/sql_identifier.js +31 -0
  174. package/dist/db/status.d.ts +62 -0
  175. package/dist/db/status.d.ts.map +1 -0
  176. package/dist/db/status.js +116 -0
  177. package/dist/dev/setup.d.ts +159 -0
  178. package/dist/dev/setup.d.ts.map +1 -0
  179. package/dist/dev/setup.js +265 -0
  180. package/dist/env/dotenv.d.ts +25 -0
  181. package/dist/env/dotenv.d.ts.map +1 -0
  182. package/dist/env/dotenv.js +52 -0
  183. package/dist/env/load.d.ts +52 -0
  184. package/dist/env/load.d.ts.map +1 -0
  185. package/dist/env/load.js +79 -0
  186. package/dist/env/mask.d.ts +19 -0
  187. package/dist/env/mask.d.ts.map +1 -0
  188. package/dist/env/mask.js +26 -0
  189. package/dist/env/resolve.d.ts +126 -0
  190. package/dist/env/resolve.d.ts.map +1 -0
  191. package/dist/env/resolve.js +200 -0
  192. package/dist/hono_context.d.ts +48 -0
  193. package/dist/hono_context.d.ts.map +1 -0
  194. package/dist/hono_context.js +22 -0
  195. package/dist/http/common_routes.d.ts +52 -0
  196. package/dist/http/common_routes.d.ts.map +1 -0
  197. package/dist/http/common_routes.js +65 -0
  198. package/dist/http/db_routes.d.ts +57 -0
  199. package/dist/http/db_routes.d.ts.map +1 -0
  200. package/dist/http/db_routes.js +176 -0
  201. package/dist/http/error_schemas.d.ts +169 -0
  202. package/dist/http/error_schemas.d.ts.map +1 -0
  203. package/dist/http/error_schemas.js +178 -0
  204. package/dist/http/middleware_spec.d.ts +19 -0
  205. package/dist/http/middleware_spec.d.ts.map +1 -0
  206. package/dist/http/middleware_spec.js +9 -0
  207. package/dist/http/origin.d.ts +57 -0
  208. package/dist/http/origin.d.ts.map +1 -0
  209. package/dist/http/origin.js +207 -0
  210. package/dist/http/proxy.d.ts +112 -0
  211. package/dist/http/proxy.d.ts.map +1 -0
  212. package/dist/http/proxy.js +240 -0
  213. package/dist/http/route_spec.d.ts +197 -0
  214. package/dist/http/route_spec.d.ts.map +1 -0
  215. package/dist/http/route_spec.js +243 -0
  216. package/dist/http/schema_helpers.d.ts +64 -0
  217. package/dist/http/schema_helpers.d.ts.map +1 -0
  218. package/dist/http/schema_helpers.js +90 -0
  219. package/dist/http/surface.d.ts +132 -0
  220. package/dist/http/surface.d.ts.map +1 -0
  221. package/dist/http/surface.js +156 -0
  222. package/dist/http/surface_query.d.ts +77 -0
  223. package/dist/http/surface_query.d.ts.map +1 -0
  224. package/dist/http/surface_query.js +86 -0
  225. package/dist/rate_limiter.d.ts +94 -0
  226. package/dist/rate_limiter.d.ts.map +1 -0
  227. package/dist/rate_limiter.js +156 -0
  228. package/dist/realtime/sse.d.ts +80 -0
  229. package/dist/realtime/sse.d.ts.map +1 -0
  230. package/dist/realtime/sse.js +109 -0
  231. package/dist/realtime/sse_auth_guard.d.ts +93 -0
  232. package/dist/realtime/sse_auth_guard.d.ts.map +1 -0
  233. package/dist/realtime/sse_auth_guard.js +111 -0
  234. package/dist/realtime/subscriber_registry.d.ts +85 -0
  235. package/dist/realtime/subscriber_registry.d.ts.map +1 -0
  236. package/dist/realtime/subscriber_registry.js +108 -0
  237. package/dist/runtime/deno.d.ts +21 -0
  238. package/dist/runtime/deno.d.ts.map +1 -0
  239. package/dist/runtime/deno.js +83 -0
  240. package/dist/runtime/deps.d.ts +113 -0
  241. package/dist/runtime/deps.d.ts.map +1 -0
  242. package/dist/runtime/deps.js +10 -0
  243. package/dist/runtime/fs.d.ts +15 -0
  244. package/dist/runtime/fs.d.ts.map +1 -0
  245. package/dist/runtime/fs.js +17 -0
  246. package/dist/runtime/mock.d.ts +81 -0
  247. package/dist/runtime/mock.d.ts.map +1 -0
  248. package/dist/runtime/mock.js +195 -0
  249. package/dist/runtime/node.d.ts +17 -0
  250. package/dist/runtime/node.d.ts.map +1 -0
  251. package/dist/runtime/node.js +117 -0
  252. package/dist/schema_meta.d.ts +16 -0
  253. package/dist/schema_meta.d.ts.map +1 -0
  254. package/dist/schema_meta.js +9 -0
  255. package/dist/sensitivity.d.ts +15 -0
  256. package/dist/sensitivity.d.ts.map +1 -0
  257. package/dist/sensitivity.js +9 -0
  258. package/dist/server/app_backend.d.ts +74 -0
  259. package/dist/server/app_backend.d.ts.map +1 -0
  260. package/dist/server/app_backend.js +39 -0
  261. package/dist/server/app_server.d.ts +201 -0
  262. package/dist/server/app_server.d.ts.map +1 -0
  263. package/dist/server/app_server.js +266 -0
  264. package/dist/server/env.d.ts +68 -0
  265. package/dist/server/env.d.ts.map +1 -0
  266. package/dist/server/env.js +95 -0
  267. package/dist/server/startup.d.ts +22 -0
  268. package/dist/server/startup.d.ts.map +1 -0
  269. package/dist/server/startup.js +48 -0
  270. package/dist/server/static.d.ts +39 -0
  271. package/dist/server/static.d.ts.map +1 -0
  272. package/dist/server/static.js +38 -0
  273. package/dist/server/validate_nginx.d.ts +34 -0
  274. package/dist/server/validate_nginx.d.ts.map +1 -0
  275. package/dist/server/validate_nginx.js +118 -0
  276. package/dist/testing/CLAUDE.md +3 -0
  277. package/dist/testing/admin_integration.d.ts +45 -0
  278. package/dist/testing/admin_integration.d.ts.map +1 -0
  279. package/dist/testing/admin_integration.js +840 -0
  280. package/dist/testing/adversarial_404.d.ts +15 -0
  281. package/dist/testing/adversarial_404.d.ts.map +1 -0
  282. package/dist/testing/adversarial_404.js +118 -0
  283. package/dist/testing/adversarial_headers.d.ts +36 -0
  284. package/dist/testing/adversarial_headers.d.ts.map +1 -0
  285. package/dist/testing/adversarial_headers.js +128 -0
  286. package/dist/testing/adversarial_input.d.ts +56 -0
  287. package/dist/testing/adversarial_input.d.ts.map +1 -0
  288. package/dist/testing/adversarial_input.js +494 -0
  289. package/dist/testing/app_server.d.ts +169 -0
  290. package/dist/testing/app_server.d.ts.map +1 -0
  291. package/dist/testing/app_server.js +240 -0
  292. package/dist/testing/assert_dev_env.d.ts +10 -0
  293. package/dist/testing/assert_dev_env.d.ts.map +1 -0
  294. package/dist/testing/assert_dev_env.js +13 -0
  295. package/dist/testing/assertions.d.ts +61 -0
  296. package/dist/testing/assertions.d.ts.map +1 -0
  297. package/dist/testing/assertions.js +96 -0
  298. package/dist/testing/attack_surface.d.ts +63 -0
  299. package/dist/testing/attack_surface.d.ts.map +1 -0
  300. package/dist/testing/attack_surface.js +224 -0
  301. package/dist/testing/audit_completeness.d.ts +29 -0
  302. package/dist/testing/audit_completeness.d.ts.map +1 -0
  303. package/dist/testing/audit_completeness.js +410 -0
  304. package/dist/testing/auth_apps.d.ts +55 -0
  305. package/dist/testing/auth_apps.d.ts.map +1 -0
  306. package/dist/testing/auth_apps.js +122 -0
  307. package/dist/testing/data_exposure.d.ts +62 -0
  308. package/dist/testing/data_exposure.d.ts.map +1 -0
  309. package/dist/testing/data_exposure.js +297 -0
  310. package/dist/testing/db.d.ts +111 -0
  311. package/dist/testing/db.d.ts.map +1 -0
  312. package/dist/testing/db.js +258 -0
  313. package/dist/testing/entities.d.ts +21 -0
  314. package/dist/testing/entities.d.ts.map +1 -0
  315. package/dist/testing/entities.js +42 -0
  316. package/dist/testing/error_coverage.d.ts +78 -0
  317. package/dist/testing/error_coverage.d.ts.map +1 -0
  318. package/dist/testing/error_coverage.js +135 -0
  319. package/dist/testing/integration.d.ts +37 -0
  320. package/dist/testing/integration.d.ts.map +1 -0
  321. package/dist/testing/integration.js +1139 -0
  322. package/dist/testing/integration_helpers.d.ts +107 -0
  323. package/dist/testing/integration_helpers.d.ts.map +1 -0
  324. package/dist/testing/integration_helpers.js +246 -0
  325. package/dist/testing/middleware.d.ts +125 -0
  326. package/dist/testing/middleware.d.ts.map +1 -0
  327. package/dist/testing/middleware.js +210 -0
  328. package/dist/testing/rate_limiting.d.ts +43 -0
  329. package/dist/testing/rate_limiting.d.ts.map +1 -0
  330. package/dist/testing/rate_limiting.js +216 -0
  331. package/dist/testing/round_trip.d.ts +37 -0
  332. package/dist/testing/round_trip.d.ts.map +1 -0
  333. package/dist/testing/round_trip.js +128 -0
  334. package/dist/testing/schema_generators.d.ts +33 -0
  335. package/dist/testing/schema_generators.d.ts.map +1 -0
  336. package/dist/testing/schema_generators.js +137 -0
  337. package/dist/testing/standard.d.ts +49 -0
  338. package/dist/testing/standard.d.ts.map +1 -0
  339. package/dist/testing/standard.js +16 -0
  340. package/dist/testing/stubs.d.ts +96 -0
  341. package/dist/testing/stubs.d.ts.map +1 -0
  342. package/dist/testing/stubs.js +192 -0
  343. package/dist/testing/surface_invariants.d.ts +189 -0
  344. package/dist/testing/surface_invariants.d.ts.map +1 -0
  345. package/dist/testing/surface_invariants.js +450 -0
  346. package/dist/ui/AccountSessions.svelte +75 -0
  347. package/dist/ui/AccountSessions.svelte.d.ts +19 -0
  348. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -0
  349. package/dist/ui/AdminAccounts.svelte +107 -0
  350. package/dist/ui/AdminAccounts.svelte.d.ts +19 -0
  351. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -0
  352. package/dist/ui/AdminAuditLog.svelte +144 -0
  353. package/dist/ui/AdminAuditLog.svelte.d.ts +4 -0
  354. package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -0
  355. package/dist/ui/AdminInvites.svelte +142 -0
  356. package/dist/ui/AdminInvites.svelte.d.ts +4 -0
  357. package/dist/ui/AdminInvites.svelte.d.ts.map +1 -0
  358. package/dist/ui/AdminOverview.svelte +337 -0
  359. package/dist/ui/AdminOverview.svelte.d.ts +4 -0
  360. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -0
  361. package/dist/ui/AdminPermitHistory.svelte +61 -0
  362. package/dist/ui/AdminPermitHistory.svelte.d.ts +19 -0
  363. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -0
  364. package/dist/ui/AdminSessions.svelte +85 -0
  365. package/dist/ui/AdminSessions.svelte.d.ts +19 -0
  366. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -0
  367. package/dist/ui/AdminSettings.svelte +32 -0
  368. package/dist/ui/AdminSettings.svelte.d.ts +19 -0
  369. package/dist/ui/AdminSettings.svelte.d.ts.map +1 -0
  370. package/dist/ui/AdminSurface.svelte +42 -0
  371. package/dist/ui/AdminSurface.svelte.d.ts +4 -0
  372. package/dist/ui/AdminSurface.svelte.d.ts.map +1 -0
  373. package/dist/ui/AppShell.svelte +93 -0
  374. package/dist/ui/AppShell.svelte.d.ts +20 -0
  375. package/dist/ui/AppShell.svelte.d.ts.map +1 -0
  376. package/dist/ui/BootstrapForm.svelte +105 -0
  377. package/dist/ui/BootstrapForm.svelte.d.ts +4 -0
  378. package/dist/ui/BootstrapForm.svelte.d.ts.map +1 -0
  379. package/dist/ui/ColumnLayout.svelte +46 -0
  380. package/dist/ui/ColumnLayout.svelte.d.ts +11 -0
  381. package/dist/ui/ColumnLayout.svelte.d.ts.map +1 -0
  382. package/dist/ui/ConfirmButton.svelte +125 -0
  383. package/dist/ui/ConfirmButton.svelte.d.ts +54 -0
  384. package/dist/ui/ConfirmButton.svelte.d.ts.map +1 -0
  385. package/dist/ui/Datatable.svelte +185 -0
  386. package/dist/ui/Datatable.svelte.d.ts +35 -0
  387. package/dist/ui/Datatable.svelte.d.ts.map +1 -0
  388. package/dist/ui/LoginForm.svelte +82 -0
  389. package/dist/ui/LoginForm.svelte.d.ts +8 -0
  390. package/dist/ui/LoginForm.svelte.d.ts.map +1 -0
  391. package/dist/ui/LogoutButton.svelte +36 -0
  392. package/dist/ui/LogoutButton.svelte.d.ts +10 -0
  393. package/dist/ui/LogoutButton.svelte.d.ts.map +1 -0
  394. package/dist/ui/MenuLink.svelte +35 -0
  395. package/dist/ui/MenuLink.svelte.d.ts +12 -0
  396. package/dist/ui/MenuLink.svelte.d.ts.map +1 -0
  397. package/dist/ui/OpenSignupToggle.svelte +36 -0
  398. package/dist/ui/OpenSignupToggle.svelte.d.ts +19 -0
  399. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -0
  400. package/dist/ui/PopoverButton.svelte +136 -0
  401. package/dist/ui/PopoverButton.svelte.d.ts +63 -0
  402. package/dist/ui/PopoverButton.svelte.d.ts.map +1 -0
  403. package/dist/ui/SignupForm.svelte +117 -0
  404. package/dist/ui/SignupForm.svelte.d.ts +7 -0
  405. package/dist/ui/SignupForm.svelte.d.ts.map +1 -0
  406. package/dist/ui/SurfaceExplorer.svelte +287 -0
  407. package/dist/ui/SurfaceExplorer.svelte.d.ts +8 -0
  408. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -0
  409. package/dist/ui/account_sessions_state.svelte.d.ts +15 -0
  410. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -0
  411. package/dist/ui/account_sessions_state.svelte.js +45 -0
  412. package/dist/ui/admin_accounts_state.svelte.d.ts +19 -0
  413. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -0
  414. package/dist/ui/admin_accounts_state.svelte.js +65 -0
  415. package/dist/ui/admin_invites_state.svelte.d.ts +19 -0
  416. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -0
  417. package/dist/ui/admin_invites_state.svelte.js +71 -0
  418. package/dist/ui/admin_sessions_state.svelte.d.ts +18 -0
  419. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -0
  420. package/dist/ui/admin_sessions_state.svelte.js +62 -0
  421. package/dist/ui/app_settings_state.svelte.d.ts +14 -0
  422. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -0
  423. package/dist/ui/app_settings_state.svelte.js +44 -0
  424. package/dist/ui/audit_log_state.svelte.d.ts +40 -0
  425. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -0
  426. package/dist/ui/audit_log_state.svelte.js +153 -0
  427. package/dist/ui/auth_state.svelte.d.ts +85 -0
  428. package/dist/ui/auth_state.svelte.d.ts.map +1 -0
  429. package/dist/ui/auth_state.svelte.js +238 -0
  430. package/dist/ui/datatable.d.ts +25 -0
  431. package/dist/ui/datatable.d.ts.map +1 -0
  432. package/dist/ui/datatable.js +9 -0
  433. package/dist/ui/enter_advance.d.ts +13 -0
  434. package/dist/ui/enter_advance.d.ts.map +1 -0
  435. package/dist/ui/enter_advance.js +30 -0
  436. package/dist/ui/loadable.svelte.d.ts +55 -0
  437. package/dist/ui/loadable.svelte.d.ts.map +1 -0
  438. package/dist/ui/loadable.svelte.js +75 -0
  439. package/dist/ui/popover.svelte.d.ts +137 -0
  440. package/dist/ui/popover.svelte.d.ts.map +1 -0
  441. package/dist/ui/popover.svelte.js +288 -0
  442. package/dist/ui/position_helpers.d.ts +27 -0
  443. package/dist/ui/position_helpers.d.ts.map +1 -0
  444. package/dist/ui/position_helpers.js +81 -0
  445. package/dist/ui/sidebar_state.svelte.d.ts +30 -0
  446. package/dist/ui/sidebar_state.svelte.d.ts.map +1 -0
  447. package/dist/ui/sidebar_state.svelte.js +39 -0
  448. package/dist/ui/table_state.svelte.d.ts +63 -0
  449. package/dist/ui/table_state.svelte.d.ts.map +1 -0
  450. package/dist/ui/table_state.svelte.js +117 -0
  451. package/dist/ui/ui_fetch.d.ts +29 -0
  452. package/dist/ui/ui_fetch.d.ts.map +1 -0
  453. package/dist/ui/ui_fetch.js +37 -0
  454. package/dist/ui/ui_format.d.ts +63 -0
  455. package/dist/ui/ui_format.d.ts.map +1 -0
  456. package/dist/ui/ui_format.js +196 -0
  457. package/package.json +121 -0
@@ -0,0 +1,240 @@
1
+ import './assert_dev_env.js';
2
+ import { z } from 'zod';
3
+ import { Logger } from '@fuzdev/fuz_util/log.js';
4
+ import { ROLE_KEEPER } from '../auth/role_schema.js';
5
+ import { create_validated_keyring } from '../auth/keyring.js';
6
+ import { generate_api_token } from '../auth/api_token.js';
7
+ import { query_create_account_with_actor } from '../auth/account_queries.js';
8
+ import { query_grant_permit } from '../auth/permit_queries.js';
9
+ import { generate_session_token, hash_session_token, AUTH_SESSION_LIFETIME_MS, query_create_session, } from '../auth/session_queries.js';
10
+ import { query_create_api_token } from '../auth/api_token_queries.js';
11
+ import { create_session_cookie_value } from '../auth/session_cookie.js';
12
+ import { run_migrations } from '../db/migrate.js';
13
+ import { AUTH_MIGRATION_NS } from '../auth/migrations.js';
14
+ import { create_app_server, } from '../server/app_server.js';
15
+ import { create_pglite_factory } from './db.js';
16
+ /* eslint-disable @typescript-eslint/require-await */
17
+ /**
18
+ * Fast password stub for tests that don't exercise login/password flows.
19
+ *
20
+ * Hashes are deterministic (`stub_hash_<password>`) and verify correctly,
21
+ * so auth bootstrap and session creation work without Argon2 overhead.
22
+ */
23
+ export const stub_password_deps = {
24
+ hash_password: async (p) => `stub_hash_${p}`,
25
+ verify_password: async (p, h) => h === `stub_hash_${p}`,
26
+ verify_dummy: async () => false,
27
+ };
28
+ /** 64-hex-char test cookie secret — deterministic, never used in production. */
29
+ export const TEST_COOKIE_SECRET = 'a'.repeat(64);
30
+ // Module-level PGlite factory for create_test_app_server when no db is provided.
31
+ // Shares the WASM instance cache from test_db.ts, avoiding redundant cold starts
32
+ // within the same vitest worker thread. Schema is reset on each create() call.
33
+ const fallback_pglite_factory = create_pglite_factory(async (db) => {
34
+ await run_migrations(db, [AUTH_MIGRATION_NS]);
35
+ });
36
+ /**
37
+ * Bootstrap a test account with credentials.
38
+ *
39
+ * Creates an account with actor, grants roles, creates an API token,
40
+ * creates a session, and signs a session cookie. Shared by
41
+ * `create_test_app_server` and `TestApp.create_account`.
42
+ */
43
+ export const bootstrap_test_account = async (options) => {
44
+ const { db, keyring, session_options, password, username = 'keeper', password_value = 'test-password-123', roles = [], } = options;
45
+ const deps = { db };
46
+ const password_hash = await password.hash_password(password_value);
47
+ const { account, actor } = await query_create_account_with_actor(deps, {
48
+ username,
49
+ password_hash,
50
+ });
51
+ // Grant roles
52
+ for (const role of roles) {
53
+ await query_grant_permit(deps, { actor_id: actor.id, role, granted_by: null }); // eslint-disable-line no-await-in-loop
54
+ }
55
+ // Create API token
56
+ const { token: api_token, id: token_id, token_hash } = generate_api_token();
57
+ await query_create_api_token(deps, token_id, account.id, 'test-cli', token_hash);
58
+ // Create session + cookie
59
+ const session_token = generate_session_token();
60
+ const session_hash = hash_session_token(session_token);
61
+ const expires_at = new Date(Date.now() + AUTH_SESSION_LIFETIME_MS);
62
+ await query_create_session(deps, session_hash, account.id, expires_at);
63
+ const session_cookie = await create_session_cookie_value(keyring, session_token, session_options);
64
+ return {
65
+ account: { id: account.id, username: account.username },
66
+ actor: { id: actor.id },
67
+ api_token,
68
+ session_cookie,
69
+ };
70
+ };
71
+ /**
72
+ * Create an app server with a bootstrapped account for testing.
73
+ *
74
+ * Sets up:
75
+ * - Auth tables (via cached PGlite factory, or reuses existing `db`)
76
+ * - A keeper account with hashed password
77
+ * - Role permits for each role in `options.roles`
78
+ * - An API token for Bearer auth
79
+ * - A session with a signed cookie value
80
+ *
81
+ * Uses `stub_password_deps` by default — deterministic hashing that works
82
+ * correctly for login/logout tests without Argon2 overhead.
83
+ *
84
+ * @param options - session options and optional overrides
85
+ * @returns a `TestAppServer` ready for HTTP testing
86
+ */
87
+ /** Silent logger for tests — suppresses all output. */
88
+ const test_log = new Logger('test', { level: 'off' });
89
+ export const create_test_app_server = async (options) => {
90
+ const { session_options, db: existing_db, db_type = 'pglite-memory', password = stub_password_deps, username = 'keeper', password_value = 'test-password-123', roles = [ROLE_KEEPER], } = options;
91
+ // Keyring from test secret
92
+ const keyring_result = create_validated_keyring(TEST_COOKIE_SECRET);
93
+ if (!keyring_result.ok) {
94
+ throw new Error(`Test keyring failed: ${keyring_result.errors.join(', ')}`);
95
+ }
96
+ const fs_stubs = {
97
+ stat: async () => null,
98
+ read_file: async () => '',
99
+ delete_file: async (_path) => { }, // eslint-disable-line @typescript-eslint/no-empty-function
100
+ };
101
+ let backend;
102
+ if (existing_db) {
103
+ // Reset singleton config rows that may retain state from a previous test.
104
+ // Harmless for fresh pglite (these are already at defaults).
105
+ await existing_db.query('UPDATE bootstrap_lock SET bootstrapped = false WHERE bootstrapped = true');
106
+ await existing_db.query('UPDATE app_settings SET open_signup = false, updated_at = NULL, updated_by = NULL WHERE open_signup = true OR updated_at IS NOT NULL');
107
+ // Use the caller's database — tables already created by the factory's init_schema.
108
+ // Caller owns the DB lifecycle — close is a no-op.
109
+ backend = {
110
+ db_type,
111
+ db_name: 'test',
112
+ migration_results: [], // migrations ran in the factory's init_schema, results not captured
113
+ close: async () => { }, // eslint-disable-line @typescript-eslint/no-empty-function
114
+ deps: {
115
+ keyring: keyring_result.keyring,
116
+ password,
117
+ db: existing_db,
118
+ log: test_log,
119
+ on_audit_event: () => { }, // eslint-disable-line @typescript-eslint/no-empty-function
120
+ ...fs_stubs,
121
+ },
122
+ };
123
+ }
124
+ else {
125
+ // In-memory PGlite via cached factory — reuses the WASM instance from test_db.ts
126
+ // instead of creating a new PGlite each time. Schema is reset and migrations re-run
127
+ // on each call, but the expensive WASM cold start only happens once per worker thread.
128
+ const db = await fallback_pglite_factory.create();
129
+ backend = {
130
+ db_type: 'pglite-memory',
131
+ db_name: '(memory)',
132
+ migration_results: [],
133
+ close: async () => { }, // eslint-disable-line @typescript-eslint/no-empty-function
134
+ deps: {
135
+ keyring: keyring_result.keyring,
136
+ password,
137
+ db,
138
+ log: test_log,
139
+ on_audit_event: () => { }, // eslint-disable-line @typescript-eslint/no-empty-function
140
+ ...fs_stubs,
141
+ },
142
+ };
143
+ }
144
+ const bootstrapped = await bootstrap_test_account({
145
+ db: backend.deps.db,
146
+ keyring: keyring_result.keyring,
147
+ session_options,
148
+ password,
149
+ username,
150
+ password_value,
151
+ roles,
152
+ });
153
+ return {
154
+ ...backend,
155
+ ...bootstrapped,
156
+ keyring: keyring_result.keyring,
157
+ cleanup: () => backend.close(),
158
+ };
159
+ };
160
+ /**
161
+ * Create a fully assembled test app with a Hono server, middleware, and routes.
162
+ *
163
+ * Combines `create_test_app_server` + `create_app_server` into a single call.
164
+ * Disables rate limiters and logging by default (test-friendly).
165
+ *
166
+ * A fresh Hono app is created each call — middleware closures bind to the
167
+ * server's deps (db, keyring), so reuse across servers is unsafe.
168
+ * The expensive resource (PGlite WASM) is cached separately in `test_db.ts`.
169
+ *
170
+ * @param options - test app configuration
171
+ * @returns a `TestApp` ready for HTTP testing
172
+ */
173
+ export const create_test_app = async (options) => {
174
+ const test_server = await create_test_app_server(options);
175
+ const result = await create_app_server({
176
+ backend: test_server,
177
+ session_options: options.session_options,
178
+ allowed_origins: [/^http:\/\/localhost/],
179
+ proxy: { trusted_proxies: ['127.0.0.1'], get_connection_ip: () => '127.0.0.1' },
180
+ env_schema: z.object({}),
181
+ ip_rate_limiter: null,
182
+ login_account_rate_limiter: null,
183
+ signup_account_rate_limiter: null,
184
+ bearer_ip_rate_limiter: null,
185
+ await_pending_effects: true,
186
+ ...options.app_options,
187
+ create_route_specs: options.create_route_specs,
188
+ });
189
+ const { app, surface_spec } = result;
190
+ const { cookie_name } = options.session_options;
191
+ const { password = stub_password_deps } = options;
192
+ const create_session_headers = (extra) => ({
193
+ host: 'localhost',
194
+ origin: 'http://localhost:5173',
195
+ cookie: `${cookie_name}=${test_server.session_cookie}`,
196
+ ...extra,
197
+ });
198
+ const create_bearer_headers = (extra) => ({
199
+ host: 'localhost',
200
+ authorization: `Bearer ${test_server.api_token}`,
201
+ ...extra,
202
+ });
203
+ let account_counter = 0;
204
+ const create_account = async (account_options) => {
205
+ account_counter++;
206
+ const bootstrapped = await bootstrap_test_account({
207
+ db: test_server.deps.db,
208
+ keyring: test_server.keyring,
209
+ session_options: options.session_options,
210
+ password,
211
+ username: account_options?.username ?? `test_user_${account_counter}`,
212
+ password_value: account_options?.password_value ?? 'test-password-123',
213
+ roles: account_options?.roles ?? [],
214
+ });
215
+ return {
216
+ ...bootstrapped,
217
+ create_session_headers: (extra) => ({
218
+ host: 'localhost',
219
+ origin: 'http://localhost:5173',
220
+ cookie: `${cookie_name}=${bootstrapped.session_cookie}`,
221
+ ...extra,
222
+ }),
223
+ create_bearer_headers: (extra) => ({
224
+ host: 'localhost',
225
+ authorization: `Bearer ${bootstrapped.api_token}`,
226
+ ...extra,
227
+ }),
228
+ };
229
+ };
230
+ return {
231
+ app,
232
+ backend: test_server,
233
+ surface: surface_spec.surface,
234
+ route_specs: surface_spec.route_specs,
235
+ create_session_headers,
236
+ create_bearer_headers,
237
+ create_account,
238
+ cleanup: () => test_server.cleanup(),
239
+ };
240
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Asserts that testing utilities are only imported in development environments.
3
+ *
4
+ * Each testing module imports this as a side effect to prevent accidental
5
+ * inclusion in production bundles. Uses `esm-env` which is set correctly
6
+ * by SvelteKit and Vite build tools — `DEV` is `true` during development
7
+ * and testing, `false` in production builds.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=assert_dev_env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert_dev_env.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/assert_dev_env.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Asserts that testing utilities are only imported in development environments.
3
+ *
4
+ * Each testing module imports this as a side effect to prevent accidental
5
+ * inclusion in production bundles. Uses `esm-env` which is set correctly
6
+ * by SvelteKit and Vite build tools — `DEV` is `true` during development
7
+ * and testing, `false` in production builds.
8
+ */
9
+ import { DEV } from 'esm-env';
10
+ if (!DEV) {
11
+ throw new Error('fuz_app testing utilities must not be imported in production. ' +
12
+ 'These modules are intended for use in test files only.');
13
+ }
@@ -0,0 +1,61 @@
1
+ import './assert_dev_env.js';
2
+ import type { z } from 'zod';
3
+ import type { AppSurface, AppSurfaceRoute } from '../http/surface.js';
4
+ import type { RouteErrorSchemas } from '../http/error_schemas.js';
5
+ /**
6
+ * Resolve an absolute path relative to the caller's module.
7
+ *
8
+ * @param filename - the filename to resolve
9
+ * @param import_meta_url - the caller's `import.meta.url`
10
+ * @returns absolute path
11
+ */
12
+ export declare const resolve_fixture_path: (filename: string, import_meta_url: string) => string;
13
+ /**
14
+ * Compare live surface against a committed snapshot JSON file.
15
+ *
16
+ * @param surface - the live surface to check
17
+ * @param snapshot_path - absolute path to the committed JSON snapshot
18
+ */
19
+ export declare const assert_surface_matches_snapshot: (surface: AppSurface, snapshot_path: string) => void;
20
+ /**
21
+ * Verify surface generation is deterministic (build twice, compare).
22
+ *
23
+ * @param build_surface - function that builds the surface
24
+ */
25
+ export declare const assert_surface_deterministic: (build_surface: () => AppSurface) => void;
26
+ /**
27
+ * Bidirectional check: no unexpected public routes, no missing expected ones.
28
+ *
29
+ * @param surface - the app surface to check
30
+ * @param expected_public - format: `['GET /health', 'POST /api/account/login']`
31
+ */
32
+ export declare const assert_only_expected_public_routes: (surface: AppSurface, expected_public: Array<string>) => void;
33
+ /**
34
+ * Verify every route under a path prefix has the exact expected middleware stack.
35
+ *
36
+ * @param surface - the app surface to check
37
+ * @param path_prefix - prefix to filter routes (e.g. `'/api/'`)
38
+ * @param expected_middleware - the exact middleware names in order
39
+ */
40
+ /**
41
+ * Look up the merged error schema for a route+status from a pre-built schema lookup.
42
+ *
43
+ * @param lookup - map from `"METHOD /path"` to merged error schemas
44
+ * @param route - the surface route to look up
45
+ * @param status - HTTP status code
46
+ */
47
+ export declare const get_route_error_schema: (lookup: Map<string, RouteErrorSchemas>, route: AppSurfaceRoute, status: number) => z.ZodType | undefined;
48
+ /**
49
+ * Assert that an error schema exists for a route+status and validate the body against it.
50
+ *
51
+ * Protected routes should always have auto-derived error schemas (401 for authenticated,
52
+ * 403 for role-restricted). A missing schema indicates a gap in error schema derivation.
53
+ *
54
+ * @param lookup - map from `"METHOD /path"` to merged error schemas
55
+ * @param route - the surface route to validate against
56
+ * @param status - expected HTTP status code
57
+ * @param body - the parsed response body to validate
58
+ */
59
+ export declare const assert_error_schema_valid: (lookup: Map<string, RouteErrorSchemas>, route: AppSurfaceRoute, status: number, body: unknown) => void;
60
+ export declare const assert_full_middleware_stack: (surface: AppSurface, path_prefix: string, expected_middleware: Array<string>) => void;
61
+ //# sourceMappingURL=assertions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/assertions.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAe7B,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,UAAU,MAAM,EAAE,iBAAiB,MAAM,KAAG,MACtB,CAAC;AAE5D;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,GAC3C,SAAS,UAAU,EACnB,eAAe,MAAM,KACnB,IAOF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GAAI,eAAe,MAAM,UAAU,KAAG,IAE9E,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAC9C,SAAS,UAAU,EACnB,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAC5B,IAWF,CAAC;AAEF;;;;;;GAMG;AACH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAClC,QAAQ,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACtC,OAAO,eAAe,EACtB,QAAQ,MAAM,KACZ,CAAC,CAAC,OAAO,GAAG,SAGd,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,GACrC,QAAQ,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACtC,OAAO,eAAe,EACtB,QAAQ,MAAM,EACd,MAAM,OAAO,KACX,IAIF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACxC,SAAS,UAAU,EACnB,aAAa,MAAM,EACnB,qBAAqB,KAAK,CAAC,MAAM,CAAC,KAChC,IAUF,CAAC"}
@@ -0,0 +1,96 @@
1
+ import './assert_dev_env.js';
2
+ /**
3
+ * Assertion helpers for auth attack surface testing.
4
+ *
5
+ * Plain functions called inside explicit `test()` blocks to verify
6
+ * surface snapshots, public routes, and middleware stacks.
7
+ *
8
+ * @module
9
+ */
10
+ import { readFileSync } from 'node:fs';
11
+ import { resolve, dirname } from 'node:path';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { assert } from 'vitest';
14
+ /**
15
+ * Resolve an absolute path relative to the caller's module.
16
+ *
17
+ * @param filename - the filename to resolve
18
+ * @param import_meta_url - the caller's `import.meta.url`
19
+ * @returns absolute path
20
+ */
21
+ export const resolve_fixture_path = (filename, import_meta_url) => resolve(dirname(fileURLToPath(import_meta_url)), filename);
22
+ /**
23
+ * Compare live surface against a committed snapshot JSON file.
24
+ *
25
+ * @param surface - the live surface to check
26
+ * @param snapshot_path - absolute path to the committed JSON snapshot
27
+ */
28
+ export const assert_surface_matches_snapshot = (surface, snapshot_path) => {
29
+ const committed = JSON.parse(readFileSync(snapshot_path, 'utf-8'));
30
+ assert.deepStrictEqual(surface, committed, 'Attack surface changed! Run `gro gen` to update the snapshot, then review the diff.');
31
+ };
32
+ /**
33
+ * Verify surface generation is deterministic (build twice, compare).
34
+ *
35
+ * @param build_surface - function that builds the surface
36
+ */
37
+ export const assert_surface_deterministic = (build_surface) => {
38
+ assert.deepStrictEqual(build_surface(), build_surface());
39
+ };
40
+ /**
41
+ * Bidirectional check: no unexpected public routes, no missing expected ones.
42
+ *
43
+ * @param surface - the app surface to check
44
+ * @param expected_public - format: `['GET /health', 'POST /api/account/login']`
45
+ */
46
+ export const assert_only_expected_public_routes = (surface, expected_public) => {
47
+ const expected = new Set(expected_public);
48
+ const actual_public = surface.routes
49
+ .filter((r) => r.auth.type === 'none')
50
+ .map((r) => `${r.method} ${r.path}`);
51
+ const unexpected = actual_public.filter((r) => !expected.has(r));
52
+ const missing = expected_public.filter((r) => !actual_public.includes(r));
53
+ assert.strictEqual(unexpected.length, 0, `Unexpected public routes: ${unexpected.join(', ')}`);
54
+ assert.strictEqual(missing.length, 0, `Expected public routes missing: ${missing.join(', ')}`);
55
+ };
56
+ /**
57
+ * Verify every route under a path prefix has the exact expected middleware stack.
58
+ *
59
+ * @param surface - the app surface to check
60
+ * @param path_prefix - prefix to filter routes (e.g. `'/api/'`)
61
+ * @param expected_middleware - the exact middleware names in order
62
+ */
63
+ /**
64
+ * Look up the merged error schema for a route+status from a pre-built schema lookup.
65
+ *
66
+ * @param lookup - map from `"METHOD /path"` to merged error schemas
67
+ * @param route - the surface route to look up
68
+ * @param status - HTTP status code
69
+ */
70
+ export const get_route_error_schema = (lookup, route, status) => {
71
+ const key = `${route.method} ${route.path}`;
72
+ return lookup.get(key)?.[status];
73
+ };
74
+ /**
75
+ * Assert that an error schema exists for a route+status and validate the body against it.
76
+ *
77
+ * Protected routes should always have auto-derived error schemas (401 for authenticated,
78
+ * 403 for role-restricted). A missing schema indicates a gap in error schema derivation.
79
+ *
80
+ * @param lookup - map from `"METHOD /path"` to merged error schemas
81
+ * @param route - the surface route to validate against
82
+ * @param status - expected HTTP status code
83
+ * @param body - the parsed response body to validate
84
+ */
85
+ export const assert_error_schema_valid = (lookup, route, status, body) => {
86
+ const schema = get_route_error_schema(lookup, route, status);
87
+ assert.ok(schema, `missing error schema for ${status} on ${route.method} ${route.path}`);
88
+ schema.parse(body);
89
+ };
90
+ export const assert_full_middleware_stack = (surface, path_prefix, expected_middleware) => {
91
+ const routes = surface.routes.filter((r) => r.path.startsWith(path_prefix));
92
+ assert.ok(routes.length > 0, `No routes found under ${path_prefix}`);
93
+ for (const route of routes) {
94
+ assert.deepStrictEqual(route.applicable_middleware, expected_middleware, `${route.method} ${route.path} has wrong middleware stack`);
95
+ }
96
+ };
@@ -0,0 +1,63 @@
1
+ import './assert_dev_env.js';
2
+ import { type SurfaceSecurityPolicyOptions, type ErrorSchemaTightnessOptions } from './surface_invariants.js';
3
+ import { type AppSurfaceSpec } from '../http/surface.js';
4
+ /** Options for adversarial test runners (auth enforcement and input validation). */
5
+ export interface AdversarialTestOptions {
6
+ /** Build the app surface bundle (surface + route specs + middleware specs). */
7
+ build: () => AppSurfaceSpec;
8
+ /** All roles in the app (e.g. `['admin', 'keeper']`). */
9
+ roles: Array<string>;
10
+ }
11
+ /**
12
+ * Generate adversarial HTTP auth enforcement test suites.
13
+ *
14
+ * Describe blocks:
15
+ * - unauthenticated → 401 — every protected route
16
+ * - wrong role → 403 — every role route, tested with all non-matching roles
17
+ * - authenticated without role → 403 — every role route, no-role context
18
+ * - correct auth passes guard — every protected route, assert not 401/403
19
+ *
20
+ * @param options - the test configuration
21
+ */
22
+ export declare const describe_adversarial_auth: (options: AdversarialTestOptions) => void;
23
+ /** Options for the standard attack surface test suite. */
24
+ export interface StandardAttackSurfaceOptions {
25
+ /** Build the app surface bundle (surface + route specs + middleware specs). */
26
+ build: () => AppSurfaceSpec;
27
+ /** Absolute path to the committed snapshot JSON file. */
28
+ snapshot_path: string;
29
+ /** Expected public routes, e.g. `['GET /health', 'POST /api/account/login']`. */
30
+ expected_public_routes: Array<string>;
31
+ /** Expected middleware names for API routes, e.g. `['origin', 'session', 'request_context', 'bearer_auth']`. */
32
+ expected_api_middleware: Array<string>;
33
+ /** All roles in the app (e.g. `['admin', 'keeper']`). */
34
+ roles: Array<string>;
35
+ /** Path prefix for middleware stack assertion. Default `'/api/'`. */
36
+ api_path_prefix?: string;
37
+ /** Security policy configuration. Omit for sensible defaults. */
38
+ security_policy?: SurfaceSecurityPolicyOptions;
39
+ /** Error schema tightness assertion. Omit for informational-only behavior. */
40
+ error_schema_tightness?: ErrorSchemaTightnessOptions;
41
+ }
42
+ /**
43
+ * Run the standard attack surface test suite.
44
+ *
45
+ * Generates 10 test groups:
46
+ * 1. Snapshot — live surface matches committed JSON
47
+ * 2. Determinism — building twice yields identical results
48
+ * 3. Public routes — bidirectional check (no unexpected, no missing)
49
+ * 4. Middleware stack — every API route has the full middleware chain
50
+ * 5. Surface invariants — structural assertions (error schemas, descriptions, duplicates, consistency)
51
+ * 6. Security policy — rate limiting on sensitive routes, no unexpected public mutations, method conventions
52
+ * 7. Error schema tightness audit — informational log of generic vs specific error schemas
53
+ * 8. Adversarial auth — unauthenticated/wrong-role/correct-auth enforcement
54
+ * 9. Adversarial input — input body and params validation
55
+ * 10. Adversarial 404 — stub 404 handlers, validate response bodies against declared schemas
56
+ *
57
+ * Consumer test files call this with project-specific options, then add
58
+ * any project-specific assertions in additional `describe` blocks.
59
+ *
60
+ * @param options - the test configuration
61
+ */
62
+ export declare const describe_standard_attack_surface_tests: (options: StandardAttackSurfaceOptions) => void;
63
+ //# sourceMappingURL=attack_surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,EAKN,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAoBjC,OAAO,EAA4B,KAAK,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAsClF,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,sBAAsB,KAAG,IAkH3E,CAAC;AAIF,0DAA0D;AAC1D,MAAM,WAAW,4BAA4B;IAC5C,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,gHAAgH;IAChH,uBAAuB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,eAAe,CAAC,EAAE,4BAA4B,CAAC;IAC/C,8EAA8E;IAC9E,sBAAsB,CAAC,EAAE,2BAA2B,CAAC;CACrD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,sCAAsC,GAClD,SAAS,4BAA4B,KACnC,IAoEF,CAAC"}