okengine 0.2.6 → 0.3.2

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 (681) hide show
  1. package/AGENTS.md +33 -30
  2. package/README.md +74 -340
  3. package/{spec/manifest.v1.schema.json → manifest.v1.schema.json} +40 -9
  4. package/package.json +47 -44
  5. package/site/content/docs/ai/llms-txt.mdx +54 -0
  6. package/site/content/docs/ai/mcp.mdx +123 -0
  7. package/site/content/docs/ai/meta.json +5 -0
  8. package/site/content/docs/ai/skills.mdx +53 -0
  9. package/site/content/docs/console/access.mdx +29 -0
  10. package/site/content/docs/console/ai.mdx +35 -0
  11. package/site/content/docs/console/architecture.mdx +35 -0
  12. package/site/content/docs/console/channels.mdx +37 -0
  13. package/site/content/docs/console/clock.mdx +31 -0
  14. package/site/content/docs/console/flows.mdx +31 -0
  15. package/site/content/docs/console/gates.mdx +35 -0
  16. package/site/content/docs/console/manifest-diff.mdx +34 -0
  17. package/site/content/docs/console/meta.json +23 -0
  18. package/site/content/docs/console/overview.mdx +40 -0
  19. package/site/content/docs/console/plugins.mdx +41 -0
  20. package/site/content/docs/console/privacy.mdx +32 -0
  21. package/site/content/docs/console/runs.mdx +40 -0
  22. package/site/content/docs/console/signals.mdx +31 -0
  23. package/site/content/docs/console/store.mdx +32 -0
  24. package/site/content/docs/console/tenancy.mdx +32 -0
  25. package/site/content/docs/console/traces.mdx +34 -0
  26. package/site/content/docs/console/vault.mdx +37 -0
  27. package/site/content/docs/elements/ai.mdx +180 -0
  28. package/site/content/docs/elements/channel.mdx +167 -0
  29. package/site/content/docs/elements/clock.mdx +182 -0
  30. package/site/content/docs/elements/flow.mdx +288 -0
  31. package/site/content/docs/elements/gate.mdx +171 -0
  32. package/site/content/docs/elements/meta.json +5 -0
  33. package/site/content/docs/elements/signal.mdx +171 -0
  34. package/site/content/docs/elements/store.mdx +320 -0
  35. package/site/content/docs/elements/vault.mdx +263 -0
  36. package/site/content/docs/get-started/basic-usage.mdx +124 -0
  37. package/site/content/docs/get-started/comparison.mdx +65 -0
  38. package/site/content/docs/get-started/installation.mdx +113 -0
  39. package/site/content/docs/get-started/introduction.mdx +123 -0
  40. package/site/content/docs/get-started/meta.json +5 -0
  41. package/site/content/docs/index.mdx +63 -0
  42. package/site/content/docs/meta.json +5 -0
  43. package/site/content/docs/plugins/compression.mdx +60 -0
  44. package/site/content/docs/plugins/cors.mdx +92 -0
  45. package/site/content/docs/plugins/csrf.mdx +96 -0
  46. package/site/content/docs/plugins/ip-allowlist.mdx +92 -0
  47. package/site/content/docs/plugins/maintenance-mode.mdx +101 -0
  48. package/site/content/docs/plugins/meta.json +15 -0
  49. package/site/content/docs/plugins/security-headers.mdx +136 -0
  50. package/site/content/docs/reference/cli.md +101 -0
  51. package/site/content/docs/reference/configuration.mdx +159 -0
  52. package/site/content/docs/reference/environment-variables.mdx +87 -0
  53. package/site/content/docs/reference/errors.mdx +80 -0
  54. package/site/content/docs/reference/fx.mdx +117 -0
  55. package/site/content/docs/reference/meta.json +5 -0
  56. package/site/content/docs/reference/plugins.mdx +249 -0
  57. package/site/content/docs/reference/security.md +63 -0
  58. package/src/auth/api-keys.ts +2 -5
  59. package/src/auth/attenuation.ts +2 -6
  60. package/src/auth/auth.test.ts +56 -31
  61. package/src/auth/invoke-as.ts +1 -3
  62. package/src/auth/operator.ts +8 -26
  63. package/src/auth/planes.ts +2 -7
  64. package/src/auth/plugin.ts +4 -7
  65. package/src/auth/roles.ts +1 -5
  66. package/src/auth/sessions.ts +10 -39
  67. package/src/cli/args.ts +1 -5
  68. package/src/cli/ask-dev-mode.ts +40 -0
  69. package/src/cli/build.ts +1 -2
  70. package/src/cli/client-add.test.ts +8 -15
  71. package/src/cli/client-add.ts +5 -14
  72. package/src/cli/completion.test.ts +1 -5
  73. package/src/cli/completion.ts +4 -17
  74. package/src/cli/db-auto-push.test.ts +64 -0
  75. package/src/cli/db-auto-push.ts +72 -0
  76. package/src/cli/db.test.ts +189 -0
  77. package/src/cli/db.ts +456 -0
  78. package/src/cli/dev-app-runner.ts +2 -8
  79. package/src/cli/dev-db-push.test.ts +193 -0
  80. package/src/cli/dev-mode.test.ts +45 -0
  81. package/src/cli/dev-mode.ts +78 -0
  82. package/src/cli/dev-schema-sync.test.ts +66 -0
  83. package/src/cli/dev-schema-sync.ts +139 -0
  84. package/src/cli/dev.test.ts +264 -15
  85. package/src/cli/dev.ts +355 -139
  86. package/src/cli/doc-staleness.test.ts +69 -0
  87. package/src/cli/docker-cli.test.ts +27 -8
  88. package/src/cli/docker.ts +11 -3
  89. package/src/cli/doctor-diff.test.ts +1 -5
  90. package/src/cli/doctor-diff.ts +17 -46
  91. package/src/cli/doctor-pii.ts +2 -7
  92. package/src/cli/doctor.test.ts +26 -4
  93. package/src/cli/doctor.ts +35 -11
  94. package/src/cli/drizzle-env.test.ts +67 -0
  95. package/src/cli/drizzle-env.ts +78 -0
  96. package/src/cli/ensure-drizzle-config.ts +50 -0
  97. package/src/cli/eval.ts +4 -14
  98. package/src/cli/gates-list.ts +1 -4
  99. package/src/cli/hero-meta.test.ts +17 -19
  100. package/src/cli/hero-meta.ts +20 -30
  101. package/src/cli/images.ts +3 -8
  102. package/src/cli/index.ts +11 -2
  103. package/src/cli/load-config.images.test.ts +14 -14
  104. package/src/cli/load-config.ts +47 -47
  105. package/src/cli/mcp-from-console.ts +1 -4
  106. package/src/cli/mode.ts +65 -0
  107. package/src/cli/openbao-bootstrap.test.ts +147 -0
  108. package/src/cli/openbao-bootstrap.ts +280 -0
  109. package/src/cli/openbao-restart.integration.test.ts +136 -0
  110. package/src/cli/ports.test.ts +7 -14
  111. package/src/cli/ports.ts +7 -5
  112. package/src/cli/privacy-erase.ts +1 -3
  113. package/src/cli/registry.ts +75 -25
  114. package/src/cli/resolve-dev-sql-env.test.ts +48 -0
  115. package/src/cli/resolve-dev-sql-env.ts +42 -0
  116. package/src/cli/schema.ts +3 -10
  117. package/src/cli/stack.ts +8 -10
  118. package/src/cli/start.ts +4 -15
  119. package/src/cli/upgrade.ts +1 -4
  120. package/src/cli/vault-cmd.ts +63 -0
  121. package/src/client/budget-entry.ts +1 -6
  122. package/src/client/create.test.ts +6 -12
  123. package/src/client/create.ts +2 -8
  124. package/src/client/errors.ts +1 -4
  125. package/src/client/index.ts +1 -6
  126. package/src/client/notes-contract.test.ts +4 -13
  127. package/src/client/transport.ts +9 -30
  128. package/src/client/types.ts +15 -30
  129. package/src/compiler/aot.test.ts +2 -9
  130. package/src/compiler/aot.ts +1 -4
  131. package/src/compiler/differential.test.ts +3 -11
  132. package/src/compiler/dynamic.ts +1 -4
  133. package/src/compiler/effects-infer.ts +8 -34
  134. package/src/compiler/emit.ts +1 -3
  135. package/src/compiler/extract.test.ts +136 -30
  136. package/src/compiler/extract.ts +485 -157
  137. package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
  138. package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
  139. package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
  140. package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
  141. package/src/compiler/fixtures/skyport.expected.json +24 -83
  142. package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
  143. package/src/compiler/http-parse.ts +2 -9
  144. package/src/compiler/index.ts +1 -5
  145. package/src/compiler/response.ts +16 -7
  146. package/src/compiler/sucrose.ts +11 -31
  147. package/src/config/define-config.test.ts +55 -34
  148. package/src/config/index.ts +177 -46
  149. package/src/config/resolve-driver.test.ts +28 -17
  150. package/src/console/budget.test.ts +1 -4
  151. package/src/console/index.ts +1 -4
  152. package/src/console/server/access.test.ts +15 -43
  153. package/src/console/server/access.ts +19 -49
  154. package/src/console/server/ai.test.ts +3 -11
  155. package/src/console/server/ai.ts +23 -46
  156. package/src/console/server/app.ts +16 -45
  157. package/src/console/server/auth-rate.test.ts +4 -12
  158. package/src/console/server/bind.ts +1 -5
  159. package/src/console/server/channels.test.ts +2 -6
  160. package/src/console/server/channels.ts +10 -35
  161. package/src/console/server/claim.ts +2 -8
  162. package/src/console/server/clock.test.ts +2 -6
  163. package/src/console/server/clock.ts +8 -26
  164. package/src/console/server/console.test.ts +1 -3
  165. package/src/console/server/diff.test.ts +5 -17
  166. package/src/console/server/diff.ts +10 -31
  167. package/src/console/server/dry-run.audit.test.ts +2 -8
  168. package/src/console/server/flows.ts +64 -233
  169. package/src/console/server/gates.test.ts +14 -50
  170. package/src/console/server/gates.ts +13 -48
  171. package/src/console/server/index.ts +2 -9
  172. package/src/console/server/live.ts +3 -12
  173. package/src/console/server/operator-db.test.ts +4 -15
  174. package/src/console/server/operator-db.ts +13 -32
  175. package/src/console/server/plugin.ts +50 -53
  176. package/src/console/server/plugins.test.ts +2 -6
  177. package/src/console/server/plugins.ts +17 -56
  178. package/src/console/server/runs-pii.ts +2 -7
  179. package/src/console/server/security.gate.test.ts +18 -40
  180. package/src/console/server/serve.ts +10 -25
  181. package/src/console/server/signals.test.ts +1 -3
  182. package/src/console/server/signals.ts +17 -40
  183. package/src/console/server/state.ts +21 -59
  184. package/src/console/server/store.test.ts +20 -22
  185. package/src/console/server/store.ts +31 -76
  186. package/src/console/server/vault.test.ts +12 -29
  187. package/src/console/server/vault.ts +44 -66
  188. package/src/console/ui/access/AccessA11yView.tsx +6 -21
  189. package/src/console/ui/access/a11y.test.tsx +3 -12
  190. package/src/console/ui/access/acknowledgement.test.ts +1 -4
  191. package/src/console/ui/access/acknowledgement.ts +1 -3
  192. package/src/console/ui/access/blast-radius.ts +1 -3
  193. package/src/console/ui/access/confirmation.test.ts +1 -5
  194. package/src/console/ui/access/confirmation.ts +1 -4
  195. package/src/console/ui/access/fixture.ts +1 -5
  196. package/src/console/ui/access/grantable.test.ts +1 -3
  197. package/src/console/ui/access/grantable.ts +2 -7
  198. package/src/console/ui/access/index.ts +2 -9
  199. package/src/console/ui/access/provenance.test.ts +1 -3
  200. package/src/console/ui/access/provenance.ts +2 -6
  201. package/src/console/ui/access/search.test.ts +1 -5
  202. package/src/console/ui/access/search.ts +2 -6
  203. package/src/console/ui/ai/AiA11yView.tsx +6 -17
  204. package/src/console/ui/ai/a11y.test.tsx +2 -5
  205. package/src/console/ui/ai/fixture.ts +2 -7
  206. package/src/console/ui/ai/format.ts +1 -3
  207. package/src/console/ui/ai/group.test.ts +1 -3
  208. package/src/console/ui/ai/group.ts +4 -12
  209. package/src/console/ui/ai/index.ts +2 -9
  210. package/src/console/ui/ai/promotion.test.ts +2 -7
  211. package/src/console/ui/ai/promotion.ts +4 -13
  212. package/src/console/ui/ai/search.test.ts +2 -11
  213. package/src/console/ui/ai/search.ts +3 -13
  214. package/src/console/ui/ai/types.ts +1 -8
  215. package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
  216. package/src/console/ui/architecture/a11y.test.tsx +1 -2
  217. package/src/console/ui/architecture/declared.ts +1 -5
  218. package/src/console/ui/architecture/index.ts +7 -35
  219. package/src/console/ui/architecture/layout.ts +1 -3
  220. package/src/console/ui/architecture/pathologies.ts +10 -19
  221. package/src/console/ui/architecture/search.ts +6 -15
  222. package/src/console/ui/architecture/traffic.ts +4 -14
  223. package/src/console/ui/architecture/types.ts +2 -10
  224. package/src/console/ui/architecture/view.test.ts +7 -19
  225. package/src/console/ui/architecture/view.ts +9 -36
  226. package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
  227. package/src/console/ui/channels/a11y.test.tsx +1 -2
  228. package/src/console/ui/channels/confirmation.test.ts +1 -4
  229. package/src/console/ui/channels/confirmation.ts +1 -4
  230. package/src/console/ui/channels/findings.ts +1 -5
  231. package/src/console/ui/channels/index.ts +2 -8
  232. package/src/console/ui/channels/locale.test.ts +1 -3
  233. package/src/console/ui/channels/locale.ts +2 -8
  234. package/src/console/ui/channels/search.ts +4 -13
  235. package/src/console/ui/channels/taxonomy.ts +1 -3
  236. package/src/console/ui/clock/ClockA11yView.tsx +9 -26
  237. package/src/console/ui/clock/a11y.test.tsx +2 -5
  238. package/src/console/ui/clock/confirmation.test.ts +1 -3
  239. package/src/console/ui/clock/confirmation.ts +1 -4
  240. package/src/console/ui/clock/findings.ts +1 -4
  241. package/src/console/ui/clock/health.ts +2 -7
  242. package/src/console/ui/clock/index.ts +2 -10
  243. package/src/console/ui/clock/search.test.ts +1 -3
  244. package/src/console/ui/clock/search.ts +2 -6
  245. package/src/console/ui/clock/timeline.test.ts +1 -3
  246. package/src/console/ui/clock/waiting-on.test.ts +1 -5
  247. package/src/console/ui/clock/waiting-on.ts +2 -7
  248. package/src/console/ui/diff/DiffA11yView.tsx +8 -17
  249. package/src/console/ui/diff/a11y.test.tsx +2 -5
  250. package/src/console/ui/diff/group.test.ts +3 -13
  251. package/src/console/ui/diff/group.ts +2 -8
  252. package/src/console/ui/diff/index.ts +2 -8
  253. package/src/console/ui/diff/search.test.ts +1 -5
  254. package/src/console/ui/diff/search.ts +4 -16
  255. package/src/console/ui/diff/summary.ts +1 -2
  256. package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
  257. package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
  258. package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
  259. package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
  260. package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
  261. package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
  262. package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
  263. package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
  264. package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
  265. package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
  266. package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
  267. package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
  268. package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
  269. package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
  270. package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
  271. package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
  272. package/src/console/ui/dist/index.html +1 -1
  273. package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
  274. package/src/console/ui/flows/a11y.test.tsx +2 -8
  275. package/src/console/ui/flows/buffer.test.ts +3 -11
  276. package/src/console/ui/flows/buffer.ts +4 -11
  277. package/src/console/ui/flows/confirmation.ts +1 -3
  278. package/src/console/ui/flows/contract.test.ts +3 -7
  279. package/src/console/ui/flows/contract.ts +12 -36
  280. package/src/console/ui/flows/graph.test.ts +3 -11
  281. package/src/console/ui/flows/graph.ts +5 -15
  282. package/src/console/ui/flows/index.ts +1 -6
  283. package/src/console/ui/flows/save-as-test.ts +1 -3
  284. package/src/console/ui/flows/search.ts +8 -25
  285. package/src/console/ui/flows/tiers.ts +2 -9
  286. package/src/console/ui/gates/GatesA11yView.tsx +4 -13
  287. package/src/console/ui/gates/a11y.test.tsx +2 -5
  288. package/src/console/ui/gates/audit.ts +1 -3
  289. package/src/console/ui/gates/denial.test.ts +1 -3
  290. package/src/console/ui/gates/denial.ts +4 -12
  291. package/src/console/ui/gates/findings.ts +1 -3
  292. package/src/console/ui/gates/group.test.ts +3 -3
  293. package/src/console/ui/gates/group.ts +3 -11
  294. package/src/console/ui/gates/index.ts +2 -10
  295. package/src/console/ui/gates/search.ts +3 -10
  296. package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
  297. package/src/console/ui/overview/a11y.test.tsx +1 -2
  298. package/src/console/ui/overview/busiest.ts +1 -3
  299. package/src/console/ui/overview/compose.ts +1 -13
  300. package/src/console/ui/overview/cost.ts +34 -38
  301. package/src/console/ui/overview/fixture.ts +21 -26
  302. package/src/console/ui/overview/golden.ts +4 -14
  303. package/src/console/ui/overview/index.ts +2 -9
  304. package/src/console/ui/overview/rank.test.ts +3 -10
  305. package/src/console/ui/overview/rank.ts +2 -7
  306. package/src/console/ui/overview/slo.test.ts +5 -9
  307. package/src/console/ui/overview/slo.ts +6 -23
  308. package/src/console/ui/overview/verdict.ts +3 -10
  309. package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
  310. package/src/console/ui/plugins/a11y.test.tsx +1 -2
  311. package/src/console/ui/plugins/fixture.ts +2 -4
  312. package/src/console/ui/plugins/group.test.ts +1 -3
  313. package/src/console/ui/plugins/group.ts +1 -6
  314. package/src/console/ui/plugins/index.ts +3 -13
  315. package/src/console/ui/plugins/search.ts +7 -19
  316. package/src/console/ui/runs/RunsA11yView.tsx +5 -20
  317. package/src/console/ui/runs/a11y.test.tsx +2 -5
  318. package/src/console/ui/runs/explain.ts +2 -6
  319. package/src/console/ui/runs/group.ts +3 -12
  320. package/src/console/ui/runs/histogram.test.ts +2 -11
  321. package/src/console/ui/runs/histogram.ts +1 -4
  322. package/src/console/ui/runs/index.ts +4 -18
  323. package/src/console/ui/runs/project.ts +2 -6
  324. package/src/console/ui/runs/query.test.ts +1 -3
  325. package/src/console/ui/runs/query.ts +12 -35
  326. package/src/console/ui/runs/search.ts +5 -19
  327. package/src/console/ui/runs/trace-link.test.ts +2 -6
  328. package/src/console/ui/runs/trace-link.ts +4 -16
  329. package/src/console/ui/runs/types.ts +1 -3
  330. package/src/console/ui/shell/App.tsx +2 -10
  331. package/src/console/ui/shell/client.ts +22 -115
  332. package/src/console/ui/shell/components/ui.tsx +1 -4
  333. package/src/console/ui/shell/layout/Shell.tsx +2 -4
  334. package/src/console/ui/shell/main.tsx +31 -96
  335. package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
  336. package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
  337. package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
  338. package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
  339. package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
  340. package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
  341. package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
  342. package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
  343. package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
  344. package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
  345. package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
  346. package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
  347. package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
  348. package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
  349. package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
  350. package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
  351. package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
  352. package/src/console/ui/shell/setup/Wizard.tsx +3 -5
  353. package/src/console/ui/shell/styles.css +1 -2
  354. package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
  355. package/src/console/ui/signals/a11y.test.tsx +2 -5
  356. package/src/console/ui/signals/confirmation.test.ts +1 -5
  357. package/src/console/ui/signals/confirmation.ts +2 -6
  358. package/src/console/ui/signals/dry-run.ts +1 -3
  359. package/src/console/ui/signals/durable.ts +1 -3
  360. package/src/console/ui/signals/findings.ts +1 -3
  361. package/src/console/ui/signals/group.test.ts +2 -8
  362. package/src/console/ui/signals/group.ts +2 -10
  363. package/src/console/ui/signals/index.ts +1 -4
  364. package/src/console/ui/signals/monitor.ts +2 -7
  365. package/src/console/ui/signals/schema-form.test.ts +3 -14
  366. package/src/console/ui/signals/schema-form.ts +1 -4
  367. package/src/console/ui/signals/search.ts +4 -13
  368. package/src/console/ui/store/StoreA11yView.tsx +3 -9
  369. package/src/console/ui/store/a11y.test.tsx +2 -5
  370. package/src/console/ui/store/confirmation.test.ts +1 -3
  371. package/src/console/ui/store/confirmation.ts +1 -4
  372. package/src/console/ui/store/dry-run.ts +2 -5
  373. package/src/console/ui/store/fixture.ts +1 -2
  374. package/src/console/ui/store/group.test.ts +1 -6
  375. package/src/console/ui/store/group.ts +1 -4
  376. package/src/console/ui/store/index.ts +1 -5
  377. package/src/console/ui/store/search.ts +2 -6
  378. package/src/console/ui/store/will-not-fire.ts +1 -2
  379. package/src/console/ui/traces/TracesA11yView.tsx +10 -29
  380. package/src/console/ui/traces/a11y.test.tsx +1 -2
  381. package/src/console/ui/traces/chain.test.ts +5 -19
  382. package/src/console/ui/traces/chain.ts +1 -3
  383. package/src/console/ui/traces/critical-path.test.ts +1 -3
  384. package/src/console/ui/traces/critical-path.ts +2 -6
  385. package/src/console/ui/traces/filter.test.ts +2 -6
  386. package/src/console/ui/traces/filter.ts +5 -13
  387. package/src/console/ui/traces/fold.test.ts +4 -12
  388. package/src/console/ui/traces/fold.ts +1 -3
  389. package/src/console/ui/traces/mini.ts +1 -3
  390. package/src/console/ui/traces/replay.test.ts +1 -3
  391. package/src/console/ui/traces/replay.ts +1 -3
  392. package/src/console/ui/traces/sampling.ts +1 -4
  393. package/src/console/ui/traces/search.ts +4 -17
  394. package/src/console/ui/traces/tier.ts +1 -3
  395. package/src/console/ui/vault/VaultA11yView.tsx +5 -17
  396. package/src/console/ui/vault/a11y.test.tsx +1 -2
  397. package/src/console/ui/vault/blast-radius.ts +1 -3
  398. package/src/console/ui/vault/confirmation.test.ts +1 -5
  399. package/src/console/ui/vault/confirmation.ts +1 -4
  400. package/src/console/ui/vault/dormant.test.ts +1 -4
  401. package/src/console/ui/vault/export-safe.test.ts +1 -5
  402. package/src/console/ui/vault/export-safe.ts +1 -4
  403. package/src/console/ui/vault/fixture.ts +3 -3
  404. package/src/console/ui/vault/group.ts +1 -2
  405. package/src/console/ui/vault/index.ts +2 -10
  406. package/src/console/ui/vault/search.ts +2 -6
  407. package/src/console/ui/vault/types.ts +1 -1
  408. package/src/console/xss.gate.test.ts +1 -3
  409. package/src/docker/compose.ts +215 -27
  410. package/src/docker/derive.ts +6 -14
  411. package/src/docker/docker.test.ts +118 -15
  412. package/src/docker/dockerfile.integration.test.ts +12 -21
  413. package/src/docker/helpers.ts +5 -4
  414. package/src/docker/index.ts +9 -6
  415. package/src/docker/pin.ts +1 -9
  416. package/src/docker/recipes/index.ts +6 -6
  417. package/src/docker/recipes/mailpit.ts +22 -0
  418. package/src/docker/recipes/openbao.ts +47 -0
  419. package/src/docker/recipes/postgres.ts +17 -6
  420. package/src/docker/recipes/redis.ts +11 -2
  421. package/src/docker/recipes/rustfs.ts +32 -0
  422. package/src/docker/stack-id.test.ts +73 -5
  423. package/src/docker/stack-id.ts +124 -33
  424. package/src/docker/stack.integration.test.ts +6 -21
  425. package/src/docker/stack.ts +36 -4
  426. package/src/docker/types.ts +16 -4
  427. package/src/docs-origin.ts +4 -4
  428. package/src/drivers/ai-anthropic.ts +5 -14
  429. package/src/drivers/ai-mock.ts +2 -5
  430. package/src/drivers/ai-openai-compatible.ts +4 -10
  431. package/src/drivers/ai-providers.test.ts +6 -13
  432. package/src/drivers/bun-native-completeness.test.ts +6 -15
  433. package/src/drivers/channel-console.ts +6 -7
  434. package/src/drivers/channel-fcm.ts +20 -30
  435. package/src/drivers/channel-resend.ts +1 -3
  436. package/src/drivers/channel-smtp.ts +2 -6
  437. package/src/drivers/channel-types.ts +2 -12
  438. package/src/drivers/channel-unifonic.ts +2 -6
  439. package/src/drivers/channel-wa-cloud.ts +2 -6
  440. package/src/drivers/channel-webpush.ts +21 -60
  441. package/src/drivers/conformance.test.ts +2 -10
  442. package/src/drivers/conformance.ts +8 -21
  443. package/src/drivers/drizzle-dialect.test.ts +20 -0
  444. package/src/drivers/drizzle-dialect.ts +37 -0
  445. package/src/drivers/fs.ts +2 -8
  446. package/src/drivers/index.ts +12 -57
  447. package/src/drivers/memory.ts +287 -75
  448. package/src/drivers/pgvector.ts +7 -11
  449. package/src/drivers/postgres.ts +7 -13
  450. package/src/drivers/redis.ts +13 -37
  451. package/src/drivers/s3.ts +15 -18
  452. package/src/drivers/signal-engine.ts +12 -49
  453. package/src/drivers/signal-memory.ts +2 -8
  454. package/src/drivers/signal-nats.ts +4 -9
  455. package/src/drivers/signal-postgres.ts +62 -129
  456. package/src/drivers/signal-redis.ts +7 -21
  457. package/src/drivers/signal-types.ts +1 -4
  458. package/src/drivers/sqlite.ts +3 -12
  459. package/src/drivers/types.ts +4 -23
  460. package/src/drivers/vault-driver-removal.test.ts +55 -0
  461. package/src/drivers/vault-env.ts +2 -6
  462. package/src/drivers/vault-infisical.ts +1 -5
  463. package/src/drivers/vault-managed.ts +1 -5
  464. package/src/drivers/vault-memory.ts +1 -5
  465. package/src/drivers/vault-openbao.test.ts +97 -0
  466. package/src/drivers/vault-openbao.ts +103 -40
  467. package/src/drivers/vault-types.ts +3 -16
  468. package/src/elements/ai/declare.ts +4 -14
  469. package/src/elements/ai/eval.ts +2 -6
  470. package/src/elements/ai/pii.ts +1 -3
  471. package/src/elements/ai/runtime.ts +12 -50
  472. package/src/elements/ai/schema.ts +4 -15
  473. package/src/elements/ai.test.ts +13 -24
  474. package/src/elements/ai.ts +1 -5
  475. package/src/elements/channel/consent.ts +3 -12
  476. package/src/elements/channel/costs.ts +4 -15
  477. package/src/elements/channel/declare.ts +1 -4
  478. package/src/elements/channel/email-auth.ts +1 -4
  479. package/src/elements/channel/locale.ts +2 -10
  480. package/src/elements/channel/mask.ts +1 -3
  481. package/src/elements/channel/mime.ts +2 -12
  482. package/src/elements/channel/outcomes.test.ts +1 -5
  483. package/src/elements/channel/outcomes.ts +5 -15
  484. package/src/elements/channel/receipts.ts +2 -7
  485. package/src/elements/channel/runtime.ts +28 -74
  486. package/src/elements/channel/suppression.ts +8 -14
  487. package/src/elements/channel.test.ts +8 -31
  488. package/src/elements/channel.ts +3 -14
  489. package/src/elements/clock/actions.ts +6 -18
  490. package/src/elements/clock/declare.ts +1 -3
  491. package/src/elements/clock/dst.ts +1 -5
  492. package/src/elements/clock/durable.ts +4 -16
  493. package/src/elements/clock/health.ts +2 -7
  494. package/src/elements/clock/leader.ts +2 -9
  495. package/src/elements/clock/reconcile.ts +4 -15
  496. package/src/elements/clock/runtime.ts +2 -5
  497. package/src/elements/clock/schedule.ts +4 -20
  498. package/src/elements/clock.test.ts +2 -7
  499. package/src/elements/clock.ts +5 -23
  500. package/src/elements/gate/permissions.ts +1 -4
  501. package/src/elements/gate/runtime.ts +7 -28
  502. package/src/elements/gate.ts +1 -5
  503. package/src/elements/index.ts +9 -7
  504. package/src/elements/signal/declare.ts +2 -7
  505. package/src/elements/signal/reconcile.test.ts +1 -4
  506. package/src/elements/signal/runtime.ts +1 -3
  507. package/src/elements/signal.test.ts +3 -15
  508. package/src/elements/signal.ts +2 -8
  509. package/src/elements/store/cache.test.ts +46 -0
  510. package/src/elements/store/cache.ts +3 -11
  511. package/src/elements/store/classify.ts +5 -22
  512. package/src/elements/store/declare.ts +11 -17
  513. package/src/elements/store/domain-ddl.test.ts +86 -0
  514. package/src/elements/store/emit-drizzle.ts +363 -0
  515. package/src/elements/store/files-policy.test.ts +1 -5
  516. package/src/elements/store/files-policy.ts +4 -12
  517. package/src/elements/store/load-plugin-tables.ts +103 -0
  518. package/src/elements/store/missing-relation.test.ts +83 -0
  519. package/src/elements/store/missing-relation.ts +38 -0
  520. package/src/elements/store/replica.ts +1 -4
  521. package/src/elements/store/resource-list-docs.fixture.ts +56 -0
  522. package/src/elements/store/resource-list-docs.test.ts +79 -0
  523. package/src/elements/store/resource.test.ts +253 -0
  524. package/src/elements/store/resource.ts +786 -0
  525. package/src/elements/store/runtime.ts +25 -28
  526. package/src/elements/store/schema-decl.test.ts +227 -0
  527. package/src/elements/store/schema-decl.ts +516 -0
  528. package/src/elements/store/sql-condition.test.ts +132 -0
  529. package/src/elements/store/sql-condition.ts +293 -65
  530. package/src/elements/store/sql-session.test.ts +135 -0
  531. package/src/elements/store/sql-session.ts +241 -84
  532. package/src/elements/store/table.ts +69 -23
  533. package/src/elements/store.test.ts +17 -39
  534. package/src/elements/store.ts +53 -31
  535. package/src/elements/vault/chain.ts +34 -0
  536. package/src/elements/vault/declare.ts +22 -32
  537. package/src/elements/vault/fingerprint.ts +2 -7
  538. package/src/elements/vault/redact.ts +2 -6
  539. package/src/elements/vault/runtime.ts +19 -33
  540. package/src/elements/vault.test.ts +12 -55
  541. package/src/elements/vault.ts +9 -13
  542. package/src/index.ts +5 -2
  543. package/src/kernel/adopt-routes.ts +15 -29
  544. package/src/kernel/app.ts +92 -118
  545. package/src/kernel/auth-resolve.ts +2 -9
  546. package/src/kernel/boot-bind/ai.ts +1 -4
  547. package/src/kernel/boot-bind/channel.test.ts +60 -0
  548. package/src/kernel/boot-bind/channel.ts +61 -5
  549. package/src/kernel/boot-bind/clock.ts +2 -6
  550. package/src/kernel/boot-bind/gate.ts +2 -8
  551. package/src/kernel/boot-bind/runs.ts +1 -3
  552. package/src/kernel/boot-bind/signal.ts +3 -10
  553. package/src/kernel/boot-bind/store.test.ts +27 -18
  554. package/src/kernel/boot-bind/store.ts +93 -52
  555. package/src/kernel/boot-bind/vault.ts +2 -8
  556. package/src/kernel/boot.test.ts +4 -10
  557. package/src/kernel/boot.ts +30 -77
  558. package/src/kernel/budget.test.ts +1 -3
  559. package/src/kernel/capability.ts +3 -10
  560. package/src/kernel/dry-run.test.ts +1 -4
  561. package/src/kernel/dry-run.ts +3 -11
  562. package/src/kernel/edge.test.ts +68 -0
  563. package/src/kernel/effects.test.ts +1 -5
  564. package/src/kernel/effects.ts +4 -11
  565. package/src/kernel/errors.registry.test.ts +2 -8
  566. package/src/kernel/errors.ts +23 -32
  567. package/src/kernel/flow.test.ts +12 -25
  568. package/src/kernel/flow.ts +13 -25
  569. package/src/kernel/fx.test.ts +31 -40
  570. package/src/kernel/fx.ts +135 -90
  571. package/src/kernel/hook-timing.test.ts +3 -6
  572. package/src/kernel/hook-timing.ts +5 -14
  573. package/src/kernel/hooks.test.ts +43 -10
  574. package/src/kernel/hooks.ts +25 -12
  575. package/src/kernel/index.ts +11 -17
  576. package/src/kernel/journal.ts +7 -31
  577. package/src/kernel/on.ts +45 -9
  578. package/src/kernel/pipeline.test.ts +10 -19
  579. package/src/kernel/pipeline.ts +5 -17
  580. package/src/kernel/plug.ts +4 -11
  581. package/src/kernel/plugin/conflicts.test.ts +13 -25
  582. package/src/kernel/plugin/decorate.test.ts +8 -13
  583. package/src/kernel/plugin/scoping.test.ts +4 -11
  584. package/src/kernel/plugin.ts +81 -27
  585. package/src/kernel/registry-isolation.test.ts +74 -0
  586. package/src/kernel/registry.ts +102 -30
  587. package/src/kernel/router.test.ts +15 -13
  588. package/src/kernel/router.ts +9 -29
  589. package/src/kernel/routing-budget.test.ts +1 -3
  590. package/src/kernel/run-telemetry.ts +1 -3
  591. package/src/kernel/triggers.ts +63 -21
  592. package/src/manifest/diff.test.ts +26 -91
  593. package/src/manifest/diff.ts +95 -225
  594. package/src/manifest/fixtures/skyport.excerpt.json +1 -1
  595. package/src/manifest/fixtures/skyport.manifest.json +1 -1
  596. package/src/manifest/index.ts +3 -10
  597. package/src/manifest/types.ts +30 -6
  598. package/src/manifest/undeclared.test.ts +4 -12
  599. package/src/manifest/undeclared.ts +1 -2
  600. package/src/manifest/validate.test.ts +2 -6
  601. package/src/manifest/validate.ts +5 -15
  602. package/src/mcp/authorization.ts +8 -27
  603. package/src/mcp/confirmation.ts +3 -10
  604. package/src/mcp/data.ts +2 -6
  605. package/src/mcp/docs-index.ts +4 -7
  606. package/src/mcp/docs-mcp.test.ts +3 -12
  607. package/src/mcp/docs-server.ts +7 -27
  608. package/src/mcp/docs-tools.ts +2 -6
  609. package/src/mcp/index.ts +1 -6
  610. package/src/mcp/injection.gate.test.ts +4 -18
  611. package/src/mcp/mcp.test.ts +18 -49
  612. package/src/mcp/protocol.ts +3 -10
  613. package/src/mcp/server.ts +11 -52
  614. package/src/mcp/session.ts +4 -14
  615. package/src/mcp/tools.ts +14 -50
  616. package/src/plugins/catalogue.test.ts +3 -7
  617. package/src/plugins/catalogue.ts +1 -3
  618. package/src/plugins/compression.test.ts +127 -0
  619. package/src/plugins/compression.ts +94 -0
  620. package/src/plugins/config-source.test.ts +204 -0
  621. package/src/plugins/config-source.ts +209 -0
  622. package/src/plugins/cors.test.ts +138 -0
  623. package/src/plugins/cors.ts +129 -0
  624. package/src/plugins/csrf.test.ts +102 -0
  625. package/src/plugins/csrf.ts +86 -0
  626. package/src/plugins/headers.ts +54 -0
  627. package/src/plugins/index.ts +26 -0
  628. package/src/plugins/ip-allowlist.test.ts +105 -0
  629. package/src/plugins/ip-allowlist.ts +76 -0
  630. package/src/plugins/maintenance-mode.test.ts +91 -0
  631. package/src/plugins/maintenance-mode.ts +85 -0
  632. package/src/plugins/node-import-scan.ts +2 -5
  633. package/src/plugins/security-headers.test.ts +243 -0
  634. package/src/plugins/security-headers.ts +255 -0
  635. package/src/plugins/supply-chain.ts +5 -17
  636. package/src/release/exports.ts +3 -8
  637. package/src/release/measure.exports.test.ts +1 -3
  638. package/src/release/measure.ts +16 -45
  639. package/src/runs/bench.test.ts +1 -3
  640. package/src/runs/collect.ts +8 -25
  641. package/src/runs/drivers/clickhouse.ts +2 -9
  642. package/src/runs/drivers/files.ts +9 -31
  643. package/src/runs/drivers/memory.ts +5 -22
  644. package/src/runs/drivers/postgres.ts +8 -20
  645. package/src/runs/duckdb.ts +2 -8
  646. package/src/runs/index.ts +3 -14
  647. package/src/runs/outlier.ts +3 -10
  648. package/src/runs/parquet.ts +8 -26
  649. package/src/runs/privacy.ts +2 -8
  650. package/src/runs/runs.test.ts +3 -9
  651. package/src/runs/runtime.ts +7 -32
  652. package/src/runs/shred.ts +10 -29
  653. package/src/runs/types.ts +1 -4
  654. package/src/runtime/bun.ts +4 -15
  655. package/src/runtime/cold-start.bench.ts +1 -3
  656. package/src/runtime/dev-request-log.test.ts +1 -4
  657. package/src/runtime/dev-request-log.ts +1 -4
  658. package/src/runtime/index.ts +1 -6
  659. package/src/runtime/primitives.ts +5 -4
  660. package/src/runtime/security.ts +3 -13
  661. package/src/runtime/serve.test.ts +4 -7
  662. package/src/runtime/types.ts +1 -4
  663. package/src/runtime/web-standard.ts +3 -15
  664. package/src/term.test.ts +4 -6
  665. package/src/term.ts +49 -98
  666. package/src/test/create-test-app.test.ts +4 -14
  667. package/src/test/create-test-app.ts +27 -33
  668. package/src/test/provisions.integration.test.ts +3 -11
  669. package/src/upgrade/codemods.test.ts +25 -6
  670. package/src/upgrade/codemods.ts +116 -3
  671. package/src/validation/standard-schema.test.ts +2 -5
  672. package/src/validation/standard-schema.ts +13 -33
  673. package/docs/spec/console.md +0 -739
  674. package/docs/spec/example.md +0 -1196
  675. package/docs/spec/four-applications.md +0 -1195
  676. package/docs/spec/unified-theory.md +0 -489
  677. package/src/cli/doc-drift.test.ts +0 -146
  678. package/src/cli/doc-drift.ts +0 -430
  679. package/src/cli/doctor-diff-examples.ts +0 -92
  680. package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
  681. package/src/drivers/vault-sops.ts +0 -271
@@ -5,9 +5,14 @@
5
5
  * Same flow code runs against sqlite, postgres, and memory.
6
6
  */
7
7
 
8
+ import type { DomainDdlMode } from "../../config/index.ts";
8
9
  import type { ClassificationMap, SqlConnection, SqlRow } from "../../drivers/types.ts";
10
+ import { throwOke } from "../../kernel/errors.ts";
9
11
  import { maskRows, tableFromSql } from "./classify.ts";
12
+ import { isMissingDomainRelationError } from "./missing-relation.ts";
10
13
  import {
14
+ andWhere,
15
+ compileOrderBy,
11
16
  compileWhere,
12
17
  resolveSelectColumns,
13
18
  type WhereMap,
@@ -15,6 +20,7 @@ import {
15
20
  import {
16
21
  mapRowToJs,
17
22
  prepareInsertRow,
23
+ prepareUpdateRow,
18
24
  resolveColumns,
19
25
  resolveTableName,
20
26
  type TableHandle,
@@ -32,31 +38,89 @@ export interface SqlSessionOptions {
32
38
  readonly revealPii?: boolean;
33
39
  /** Which connection was chosen — exposed for replica proofs. */
34
40
  readonly routedRole: "primary" | "replica";
41
+ /**
42
+ * Domain DDL policy. `ensure` runs `CREATE TABLE IF NOT EXISTS` on first
43
+ * touch; `off` means migrations / `oke db push` own the schema (docker/prod
44
+ * and local+autoPush). Default `ensure` for backward-compatible tests.
45
+ */
46
+ readonly domainDdl?: DomainDdlMode;
35
47
  }
36
48
 
37
49
  /**
38
- * Continuations after `.where(...)` on a select — awaitable, optional `.limit`.
50
+ * Continuations after `.orderBy(...)` — awaitable, optional `.limit` /
51
+ * `.offset`.
52
+ */
53
+ export interface SelectOrderBuilder extends PromiseLike<SqlRow[]> {
54
+ /**
55
+ * Cap the number of returned rows.
56
+ *
57
+ * @param n - Max rows
58
+ */
59
+ limit(n: number): Promise<SqlRow[]>;
60
+ /**
61
+ * Skip the first `n` rows (`LIMIT … OFFSET …`).
62
+ *
63
+ * @param n - Rows to skip
64
+ */
65
+ offset(n: number): Promise<SqlRow[]>;
66
+ }
67
+
68
+ /**
69
+ * Continuations after `.where(...)` on a select — awaitable, optional
70
+ * `.orderBy(...)` / `.limit(...)` / `.offset(...)`.
39
71
  */
40
72
  export interface SelectWhereBuilder extends PromiseLike<SqlRow[]> {
73
+ /**
74
+ * Order rows with Drizzle `asc()` / `desc()` terms.
75
+ *
76
+ * @param orders - Order terms
77
+ */
78
+ orderBy(...orders: readonly unknown[]): SelectOrderBuilder;
41
79
  /**
42
80
  * Cap the number of returned rows.
43
81
  *
44
82
  * @param n - Max rows
45
83
  */
46
84
  limit(n: number): Promise<SqlRow[]>;
85
+ /**
86
+ * Skip the first `n` rows.
87
+ *
88
+ * @param n - Rows to skip
89
+ */
90
+ offset(n: number): Promise<SqlRow[]>;
47
91
  }
48
92
 
49
93
  /**
50
- * Result of `.from(table)` — awaitable (all rows) or chain `.where(...)`.
94
+ * Result of `.from(table)` — awaitable (all rows) or chain
95
+ * `.where(...)` / `.orderBy(...)` / `.limit(...)` / `.offset(...)` in any
96
+ * order.
51
97
  */
52
98
  export interface SelectFromBuilder extends PromiseLike<SqlRow[]> {
53
99
  /**
54
100
  * Filter with a plain equality map or a Drizzle SQL condition
55
- * (`eq`, `and`, `lt`, …).
101
+ * (`eq`, `and`, `or`, `lt`, `like`, …).
56
102
  *
57
103
  * @param where - Condition
58
104
  */
59
105
  where(where: unknown): SelectWhereBuilder;
106
+ /**
107
+ * Order rows with Drizzle `asc()` / `desc()` terms.
108
+ *
109
+ * @param orders - Order terms
110
+ */
111
+ orderBy(...orders: readonly unknown[]): SelectOrderBuilder;
112
+ /**
113
+ * Cap the number of returned rows.
114
+ *
115
+ * @param n - Max rows
116
+ */
117
+ limit(n: number): Promise<SqlRow[]>;
118
+ /**
119
+ * Skip the first `n` rows.
120
+ *
121
+ * @param n - Rows to skip
122
+ */
123
+ offset(n: number): Promise<SqlRow[]>;
60
124
  }
61
125
 
62
126
  /** Fluent select builder. */
@@ -172,10 +236,7 @@ export interface SqlStoreHandle {
172
236
  * @param table - Table
173
237
  * @param idOrWhere - Primary key string, or column equality map
174
238
  */
175
- exists(
176
- table: TableHandle | unknown,
177
- idOrWhere: string | WhereMap,
178
- ): Promise<boolean>;
239
+ exists(table: TableHandle | unknown, idOrWhere: string | WhereMap): Promise<boolean>;
179
240
  /**
180
241
  * Atomically add `by` to `column` on the PK row.
181
242
  *
@@ -184,12 +245,7 @@ export interface SqlStoreHandle {
184
245
  * @param column - Numeric column to bump
185
246
  * @param by - Delta (default `1`)
186
247
  */
187
- increment(
188
- table: TableHandle | unknown,
189
- id: string,
190
- column: string,
191
- by?: number,
192
- ): Promise<number>;
248
+ increment(table: TableHandle | unknown, id: string, column: string, by?: number): Promise<number>;
193
249
  /**
194
250
  * Raw SQL — PII masking still applied at the boundary.
195
251
  *
@@ -197,6 +253,21 @@ export interface SqlStoreHandle {
197
253
  * @param params - Bound parameters
198
254
  */
199
255
  raw(sql: string, params?: readonly unknown[]): Promise<SqlRow[]>;
256
+ /**
257
+ * Count rows (`COUNT(*)`), optionally filtered.
258
+ *
259
+ * @param table - Table
260
+ * @param where - Optional condition
261
+ */
262
+ count(table: TableHandle | unknown, where?: unknown): Promise<number>;
263
+ /**
264
+ * One page of rows — offset or keyset mode, composed through the same
265
+ * fluent select path (Drizzle conditions in, `compileWhere` out).
266
+ *
267
+ * @param table - Table
268
+ * @param options - Page options
269
+ */
270
+ page(table: TableHandle | unknown, options: SqlPageOptions): Promise<SqlRow[]>;
200
271
  /**
201
272
  * Ensure a simple table exists (test / bootstrap helper).
202
273
  *
@@ -205,6 +276,24 @@ export interface SqlStoreHandle {
205
276
  ensureTable(table: TableHandle): Promise<void>;
206
277
  }
207
278
 
279
+ /** Options for {@link SqlStoreHandle.page}. */
280
+ export interface SqlPageOptions {
281
+ /** Filter condition (equality map or Drizzle SQL). */
282
+ readonly where?: unknown;
283
+ /** Drizzle `asc()` / `desc()` terms (or bare columns). */
284
+ readonly orderBy?: readonly unknown[];
285
+ /** Max rows to return. */
286
+ readonly limit?: number;
287
+ /** Offset mode — skip rows (uses `OFFSET`). */
288
+ readonly offset?: number;
289
+ /**
290
+ * Keyset mode — a Drizzle SQL condition describing "rows strictly after
291
+ * the cursor" (composed by the caller / `store.resource`); ANDed onto
292
+ * `where`. Cannot combine with `offset`.
293
+ */
294
+ readonly after?: unknown;
295
+ }
296
+
208
297
  /**
209
298
  * Create a SQL store handle over a connection.
210
299
  *
@@ -216,38 +305,55 @@ export function createSqlStoreHandle(
216
305
  options: SqlSessionOptions,
217
306
  ): SqlStoreHandle {
218
307
  const { connection, classifications, revealPii } = options;
308
+ const domainDdl: DomainDdlMode = options.domainDdl ?? "ensure";
219
309
 
220
310
  function mask(rows: SqlRow[], table?: string): SqlRow[] {
221
311
  return maskRows(rows, { classifications, table, revealPii });
222
312
  }
223
313
 
314
+ /**
315
+ * Run a connection op; remap missing-relation driver errors to OKE1101
316
+ * when domain auto-DDL is off.
317
+ */
318
+ async function withSchemaGuard<T>(fn: () => Promise<T>): Promise<T> {
319
+ try {
320
+ return await fn();
321
+ } catch (err) {
322
+ if (domainDdl === "off" && isMissingDomainRelationError(err)) {
323
+ throwOke("DOMAIN_SCHEMA_MISSING");
324
+ }
325
+ throw err;
326
+ }
327
+ }
328
+
329
+ function query(sql: string, params: readonly unknown[] = []): Promise<SqlRow[]> {
330
+ return withSchemaGuard(() => connection.query(sql, params));
331
+ }
332
+
333
+ function exec(sql: string, params: readonly unknown[] = []): Promise<{ changes: number }> {
334
+ return withSchemaGuard(() => connection.exec(sql, params));
335
+ }
336
+
224
337
  async function ensureFromMeta(table: TableHandle | unknown): Promise<void> {
338
+ if (domainDdl !== "ensure") return;
225
339
  const cols = resolveColumns(table);
226
340
  if (cols.length === 0) return;
227
341
  const name = resolveTableName(table);
228
342
  const pk = cols.find((c) => c.primary)?.sqlName;
229
343
  const colSql = cols
230
344
  .map((c) => {
231
- const typ =
232
- pk && c.sqlName === pk
233
- ? `${c.sqlType} PRIMARY KEY`
234
- : c.sqlType;
345
+ const typ = pk && c.sqlName === pk ? `${c.sqlType} PRIMARY KEY` : c.sqlType;
235
346
  return `${quoteIdent(c.sqlName)} ${typ}`;
236
347
  })
237
348
  .join(", ");
238
- await connection.exec(
239
- `CREATE TABLE IF NOT EXISTS ${quoteIdent(name)} (${colSql})`,
240
- );
349
+ await exec(`CREATE TABLE IF NOT EXISTS ${quoteIdent(name)} (${colSql})`);
241
350
  }
242
351
 
243
352
  function toJs(table: TableHandle | unknown, rows: SqlRow[]): SqlRow[] {
244
353
  return rows.map((r) => mapRowToJs(table, r) as SqlRow);
245
354
  }
246
355
 
247
- function normalizeWhereMap(
248
- table: TableHandle | unknown,
249
- where: WhereMap,
250
- ): WhereMap {
356
+ function normalizeWhereMap(table: TableHandle | unknown, where: WhereMap): WhereMap {
251
357
  const cols = resolveColumns(table);
252
358
  if (cols.length === 0) return where;
253
359
  const out: Record<string, unknown> = {};
@@ -273,11 +379,18 @@ export function createSqlStoreHandle(
273
379
  return compileWhere(where);
274
380
  }
275
381
 
382
+ /** Accumulated select state across the fluent chain. */
383
+ interface SelectPlan {
384
+ readonly where?: unknown;
385
+ readonly orders?: readonly unknown[];
386
+ readonly limit?: number;
387
+ readonly offset?: number;
388
+ }
389
+
276
390
  async function runSelect(
277
391
  table: TableHandle | unknown,
278
392
  projection: ReturnType<typeof resolveSelectColumns>,
279
- where: unknown | undefined,
280
- limit?: number,
393
+ plan: SelectPlan = {},
281
394
  ): Promise<SqlRow[]> {
282
395
  await ensureFromMeta(table);
283
396
  const name = resolveTableName(table);
@@ -294,20 +407,31 @@ export function createSqlStoreHandle(
294
407
 
295
408
  let sql = `SELECT ${selectList} FROM ${quoteIdent(name)}`;
296
409
  const params: unknown[] = [];
297
- if (where !== undefined) {
298
- const compiled = compileTableWhere(table, where);
410
+ if (plan.where !== undefined) {
411
+ const compiled = compileTableWhere(table, plan.where);
299
412
  if (compiled.clause) {
300
413
  sql += ` WHERE ${compiled.clause}`;
301
414
  params.push(...compiled.params);
302
415
  }
303
416
  }
304
- if (limit !== undefined) {
305
- sql += ` LIMIT ${Math.max(0, Math.floor(limit))}`;
417
+ if (plan.orders !== undefined && plan.orders.length > 0) {
418
+ const terms = compileOrderBy(plan.orders);
419
+ sql += ` ORDER BY ${terms.map((o) => `${quoteIdent(o.column)} ${o.direction}`).join(", ")}`;
420
+ }
421
+ if (plan.limit !== undefined) {
422
+ sql += ` LIMIT ${Math.max(0, Math.floor(plan.limit))}`;
423
+ }
424
+ if (plan.offset !== undefined) {
425
+ sql += ` OFFSET ${Math.max(0, Math.floor(plan.offset))}`;
306
426
  }
307
427
 
308
- const rows = await connection.query(sql, params);
428
+ const rows = await query(sql, params);
429
+ // Map to declared JS keys first, then mask — classifications are keyed by
430
+ // TS field names (`email`), so masking before remapping would miss a
431
+ // `.pii()` column whose SQL name differs (`email_addr`) and leak cleartext
432
+ // under the final client-facing key.
309
433
  if (projection === null) {
310
- return toJs(table, mask(rows, name));
434
+ return mask(toJs(table, rows), name);
311
435
  }
312
436
  // Projected aliases are already the returned keys.
313
437
  return mask(
@@ -322,26 +446,39 @@ export function createSqlStoreHandle(
322
446
  );
323
447
  }
324
448
 
325
- function selectFrom(
326
- table: TableHandle | unknown,
327
- columns?: unknown,
328
- ): SelectFromBuilder {
449
+ function selectFrom(table: TableHandle | unknown, columns?: unknown): SelectFromBuilder {
329
450
  const projection = resolveSelectColumns(columns);
330
- const all = runSelect(table, projection, undefined);
451
+
452
+ // Builders are lazy: the query runs on the first await / `.limit(n)` /
453
+ // `.offset(n)`, so a chained `where → orderBy → limit` issues one SELECT.
454
+ function tail(plan: SelectPlan): SelectOrderBuilder {
455
+ return {
456
+ limit(n) {
457
+ return runSelect(table, projection, { ...plan, limit: n });
458
+ },
459
+ offset(n) {
460
+ return runSelect(table, projection, { ...plan, offset: n });
461
+ },
462
+ then(onfulfilled, onrejected) {
463
+ return runSelect(table, projection, plan).then(onfulfilled, onrejected);
464
+ },
465
+ };
466
+ }
467
+
468
+ function filtered(where: unknown): SelectWhereBuilder {
469
+ const plan: SelectPlan = where === undefined ? {} : { where };
470
+ return {
471
+ ...tail(plan),
472
+ orderBy(...orders) {
473
+ return tail({ ...plan, orders });
474
+ },
475
+ };
476
+ }
477
+
331
478
  return {
479
+ ...filtered(undefined),
332
480
  where(where) {
333
- const filtered = runSelect(table, projection, where);
334
- return {
335
- limit(n) {
336
- return runSelect(table, projection, where, n);
337
- },
338
- then(onfulfilled, onrejected) {
339
- return filtered.then(onfulfilled, onrejected);
340
- },
341
- };
342
- },
343
- then(onfulfilled, onrejected) {
344
- return all.then(onfulfilled, onrejected);
481
+ return filtered(where);
345
482
  },
346
483
  };
347
484
  }
@@ -371,7 +508,7 @@ export function createSqlStoreHandle(
371
508
  const colList = cols.map(quoteIdent).join(", ");
372
509
  const params = cols.map((c) => prepared[c]);
373
510
  const sql = `INSERT INTO ${quoteIdent(name)} (${colList}) VALUES (${placeholders})`;
374
- await connection.exec(sql, params);
511
+ await exec(sql, params);
375
512
  };
376
513
  return {
377
514
  async returning() {
@@ -382,8 +519,8 @@ export function createSqlStoreHandle(
382
519
  const colList = cols.map(quoteIdent).join(", ");
383
520
  const params = cols.map((c) => prepared[c]);
384
521
  const sql = `INSERT INTO ${quoteIdent(name)} (${colList}) VALUES (${placeholders}) RETURNING *`;
385
- const rows = await connection.query(sql, params);
386
- return toJs(table, mask(rows, name));
522
+ const rows = await query(sql, params);
523
+ return mask(toJs(table, rows), name);
387
524
  },
388
525
  execute: runExecute,
389
526
  then(onfulfilled, onrejected) {
@@ -401,21 +538,16 @@ export function createSqlStoreHandle(
401
538
  return {
402
539
  async where(where) {
403
540
  await ensureFromMeta(table);
404
- const prepared = prepareInsertRow(table, row);
541
+ const prepared = prepareUpdateRow(table, row);
405
542
  const setEntries = Object.entries(prepared);
406
543
  if (setEntries.length === 0) return 0;
407
- const setSql = setEntries
408
- .map(([col]) => `${quoteIdent(col)} = ?`)
409
- .join(", ");
544
+ const setSql = setEntries.map(([col]) => `${quoteIdent(col)} = ?`).join(", ");
410
545
  const compiled = compileTableWhere(table, where);
411
546
  if (!compiled.clause) {
412
547
  throw new Error("update().set().where(): condition required");
413
548
  }
414
- const params = [
415
- ...setEntries.map(([, v]) => v),
416
- ...compiled.params,
417
- ];
418
- const result = await connection.exec(
549
+ const params = [...setEntries.map(([, v]) => v), ...compiled.params];
550
+ const result = await exec(
419
551
  `UPDATE ${quoteIdent(name)} SET ${setSql} WHERE ${compiled.clause}`,
420
552
  params,
421
553
  );
@@ -430,27 +562,22 @@ export function createSqlStoreHandle(
430
562
  await ensureFromMeta(table);
431
563
  const name = resolveTableName(table);
432
564
  const pk = resolvePkColumn(table);
433
- const rows = await connection.query(
434
- `SELECT * FROM ${quoteIdent(name)} WHERE ${quoteIdent(pk)} = ?`,
435
- [idValue],
436
- );
437
- const masked = toJs(table, mask(rows, name));
565
+ const rows = await query(`SELECT * FROM ${quoteIdent(name)} WHERE ${quoteIdent(pk)} = ?`, [
566
+ idValue,
567
+ ]);
568
+ const masked = mask(toJs(table, rows), name);
438
569
  return masked[0] ?? null;
439
570
  },
440
571
 
441
- delete: ((
442
- table: TableHandle | unknown,
443
- idValue?: string,
444
- ): DeleteBuilder | Promise<boolean> => {
572
+ delete: ((table: TableHandle | unknown, idValue?: string): DeleteBuilder | Promise<boolean> => {
445
573
  if (idValue !== undefined) {
446
574
  return (async () => {
447
575
  await ensureFromMeta(table);
448
576
  const name = resolveTableName(table);
449
577
  const pk = resolvePkColumn(table);
450
- const result = await connection.exec(
451
- `DELETE FROM ${quoteIdent(name)} WHERE ${quoteIdent(pk)} = ?`,
452
- [idValue],
453
- );
578
+ const result = await exec(`DELETE FROM ${quoteIdent(name)} WHERE ${quoteIdent(pk)} = ?`, [
579
+ idValue,
580
+ ]);
454
581
  return result.changes > 0;
455
582
  })();
456
583
  }
@@ -462,7 +589,7 @@ export function createSqlStoreHandle(
462
589
  if (!compiled.clause) {
463
590
  throw new Error("delete().where(): condition required");
464
591
  }
465
- const result = await connection.exec(
592
+ const result = await exec(
466
593
  `DELETE FROM ${quoteIdent(name)} WHERE ${compiled.clause}`,
467
594
  compiled.params,
468
595
  );
@@ -483,7 +610,7 @@ export function createSqlStoreHandle(
483
610
  if (!compiled.clause) {
484
611
  throw new Error("exists() requires at least one where predicate");
485
612
  }
486
- const rows = await connection.query(
613
+ const rows = await query(
487
614
  `SELECT 1 AS "ok" FROM ${quoteIdent(name)} WHERE ${compiled.clause} LIMIT 1`,
488
615
  compiled.params,
489
616
  );
@@ -498,25 +625,57 @@ export function createSqlStoreHandle(
498
625
  const colMeta = cols.find((c) => c.key === column || c.sqlName === column);
499
626
  const sqlCol = colMeta?.sqlName ?? column;
500
627
  const col = quoteIdent(sqlCol);
501
- const rows = await connection.query(
628
+ const rows = await query(
502
629
  `UPDATE ${quoteIdent(name)} SET ${col} = ${col} + ? WHERE ${quoteIdent(pk)} = ? RETURNING ${col}`,
503
630
  [by, idValue],
504
631
  );
505
632
  const row = rows[0];
506
633
  if (!row) {
507
- throw new Error(
508
- `increment(): no row with ${pk} ${JSON.stringify(idValue)} in ${name}`,
509
- );
634
+ throw new Error(`increment(): no row with ${pk} ${JSON.stringify(idValue)} in ${name}`);
510
635
  }
511
636
  return asNumber(row[sqlCol], sqlCol);
512
637
  },
513
638
 
514
639
  async raw(sql, params = []) {
515
640
  const table = tableFromSql(sql);
516
- const rows = await connection.query(sql, params);
641
+ const rows = await query(sql, params);
517
642
  return mask(rows, table);
518
643
  },
519
644
 
645
+ async count(table, where) {
646
+ await ensureFromMeta(table);
647
+ const name = resolveTableName(table);
648
+ let sql = `SELECT COUNT(*) AS "count" FROM ${quoteIdent(name)}`;
649
+ const params: unknown[] = [];
650
+ if (where !== undefined) {
651
+ const compiled = compileTableWhere(table, where);
652
+ if (compiled.clause) {
653
+ sql += ` WHERE ${compiled.clause}`;
654
+ params.push(...compiled.params);
655
+ }
656
+ }
657
+ const rows = await query(sql, params);
658
+ return asNumber(rows[0]?.count ?? rows[0]?.COUNT ?? 0, "count");
659
+ },
660
+
661
+ async page(table, options) {
662
+ if (options.offset !== undefined && options.after !== undefined) {
663
+ throw new Error("page(): offset and after (keyset) cannot combine");
664
+ }
665
+ const where =
666
+ options.after === undefined
667
+ ? options.where
668
+ : options.where === undefined
669
+ ? options.after
670
+ : andWhere(options.where, options.after);
671
+ return runSelect(table, null, {
672
+ where,
673
+ orders: options.orderBy,
674
+ limit: options.limit,
675
+ offset: options.offset,
676
+ });
677
+ },
678
+
520
679
  async ensureTable(table) {
521
680
  const cols = Object.values(table.columns);
522
681
  const pk = resolvePkColumn(table);
@@ -534,9 +693,7 @@ export function createSqlStoreHandle(
534
693
  return `${quoteIdent(c.name)} ${typ}`;
535
694
  })
536
695
  .join(", ");
537
- await connection.exec(
538
- `CREATE TABLE IF NOT EXISTS ${quoteIdent(table.name)} (${colSql})`,
539
- );
696
+ await exec(`CREATE TABLE IF NOT EXISTS ${quoteIdent(table.name)} (${colSql})`);
540
697
  },
541
698
  };
542
699
 
@@ -31,9 +31,7 @@ export interface TableHandle {
31
31
  */
32
32
  export function defineTable(
33
33
  name: string,
34
- columns: Readonly<
35
- Record<string, ColumnDef | ColumnClassification | true | undefined>
36
- >,
34
+ columns: Readonly<Record<string, ColumnDef | ColumnClassification | true | undefined>>,
37
35
  ): TableHandle {
38
36
  const resolved: Record<string, ColumnDef> = {};
39
37
  for (const [key, value] of Object.entries(columns)) {
@@ -120,14 +118,38 @@ export function resolveColumns(table: unknown): ResolvedColumn[] {
120
118
  if (table && typeof table === "object") {
121
119
  const t = table as Record<string, unknown>;
122
120
  if ("columns" in t && t.columns && typeof t.columns === "object") {
123
- return Object.entries(t.columns as Record<string, ColumnDef>).map(
124
- ([key, col]) => ({
121
+ return Object.entries(
122
+ t.columns as Record<
123
+ string,
124
+ ColumnDef & {
125
+ sqlName?: string;
126
+ sqlType?: string;
127
+ primaryKey?: boolean;
128
+ defaultFn?: () => unknown;
129
+ }
130
+ >,
131
+ ).map(([key, col]) => {
132
+ const sqlName = col.sqlName ?? col.name;
133
+ const primary =
134
+ typeof col.primaryKey === "boolean"
135
+ ? col.primaryKey
136
+ : col.name === "id" || key === "id" || sqlName === "id";
137
+ const sqlType =
138
+ col.sqlType === "integer" || col.sqlType === "INTEGER"
139
+ ? ("INTEGER" as const)
140
+ : col.sqlType === "real" || col.sqlType === "REAL"
141
+ ? ("REAL" as const)
142
+ : col.sqlType === "blob" || col.sqlType === "BLOB"
143
+ ? ("BLOB" as const)
144
+ : ("TEXT" as const);
145
+ return {
125
146
  key,
126
- sqlName: col.name,
127
- primary: col.name === "id" || key === "id",
128
- sqlType: "TEXT" as const,
129
- }),
130
- );
147
+ sqlName,
148
+ primary,
149
+ sqlType,
150
+ ...(typeof col.defaultFn === "function" ? { defaultFn: col.defaultFn } : {}),
151
+ };
152
+ });
131
153
  }
132
154
  if (isDrizzleTable(t)) {
133
155
  return drizzleColumns(t);
@@ -168,18 +190,14 @@ function drizzleColumns(t: Record<string, unknown>): ResolvedColumn[] {
168
190
  config?: { primaryKey?: boolean };
169
191
  };
170
192
  const sqlName = typeof col.name === "string" ? col.name : key;
171
- const primary = Boolean(
172
- col.primary || col.config?.primaryKey || sqlName === "id",
173
- );
193
+ const primary = Boolean(col.primary || col.config?.primaryKey || sqlName === "id");
174
194
  const sqlType = drizzleSqlType(col.columnType, col.dataType);
175
195
  out.push({
176
196
  key,
177
197
  sqlName,
178
198
  primary,
179
199
  sqlType,
180
- ...(typeof col.defaultFn === "function"
181
- ? { defaultFn: col.defaultFn.bind(col) }
182
- : {}),
200
+ ...(typeof col.defaultFn === "function" ? { defaultFn: col.defaultFn.bind(col) } : {}),
183
201
  });
184
202
  }
185
203
  return out;
@@ -234,10 +252,39 @@ export function prepareInsertRow(
234
252
  }
235
253
 
236
254
  /**
237
- * Map a SQL-keyed row back to JS keys when Drizzle/TableHandle metadata exists.
255
+ * Map a JS-keyed partial row to SQL column names for `UPDATE … SET`.
256
+ * Unlike {@link prepareInsertRow}, `$defaultFn`s are never applied — column
257
+ * defaults are insert physics, not update physics.
238
258
  *
239
259
  * @param table - Table-like value
240
- * @param row - Driver row
260
+ * @param row - Incoming values (JS keys)
261
+ */
262
+ export function prepareUpdateRow(
263
+ table: unknown,
264
+ row: Readonly<Record<string, unknown>>,
265
+ ): Record<string, unknown> {
266
+ const cols = resolveColumns(table);
267
+ if (cols.length === 0) return { ...row };
268
+ const byKey = new Map(cols.map((c) => [c.key, c]));
269
+ const bySql = new Map(cols.map((c) => [c.sqlName, c]));
270
+ const out: Record<string, unknown> = {};
271
+ for (const [k, v] of Object.entries(row)) {
272
+ const col = byKey.get(k) ?? bySql.get(k);
273
+ out[col?.sqlName ?? k] = v;
274
+ }
275
+ return out;
276
+ }
277
+
278
+ /**
279
+ * Map a SQL-keyed driver row to declared JS field names only.
280
+ *
281
+ * When Drizzle/TableHandle metadata exists, the result contains exactly the
282
+ * table's declared keys (`createdAt`) — never the raw SQL names
283
+ * (`created_at`) alongside or instead of them. Without metadata, the row is
284
+ * returned as-is (opaque / raw SQL).
285
+ *
286
+ * @param table - Table-like value
287
+ * @param row - Driver row (SQL column names, or already JS-keyed)
241
288
  */
242
289
  export function mapRowToJs(
243
290
  table: unknown,
@@ -245,9 +292,10 @@ export function mapRowToJs(
245
292
  ): Record<string, unknown> {
246
293
  const cols = resolveColumns(table);
247
294
  if (cols.length === 0) return { ...row };
248
- const out: Record<string, unknown> = { ...row };
295
+ const out: Record<string, unknown> = {};
249
296
  for (const col of cols) {
250
- if (col.sqlName in row) out[col.key] = row[col.sqlName];
297
+ if (col.key in row) out[col.key] = row[col.key];
298
+ else if (col.sqlName in row) out[col.key] = row[col.sqlName];
251
299
  }
252
300
  return out;
253
301
  }
@@ -257,9 +305,7 @@ export function mapRowToJs(
257
305
  *
258
306
  * @param table - Table handle
259
307
  */
260
- export function classificationsFromTable(
261
- table: TableHandle,
262
- ): Record<string, ColumnClassification> {
308
+ export function classificationsFromTable(table: TableHandle): Record<string, ColumnClassification> {
263
309
  const out: Record<string, ColumnClassification> = {};
264
310
  for (const [key, col] of Object.entries(table.columns)) {
265
311
  if (col.classification) out[key] = col.classification;