@pikku/cli 0.12.96 → 0.12.100

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 (423) hide show
  1. package/console-app/assets/abnfDiagram-VRR7QNED-Icjp9hnB.js +1 -0
  2. package/console-app/assets/arc-BfGls--L.js +1 -0
  3. package/console-app/assets/architecture-TIHT7OUA-C8l7I5Lm.js +1 -0
  4. package/console-app/assets/architectureDiagram-ZJ3FMSHR-CpnsLBns.js +36 -0
  5. package/console-app/assets/array-BifhSqXX.js +1 -0
  6. package/console-app/assets/blockDiagram-677ZJIJ3-ByKRMGSr.js +132 -0
  7. package/console-app/assets/c4Diagram-LMCZKHZV-CzJSbsUo.js +10 -0
  8. package/console-app/assets/channel-BgJ-Z0cx.js +1 -0
  9. package/console-app/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  10. package/console-app/assets/chunk-32BRIVSS-D_tc4HCY.js +1 -0
  11. package/console-app/assets/chunk-52WLFC77-wkQkuUXG.js +10 -0
  12. package/console-app/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  13. package/console-app/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
  14. package/console-app/assets/chunk-C7G6YPKG-BFW3xG3R.js +1 -0
  15. package/console-app/assets/chunk-EX3LRPZG-Car090Sw.js +231 -0
  16. package/console-app/assets/chunk-FWX5IMBZ-c2ud9kQ-.js +2 -0
  17. package/console-app/assets/chunk-HOUHSVGY-RYmQka5R.js +1 -0
  18. package/console-app/assets/chunk-ICXQ74PX-C-dqYC_9.js +2 -0
  19. package/console-app/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  20. package/console-app/assets/chunk-KEIR6QF5-DNzq6p3w.js +161 -0
  21. package/console-app/assets/chunk-MOJQB5TN-Cu3FUWwl.js +88 -0
  22. package/console-app/assets/chunk-OGEWGWER-Z7f1yArD.js +1 -0
  23. package/console-app/assets/chunk-PUDLZKDR-Bp68DuRj.js +156 -0
  24. package/console-app/assets/chunk-Q4XR5HBZ-CdKSYWZ4.js +70 -0
  25. package/console-app/assets/chunk-RYQCIY6F-9ISCAKm2.js +1 -0
  26. package/console-app/assets/chunk-V7JOEXUC-2EOc1nQB.js +206 -0
  27. package/console-app/assets/chunk-VAUOI2AC-DwKsbf70.js +1 -0
  28. package/console-app/assets/chunk-VR4S4FIN-BPvN0PUm.js +1 -0
  29. package/console-app/assets/chunk-WYO6CB5R-DOpurCTP.js +127 -0
  30. package/console-app/assets/chunk-XXDRQBXY-RuYSFsQb.js +1 -0
  31. package/console-app/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  32. package/console-app/assets/chunk-ZGVPDNZ5-Bu2weVOL.js +62 -0
  33. package/console-app/assets/chunk-ZIRB5QZD-H-kepumB.js +32 -0
  34. package/console-app/assets/classDiagram-OUVF2IWQ-ohoLCI8g.js +1 -0
  35. package/console-app/assets/classDiagram-v2-EOCWNBFH-ohoLCI8g.js +1 -0
  36. package/console-app/assets/cose-bilkent-JH36ORCC-nau-QGCX.js +1 -0
  37. package/console-app/assets/cynefin-VYW2F7L2-BBw-E7lg.js +1 -0
  38. package/console-app/assets/cynefinDiagram-TSTJHNR4-BvnMvOvH.js +62 -0
  39. package/console-app/assets/cytoscape.esm-h6BdjjI9.js +321 -0
  40. package/console-app/assets/dagre-CXRCoUWR.js +1 -0
  41. package/console-app/assets/dagre-VKFMJZFB-CHEqPR29.js +4 -0
  42. package/console-app/assets/defaultLocale-C8Fc0cco.js +1 -0
  43. package/console-app/assets/diagram-FQU43EPY-JijKRWyb.js +3 -0
  44. package/console-app/assets/diagram-G47NLZAW-G5UsB31f.js +24 -0
  45. package/console-app/assets/diagram-NH7WQ7WH-BhuJ6fPu.js +24 -0
  46. package/console-app/assets/diagram-OA4YK3LP-DaUF-8N4.js +30 -0
  47. package/console-app/assets/diagram-WEI45ONY-wLsJIhoM.js +41 -0
  48. package/console-app/assets/dist-fbBkbDNG.js +1 -0
  49. package/console-app/assets/ebnfDiagram-CCIWWBDH-BZCEa3Dz.js +1 -0
  50. package/console-app/assets/erDiagram-Q63AITRT-4XoEUtEh.js +85 -0
  51. package/console-app/assets/eventmodeling-45OFAUF4-DZ7z4YJO.js +1 -0
  52. package/console-app/assets/flowDiagram-23GEKE2U-rd7-NwZT.js +1 -0
  53. package/console-app/assets/ganttDiagram-NO4QXBWP-BXU7pfq6.js +292 -0
  54. package/console-app/assets/gitGraph-TEB2WS4Q-BdMAmvpU.js +1 -0
  55. package/console-app/assets/gitGraphDiagram-IHSO6WYX-3Hn0zwZR.js +106 -0
  56. package/console-app/assets/graphlib-B8gBHxth.js +1 -0
  57. package/console-app/assets/{index-CyYHTGWZ.css → index-BXMjqLQ5.css} +1 -1
  58. package/console-app/assets/{index-CeQodYfg.js → index-Din2vBeb.js} +153 -165
  59. package/console-app/assets/info-DKCQHKI2-Dc_oQkp5.js +1 -0
  60. package/console-app/assets/infoDiagram-FWYZ7A6U-B3v4xCUn.js +2 -0
  61. package/console-app/assets/init-D6jRqBbL.js +1 -0
  62. package/console-app/assets/ishikawaDiagram-FXEZZL3T-DzWq9Vtp.js +70 -0
  63. package/console-app/assets/journeyDiagram-5HDEW3XC-C0buWi_a.js +139 -0
  64. package/console-app/assets/kanban-definition-HUTT4EX6-DRAN9HhV.js +89 -0
  65. package/console-app/assets/katex-Vhh-h91d.js +257 -0
  66. package/console-app/assets/line-UqgRNiAC.js +1 -0
  67. package/console-app/assets/linear-FTAGuk_3.js +1 -0
  68. package/console-app/assets/map-DsCK-0Cs.js +1 -0
  69. package/console-app/assets/mermaid-parser.core-DIHI27FL.js +7 -0
  70. package/console-app/assets/mermaid.core-D4q8kvcu.js +11 -0
  71. package/console-app/assets/mindmap-definition-LN4V7U3C-DN-_CNLb.js +96 -0
  72. package/console-app/assets/ordinal-hYBb2elL.js +1 -0
  73. package/console-app/assets/packet-7NZHBO7P-8a3PoQAb.js +1 -0
  74. package/console-app/assets/path-BWPyau1x.js +1 -0
  75. package/console-app/assets/pegDiagram-2B236MQR-Bh2MhzCN.js +1 -0
  76. package/console-app/assets/pie-RZYD4A2V-Bi6zbJDl.js +1 -0
  77. package/console-app/assets/pieDiagram-ENE6RG2P-D2Z0W5UU.js +39 -0
  78. package/console-app/assets/quadrantDiagram-ABIIQ3AL-DNOKka0p.js +7 -0
  79. package/console-app/assets/radar-I7S5WNFK-CAxa68Sg.js +1 -0
  80. package/console-app/assets/railroad-3IZDKUUU-CZb1usP7.js +1 -0
  81. package/console-app/assets/railroad-abnf-AHOZXSZD-DkQZciri.js +1 -0
  82. package/console-app/assets/railroad-ebnf-EBAXGLYW-CPBeASA9.js +1 -0
  83. package/console-app/assets/railroad-peg-LSFZ7HO6-CXEVIZ0g.js +1 -0
  84. package/console-app/assets/railroadDiagram-RFXS5EU6-B1K2hbTD.js +1 -0
  85. package/console-app/assets/requirementDiagram-TGXJPOKE-K8wcOO0Q.js +84 -0
  86. package/console-app/assets/rough.esm-CSKSodPl.js +1 -0
  87. package/console-app/assets/sankeyDiagram-HTMAVEWB-WBPBkgNx.js +40 -0
  88. package/console-app/assets/sequenceDiagram-DBY2YBRQ-Dz80qZZv.js +162 -0
  89. package/console-app/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
  90. package/console-app/assets/src-CnJCXDL0.js +1 -0
  91. package/console-app/assets/stateDiagram-2N3HPSRC-DMur7lZf.js +1 -0
  92. package/console-app/assets/stateDiagram-v2-6OUMAXLB-BDgLCrot.js +1 -0
  93. package/console-app/assets/swimlanes-5IMT3BWC-BlLdYcPU.js +2 -0
  94. package/console-app/assets/swimlanesDiagram-G3AALYLV-CZ5rQIcE.js +8 -0
  95. package/console-app/assets/timeline-definition-FHXFAJF6-CBOit0JY.js +120 -0
  96. package/console-app/assets/treeView-QDETBFTQ-DM1i1ast.js +1 -0
  97. package/console-app/assets/treemap-6X3UGDF4-ACrBEfY6.js +1 -0
  98. package/console-app/assets/vennDiagram-L72KCM5P-BmeFWb5N.js +34 -0
  99. package/console-app/assets/wardley-OPB4EBWU-BpIbeh58.js +1 -0
  100. package/console-app/assets/wardleyDiagram-EHGQE667-CxL7Mv7y.js +78 -0
  101. package/console-app/assets/xychartDiagram-FW5EYKEG-DkV75xT2.js +7 -0
  102. package/console-app/index.html +2 -2
  103. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  104. package/dist/.pikku/auth/auth.types.d.ts +1 -1
  105. package/dist/.pikku/auth/auth.types.js +1 -1
  106. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  107. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  108. package/dist/.pikku/cli/pikku-cli-channel.d.ts +11 -2
  109. package/dist/.pikku/cli/pikku-cli-channel.js +23 -8
  110. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  111. package/dist/.pikku/cli/pikku-cli-client.gen.js +36 -9
  112. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  113. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  114. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  115. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  116. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +2 -2
  117. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +7 -8
  118. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  119. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  120. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  121. package/dist/.pikku/cli/pikku-cli.gen.js +18 -2
  122. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  123. package/dist/.pikku/function/pikku-function-types.gen.d.ts +24 -9
  124. package/dist/.pikku/function/pikku-function-types.gen.js +2 -2
  125. package/dist/.pikku/function/pikku-functions-meta.gen.js +2 -2
  126. package/dist/.pikku/function/pikku-functions-meta.gen.json +48 -39
  127. package/dist/.pikku/function/pikku-functions.gen.js +3 -3
  128. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  129. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  130. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  131. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  132. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
  133. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
  134. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  135. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  136. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  137. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  138. package/dist/.pikku/pikku-services.gen.d.ts +2 -1
  139. package/dist/.pikku/pikku-services.gen.js +1 -0
  140. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  141. package/dist/.pikku/pikku-types.gen.js +1 -1
  142. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  143. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  144. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +2 -2
  145. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  146. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  147. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +2 -2
  148. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
  149. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +2 -2
  150. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
  151. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +2 -2
  152. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  153. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
  154. package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
  155. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  156. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  157. package/dist/.pikku/schemas/register.gen.js +3 -3
  158. package/dist/.pikku/schemas/schemas/DbResetInput.schema.json +1 -1
  159. package/dist/.pikku/schemas/schemas/{DbSeedInput.schema.json → PikkuVirtualUserFunctionsOutput.schema.json} +1 -1
  160. package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
  161. package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
  162. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  163. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  164. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  165. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  166. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  167. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  168. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  169. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  170. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  171. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  172. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  173. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  174. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  175. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +20 -14
  176. package/dist/.pikku/workflow/pikku-personas.gen.js +1 -1
  177. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +29 -13
  178. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  179. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +2 -2
  180. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  181. package/dist/bin/pikku-bin.mjs +2 -2
  182. package/dist/src/cli.wiring.js +8 -7
  183. package/dist/src/deploy/analyzer/analyzer.js +0 -6
  184. package/dist/src/deploy/codegen/per-unit-codegen.js +0 -3
  185. package/dist/src/deploy/server-entry.js +1 -1
  186. package/dist/src/fabric/fabric-commands.d.ts +26 -26
  187. package/dist/src/fabric/functions/add.function.d.ts +1 -1
  188. package/dist/src/fabric/functions/addon-verify.function.d.ts +1 -1
  189. package/dist/src/fabric/functions/db-schema.function.d.ts +1 -1
  190. package/dist/src/fabric/functions/deploy-list.function.d.ts +1 -1
  191. package/dist/src/fabric/functions/deploy-units.function.d.ts +1 -1
  192. package/dist/src/fabric/functions/deploy.function.d.ts +2 -2
  193. package/dist/src/fabric/functions/domains-add.function.d.ts +1 -1
  194. package/dist/src/fabric/functions/domains-list.function.d.ts +1 -1
  195. package/dist/src/fabric/functions/domains-remove.function.d.ts +1 -1
  196. package/dist/src/fabric/functions/errors.function.d.ts +1 -1
  197. package/dist/src/fabric/functions/init.function.d.ts +1 -1
  198. package/dist/src/fabric/functions/link.function.d.ts +1 -1
  199. package/dist/src/fabric/functions/llm-key.function.d.ts +1 -1
  200. package/dist/src/fabric/functions/login.function.d.ts +1 -1
  201. package/dist/src/fabric/functions/logs.function.d.ts +1 -1
  202. package/dist/src/fabric/functions/metrics.function.d.ts +1 -1
  203. package/dist/src/fabric/functions/publish.function.d.ts +1 -1
  204. package/dist/src/fabric/functions/rollback.function.d.ts +1 -1
  205. package/dist/src/fabric/functions/secrets-list.function.d.ts +1 -1
  206. package/dist/src/fabric/functions/secrets-rotate.function.d.ts +1 -1
  207. package/dist/src/fabric/functions/secrets-set.function.d.ts +1 -1
  208. package/dist/src/fabric/functions/smoke.function.d.ts +1 -1
  209. package/dist/src/fabric/functions/status.function.d.ts +1 -1
  210. package/dist/src/fabric/functions/trace.function.d.ts +1 -1
  211. package/dist/src/fabric/functions/validate.function.d.ts +1 -1
  212. package/dist/src/fabric/functions/validate.function.js +76 -176
  213. package/dist/src/functions/commands/all.d.ts +1 -1
  214. package/dist/src/functions/commands/audit.d.ts +1 -1
  215. package/dist/src/functions/commands/binary.d.ts +1 -1
  216. package/dist/src/functions/commands/bootstrap.d.ts +1 -1
  217. package/dist/src/functions/commands/db-audit.d.ts +1 -1
  218. package/dist/src/functions/commands/db-audit.js +1 -1
  219. package/dist/src/functions/commands/db-baseline.d.ts +1 -1
  220. package/dist/src/functions/commands/db-baseline.js +1 -1
  221. package/dist/src/functions/commands/db-check.d.ts +1 -1
  222. package/dist/src/functions/commands/db-check.js +6 -5
  223. package/dist/src/functions/commands/db-codegen.d.ts +1 -1
  224. package/dist/src/functions/commands/db-codegen.js +1 -1
  225. package/dist/src/functions/commands/db-export.d.ts +1 -1
  226. package/dist/src/functions/commands/db-generate.d.ts +1 -1
  227. package/dist/src/functions/commands/db-generate.js +1 -1
  228. package/dist/src/functions/commands/db-migrate.d.ts +1 -1
  229. package/dist/src/functions/commands/db-migrate.js +1 -1
  230. package/dist/src/functions/commands/db-reset.d.ts +15 -1
  231. package/dist/src/functions/commands/db-reset.js +18 -6
  232. package/dist/src/functions/commands/db-shared.d.ts +14 -0
  233. package/dist/src/functions/commands/deploy-apply.d.ts +1 -1
  234. package/dist/src/functions/commands/deploy-info.d.ts +1 -1
  235. package/dist/src/functions/commands/deploy-plan.d.ts +1 -1
  236. package/dist/src/functions/commands/dev.d.ts +1 -1
  237. package/dist/src/functions/commands/dev.js +2 -2
  238. package/dist/src/functions/commands/emails-init.d.ts +1 -1
  239. package/dist/src/functions/commands/enable.d.ts +8 -8
  240. package/dist/src/functions/commands/import-n8n.d.ts +1 -1
  241. package/dist/src/functions/commands/info.d.ts +4 -4
  242. package/dist/src/functions/commands/knowledge-index.d.ts +1 -1
  243. package/dist/src/functions/commands/knowledge-validate.d.ts +1 -1
  244. package/dist/src/functions/commands/login.d.ts +3 -3
  245. package/dist/src/functions/commands/meta.d.ts +19 -19
  246. package/dist/src/functions/commands/new-addon.d.ts +1 -1
  247. package/dist/src/functions/commands/new-addon.js +2 -2
  248. package/dist/src/functions/commands/new-function.d.ts +1 -1
  249. package/dist/src/functions/commands/new-middleware.d.ts +1 -1
  250. package/dist/src/functions/commands/new-permission.d.ts +1 -1
  251. package/dist/src/functions/commands/new-wiring.d.ts +1 -1
  252. package/dist/src/functions/commands/persona-sync.d.ts +2 -2
  253. package/dist/src/functions/commands/persona-sync.js +1 -1
  254. package/dist/src/functions/commands/persona.d.ts +2 -2
  255. package/dist/src/functions/commands/persona.js +16 -18
  256. package/dist/src/functions/commands/pikku-command-bootstrap.d.ts +1 -1
  257. package/dist/src/functions/commands/pikku-command-summary.d.ts +1 -1
  258. package/dist/src/functions/commands/roles-audit.d.ts +1 -1
  259. package/dist/src/functions/commands/roles-prune.d.ts +1 -1
  260. package/dist/src/functions/commands/scenario-ladder.js +1 -1
  261. package/dist/src/functions/commands/scenario.d.ts +2 -2
  262. package/dist/src/functions/commands/scenario.js +40 -11
  263. package/dist/src/functions/commands/scopes-audit.d.ts +1 -1
  264. package/dist/src/functions/commands/scopes-prune.d.ts +1 -1
  265. package/dist/src/functions/commands/scopes-shared.d.ts +4 -0
  266. package/dist/src/functions/commands/scopes-shared.js +1 -1
  267. package/dist/src/functions/commands/serve.d.ts +1 -1
  268. package/dist/src/functions/commands/serve.js +2 -2
  269. package/dist/src/functions/commands/skills.d.ts +2 -2
  270. package/dist/src/functions/commands/versions-check.d.ts +1 -1
  271. package/dist/src/functions/commands/versions-check.js +3 -3
  272. package/dist/src/functions/commands/versions-init.d.ts +1 -1
  273. package/dist/src/functions/commands/versions-update.d.ts +1 -1
  274. package/dist/src/functions/commands/watch.d.ts +1 -1
  275. package/dist/src/functions/commands/workspace-validate.d.ts +1 -1
  276. package/dist/src/functions/db/annotation-parser.d.ts +14 -0
  277. package/dist/src/functions/db/annotation-parser.js +50 -2
  278. package/dist/src/functions/db/better-auth-schema.js +2 -1
  279. package/dist/src/functions/db/db-codegen.d.ts +12 -0
  280. package/dist/src/functions/db/db-codegen.js +149 -16
  281. package/dist/src/functions/db/local-db.d.ts +87 -6
  282. package/dist/src/functions/db/local-db.js +202 -35
  283. package/dist/src/functions/db/sqlite/dev-seed.d.ts +12 -0
  284. package/dist/src/functions/db/sqlite/dev-seed.js +23 -0
  285. package/dist/src/functions/db/sqlite/sqlite-runtime-bun.js +1 -1
  286. package/dist/src/functions/runtimes/fetch/index.d.ts +1 -1
  287. package/dist/src/functions/runtimes/nextjs/pikku-command-nextjs.d.ts +1 -1
  288. package/dist/src/functions/runtimes/tanstack-start/pikku-command-tanstack-start.d.ts +1 -1
  289. package/dist/src/functions/runtimes/websocket/pikku-command-websocket-typed.d.ts +1 -1
  290. package/dist/src/functions/validate/bootstrap-checks.d.ts +19 -0
  291. package/dist/src/functions/validate/bootstrap-checks.js +90 -0
  292. package/dist/src/functions/validate/persona-checks.d.ts +24 -0
  293. package/dist/src/functions/validate/persona-checks.js +136 -0
  294. package/dist/src/functions/validate/scenario-file-checks.d.ts +17 -0
  295. package/dist/src/functions/validate/scenario-file-checks.js +123 -0
  296. package/dist/src/functions/validate/shared-checks.d.ts +59 -0
  297. package/dist/src/functions/validate/shared-checks.js +311 -0
  298. package/dist/src/functions/validate/workspace-validate.d.ts +1 -2
  299. package/dist/src/functions/validate/workspace-validate.js +4 -196
  300. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent-types.d.ts +1 -1
  301. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.d.ts +1 -1
  302. package/dist/src/functions/wirings/ai-agent/pikku-command-ai-agent.js +1 -1
  303. package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.d.ts +1 -1
  304. package/dist/src/functions/wirings/auth/pikku-command-auth.d.ts +1 -1
  305. package/dist/src/functions/wirings/auth/serialize-auth-gen.js +16 -1
  306. package/dist/src/functions/wirings/auth/serialize-auth-types.d.ts +3 -1
  307. package/dist/src/functions/wirings/auth/serialize-auth-types.js +3 -1
  308. package/dist/src/functions/wirings/channels/pikku-channels.d.ts +1 -1
  309. package/dist/src/functions/wirings/channels/pikku-channels.js +1 -1
  310. package/dist/src/functions/wirings/channels/pikku-command-channel-types.d.ts +1 -1
  311. package/dist/src/functions/wirings/channels/pikku-command-channels-map.d.ts +1 -1
  312. package/dist/src/functions/wirings/channels/pikku-command-channels.d.ts +1 -1
  313. package/dist/src/functions/wirings/channels/pikku-command-channels.js +1 -1
  314. package/dist/src/functions/wirings/channels/serialize-typed-channel-map.js +10 -2
  315. package/dist/src/functions/wirings/cli/pikku-command-cli-entry.d.ts +1 -1
  316. package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +9 -4
  317. package/dist/src/functions/wirings/cli/pikku-command-cli-types.d.ts +1 -1
  318. package/dist/src/functions/wirings/cli/pikku-command-cli.d.ts +1 -1
  319. package/dist/src/functions/wirings/cli/pikku-command-cli.js +1 -1
  320. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +32 -10
  321. package/dist/src/functions/wirings/cli/serialize-channel-cli.js +4 -4
  322. package/dist/src/functions/wirings/cli/serialize-cli-entrypoint-guard.d.ts +12 -0
  323. package/dist/src/functions/wirings/cli/serialize-cli-entrypoint-guard.js +28 -0
  324. package/dist/src/functions/wirings/cli/serialize-local-cli-bootstrap.js +4 -1
  325. package/dist/src/functions/wirings/console/pikku-command-console-functions.d.ts +1 -1
  326. package/dist/src/functions/wirings/console/pikku-command-node-types.d.ts +1 -1
  327. package/dist/src/functions/wirings/console/pikku-command-nodes-meta.d.ts +1 -1
  328. package/dist/src/functions/wirings/console/serialize-console-functions.js +1 -1
  329. package/dist/src/functions/wirings/credentials/pikku-command-credentials.d.ts +1 -1
  330. package/dist/src/functions/wirings/emails/pikku-command-emails.d.ts +1 -1
  331. package/dist/src/functions/wirings/functions/pikku-command-addon-types.d.ts +1 -1
  332. package/dist/src/functions/wirings/functions/pikku-command-function-types-split.d.ts +1 -1
  333. package/dist/src/functions/wirings/functions/pikku-command-function-types.d.ts +1 -1
  334. package/dist/src/functions/wirings/functions/pikku-command-functions.d.ts +1 -1
  335. package/dist/src/functions/wirings/functions/pikku-command-functions.js +1 -1
  336. package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
  337. package/dist/src/functions/wirings/functions/schemas.d.ts +1 -1
  338. package/dist/src/functions/wirings/functions/serialize-addon-types.js +1 -1
  339. package/dist/src/functions/wirings/functions/serialize-function-types.js +37 -9
  340. package/dist/src/functions/wirings/gateway/pikku-command-gateway.d.ts +1 -1
  341. package/dist/src/functions/wirings/graph/pikku-command-graph-wirings.d.ts +1 -1
  342. package/dist/src/functions/wirings/http/pikku-command-http-map.d.ts +1 -1
  343. package/dist/src/functions/wirings/http/pikku-command-http-routes.d.ts +1 -1
  344. package/dist/src/functions/wirings/http/pikku-command-http-routes.js +1 -1
  345. package/dist/src/functions/wirings/http/pikku-command-http-types.d.ts +1 -1
  346. package/dist/src/functions/wirings/http/pikku-command-openapi.d.ts +1 -1
  347. package/dist/src/functions/wirings/http/pikku-http-routes.d.ts +1 -1
  348. package/dist/src/functions/wirings/http/pikku-http-routes.js +1 -1
  349. package/dist/src/functions/wirings/mcp/pikku-command-mcp-json.d.ts +1 -1
  350. package/dist/src/functions/wirings/mcp/pikku-command-mcp-types.d.ts +1 -1
  351. package/dist/src/functions/wirings/mcp/pikku-command-mcp.d.ts +1 -1
  352. package/dist/src/functions/wirings/mcp/pikku-command-mcp.js +1 -1
  353. package/dist/src/functions/wirings/middleware/pikku-command-middleware.d.ts +1 -1
  354. package/dist/src/functions/wirings/package/pikku-command-package-types.d.ts +3 -3
  355. package/dist/src/functions/wirings/package/pikku-command-package.d.ts +1 -1
  356. package/dist/src/functions/wirings/package/serialize-package.js +1 -1
  357. package/dist/src/functions/wirings/permissions/pikku-command-permissions.d.ts +1 -1
  358. package/dist/src/functions/wirings/personas/personas-secrets-file.d.ts +8 -0
  359. package/dist/src/functions/wirings/personas/personas-secrets-file.js +9 -0
  360. package/dist/src/functions/wirings/personas/pikku-command-personas.d.ts +1 -1
  361. package/dist/src/functions/wirings/personas/pikku-command-personas.js +14 -0
  362. package/dist/src/functions/wirings/personas/serialize-personas-secrets.d.ts +16 -0
  363. package/dist/src/functions/wirings/personas/serialize-personas-secrets.js +34 -0
  364. package/dist/src/functions/wirings/queue/pikku-command-queue-map.d.ts +1 -1
  365. package/dist/src/functions/wirings/queue/pikku-command-queue-service.d.ts +1 -1
  366. package/dist/src/functions/wirings/queue/pikku-command-queue-types.d.ts +1 -1
  367. package/dist/src/functions/wirings/queue/pikku-command-queue.d.ts +1 -1
  368. package/dist/src/functions/wirings/queue/pikku-queue-map.d.ts +1 -1
  369. package/dist/src/functions/wirings/queue/pikku-queue.d.ts +1 -1
  370. package/dist/src/functions/wirings/queue/serialize-queue-map.js +2 -1
  371. package/dist/src/functions/wirings/queue/serialize-queue-wrapper.js +2 -1
  372. package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.d.ts +1 -1
  373. package/dist/src/functions/wirings/realtime/pikku-command-realtime.d.ts +1 -1
  374. package/dist/src/functions/wirings/roles/pikku-command-roles.d.ts +1 -1
  375. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -1
  376. package/dist/src/functions/wirings/rpc/pikku-command-react-query.d.ts +1 -1
  377. package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -1
  378. package/dist/src/functions/wirings/rpc/pikku-command-rpc-client.d.ts +1 -1
  379. package/dist/src/functions/wirings/rpc/pikku-command-rpc-map.d.ts +3 -3
  380. package/dist/src/functions/wirings/rpc/pikku-command-rpc.d.ts +1 -1
  381. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +1 -1
  382. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +1 -1
  383. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +2 -2
  384. package/dist/src/functions/wirings/scheduler/pikku-command-scheduler-types.d.ts +1 -1
  385. package/dist/src/functions/wirings/scheduler/pikku-command-scheduler.d.ts +1 -1
  386. package/dist/src/functions/wirings/scopes/pikku-command-scopes.d.ts +1 -1
  387. package/dist/src/functions/wirings/secrets/pikku-command-secrets.d.ts +1 -1
  388. package/dist/src/functions/wirings/triggers/pikku-command-trigger-types.d.ts +1 -1
  389. package/dist/src/functions/wirings/triggers/pikku-command-trigger.d.ts +1 -1
  390. package/dist/src/functions/wirings/triggers/serialize-trigger-meta.js +2 -2
  391. package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.d.ts +1 -1
  392. package/dist/src/functions/wirings/variables/pikku-command-variables.d.ts +1 -1
  393. package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.d.ts +1 -0
  394. package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.js +42 -0
  395. package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.d.ts +28 -0
  396. package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.js +439 -0
  397. package/dist/src/functions/wirings/webhook/pikku-command-webhook.d.ts +1 -1
  398. package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.d.ts +1 -1
  399. package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -1
  400. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +2 -2
  401. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +2 -2
  402. package/dist/src/functions/wirings/workflow/serialize-workflow-routes.js +15 -32
  403. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +36 -23
  404. package/dist/src/functions/workflows/all.workflow.js +49 -16
  405. package/dist/src/server/bun-server-runner.d.ts +2 -2
  406. package/dist/src/server/bun-server-runner.js +5 -1
  407. package/dist/src/services/cli-logger.service.d.ts +28 -16
  408. package/dist/src/services/cli-logger.service.js +25 -16
  409. package/dist/src/services.d.ts +1 -1
  410. package/dist/src/services.js +8 -0
  411. package/dist/src/utils/file-import-path.js +9 -0
  412. package/dist/src/utils/pikku-cli-config.js +7 -0
  413. package/dist/src/utils/resolve-personas.d.ts +4 -9
  414. package/dist/src/utils/resolve-personas.js +4 -15
  415. package/dist/src/utils/serialize-meta-ts.js +1 -1
  416. package/dist/tsconfig.tsbuildinfo +1 -1
  417. package/package.json +13 -13
  418. package/dist/.pikku/schemas/schemas/BootstrapInput.schema.json +0 -1
  419. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +0 -1
  420. package/dist/src/functions/commands/db-seed.d.ts +0 -1
  421. package/dist/src/functions/commands/db-seed.js +0 -24
  422. package/dist/src/functions/db/sqlite/seed.d.ts +0 -11
  423. package/dist/src/functions/db/sqlite/seed.js +0 -22
@@ -3,7 +3,7 @@ import { type MigrateResult } from './db-migrator.js';
3
3
  import type { ColumnInfo } from './db-introspector.js';
4
4
  import { type CodegenResult } from './db-codegen.js';
5
5
  import { type ZodCodegenResult } from './zod-codegen.js';
6
- import { type SeedResult } from './sqlite/seed.js';
6
+ import { type DevSeedResult } from './sqlite/dev-seed.js';
7
7
  import type { UserConfigShape } from '../commands/db-shared.js';
8
8
  interface ResolvedDbBase {
9
9
  rootDir: string;
@@ -18,12 +18,18 @@ interface ResolvedDbBase {
18
18
  enumsFile: string;
19
19
  zodFile: string;
20
20
  camelCase: boolean;
21
+ /**
22
+ * Schema whose qualifier the generated types drop, from `db.defaultSchema`.
23
+ * Unlike `schema` this applies to both dialects — sqlite has no schemas to
24
+ * qualify with, so it is simply inert there.
25
+ */
26
+ defaultSchema?: string;
21
27
  }
22
28
  export interface ResolvedSqliteDb extends ResolvedDbBase {
23
29
  dialect: 'sqlite';
24
30
  dbFile: string;
25
31
  runtimeDir: string;
26
- seedFile: string;
32
+ devSeedFile: string;
27
33
  }
28
34
  export interface ResolvedPostgresDb extends ResolvedDbBase {
29
35
  dialect: 'postgres';
@@ -31,7 +37,25 @@ export interface ResolvedPostgresDb extends ResolvedDbBase {
31
37
  connectionString?: string;
32
38
  pgliteDir?: string;
33
39
  runtimeDir: string;
34
- seedFile: string;
40
+ devSeedFile: string;
41
+ /**
42
+ * Postgres extensions the embedded PGlite databases must load, as declared by
43
+ * `pgliteExtensions` in the project's config. See
44
+ * {@link loadPGliteExtensions}.
45
+ *
46
+ * Carried even in `url` mode: the shadow database the CLI migrates and
47
+ * introspects is PGlite whichever server the project itself runs against, so
48
+ * a migration that needs an extension needs it here too.
49
+ */
50
+ pgliteExtensions: string[];
51
+ /**
52
+ * The schema generated migrations create their tables in, from `db.schema`.
53
+ *
54
+ * Postgres only — hence its absence from `ResolvedSqliteDb` rather than a
55
+ * runtime check. sqlite's `REFERENCES` clause takes a bare table name, so
56
+ * qualified DDL does not compile there at all.
57
+ */
58
+ schema?: string;
35
59
  }
36
60
  export type ResolvedDb = ResolvedSqliteDb | ResolvedPostgresDb;
37
61
  /**
@@ -45,9 +69,47 @@ export declare function parseDatabaseUrl(url: string): Pick<UserConfigShape, 'sq
45
69
  * Resolve a UserConfigShape into an absolute-path descriptor.
46
70
  * Returns null when neither sqliteDb nor postgresUrl is configured.
47
71
  */
48
- export declare function resolveDb(userConfig: UserConfigShape, rootDir: string, outDir: string, runtimeDir?: string): ResolvedDb | null;
72
+ export declare function resolveDb(userConfig: UserConfigShape, rootDir: string, outDir: string, runtimeDir?: string, dbConfig?: {
73
+ schema?: string;
74
+ defaultSchema?: string;
75
+ } | string): ResolvedDb | null;
49
76
  /** @deprecated Use resolveDb(userConfig, ...) instead. */
50
77
  export declare function resolveLocalDb(sqliteDb: string | undefined, rootDir: string, outDir: string, runtimeDir?: string): ResolvedSqliteDb | null;
78
+ /**
79
+ * What an embedded PGlite instance needs beyond its data directory: where to
80
+ * resolve extension packages from, and which ones to load.
81
+ *
82
+ * A `ResolvedPostgresDb` already is one, which is what lets every call site
83
+ * that has one pass it straight through.
84
+ */
85
+ export interface PGliteExtensionContext {
86
+ rootDir: string;
87
+ pgliteExtensions: string[];
88
+ }
89
+ /**
90
+ * A PGlite extension, as the packages that publish one export it: an object
91
+ * carrying the `setup` that hands PGlite the WASM bundle, or a URL/string
92
+ * pointing at a remote one.
93
+ *
94
+ * Structural rather than imported from PGlite so a project's extension package
95
+ * — built against its own copy of `@electric-sql/pglite` — is recognised
96
+ * whatever the two versions are.
97
+ */
98
+ type PGliteExtension = {
99
+ name?: string;
100
+ setup: (...args: any[]) => unknown;
101
+ };
102
+ /**
103
+ * Load every extension the project declares, keyed the way PGlite wants them.
104
+ *
105
+ * The key is the export name (`vector`, `hstore`), which is also the name the
106
+ * SQL uses, so `CREATE EXTENSION vector` finds what a declaration of
107
+ * `@electric-sql/pglite-pgvector` loaded. A module exporting several is fine —
108
+ * all of them are taken — and a `default` export is used only when it is the
109
+ * only extension there, so a package that default-exports the same object it
110
+ * also names is not registered twice.
111
+ */
112
+ export declare function loadPGliteExtensions(rootDir: string, specs: string[]): Promise<Record<string, PGliteExtension>>;
51
113
  export interface MigrateAndCodegenOutcome {
52
114
  migrate: MigrateResult;
53
115
  codegen: CodegenResult;
@@ -73,7 +135,15 @@ export interface MigrateAndCodegenOptions {
73
135
  scratch?: boolean;
74
136
  }
75
137
  export declare function migrateAndCodegen(resolved: ResolvedDb, options?: MigrateAndCodegenOptions): Promise<MigrateAndCodegenOutcome>;
76
- export declare function seed(resolved: ResolvedDb): Promise<SeedResult>;
138
+ /**
139
+ * Apply the dev seed file. Only {@link reset} calls this, immediately after
140
+ * migrating a database it has just wiped, which is what lets a seed file be
141
+ * plain `INSERT`s rather than idempotent ones.
142
+ *
143
+ * `reset` refuses production before it gets here, so this guard is unreachable
144
+ * through the CLI. It stays because the export is reachable without it.
145
+ */
146
+ export declare function devSeed(resolved: ResolvedDb): Promise<DevSeedResult>;
77
147
  export declare function reset(resolved: ResolvedDb, rootDir: string): Promise<void>;
78
148
  export declare function createKysely<DB>(resolved: ResolvedDb): Promise<Kysely<DB>>;
79
149
  /**
@@ -229,6 +299,17 @@ export interface SchemaSource {
229
299
  desired: DesiredSchema;
230
300
  /** Prose for the migration header, saying where the SQL came from. */
231
301
  origin: string;
302
+ /**
303
+ * The schema this source's SQL is qualified into, when it is.
304
+ *
305
+ * Carried per source rather than read off the resolved database because only
306
+ * the sources pikku compiles can honour it. Better Auth writes its own
307
+ * migration SQL through its own migrator and an addon ships SQL as text —
308
+ * neither goes through the schema builder, so neither can be qualified from
309
+ * here, and claiming otherwise on their behalf would emit a delta that names
310
+ * a table in a schema their `CREATE TABLE` never put it in.
311
+ */
312
+ schema?: string;
232
313
  }
233
314
  /** One dialect's worth of a published schema. */
234
315
  export interface ExportedSchema {
@@ -265,7 +346,7 @@ export interface AddonDeclaration {
265
346
  * happens to be configured against — an addon is published once and consumed by
266
347
  * projects on either engine.
267
348
  */
268
- export declare function exportSchema(rootDir: string): Promise<SchemaArtifact>;
349
+ export declare function exportSchema(rootDir: string, pgliteExtensions?: string[]): Promise<SchemaArtifact>;
269
350
  /**
270
351
  * The schema every wired addon publishes, as sources.
271
352
  *
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, rmSync, writeFileSync, readFileSync, readdirSync, } from 'node:fs';
2
2
  import { resolve, isAbsolute, relative, dirname, join } from 'node:path';
3
3
  import { createRequire } from 'node:module';
4
+ import { pathToFileURL } from 'node:url';
4
5
  import { runInNewContext } from 'node:vm';
5
6
  import { transformSync } from 'esbuild';
6
7
  import { CamelCasePlugin, Kysely, PostgresDialect } from 'kysely';
@@ -15,7 +16,7 @@ import { SqliteMigrationExecutor } from './sqlite/sqlite-migrator.js';
15
16
  import { SqliteIntrospector } from './sqlite/sqlite-introspector.js';
16
17
  import { createSqliteKysely } from './sqlite/sqlite-kysely.js';
17
18
  import { loadSqliteRuntime } from './sqlite/sqlite-runtime.js';
18
- import { seed as runSeed } from './sqlite/seed.js';
19
+ import { devSeed as runDevSeed } from './sqlite/dev-seed.js';
19
20
  import { PostgresMigrationExecutor } from './postgres/postgres-migrator.js';
20
21
  import { createPGliteKysely } from './postgres/pglite-kysely.js';
21
22
  import { PostgresIntrospector } from './postgres/postgres-introspector.js';
@@ -37,7 +38,11 @@ export function parseDatabaseUrl(url) {
37
38
  * Resolve a UserConfigShape into an absolute-path descriptor.
38
39
  * Returns null when neither sqliteDb nor postgresUrl is configured.
39
40
  */
40
- export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
41
+ export function resolveDb(userConfig, rootDir, outDir, runtimeDir, dbConfig) {
42
+ // The parameter took a bare schema string before `defaultSchema` existed;
43
+ // both forms are accepted so callers outside this repo keep working.
44
+ const schema = typeof dbConfig === 'string' ? dbConfig : dbConfig?.schema;
45
+ const defaultSchema = typeof dbConfig === 'string' ? undefined : dbConfig?.defaultSchema;
41
46
  const resolvedRuntimeDir = runtimeDir
42
47
  ? resolveAgainst(rootDir, runtimeDir)
43
48
  : join(rootDir, '.pikku-runtime');
@@ -58,17 +63,21 @@ export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
58
63
  classificationsGenJsonFile: join(rootDir, 'db', 'annotations.gen.json'),
59
64
  zodFile: join(outDir, 'db', 'zod.gen.ts'),
60
65
  camelCase: true,
66
+ defaultSchema,
61
67
  });
62
68
  if (userConfig.postgresUrl && userConfig.sqliteDb) {
63
69
  throw new Error('Both postgresUrl and sqliteDb are set. Configure exactly one database dialect.');
64
70
  }
71
+ const pgliteExtensions = userConfig.pgliteExtensions ?? [];
65
72
  if (userConfig.postgresUrl) {
66
73
  return {
67
74
  dialect: 'postgres',
68
75
  mode: 'url',
69
76
  connectionString: userConfig.postgresUrl,
70
77
  runtimeDir: resolvedRuntimeDir,
71
- seedFile: resolveAgainst(rootDir, 'db/postgres-seed.sql'),
78
+ devSeedFile: resolveAgainst(rootDir, 'db/postgres-dev-seed.sql'),
79
+ pgliteExtensions,
80
+ schema,
72
81
  ...base('db/postgres'),
73
82
  };
74
83
  }
@@ -77,11 +86,17 @@ export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
77
86
  ? '.pikku-runtime/dev.db'
78
87
  : undefined);
79
88
  if (sqliteDb) {
89
+ if (schema) {
90
+ throw new Error(`db.schema is set to '${schema}', but the resolved database is sqlite. ` +
91
+ 'sqlite has one schema to be in, and its REFERENCES clause takes a bare ' +
92
+ 'table name, so qualified DDL does not compile there. Remove db.schema, ' +
93
+ 'or configure postgres.');
94
+ }
80
95
  return {
81
96
  dialect: 'sqlite',
82
97
  dbFile: resolveAgainst(rootDir, sqliteDb),
83
98
  runtimeDir: resolvedRuntimeDir,
84
- seedFile: resolveAgainst(rootDir, 'db/sqlite-seed.sql'),
99
+ devSeedFile: resolveAgainst(rootDir, 'db/sqlite-dev-seed.sql'),
85
100
  ...base('db/sqlite'),
86
101
  };
87
102
  }
@@ -91,7 +106,9 @@ export function resolveDb(userConfig, rootDir, outDir, runtimeDir) {
91
106
  mode: 'pglite',
92
107
  pgliteDir: join(resolvedRuntimeDir, 'dev-postgres'),
93
108
  runtimeDir: resolvedRuntimeDir,
94
- seedFile: resolveAgainst(rootDir, 'db/postgres-seed.sql'),
109
+ devSeedFile: resolveAgainst(rootDir, 'db/postgres-dev-seed.sql'),
110
+ pgliteExtensions,
111
+ schema,
95
112
  ...base('db/postgres'),
96
113
  };
97
114
  }
@@ -120,7 +137,7 @@ async function createPostgresClient(resolved) {
120
137
  throw new Error('PGlite Postgres resolution is missing pgliteDir.');
121
138
  }
122
139
  mkdirSync(dirname(resolved.pgliteDir), { recursive: true });
123
- const db = await createEmbeddedPostgres(resolved.pgliteDir);
140
+ const db = await createEmbeddedPostgres(resolved, resolved.pgliteDir);
124
141
  return pgliteAsClient(db);
125
142
  }
126
143
  let embeddedPostgresWasm;
@@ -157,21 +174,107 @@ async function loadEmbeddedPostgresWasm() {
157
174
  return undefined;
158
175
  }
159
176
  }
160
- async function createEmbeddedPostgres(dataDir) {
177
+ const isPGliteExtension = (value) => typeof value === 'object' &&
178
+ value !== null &&
179
+ typeof value.setup === 'function';
180
+ /**
181
+ * Turn a declared extension specifier into the module that publishes it.
182
+ *
183
+ * A bare name is one of PGlite's own contrib extensions (`hstore`, `citext`,
184
+ * `uuid_ossp`), which ship with the CLI's copy of PGlite and need nothing
185
+ * installed. Anything else is a package the project depends on — pgvector, say,
186
+ * as `@electric-sql/pglite-pgvector` — so it is resolved from the project first
187
+ * and only then from the CLI, since the project is where a user installs it.
188
+ */
189
+ async function importPGliteExtensionModule(spec, rootDir) {
190
+ const id = spec.includes('/') || spec.startsWith('@')
191
+ ? spec
192
+ : `@electric-sql/pglite/contrib/${spec}`;
193
+ for (const from of [join(rootDir, 'package.json'), import.meta.url]) {
194
+ let resolvedPath;
195
+ try {
196
+ resolvedPath = createRequire(from).resolve(id);
197
+ }
198
+ catch {
199
+ continue;
200
+ }
201
+ return (await import(pathToFileURL(resolvedPath).href));
202
+ }
203
+ throw new Error(`The PGlite extension '${spec}' could not be resolved as '${id}', ` +
204
+ `from either the project (${rootDir}) or the pikku CLI. ` +
205
+ `Install it in your project, or name one of PGlite's bundled contrib ` +
206
+ `extensions (hstore, citext, uuid_ossp, …), which need no install.`);
207
+ }
208
+ /**
209
+ * Load every extension the project declares, keyed the way PGlite wants them.
210
+ *
211
+ * The key is the export name (`vector`, `hstore`), which is also the name the
212
+ * SQL uses, so `CREATE EXTENSION vector` finds what a declaration of
213
+ * `@electric-sql/pglite-pgvector` loaded. A module exporting several is fine —
214
+ * all of them are taken — and a `default` export is used only when it is the
215
+ * only extension there, so a package that default-exports the same object it
216
+ * also names is not registered twice.
217
+ */
218
+ export async function loadPGliteExtensions(rootDir, specs) {
219
+ const extensions = {};
220
+ for (const spec of specs) {
221
+ const module = await importPGliteExtensionModule(spec, rootDir);
222
+ const found = Object.entries(module).filter(([, value]) => isPGliteExtension(value));
223
+ const named = found.filter(([name]) => name !== 'default');
224
+ const chosen = named.length > 0 ? named : found;
225
+ if (chosen.length === 0) {
226
+ throw new Error(`'${spec}' exports no PGlite extension. A PGlite extension is an ` +
227
+ `object with a 'setup' function — check that the package is one, ` +
228
+ `and that its version matches the PGlite the CLI runs.`);
229
+ }
230
+ for (const [name, extension] of chosen) {
231
+ extensions[name === 'default' ? (extension.name ?? spec) : name] =
232
+ extension;
233
+ }
234
+ }
235
+ return extensions;
236
+ }
237
+ async function createEmbeddedPostgres(context, dataDir) {
161
238
  embeddedPostgresWasm ??= loadEmbeddedPostgresWasm();
162
- const [{ PGlite }, { pgcrypto }, wasm] = await Promise.all([
239
+ const [{ PGlite }, { pgcrypto }, wasm, declared] = await Promise.all([
163
240
  import('@electric-sql/pglite'),
164
241
  import('@electric-sql/pglite/contrib/pgcrypto'),
165
242
  embeddedPostgresWasm,
243
+ loadPGliteExtensions(context.rootDir, context.pgliteExtensions),
166
244
  ]);
167
245
  return new PGlite({
168
246
  ...(dataDir ? { dataDir } : {}),
169
247
  ...wasm,
170
248
  extensions: {
171
249
  pgcrypto,
250
+ ...declared,
172
251
  },
173
252
  });
174
253
  }
254
+ /**
255
+ * PGlite reports an extension it was never given as a plain
256
+ * `extension "x" is not available`, which reads as though the SQL is at fault.
257
+ * It is not: the database is real Postgres, the migration is fine, and the one
258
+ * thing missing is the declaration that would have loaded the extension into
259
+ * this particular instance. Say so, since nothing else in the message points
260
+ * anywhere near the fix.
261
+ */
262
+ function explainMissingExtension(error, declared) {
263
+ const message = error instanceof Error ? error.message : '';
264
+ const match = /extension "([^"]+)" is not available/.exec(message);
265
+ if (!match)
266
+ return error;
267
+ const name = match[1];
268
+ return new Error(`The embedded PGlite database has no '${name}' extension. ` +
269
+ `The CLI migrates a PGlite shadow database to type and diff your schema, ` +
270
+ `so every extension your migrations use has to be declared as ` +
271
+ `pgliteExtensions in createConfig — e.g. pgliteExtensions: ['${name}'] ` +
272
+ `for a PGlite contrib extension, or the package that publishes it ` +
273
+ `('@electric-sql/pglite-pgvector' for pgvector).` +
274
+ (declared.length > 0
275
+ ? ` Currently declared: ${declared.join(', ')}.`
276
+ : ''), { cause: error });
277
+ }
175
278
  function pgliteAsClient(db) {
176
279
  return {
177
280
  query: (sql, params) => db.query(sql, params),
@@ -189,6 +292,14 @@ async function withPostgresClient(resolved, run) {
189
292
  try {
190
293
  return await run(client);
191
294
  }
295
+ catch (error) {
296
+ // Only the embedded database's missing extensions are the declaration's
297
+ // doing. On a real server it is the server that lacks the extension, and
298
+ // pointing at the CLI's config would send the reader the wrong way.
299
+ throw resolved.mode === 'pglite'
300
+ ? explainMissingExtension(error, resolved.pgliteExtensions)
301
+ : error;
302
+ }
192
303
  finally {
193
304
  await client.end();
194
305
  }
@@ -226,6 +337,7 @@ export async function migrateAndCodegen(resolved, options = {}) {
226
337
  schemaJsonFile: resolved.schemaJsonFile,
227
338
  enumsFile: resolved.enumsFile,
228
339
  camelCase: resolved.camelCase,
340
+ defaultSchema: resolved.defaultSchema,
229
341
  rootDir: resolved.rootDir,
230
342
  dialect: 'sqlite',
231
343
  migrationsDir: resolved.migrationsDir,
@@ -237,7 +349,7 @@ export async function migrateAndCodegen(resolved, options = {}) {
237
349
  }
238
350
  else {
239
351
  const withClient = options.scratch
240
- ? (_r, run) => withScratchPostgresDatabase(run)
352
+ ? (r, run) => withScratchPostgresDatabase(r, run)
241
353
  : withPostgresClient;
242
354
  await withClient(resolved, async (client) => {
243
355
  const introspector = new PostgresIntrospector(client);
@@ -253,6 +365,7 @@ export async function migrateAndCodegen(resolved, options = {}) {
253
365
  schemaJsonFile: resolved.schemaJsonFile,
254
366
  enumsFile: resolved.enumsFile,
255
367
  camelCase: resolved.camelCase,
368
+ defaultSchema: resolved.defaultSchema,
256
369
  rootDir: resolved.rootDir,
257
370
  dialect: 'postgres',
258
371
  migrationsDir: resolved.migrationsDir,
@@ -282,21 +395,32 @@ export async function migrateAndCodegen(resolved, options = {}) {
282
395
  };
283
396
  }
284
397
  // ─── SQLite-only operations ───────────────────────────────────────────────────
285
- export async function seed(resolved) {
398
+ /**
399
+ * Apply the dev seed file. Only {@link reset} calls this, immediately after
400
+ * migrating a database it has just wiped, which is what lets a seed file be
401
+ * plain `INSERT`s rather than idempotent ones.
402
+ *
403
+ * `reset` refuses production before it gets here, so this guard is unreachable
404
+ * through the CLI. It stays because the export is reachable without it.
405
+ */
406
+ export async function devSeed(resolved) {
407
+ if (process.env.NODE_ENV === 'production') {
408
+ throw new Error(`pikku dev seed refused: NODE_ENV=production. Seed data is test data — it only runs in dev.`);
409
+ }
286
410
  if (resolved.dialect === 'sqlite') {
287
411
  const runtime = await loadSqliteRuntime();
288
412
  const db = runtime.open(resolved.dbFile);
289
413
  try {
290
- return runSeed(db, resolved.seedFile);
414
+ return runDevSeed(db, resolved.devSeedFile);
291
415
  }
292
416
  finally {
293
417
  db.close();
294
418
  }
295
419
  }
296
- if (!existsSync(resolved.seedFile)) {
420
+ if (!existsSync(resolved.devSeedFile)) {
297
421
  return { applied: false, bytes: 0 };
298
422
  }
299
- const sql = readFileSync(resolved.seedFile, 'utf8');
423
+ const sql = readFileSync(resolved.devSeedFile, 'utf8');
300
424
  if (sql.trim().length === 0) {
301
425
  return { applied: false, bytes: 0 };
302
426
  }
@@ -346,8 +470,7 @@ export async function reset(resolved, rootDir) {
346
470
  AND schema_name NOT LIKE 'pg_temp_%'
347
471
  `);
348
472
  for (const { schema_name: schemaName } of result.rows) {
349
- const quoted = `"${schemaName.replace(/"/g, '""')}"`;
350
- await client.query(`DROP SCHEMA IF EXISTS ${quoted} CASCADE`);
473
+ await client.query(`DROP SCHEMA IF EXISTS ${quoteIdentifier(schemaName)} CASCADE`);
351
474
  }
352
475
  await client.query('CREATE SCHEMA IF NOT EXISTS public');
353
476
  });
@@ -474,7 +597,7 @@ export async function createKysely(resolved) {
474
597
  }
475
598
  mkdirSync(dirname(resolved.pgliteDir), { recursive: true });
476
599
  return createPGliteKysely({
477
- db: await createEmbeddedPostgres(resolved.pgliteDir),
600
+ db: await createEmbeddedPostgres(resolved, resolved.pgliteDir),
478
601
  camelCase: resolved.camelCase,
479
602
  plugins,
480
603
  });
@@ -486,11 +609,22 @@ async function introspectorToMap(intro) {
486
609
  }
487
610
  return map;
488
611
  }
489
- function diffSchemas(desired, actual) {
612
+ /**
613
+ * The tables and columns `desired` has that `actual` does not.
614
+ *
615
+ * `schema` is the one the desired bare names belong in, when the caller knows.
616
+ * Given it, only that schema's copy of a table counts: a `workflow_step` in
617
+ * `public` is a different table from the `app.workflow_step` a source with
618
+ * `db.schema: "app"` wants, and letting it match would report the source
619
+ * satisfied by a table its SQL never creates.
620
+ */
621
+ function diffSchemas(desired, actual, schema) {
490
622
  const missingTables = [];
491
623
  const missingColumns = [];
492
624
  for (const [table, cols] of desired) {
493
- const actualCols = actual.get(table) ?? schemaQualifiedMatch(actual, table);
625
+ const actualCols = schema
626
+ ? actual.get(qualifiedTableKey(schema, table))
627
+ : (actual.get(table) ?? schemaQualifiedMatch(actual, table));
494
628
  if (!actualCols) {
495
629
  missingTables.push(table);
496
630
  continue;
@@ -501,6 +635,19 @@ function diffSchemas(desired, actual) {
501
635
  }
502
636
  return { missingTables, missingColumns };
503
637
  }
638
+ /**
639
+ * How an introspected schema map keys a table in a given schema.
640
+ *
641
+ * Introspection elides `public`, so the key for a table there is the bare name.
642
+ * Anything else carries its qualifier.
643
+ */
644
+ function qualifiedTableKey(schema, table) {
645
+ return schema === 'public' ? table : `${schema}.${table}`;
646
+ }
647
+ /** A PostgreSQL identifier, quoted so its casing survives the parser. */
648
+ function quoteIdentifier(name) {
649
+ return `"${name.replace(/"/g, '""')}"`;
650
+ }
504
651
  /**
505
652
  * The one table in `actual` whose name matches `table` once its schema is
506
653
  * dropped, if there is exactly one.
@@ -530,11 +677,14 @@ function isPostgresAuthDatabase(options) {
530
677
  // target server. Creating a real database via `CREATE DATABASE` would require
531
678
  // elevated privileges that application roles (correctly) don't have, which made
532
679
  // `pikku db migrate` fail against managed/locked-down Postgres (error 42501).
533
- async function withScratchPostgresDatabase(run) {
534
- const scratchDb = await createEmbeddedPostgres();
680
+ async function withScratchPostgresDatabase(context, run) {
681
+ const scratchDb = await createEmbeddedPostgres(context);
535
682
  try {
536
683
  return await run(pgliteAsClient(scratchDb));
537
684
  }
685
+ catch (error) {
686
+ throw explainMissingExtension(error, context.pgliteExtensions);
687
+ }
538
688
  finally {
539
689
  if (!scratchDb.closed) {
540
690
  await scratchDb.close();
@@ -551,8 +701,8 @@ async function postgresDatabaseToMap(client) {
551
701
  await intro.close();
552
702
  }
553
703
  }
554
- async function desiredPostgresAuthSchema(rootDir, srcDirectories, logger) {
555
- return withScratchPostgresDatabase(async (scratchDb) => {
704
+ async function desiredPostgresAuthSchema(context, rootDir, srcDirectories, logger) {
705
+ return withScratchPostgresDatabase(context, async (scratchDb) => {
556
706
  // The scratch DB is always an embedded PGlite instance (see
557
707
  // withScratchPostgresDatabase), so drive Better Auth's migration codegen
558
708
  // through the PGlite-backed Kysely regardless of how the app DB is
@@ -598,7 +748,7 @@ export async function desiredAuthSchema(resolved, rootDir, srcDirectories, logge
598
748
  if (resolved.dialect !== 'postgres') {
599
749
  throw new Error('Better Auth database.type is postgres, but the resolved app database is not postgres.');
600
750
  }
601
- return desiredPostgresAuthSchema(rootDir, srcDirectories, logger);
751
+ return desiredPostgresAuthSchema(resolved, rootDir, srcDirectories, logger);
602
752
  }
603
753
  const { runMigrations, compileMigrations } = await getAuthMigrations(options);
604
754
  await runMigrations();
@@ -685,7 +835,7 @@ export async function desiredRuntimeSchema(resolved, rootDir, srcDirectories, lo
685
835
  db.close();
686
836
  }
687
837
  }
688
- return withScratchPostgresDatabase(async (db) => {
838
+ return withScratchPostgresDatabase(resolved, async (db) => {
689
839
  const kysely = createPGliteKysely({
690
840
  db: db.__pglite,
691
841
  camelCase: true,
@@ -694,7 +844,7 @@ export async function desiredRuntimeSchema(resolved, rootDir, srcDirectories, lo
694
844
  const { tables, schemas, types } = await collect(kysely, () => postgresDatabaseToMap(db));
695
845
  return {
696
846
  tables,
697
- sql: compilePikkuSchemas(kysely, schemas, types),
847
+ sql: compilePikkuSchemas(kysely, schemas, types, resolved.schema),
698
848
  skipped,
699
849
  };
700
850
  }
@@ -736,8 +886,8 @@ async function coveredSqliteSchema(migrationsDir) {
736
886
  db.close();
737
887
  }
738
888
  }
739
- async function coveredPostgresSchema(migrationsDir) {
740
- return withScratchPostgresDatabase(async (client) => {
889
+ async function coveredPostgresSchema(migrationsDir, context) {
890
+ return withScratchPostgresDatabase(context, async (client) => {
741
891
  await migrate(new PostgresMigrationExecutor(client), migrationsDir);
742
892
  return postgresDatabaseToMap(client);
743
893
  });
@@ -764,7 +914,7 @@ async function coveredPostgresSchema(migrationsDir) {
764
914
  export async function computeSchemaDrift(resolved, rootDir, srcDirectories, logger) {
765
915
  const covered = resolved.dialect === 'sqlite'
766
916
  ? await coveredSqliteSchema(resolved.migrationsDir)
767
- : await coveredPostgresSchema(resolved.migrationsDir);
917
+ : await coveredPostgresSchema(resolved.migrationsDir, resolved);
768
918
  const actual = await introspectSchema(resolved);
769
919
  const { missingTables, missingColumns } = diffSchemas(covered, actual);
770
920
  // Compare on the full name. A migration that names no schema lands in
@@ -889,7 +1039,7 @@ const concatMigrations = (migrationsDir) => readdirSync(migrationsDir)
889
1039
  * happens to be configured against — an addon is published once and consumed by
890
1040
  * projects on either engine.
891
1041
  */
892
- export async function exportSchema(rootDir) {
1042
+ export async function exportSchema(rootDir, pgliteExtensions = []) {
893
1043
  const artifact = {};
894
1044
  const sqliteDir = join(rootDir, 'db', 'sqlite');
895
1045
  if (existsSync(sqliteDir)) {
@@ -902,7 +1052,7 @@ export async function exportSchema(rootDir) {
902
1052
  if (existsSync(postgresDir)) {
903
1053
  artifact.postgres = {
904
1054
  sql: concatMigrations(postgresDir),
905
- tables: serializeSchemaMap(await coveredPostgresSchema(postgresDir)),
1055
+ tables: serializeSchemaMap(await coveredPostgresSchema(postgresDir, { rootDir, pgliteExtensions })),
906
1056
  };
907
1057
  }
908
1058
  return artifact;
@@ -975,6 +1125,7 @@ export async function schemaSources(resolved, rootDir, srcDirectories, logger, a
975
1125
  name: 'pikku-runtime',
976
1126
  desired: runtime,
977
1127
  origin: "@pikku/kysely's runtime services",
1128
+ schema: resolved.dialect === 'postgres' ? resolved.schema : undefined,
978
1129
  });
979
1130
  }
980
1131
  sources.push(...(await addonSchemaSources(rootDir, resolved.dialect, addons, logger)));
@@ -1042,15 +1193,31 @@ export async function generateMigrations(resolved, rootDir, srcDirectories, logg
1042
1193
  // is part of what the next one is compared against.
1043
1194
  const covered = resolved.dialect === 'sqlite'
1044
1195
  ? await coveredSqliteSchema(resolved.migrationsDir)
1045
- : await coveredPostgresSchema(resolved.migrationsDir);
1046
- const { missingTables, missingColumns } = diffSchemas(source.desired.tables, covered);
1196
+ : await coveredPostgresSchema(resolved.migrationsDir, resolved);
1197
+ const { missingTables, missingColumns } = diffSchemas(source.desired.tables, covered, source.schema);
1047
1198
  if (missingTables.length === 0 && missingColumns.length === 0) {
1048
1199
  result.upToDate.push(source.name);
1049
1200
  continue;
1050
1201
  }
1051
- const partial = [...source.desired.tables.keys()].some((t) => covered.has(t));
1202
+ // Matched the same way `diffSchemas` matches, qualifier and all. A project
1203
+ // that keeps its tables in a schema has them covered as `app.workflow_step`
1204
+ // while the declaration names them bare, so a strict `covered.has(t)` reads
1205
+ // "nothing is covered" and re-emits the whole schema over tables that are
1206
+ // already there — and a copy in some other schema is not that table, so it
1207
+ // must not count either.
1208
+ const partial = [...source.desired.tables.keys()].some((t) => source.schema
1209
+ ? covered.has(qualifiedTableKey(source.schema, t))
1210
+ : covered.has(t) || schemaQualifiedMatch(covered, t) !== undefined);
1052
1211
  let body;
1053
1212
  let needsBackfill = [];
1213
+ // The source's own SQL is already qualified when it can be; the delta below
1214
+ // is written here from bare introspected names, so it has to be qualified
1215
+ // to match, or it alters a table in whichever schema `search_path` finds.
1216
+ // Quoted, because the compiled SQL this delta has to line up with goes
1217
+ // through the schema builder and is quoted there. `db.schema: "App"` left
1218
+ // raw folds to `app`, so the delta would alter a table in a schema the
1219
+ // runtime never uses.
1220
+ const qualify = (table) => source.schema ? `${quoteIdentifier(source.schema)}.${table}` : table;
1054
1221
  if (!partial) {
1055
1222
  body = source.desired.sql;
1056
1223
  }
@@ -1071,7 +1238,7 @@ export async function generateMigrations(resolved, rootDir, srcDirectories, logg
1071
1238
  statements.push(`-- REVIEW: ${table} is new, and its CREATE TABLE could not be found in the\n` +
1072
1239
  `-- source's own SQL. The column list below carries no indexes, constraints\n` +
1073
1240
  `-- or foreign keys — copy the real statement over it before applying.\n` +
1074
- `CREATE TABLE ${table} (\n` +
1241
+ `CREATE TABLE ${qualify(table)} (\n` +
1075
1242
  [...(columns?.values() ?? [])]
1076
1243
  .map((c) => ` ${c.name} ${c.type}${c.notNull ? ' NOT NULL' : ''}`)
1077
1244
  .join(',\n') +
@@ -1081,7 +1248,7 @@ export async function generateMigrations(resolved, rootDir, srcDirectories, logg
1081
1248
  const infos = columns
1082
1249
  .map((name) => source.desired.tables.get(table)?.get(name))
1083
1250
  .filter((c) => c !== undefined);
1084
- const added = addColumnStatements(table, infos);
1251
+ const added = addColumnStatements(qualify(table), infos);
1085
1252
  statements.push(...added.sql);
1086
1253
  needsBackfill.push(...added.needsBackfill);
1087
1254
  }
@@ -0,0 +1,12 @@
1
+ import type { SyncSqliteDatabase } from './sqlite-runtime.js';
2
+ export interface DevSeedResult {
3
+ applied: boolean;
4
+ bytes: number;
5
+ }
6
+ /**
7
+ * Apply db/<engine>-dev-seed.sql to the open db. Only `pikku db reset` reaches
8
+ * here, against a database it has just wiped and migrated, so the file may be
9
+ * plain `INSERT`s — it is never applied twice. Returns `applied: false` if the
10
+ * file doesn't exist; throws on SQL errors.
11
+ */
12
+ export declare function devSeed(db: SyncSqliteDatabase, devSeedFile: string): DevSeedResult;
@@ -0,0 +1,23 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ /**
3
+ * Apply db/<engine>-dev-seed.sql to the open db. Only `pikku db reset` reaches
4
+ * here, against a database it has just wiped and migrated, so the file may be
5
+ * plain `INSERT`s — it is never applied twice. Returns `applied: false` if the
6
+ * file doesn't exist; throws on SQL errors.
7
+ */
8
+ export function devSeed(db, devSeedFile) {
9
+ if (!existsSync(devSeedFile)) {
10
+ return { applied: false, bytes: 0 };
11
+ }
12
+ const raw = readFileSync(devSeedFile);
13
+ db.exec('BEGIN');
14
+ try {
15
+ db.exec(raw.toString('utf8'));
16
+ db.exec('COMMIT');
17
+ }
18
+ catch (err) {
19
+ db.exec('ROLLBACK');
20
+ throw err;
21
+ }
22
+ return { applied: true, bytes: raw.length };
23
+ }