@supatype/cli 0.1.6 → 0.1.9

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 (477) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +152 -102
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/LICENSE +202 -0
  5. package/deno.d.ts +52 -0
  6. package/dist/app/framework.js +1 -1
  7. package/dist/app/framework.js.map +1 -1
  8. package/dist/augmentation-generator.d.ts +22 -0
  9. package/dist/augmentation-generator.d.ts.map +1 -1
  10. package/dist/augmentation-generator.js +19 -5
  11. package/dist/augmentation-generator.js.map +1 -1
  12. package/dist/binary-cache.d.ts +42 -6
  13. package/dist/binary-cache.d.ts.map +1 -1
  14. package/dist/binary-cache.js +76 -44
  15. package/dist/binary-cache.js.map +1 -1
  16. package/dist/cache-clean.d.ts +15 -0
  17. package/dist/cache-clean.d.ts.map +1 -0
  18. package/dist/cache-clean.js +76 -0
  19. package/dist/cache-clean.js.map +1 -0
  20. package/dist/cache-pins.d.ts +51 -0
  21. package/dist/cache-pins.d.ts.map +1 -0
  22. package/dist/cache-pins.js +184 -0
  23. package/dist/cache-pins.js.map +1 -0
  24. package/dist/cli-artifacts.d.ts +32 -0
  25. package/dist/cli-artifacts.d.ts.map +1 -0
  26. package/dist/cli-artifacts.js +49 -0
  27. package/dist/cli-artifacts.js.map +1 -0
  28. package/dist/cli-install-method.d.ts +27 -0
  29. package/dist/cli-install-method.d.ts.map +1 -0
  30. package/dist/cli-install-method.js +78 -0
  31. package/dist/cli-install-method.js.map +1 -0
  32. package/dist/cli-package-version.d.ts +1 -1
  33. package/dist/cli-package-version.d.ts.map +1 -1
  34. package/dist/cli-package-version.js +6 -1
  35. package/dist/cli-package-version.js.map +1 -1
  36. package/dist/cli-standalone.d.ts +13 -4
  37. package/dist/cli-standalone.d.ts.map +1 -1
  38. package/dist/cli-standalone.js +86 -31
  39. package/dist/cli-standalone.js.map +1 -1
  40. package/dist/cli-version-embedded.d.ts +10 -0
  41. package/dist/cli-version-embedded.d.ts.map +1 -0
  42. package/dist/cli-version-embedded.js +13 -0
  43. package/dist/cli-version-embedded.js.map +1 -0
  44. package/dist/cli.d.ts.map +1 -1
  45. package/dist/cli.js +7 -1
  46. package/dist/cli.js.map +1 -1
  47. package/dist/cloud-credentials.d.ts +34 -0
  48. package/dist/cloud-credentials.d.ts.map +1 -0
  49. package/dist/cloud-credentials.js +139 -0
  50. package/dist/cloud-credentials.js.map +1 -0
  51. package/dist/commands/add.js +1 -1
  52. package/dist/commands/add.js.map +1 -1
  53. package/dist/commands/admin.d.ts +11 -0
  54. package/dist/commands/admin.d.ts.map +1 -1
  55. package/dist/commands/admin.js +123 -21
  56. package/dist/commands/admin.js.map +1 -1
  57. package/dist/commands/adopt.js +1 -1
  58. package/dist/commands/adopt.js.map +1 -1
  59. package/dist/commands/app.js +2 -2
  60. package/dist/commands/app.js.map +1 -1
  61. package/dist/commands/cache.d.ts +1 -1
  62. package/dist/commands/cache.d.ts.map +1 -1
  63. package/dist/commands/cache.js +69 -73
  64. package/dist/commands/cache.js.map +1 -1
  65. package/dist/commands/cloud.d.ts.map +1 -1
  66. package/dist/commands/cloud.js +32 -8
  67. package/dist/commands/cloud.js.map +1 -1
  68. package/dist/commands/db.d.ts +3 -2
  69. package/dist/commands/db.d.ts.map +1 -1
  70. package/dist/commands/db.js +149 -3
  71. package/dist/commands/db.js.map +1 -1
  72. package/dist/commands/deploy.d.ts +9 -9
  73. package/dist/commands/deploy.js +12 -12
  74. package/dist/commands/deploy.js.map +1 -1
  75. package/dist/commands/dev.d.ts +3 -3
  76. package/dist/commands/dev.d.ts.map +1 -1
  77. package/dist/commands/dev.js +63 -23
  78. package/dist/commands/dev.js.map +1 -1
  79. package/dist/commands/doctor.d.ts +28 -0
  80. package/dist/commands/doctor.d.ts.map +1 -1
  81. package/dist/commands/doctor.js +60 -3
  82. package/dist/commands/doctor.js.map +1 -1
  83. package/dist/commands/engine.d.ts +1 -1
  84. package/dist/commands/engine.js +1 -1
  85. package/dist/commands/functions.d.ts +7 -0
  86. package/dist/commands/functions.d.ts.map +1 -1
  87. package/dist/commands/functions.js +45 -11
  88. package/dist/commands/functions.js.map +1 -1
  89. package/dist/commands/generate.d.ts.map +1 -1
  90. package/dist/commands/generate.js +5 -1
  91. package/dist/commands/generate.js.map +1 -1
  92. package/dist/commands/hooks.d.ts +12 -0
  93. package/dist/commands/hooks.d.ts.map +1 -0
  94. package/dist/commands/hooks.js +118 -0
  95. package/dist/commands/hooks.js.map +1 -0
  96. package/dist/commands/init.d.ts.map +1 -1
  97. package/dist/commands/init.js +64 -30
  98. package/dist/commands/init.js.map +1 -1
  99. package/dist/commands/internal.d.ts +6 -0
  100. package/dist/commands/internal.d.ts.map +1 -0
  101. package/dist/commands/internal.js +22 -0
  102. package/dist/commands/internal.js.map +1 -0
  103. package/dist/commands/link-helpers.d.ts.map +1 -1
  104. package/dist/commands/link-helpers.js +8 -2
  105. package/dist/commands/link-helpers.js.map +1 -1
  106. package/dist/commands/login.d.ts +7 -0
  107. package/dist/commands/login.d.ts.map +1 -0
  108. package/dist/commands/login.js +110 -0
  109. package/dist/commands/login.js.map +1 -0
  110. package/dist/commands/logs.d.ts +1 -1
  111. package/dist/commands/migrate.js +5 -5
  112. package/dist/commands/migrate.js.map +1 -1
  113. package/dist/commands/pg.d.ts +1 -1
  114. package/dist/commands/pg.js +1 -1
  115. package/dist/commands/plugins.js +1 -1
  116. package/dist/commands/plugins.js.map +1 -1
  117. package/dist/commands/pull.js +2 -2
  118. package/dist/commands/pull.js.map +1 -1
  119. package/dist/commands/push.d.ts.map +1 -1
  120. package/dist/commands/push.js +110 -7
  121. package/dist/commands/push.js.map +1 -1
  122. package/dist/commands/self-host.d.ts +1 -1
  123. package/dist/commands/self-host.js +1 -1
  124. package/dist/commands/self-update.d.ts +3 -2
  125. package/dist/commands/self-update.d.ts.map +1 -1
  126. package/dist/commands/self-update.js +31 -16
  127. package/dist/commands/self-update.js.map +1 -1
  128. package/dist/commands/status.d.ts +1 -1
  129. package/dist/commands/update.d.ts +1 -1
  130. package/dist/commands/update.js +1 -1
  131. package/dist/config.d.ts +1 -1
  132. package/dist/config.d.ts.map +1 -1
  133. package/dist/config.js +19 -4
  134. package/dist/config.js.map +1 -1
  135. package/dist/db-preflight.d.ts +78 -0
  136. package/dist/db-preflight.d.ts.map +1 -0
  137. package/dist/db-preflight.js +452 -0
  138. package/dist/db-preflight.js.map +1 -0
  139. package/dist/dev-compose.d.ts +4 -4
  140. package/dist/dev-compose.d.ts.map +1 -1
  141. package/dist/dev-compose.js +143 -88
  142. package/dist/dev-compose.js.map +1 -1
  143. package/dist/dev-log-filter.d.ts +1 -1
  144. package/dist/dev-log-filter.d.ts.map +1 -1
  145. package/dist/dev-log-filter.js +1 -1
  146. package/dist/dev-log-filter.js.map +1 -1
  147. package/dist/dev-ports.d.ts +2 -2
  148. package/dist/dev-ports.d.ts.map +1 -1
  149. package/dist/dev-ports.js +2 -2
  150. package/dist/dev-ports.js.map +1 -1
  151. package/dist/dev-session.d.ts +5 -5
  152. package/dist/dev-session.d.ts.map +1 -1
  153. package/dist/dev-session.js +6 -6
  154. package/dist/dev-session.js.map +1 -1
  155. package/dist/dev-shutdown.d.ts +5 -5
  156. package/dist/dev-shutdown.d.ts.map +1 -1
  157. package/dist/dev-shutdown.js +7 -7
  158. package/dist/dev-shutdown.js.map +1 -1
  159. package/dist/dev-task-colors.d.ts +1 -1
  160. package/dist/dev-task-colors.d.ts.map +1 -1
  161. package/dist/dev-task-colors.js +1 -1
  162. package/dist/dev-task-colors.js.map +1 -1
  163. package/dist/docker-postgres.d.ts +5 -5
  164. package/dist/docker-postgres.d.ts.map +1 -1
  165. package/dist/docker-postgres.js +5 -5
  166. package/dist/docker-postgres.js.map +1 -1
  167. package/dist/docker-runtime.d.ts +2 -2
  168. package/dist/docker-runtime.d.ts.map +1 -1
  169. package/dist/docker-runtime.js +5 -5
  170. package/dist/docker-runtime.js.map +1 -1
  171. package/dist/engine-client.d.ts +1 -1
  172. package/dist/engine-client.js +3 -3
  173. package/dist/engine-client.js.map +1 -1
  174. package/dist/engine-push-output.js +1 -1
  175. package/dist/engine-push-output.js.map +1 -1
  176. package/dist/ensure-binary.d.ts.map +1 -1
  177. package/dist/ensure-binary.js +17 -0
  178. package/dist/ensure-binary.js.map +1 -1
  179. package/dist/ensure-component-binaries.js +1 -1
  180. package/dist/ensure-component-binaries.js.map +1 -1
  181. package/dist/env-file.d.ts +40 -2
  182. package/dist/env-file.d.ts.map +1 -1
  183. package/dist/env-file.js +132 -11
  184. package/dist/env-file.js.map +1 -1
  185. package/dist/field-masking-tier.d.ts +50 -0
  186. package/dist/field-masking-tier.d.ts.map +1 -0
  187. package/dist/field-masking-tier.js +91 -0
  188. package/dist/field-masking-tier.js.map +1 -0
  189. package/dist/functions-deno-types.d.ts +24 -0
  190. package/dist/functions-deno-types.d.ts.map +1 -0
  191. package/dist/functions-deno-types.js +155 -0
  192. package/dist/functions-deno-types.js.map +1 -0
  193. package/dist/functions-router-gen.js +1 -1
  194. package/dist/gitignore.d.ts +2 -2
  195. package/dist/gitignore.d.ts.map +1 -1
  196. package/dist/gitignore.js +3 -3
  197. package/dist/gitignore.js.map +1 -1
  198. package/dist/hook-upload.d.ts +30 -0
  199. package/dist/hook-upload.d.ts.map +1 -0
  200. package/dist/hook-upload.js +86 -0
  201. package/dist/hook-upload.js.map +1 -0
  202. package/dist/hooks-generator.d.ts +8 -0
  203. package/dist/hooks-generator.d.ts.map +1 -0
  204. package/dist/hooks-generator.js +332 -0
  205. package/dist/hooks-generator.js.map +1 -0
  206. package/dist/index.d.ts +1 -1
  207. package/dist/index.js +1 -1
  208. package/dist/init-project-detect.d.ts +1 -1
  209. package/dist/init-project-detect.d.ts.map +1 -1
  210. package/dist/init-project-detect.js +1 -1
  211. package/dist/init-project-detect.js.map +1 -1
  212. package/dist/link.d.ts +4 -0
  213. package/dist/link.d.ts.map +1 -1
  214. package/dist/link.js +2 -0
  215. package/dist/link.js.map +1 -1
  216. package/dist/local-secrets.d.ts +71 -0
  217. package/dist/local-secrets.d.ts.map +1 -0
  218. package/dist/local-secrets.js +100 -0
  219. package/dist/local-secrets.js.map +1 -0
  220. package/dist/main.d.ts +2 -0
  221. package/dist/main.d.ts.map +1 -0
  222. package/dist/main.js +20 -0
  223. package/dist/main.js.map +1 -0
  224. package/dist/model-hooks.d.ts +73 -0
  225. package/dist/model-hooks.d.ts.map +1 -0
  226. package/dist/model-hooks.js +211 -0
  227. package/dist/model-hooks.js.map +1 -0
  228. package/dist/pgbouncer-userlist.d.ts +1 -1
  229. package/dist/pgbouncer-userlist.d.ts.map +1 -1
  230. package/dist/pgbouncer-userlist.js +2 -2
  231. package/dist/pgbouncer-userlist.js.map +1 -1
  232. package/dist/postgres-ctl.d.ts +12 -1
  233. package/dist/postgres-ctl.d.ts.map +1 -1
  234. package/dist/postgres-ctl.js +28 -5
  235. package/dist/postgres-ctl.js.map +1 -1
  236. package/dist/process-manager.d.ts +2 -2
  237. package/dist/process-manager.d.ts.map +1 -1
  238. package/dist/process-manager.js +4 -4
  239. package/dist/process-manager.js.map +1 -1
  240. package/dist/project-config.d.ts +122 -2
  241. package/dist/project-config.d.ts.map +1 -1
  242. package/dist/project-config.js +150 -1
  243. package/dist/project-config.js.map +1 -1
  244. package/dist/pull-utils.d.ts +2 -2
  245. package/dist/pull-utils.d.ts.map +1 -1
  246. package/dist/pull-utils.js +4 -4
  247. package/dist/pull-utils.js.map +1 -1
  248. package/dist/realtime-launch.js +1 -1
  249. package/dist/realtime-launch.js.map +1 -1
  250. package/dist/release-pins.d.ts +1 -1
  251. package/dist/release-pins.js +2 -2
  252. package/dist/release-pins.js.map +1 -1
  253. package/dist/resolve-api-url.js +1 -1
  254. package/dist/resolve-api-url.js.map +1 -1
  255. package/dist/resolve-target.d.ts +4 -0
  256. package/dist/resolve-target.d.ts.map +1 -1
  257. package/dist/resolve-target.js +69 -73
  258. package/dist/resolve-target.js.map +1 -1
  259. package/dist/rest-cache-admin.js +2 -2
  260. package/dist/rest-cache-admin.js.map +1 -1
  261. package/dist/runtime-routes.d.ts +1 -1
  262. package/dist/runtime-routes.js +1 -1
  263. package/dist/schema-ast-v2.d.ts +5 -4
  264. package/dist/schema-ast-v2.d.ts.map +1 -1
  265. package/dist/schema-ast-v2.js +5 -3
  266. package/dist/schema-ast-v2.js.map +1 -1
  267. package/dist/schema-push-lock.d.ts.map +1 -1
  268. package/dist/schema-push-lock.js +43 -16
  269. package/dist/schema-push-lock.js.map +1 -1
  270. package/dist/scripts/postinstall.d.ts +1 -1
  271. package/dist/scripts/postinstall.js +1 -1
  272. package/dist/self-host-compose.d.ts +26 -2
  273. package/dist/self-host-compose.d.ts.map +1 -1
  274. package/dist/self-host-compose.js +305 -73
  275. package/dist/self-host-compose.js.map +1 -1
  276. package/dist/service-role-check.d.ts +21 -0
  277. package/dist/service-role-check.d.ts.map +1 -0
  278. package/dist/service-role-check.js +85 -0
  279. package/dist/service-role-check.js.map +1 -0
  280. package/dist/storage-provision.d.ts +1 -1
  281. package/dist/storage-provision.js +3 -3
  282. package/dist/storage-provision.js.map +1 -1
  283. package/dist/studio-dev-server.d.ts +1 -1
  284. package/dist/studio-dev-server.d.ts.map +1 -1
  285. package/dist/systemd.d.ts +1 -1
  286. package/dist/systemd.js +1 -1
  287. package/dist/target-client.d.ts +17 -0
  288. package/dist/target-client.d.ts.map +1 -1
  289. package/dist/target-client.js +69 -17
  290. package/dist/target-client.js.map +1 -1
  291. package/dist/tsx-runner.js +1 -1
  292. package/dist/tsx-runner.js.map +1 -1
  293. package/dist/type-extractor.d.ts.map +1 -1
  294. package/dist/type-extractor.js +738 -34
  295. package/dist/type-extractor.js.map +1 -1
  296. package/dist/type-resolver.js +1 -1
  297. package/dist/type-resolver.js.map +1 -1
  298. package/dist/ui/brand.d.ts +1 -1
  299. package/dist/ui/brand.js +1 -1
  300. package/dist/ui/components/LogoWordmark.d.ts +1 -1
  301. package/dist/ui/components/LogoWordmark.d.ts.map +1 -1
  302. package/dist/ui/components/LogoWordmark.js +1 -1
  303. package/dist/ui/components/LogoWordmark.js.map +1 -1
  304. package/dist/ui/components/SelectField.js +1 -1
  305. package/dist/ui/components/SelectField.js.map +1 -1
  306. package/dist/ui/confirm.d.ts +1 -1
  307. package/dist/ui/confirm.js +1 -1
  308. package/dist/ui/fatal.d.ts +1 -1
  309. package/dist/ui/fatal.d.ts.map +1 -1
  310. package/dist/ui/fatal.js +1 -1
  311. package/dist/ui/fatal.js.map +1 -1
  312. package/dist/ui/flows/prompt-fields.js +1 -1
  313. package/dist/ui/flows/prompt-fields.js.map +1 -1
  314. package/dist/ui/interactive.d.ts +1 -1
  315. package/dist/ui/interactive.d.ts.map +1 -1
  316. package/dist/ui/interactive.js +1 -1
  317. package/dist/ui/interactive.js.map +1 -1
  318. package/dist/ui/progress.d.ts +1 -1
  319. package/dist/ui/progress.js +1 -1
  320. package/dist/ui/runtime/command-chrome.js +2 -2
  321. package/dist/ui/runtime/command-chrome.js.map +1 -1
  322. package/dist/ui/runtime/run-clack-flow.js +1 -1
  323. package/dist/ui/runtime/run-clack-flow.js.map +1 -1
  324. package/dist/ui/runtime/stdin-after-ink.d.ts.map +1 -1
  325. package/dist/ui/runtime/stdin-after-ink.js +4 -2
  326. package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
  327. package/dist/ui/theme.d.ts +1 -1
  328. package/dist/ui/theme.js +1 -1
  329. package/dist/valkey-sidecar.d.ts +1 -1
  330. package/dist/valkey-sidecar.d.ts.map +1 -1
  331. package/dist/valkey-sidecar.js +2 -2
  332. package/dist/valkey-sidecar.js.map +1 -1
  333. package/package.json +6 -2
  334. package/scripts/build-release-artifacts.sh +112 -0
  335. package/scripts/generate-homebrew-formula.mjs +123 -0
  336. package/scripts/mirror-deno-release.sh +1 -1
  337. package/src/TYPE-RESOLUTION.md +31 -31
  338. package/src/app/framework.ts +1 -1
  339. package/src/augmentation-generator.ts +19 -6
  340. package/src/binary-cache.ts +94 -47
  341. package/src/cache-clean.ts +81 -0
  342. package/src/cache-pins.ts +243 -0
  343. package/src/cli-artifacts.ts +65 -0
  344. package/src/cli-install-method.ts +87 -0
  345. package/src/cli-package-version.ts +5 -1
  346. package/src/cli-standalone.ts +116 -34
  347. package/src/cli-version-embedded.ts +12 -0
  348. package/src/cli.ts +7 -1
  349. package/src/cloud-credentials.ts +183 -0
  350. package/src/commands/add.ts +1 -1
  351. package/src/commands/admin.ts +142 -27
  352. package/src/commands/adopt.ts +1 -1
  353. package/src/commands/app.ts +2 -2
  354. package/src/commands/cache.ts +92 -77
  355. package/src/commands/cloud.ts +32 -8
  356. package/src/commands/db.ts +164 -3
  357. package/src/commands/deploy.ts +12 -12
  358. package/src/commands/dev.ts +72 -23
  359. package/src/commands/doctor.ts +69 -3
  360. package/src/commands/engine.ts +1 -1
  361. package/src/commands/functions.ts +47 -10
  362. package/src/commands/generate.ts +5 -1
  363. package/src/commands/hooks.ts +138 -0
  364. package/src/commands/init.ts +65 -31
  365. package/src/commands/internal.ts +23 -0
  366. package/src/commands/link-helpers.ts +9 -2
  367. package/src/commands/login.ts +127 -0
  368. package/src/commands/logs.ts +1 -1
  369. package/src/commands/migrate.ts +5 -5
  370. package/src/commands/pg.ts +1 -1
  371. package/src/commands/plugins.ts +1 -1
  372. package/src/commands/pull.ts +2 -2
  373. package/src/commands/push.ts +124 -7
  374. package/src/commands/self-host.ts +1 -1
  375. package/src/commands/self-update.ts +41 -19
  376. package/src/commands/status.ts +1 -1
  377. package/src/commands/update.ts +1 -1
  378. package/src/config.ts +23 -4
  379. package/src/db-preflight.ts +575 -0
  380. package/src/dev-compose.ts +158 -89
  381. package/src/dev-log-filter.ts +1 -1
  382. package/src/dev-ports.ts +3 -3
  383. package/src/dev-session.ts +6 -6
  384. package/src/dev-shutdown.ts +8 -8
  385. package/src/dev-task-colors.ts +1 -1
  386. package/src/docker-postgres.ts +6 -6
  387. package/src/docker-runtime.ts +5 -5
  388. package/src/engine-client.ts +3 -3
  389. package/src/engine-push-output.ts +1 -1
  390. package/src/ensure-binary.ts +20 -0
  391. package/src/ensure-component-binaries.ts +1 -1
  392. package/src/env-file.ts +157 -11
  393. package/src/field-masking-tier.ts +107 -0
  394. package/src/functions-deno-types.ts +188 -0
  395. package/src/functions-router-gen.ts +1 -1
  396. package/src/gitignore.ts +3 -3
  397. package/src/hook-upload.ts +107 -0
  398. package/src/hooks-generator.ts +352 -0
  399. package/src/index.ts +1 -1
  400. package/src/init-project-detect.ts +1 -1
  401. package/src/link.ts +7 -0
  402. package/src/local-secrets.ts +104 -0
  403. package/src/main.ts +20 -0
  404. package/src/model-hooks.ts +260 -0
  405. package/src/pgbouncer-userlist.ts +2 -2
  406. package/src/postgres-ctl.ts +32 -5
  407. package/src/process-manager.ts +4 -4
  408. package/src/project-config.ts +237 -3
  409. package/src/pull-utils.ts +4 -4
  410. package/src/realtime-launch.ts +1 -1
  411. package/src/release-pins.ts +2 -2
  412. package/src/resolve-api-url.ts +1 -1
  413. package/src/resolve-target.ts +113 -68
  414. package/src/rest-cache-admin.ts +2 -2
  415. package/src/runtime-routes.ts +2 -2
  416. package/src/schema-ast-v2.ts +8 -5
  417. package/src/schema-push-lock.ts +56 -17
  418. package/src/scripts/postinstall.ts +1 -1
  419. package/src/self-host-compose.ts +348 -72
  420. package/src/service-role-check.ts +111 -0
  421. package/src/storage-provision.ts +3 -3
  422. package/src/studio-dev-server.ts +1 -1
  423. package/src/systemd.ts +1 -1
  424. package/src/target-client.ts +105 -18
  425. package/src/tsx-runner.ts +1 -1
  426. package/src/type-extractor.ts +885 -30
  427. package/src/type-resolver.ts +1 -1
  428. package/src/ui/README.md +1 -1
  429. package/src/ui/brand.ts +1 -1
  430. package/src/ui/components/LogoWordmark.tsx +1 -1
  431. package/src/ui/components/SelectField.tsx +1 -1
  432. package/src/ui/confirm.ts +1 -1
  433. package/src/ui/fatal.ts +1 -1
  434. package/src/ui/flows/prompt-fields.tsx +1 -1
  435. package/src/ui/interactive.ts +1 -1
  436. package/src/ui/progress.ts +1 -1
  437. package/src/ui/runtime/command-chrome.ts +2 -2
  438. package/src/ui/runtime/run-clack-flow.tsx +1 -1
  439. package/src/ui/runtime/stdin-after-ink.ts +4 -2
  440. package/src/ui/theme.ts +1 -1
  441. package/src/valkey-sidecar.ts +2 -2
  442. package/tests/access-composition.test.ts +667 -0
  443. package/tests/admin-studio-membership.test.ts +121 -0
  444. package/tests/api-schemas.test.ts +83 -0
  445. package/tests/archive-name-alias.test.ts +42 -0
  446. package/tests/augmentation-generator.test.ts +28 -0
  447. package/tests/cache-clean.test.ts +206 -0
  448. package/tests/cli-help.test.ts +11 -2
  449. package/tests/cli-install-method.test.ts +66 -0
  450. package/tests/command-chrome-coverage.test.ts +31 -26
  451. package/tests/command-chrome-wrap.test.ts +1 -0
  452. package/tests/db-preflight.test.ts +72 -0
  453. package/tests/doctor-render.test.ts +62 -0
  454. package/tests/doctor-service-role.test.ts +55 -0
  455. package/tests/engine-push-output.test.ts +1 -1
  456. package/tests/env-file.test.ts +121 -0
  457. package/tests/external-database-compose.test.ts +184 -0
  458. package/tests/external-database-config.test.ts +154 -0
  459. package/tests/field-masking-tier.test.ts +184 -0
  460. package/tests/functions-deno-types.test.ts +197 -0
  461. package/tests/homebrew-formula.test.ts +100 -0
  462. package/tests/hook-upload.test.ts +125 -0
  463. package/tests/hooks-generator.test.ts +212 -0
  464. package/tests/init.test.ts +5 -2
  465. package/tests/keys.test.ts +8 -2
  466. package/tests/local-secrets.test.ts +92 -0
  467. package/tests/model-hooks.test.ts +322 -0
  468. package/tests/runtime-contract.test.ts +113 -1
  469. package/tests/service-role-check.test.ts +109 -0
  470. package/tests/service-role-routes.test.ts +51 -0
  471. package/tests/storage-provision.test.ts +1 -1
  472. package/tests/target-client-refresh.test.ts +94 -0
  473. package/tests/type-extractor.test.ts +187 -0
  474. package/tsconfig.tsbuildinfo +1 -1
  475. package/vitest.config.ts +7 -1
  476. package/scripts/build-release-bundle.mjs +0 -27
  477. package/tests/engine-distribution.test.ts +0 -418
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `supatype dev` when `provider: docker` full self-host Compose stack (Kong gateway).
2
+ * `supatype dev` when `provider: docker`, full self-host Compose stack (Kong gateway).
3
3
  */
4
4
 
5
5
  import { existsSync, mkdirSync, writeFileSync } from "node:fs"
@@ -15,6 +15,7 @@ import {
15
15
  projectRootFromConfig,
16
16
  resolveRuntimeProvider,
17
17
  schemaPathFromProject,
18
+ usesExternalDatabase,
18
19
  type SupatypeProjectConfig,
19
20
  } from "./project-config.js"
20
21
  import { signJwt } from "./jwt.js"
@@ -40,6 +41,12 @@ import { ensureLocalServerDockerImage } from "./compose-local-server-image.js"
40
41
  import { ensureEngine, engineRequest, type DiffResult } from "./engine-client.js"
41
42
  import { writeSchemaSourcePushArtifacts, type SchemaSourcePushArtifacts } from "./schema-sources.js"
42
43
  import { readEnvValue, upsertEnvFile } from "./env-file.js"
44
+ import {
45
+ devJwtSecret,
46
+ devPostgresPassword,
47
+ seedMissingDatabaseIdentity,
48
+ seedMissingLocalSecrets,
49
+ } from "./local-secrets.js"
43
50
  import { writeLocalEnvironment } from "./link.js"
44
51
  import { registerDevShutdown } from "./dev-shutdown.js"
45
52
  import {
@@ -55,16 +62,19 @@ import type { ExtractedSchemaAstV2 } from "./schema-ast-v2.js"
55
62
  import { ensureFirstAdminUserForProject } from "./commands/admin.js"
56
63
  import { publishDevReady } from "./dev-ready-panel.js"
57
64
 
58
- const LOCAL_JWT_SECRET = "super-secret-jwt-token-with-at-least-32-characters-long"
59
-
60
65
  /** Default host port for compose Postgres when `overrides.engine` is set (devLocal). */
61
66
  const COMPOSE_DEV_DB_PORT = 54329
62
67
 
63
68
  /** Sync optional Docker image pins from config into `.env` (no JWT rotation). */
64
69
  export function syncComposeImagePins(cwd: string, config: SupatypeProjectConfig): void {
65
70
  const imagePins = composeDockerImageEnv(config)
71
+ // Clean up only what a previous run wrote from config. A hand-written image tag in `.env` is the
72
+ // documented way to run a local build, and this used to delete it on every compose run.
66
73
  const removeImageKeys = COMPOSE_PINNED_IMAGE_ENV_KEYS.filter((key) => !(key in imagePins))
67
- upsertEnvFile(cwd, imagePins, removeImageKeys)
74
+ upsertEnvFile(cwd, imagePins, {
75
+ removeManaged: removeImageKeys,
76
+ managed: COMPOSE_PINNED_IMAGE_ENV_KEYS,
77
+ })
68
78
  }
69
79
 
70
80
  export interface DevComposeOptions {
@@ -72,8 +82,10 @@ export interface DevComposeOptions {
72
82
  }
73
83
 
74
84
  /** In-compose Postgres URL (SCRAM; not published to the host). */
75
- export function composeDbUrl(): string {
76
- return "postgresql://supatype_admin:postgres@db:5432/supatype?sslmode=disable"
85
+ export function composeDbUrl(cwd: string): string {
86
+ const user = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin")
87
+ const db = readEnvValue(cwd, "POSTGRES_DB", "supatype")
88
+ return `postgresql://${user}:${devPostgresPassword(cwd)}@db:5432/${db}?sslmode=disable`
77
89
  }
78
90
 
79
91
  /**
@@ -84,10 +96,23 @@ async function resolveDevDbPort(cwd: string): Promise<number> {
84
96
  return ensureDevDbPort(cwd)
85
97
  }
86
98
 
99
+ /**
100
+ * The database URL to hand a tool, from wherever it happens to run.
101
+ *
102
+ * The compose helpers below describe the `db` *container*, on the host at
103
+ * `SUPATYPE_DEV_DB_PORT`, or in-network at `db:5432`. Neither exists for a project pointed at an
104
+ * external database, and passing one produced "pool timed out while waiting for an open connection"
105
+ *- a message with nothing in it about the URL being wrong.
106
+ */
107
+ function projectDatabaseUrl(cwd: string, config: SupatypeProjectConfig, inNetwork = false): string {
108
+ if (usesExternalDatabase(config)) return connectionString(config)
109
+ return inNetwork ? composeDbUrl(cwd) : hostComposeDbUrl(cwd)
110
+ }
111
+
87
112
  function hostComposeDbUrl(cwd: string): string {
88
113
  const port = readEnvValue(cwd, "SUPATYPE_DEV_DB_PORT", String(COMPOSE_DEV_DB_PORT))
89
114
  const user = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin")
90
- const pass = readEnvValue(cwd, "POSTGRES_PASSWORD", "postgres")
115
+ const pass = devPostgresPassword(cwd)
91
116
  const db = readEnvValue(cwd, "POSTGRES_DB", "supatype")
92
117
  return `postgresql://${user}:${pass}@127.0.0.1:${port}/${db}?sslmode=disable`
93
118
  }
@@ -117,19 +142,12 @@ export async function ensureDockerDbPublishedForHostEngine(
117
142
 
118
143
  const now = Math.floor(Date.now() / 1000)
119
144
  const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
120
- const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET)
121
- const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET)
145
+ const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
146
+ const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
122
147
  ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort)
123
148
 
124
149
  const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
125
- const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
126
- quiet: true,
127
- ...(brand !== undefined && { brand }),
128
- })
129
- if (up !== 0) {
130
- exitComposeFailed(up, "Could not start Postgres (compose db service).", brand)
131
- }
132
- await waitComposeHealthy(paths, cwd, 120_000, project)
150
+ await startComposeDatabase(config, paths, cwd, project, brand)
133
151
  }
134
152
 
135
153
  /**
@@ -142,6 +160,9 @@ export function usesLocalDockerEngineDb(
142
160
  ): boolean {
143
161
  if (explicitConnection?.trim()) return false
144
162
  if (config.connection?.trim()) return false
163
+ // An external database is already reachable and is not ours to publish. Without this the engine
164
+ // path tried `compose up -d db` against a compose file that deliberately has no `db` service.
165
+ if (usesExternalDatabase(config)) return false
145
166
  return resolveRuntimeProvider(config) === "docker" && hasEngineOverride(config)
146
167
  }
147
168
 
@@ -168,6 +189,36 @@ async function resolveKongPort(cwd: string): Promise<number> {
168
189
  return ensureKongPort(cwd, { context: "dev" })
169
190
  }
170
191
 
192
+ /**
193
+ * Bring up the compose `db` service and wait for it to answer.
194
+ *
195
+ * A no-op when the project uses an external database: there is no such service, the database is
196
+ * already running, and its readiness is the operator's, `supatype db check` is what reports on it.
197
+ * Four call sites did this inline, so an external project hit `compose up -d db` against a compose
198
+ * file that deliberately has no `db`.
199
+ */
200
+ async function startComposeDatabase(
201
+ config: SupatypeProjectConfig,
202
+ paths: SelfHostComposePaths,
203
+ cwd: string,
204
+ project: string,
205
+ brand: DockerBrandOptions | undefined,
206
+ timeoutMs = 120_000,
207
+ onFailure?: () => void,
208
+ ): Promise<void> {
209
+ if (usesExternalDatabase(config)) return
210
+
211
+ const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
212
+ quiet: true,
213
+ ...(brand !== undefined && { brand }),
214
+ })
215
+ if (up !== 0) {
216
+ onFailure?.()
217
+ exitComposeFailed(up, "Could not start Postgres (compose db service).", brand)
218
+ }
219
+ await waitComposeHealthy(paths, cwd, timeoutMs, project)
220
+ }
221
+
171
222
  function upsertDevComposeEnv(
172
223
  cwd: string,
173
224
  config: SupatypeProjectConfig,
@@ -179,11 +230,25 @@ function upsertDevComposeEnv(
179
230
  ): void {
180
231
  const apiUrl = `http://localhost:${kongPort}`
181
232
  const imagePins = composeDockerImageEnv(config)
233
+ // `POSTGRES_PASSWORD` and `JWT_SECRET` are deliberately absent.
234
+ //
235
+ // They used to be pinned here to published constants on every `dev` run, against the same
236
+ // `.env` a self-host deployment reads, so a project could not hold its own secrets, and one
237
+ // `dev` after generating them put the published values back with nothing to show it. They are
238
+ // now resolved from `.env` (see `local-secrets.ts`) and written by `init` alone.
239
+ //
240
+ // The keys below still have to be written, because they are *derived*: the anon and
241
+ // service-role tokens are signed with the effective secret, so leaving a stale pair in place
242
+ // would desync them from the secret that validates them.
182
243
  const updates: Record<string, string> = {
183
- POSTGRES_USER: "supatype_admin",
184
- POSTGRES_PASSWORD: "postgres",
185
- POSTGRES_DB: "supatype",
186
- JWT_SECRET: LOCAL_JWT_SECRET,
244
+ // The docker dev path renders the *self-host* compose file, where the secrets have no
245
+ // defaults: an unset value is a hard compose error rather than a service quietly starting
246
+ // with a published constant. This guarantees presence without overwriting: only keys
247
+ // genuinely absent from `.env` are filled, and with the value the project has been running
248
+ // with rather than a fresh one.
249
+ ...seedMissingLocalSecrets(cwd),
250
+ // Project configuration, seeded not overwritten, see seedMissingDatabaseIdentity.
251
+ ...seedMissingDatabaseIdentity(cwd),
187
252
  ANON_KEY: anonKey,
188
253
  SERVICE_ROLE_KEY: serviceRoleKey,
189
254
  PUBLIC_SUPATYPE_ANON_KEY: anonKey,
@@ -198,13 +263,26 @@ function upsertDevComposeEnv(
198
263
  ...imagePins,
199
264
  ...(localServerImage !== undefined && { SUPATYPE_SERVER_IMAGE: localServerImage }),
200
265
  }
201
- if (devDbPort !== undefined) {
266
+ // Never for an external database: this URL describes the `db` container, which that project does
267
+ // not have. Writing it overwrote the operator's own DATABASE_URL, the value the whole stack and
268
+ // every CLI command reads, with a DSN pointing at a database that does not exist. Found by
269
+ // rehearsing a push against a real external Postgres, where the compose guard then refused to
270
+ // proceed because .env and the config disagreed. They disagreed because of this line.
271
+ if (devDbPort !== undefined && !usesExternalDatabase(config)) {
202
272
  updates.SUPATYPE_DEV_DB_PORT = String(devDbPort)
273
+ // User and database from the project, not hardcoded, same reason as
274
+ // `seedMissingDatabaseIdentity`: a project not named "supatype" had this URL pointing at a
275
+ // database that does not exist.
276
+ const dbUser = readEnvValue(cwd, "POSTGRES_USER", "supatype_admin")
277
+ const dbName = readEnvValue(cwd, "POSTGRES_DB", "supatype")
203
278
  updates.DATABASE_URL =
204
- `postgresql://supatype_admin:postgres@localhost:${devDbPort}/supatype?sslmode=disable`
279
+ `postgresql://${dbUser}:${devPostgresPassword(cwd)}@localhost:${devDbPort}/${dbName}?sslmode=disable`
205
280
  }
206
281
  const removeImageKeys = COMPOSE_PINNED_IMAGE_ENV_KEYS.filter((key) => !(key in imagePins))
207
- upsertEnvFile(cwd, updates, removeImageKeys)
282
+ upsertEnvFile(cwd, updates, {
283
+ removeManaged: removeImageKeys,
284
+ managed: COMPOSE_PINNED_IMAGE_ENV_KEYS,
285
+ })
208
286
  }
209
287
 
210
288
  /** Keep compose + Studio on the same freshly signed dev JWTs; sync optional image pins from config. */
@@ -280,7 +358,7 @@ function dumpComposeDbLogs(
280
358
  maxBuffer: 10 * 1024 * 1024,
281
359
  })
282
360
  const body = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim()
283
- const content = body || `(empty docker compose logs db exit ${result.status ?? "?"})\n`
361
+ const content = body || `(empty, docker compose logs db exit ${result.status ?? "?"})\n`
284
362
  try {
285
363
  writeFileSync(logPath, content)
286
364
  } catch {
@@ -325,7 +403,7 @@ async function waitStorageApiReady(
325
403
  const body = await res.text()
326
404
  const kongUpstreamDown = body.includes("invalid response was received from the upstream server")
327
405
  if (!kongUpstreamDown && res.status !== 503) {
328
- // Non-transient storage response (e.g. 401) stop waiting.
406
+ // Non-transient storage response (e.g. 401), stop waiting.
329
407
  return
330
408
  }
331
409
  } catch {
@@ -334,7 +412,7 @@ async function waitStorageApiReady(
334
412
  await new Promise((r) => setTimeout(r, 1000))
335
413
  }
336
414
  console.warn(
337
- `[supatype] Storage API at ${url} did not become ready within ${maxSec}s bucket provisioning may fail.`,
415
+ `[supatype] Storage API at ${url} did not become ready within ${maxSec}s, bucket provisioning may fail.`,
338
416
  )
339
417
  }
340
418
 
@@ -367,7 +445,7 @@ async function refreshSchemaArtifacts(
367
445
  await ensureEngine()
368
446
  } catch (err) {
369
447
  console.warn(
370
- `[supatype] Host engine unavailable admin/types not refreshed: ${(err as Error).message}`,
448
+ `[supatype] Host engine unavailable, admin/types not refreshed: ${(err as Error).message}`,
371
449
  )
372
450
  return
373
451
  }
@@ -402,7 +480,7 @@ async function refreshSchemaArtifacts(
402
480
  console.log("[supatype] Admin config written to .supatype/admin-config.json")
403
481
  } catch (err) {
404
482
  console.warn(
405
- `[supatype] Admin config generation failed Studio may show stale field widgets: ${(err as Error).message}`,
483
+ `[supatype] Admin config generation failed, Studio may show stale field widgets: ${(err as Error).message}`,
406
484
  )
407
485
  }
408
486
  }
@@ -420,7 +498,7 @@ async function runComposeSchemaPush(
420
498
  const supatypeDir = join(cwd, ".supatype")
421
499
  mkdirSync(supatypeDir, { recursive: true })
422
500
  const astPath = join(supatypeDir, "schema.ast.json")
423
- // Always materialise on disk schema-engine reads via bind mount; skip must not omit the write.
501
+ // Always materialise on disk, schema-engine reads via bind mount; skip must not omit the write.
424
502
  writeFileSync(astPath, astJson)
425
503
  if (astJson === _lastPushedAst && astJson !== _lastFailedAst) return
426
504
 
@@ -428,7 +506,7 @@ async function runComposeSchemaPush(
428
506
  throw new Error(`Failed to write schema AST at ${astPath}`)
429
507
  }
430
508
 
431
- // Admin + types come from the AST only (no DB) refresh before push so Studio stays
509
+ // Admin + types come from the AST only (no DB), refresh before push so Studio stays
432
510
  // in sync even when migration fails (e.g. bad engine image, lossy column change).
433
511
  await refreshSchemaArtifacts(cwd, config, ast)
434
512
 
@@ -440,7 +518,7 @@ async function runComposeSchemaPush(
440
518
  try {
441
519
  await engineRequest("/push", {
442
520
  ast,
443
- database_url: hostComposeDbUrl(cwd),
521
+ database_url: projectDatabaseUrl(cwd, config),
444
522
  schema: pgSchema,
445
523
  force: true,
446
524
  ...(sources
@@ -474,7 +552,7 @@ async function runComposeSchemaPush(
474
552
  }
475
553
  return result
476
554
  }
477
- // B: only hold the advisory lock when realtime is already decoding first-boot
555
+ // B: only hold the advisory lock when realtime is already decoding, first-boot
478
556
  // push (db only) must not take the lock; that path crashed under lock+DDL in CI.
479
557
  const push = composeServiceIsRunning(paths, cwd, composeProject, "realtime")
480
558
  ? await withComposeSchemaPushLock(paths, cwd, composeProject, runPush)
@@ -540,7 +618,7 @@ async function runComposeEnginePush(
540
618
  "-i",
541
619
  "/project/.supatype/schema.ast.json",
542
620
  "--database-url",
543
- composeDbUrl(),
621
+ projectDatabaseUrl(cwd, config, true),
544
622
  "--force",
545
623
  "--non-interactive",
546
624
  )
@@ -606,7 +684,7 @@ async function runComposeEngineDiff(
606
684
  "-i",
607
685
  "/project/.supatype/schema.ast.json",
608
686
  "--database-url",
609
- composeDbUrl(),
687
+ projectDatabaseUrl(cwd, config, true),
610
688
  "--schema",
611
689
  pgSchema,
612
690
  )
@@ -633,7 +711,7 @@ async function runComposeEngineDiff(
633
711
 
634
712
  /**
635
713
  * `supatype diff` when `provider: docker`. Uses in-compose schema-engine unless
636
- * `overrides.engine` is set then Postgres is published to the host and diff runs
714
+ * `overrides.engine` is set: then Postgres is published to the host and diff runs
637
715
  * through the local engine binary.
638
716
  */
639
717
  export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfig): Promise<DiffResult> {
@@ -651,7 +729,7 @@ export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfi
651
729
  await ensureEngine()
652
730
  return engineRequest<DiffResult>("/diff", {
653
731
  ast,
654
- database_url: hostComposeDbUrl(cwd),
732
+ database_url: projectDatabaseUrl(cwd, config),
655
733
  schema: pgSchema,
656
734
  })
657
735
  }
@@ -659,21 +737,14 @@ export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfi
659
737
  const kongPort = await resolveKongPort(cwd)
660
738
  const now = Math.floor(Date.now() / 1000)
661
739
  const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
662
- const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET)
663
- const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET)
740
+ const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
741
+ const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
664
742
  ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, undefined)
665
743
 
666
744
  const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
667
745
  const diffBrand = { intro: "Schema diff" }
668
746
 
669
- const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
670
- quiet: true,
671
- brand: diffBrand,
672
- })
673
- if (up !== 0) {
674
- exitComposeFailed(up, "Could not start Postgres (compose db service).", diffBrand)
675
- }
676
- await waitComposeHealthy(paths, cwd, 120_000, project)
747
+ await startComposeDatabase(config, paths, cwd, project, diffBrand)
677
748
 
678
749
  const schemaPath = schemaPathFromProject(config, cwd)
679
750
  const ast = loadSchemaAst(schemaPath, cwd)
@@ -701,7 +772,7 @@ export async function diffSchemaDocker(cwd: string, config: SupatypeProjectConfi
701
772
 
702
773
  /**
703
774
  * `supatype push` when `provider: docker`. Uses in-compose schema-engine unless
704
- * `overrides.engine` is set then Postgres is published to the host and push runs
775
+ * `overrides.engine` is set: then Postgres is published to the host and push runs
705
776
  * through the local engine binary (AST v2, contributor builds).
706
777
  */
707
778
  export async function pushSchemaDocker(cwd: string, config: SupatypeProjectConfig): Promise<void> {
@@ -710,26 +781,25 @@ export async function pushSchemaDocker(cwd: string, config: SupatypeProjectConfi
710
781
  }
711
782
  const project = composeProjectName(config.project.name)
712
783
  const kongPort = await resolveKongPort(cwd)
713
- const devDbPort = hasEngineOverride(config) ? await resolveDevDbPort(cwd) : undefined
784
+ // No dev db port for an external database: `ensureDevDbPort` allocates a host port for the `db`
785
+ // container *and persists a matching DATABASE_URL*, which overwrote the operator's own URL, the
786
+ // one the whole stack and every CLI command reads.
787
+ const devDbPort =
788
+ hasEngineOverride(config) && !usesExternalDatabase(config)
789
+ ? await resolveDevDbPort(cwd)
790
+ : undefined
714
791
 
715
792
  const now = Math.floor(Date.now() / 1000)
716
793
  const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
717
- const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET)
718
- const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET)
794
+ const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
795
+ const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
719
796
  ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort)
720
797
 
721
798
  const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
722
799
  const pushBrand = { intro: "Push schema" }
723
800
 
724
- console.log(`[supatype] provider: docker applying schema via compose (project ${project})...`)
725
- const up = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
726
- quiet: true,
727
- brand: pushBrand,
728
- })
729
- if (up !== 0) {
730
- exitComposeFailed(up, "Could not start Postgres (compose db service).", pushBrand)
731
- }
732
- await waitComposeHealthy(paths, cwd, 120_000, project)
801
+ console.log(`[supatype] provider docker, applying schema via compose (project ${project})...`)
802
+ await startComposeDatabase(config, paths, cwd, project, pushBrand)
733
803
 
734
804
  const schemaPath = schemaPathFromProject(config, cwd)
735
805
  const ast = loadSchemaAst(schemaPath, cwd)
@@ -762,19 +832,25 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
762
832
  // stack on the machine (own containers, volumes, network, and gateway port).
763
833
  const project = composeProjectName(config.project.name)
764
834
  const kongPort = await resolveKongPort(cwd)
765
- const devDbPort = hasEngineOverride(config) ? await resolveDevDbPort(cwd) : undefined
835
+ // No dev db port for an external database: `ensureDevDbPort` allocates a host port for the `db`
836
+ // container *and persists a matching DATABASE_URL*, which overwrote the operator's own URL, the
837
+ // one the whole stack and every CLI command reads.
838
+ const devDbPort =
839
+ hasEngineOverride(config) && !usesExternalDatabase(config)
840
+ ? await resolveDevDbPort(cwd)
841
+ : undefined
766
842
 
767
843
  const now = Math.floor(Date.now() / 1000)
768
844
  const jwtBase = { iss: "supatype", iat: now, exp: now + 315_360_000 }
769
- const anonKey = signJwt({ ...jwtBase, role: "anon" }, LOCAL_JWT_SECRET)
770
- const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, LOCAL_JWT_SECRET)
845
+ const anonKey = signJwt({ ...jwtBase, role: "anon" }, devJwtSecret(cwd))
846
+ const serviceRoleKey = signJwt({ ...jwtBase, role: "service_role" }, devJwtSecret(cwd))
771
847
 
772
848
  const devBrand = { intro: "Local development" }
773
849
  const localServerImage = await ensureLocalServerDockerImage(cwd, config, devBrand)
774
850
 
775
851
  ensureDevComposeEnv(cwd, config, anonKey, serviceRoleKey, kongPort, devDbPort, localServerImage)
776
852
 
777
- console.log(`[supatype] provider: docker starting self-host Compose stack (project ${project}, gateway :${kongPort})...`)
853
+ console.log(`[supatype] provider docker, starting self-host Compose stack (project ${project}, gateway :${kongPort})...`)
778
854
  const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
779
855
  if (ensureDevApiConfig(cwd)) {
780
856
  console.log("[supatype] API config written to .supatype/api-config.json")
@@ -818,19 +894,11 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
818
894
  await recoverStaleDevSession(cwd)
819
895
  await handleComposeProjectRename(cwd, config.project.name, paths)
820
896
 
821
- console.log("[supatype] Bringing up Postgres (compose db)...")
822
- const upDbStatus = runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
823
- quiet: true,
824
- brand: devBrand,
825
- })
826
- if (upDbStatus !== 0) {
827
- endDevSession()
828
- exitComposeFailed(upDbStatus, "Could not start Postgres (compose db service).", devBrand)
897
+ if (!usesExternalDatabase(config)) {
898
+ console.log("[supatype] Bringing up Postgres (compose db)...")
829
899
  }
830
-
831
- console.log("[supatype] Waiting for Postgres (compose)...")
832
- await waitComposeHealthy(paths, cwd, 180_000, project)
833
- // Settle before DDL — pg_isready can pass slightly before the instance is stable.
900
+ await startComposeDatabase(config, paths, cwd, project, devBrand, 180_000, endDevSession)
901
+ // Settle before DDL: pg_isready can pass slightly before the instance is stable.
834
902
  await new Promise((r) => setTimeout(r, 3000))
835
903
 
836
904
  // A: apply schema before realtime (and the rest of the stack) starts decoding WAL.
@@ -851,16 +919,17 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
851
919
  )
852
920
  dumpComposeDbLogs(paths, cwd, project, `schema push attempt ${attempt}/${maxAttempts}`)
853
921
  if (attempt < maxAttempts) {
854
- console.log("[supatype] Resetting Postgres after failed schema push...")
855
- runDockerCompose(paths.composePath, ["down", "-v"], cwd, project, {
856
- quiet: true,
857
- brand: devBrand,
858
- })
859
- runDockerCompose(paths.composePath, ["up", "-d", "db"], cwd, project, {
860
- quiet: true,
861
- brand: devBrand,
862
- })
863
- await waitComposeHealthy(paths, cwd, 120_000, project)
922
+ // Only for a database Supatype created. Tearing down an external one is not ours to do,
923
+ // and `down -v` would destroy the stack's other volumes for a failure that was never
924
+ // about Postgres.
925
+ if (!usesExternalDatabase(config)) {
926
+ console.log("[supatype] Resetting Postgres after failed schema push...")
927
+ runDockerCompose(paths.composePath, ["down", "-v"], cwd, project, {
928
+ quiet: true,
929
+ brand: devBrand,
930
+ })
931
+ await startComposeDatabase(config, paths, cwd, project, devBrand)
932
+ }
864
933
  await new Promise((r) => setTimeout(r, 3000 * attempt))
865
934
  }
866
935
  }
@@ -927,7 +996,7 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
927
996
  writeLocalEnvironment(cwd, {
928
997
  target: "local",
929
998
  apiUrl: `http://localhost:${kongPort}`,
930
- databaseUrl: hasEngineOverride(config) ? hostComposeDbUrl(cwd) : composeDbUrl(),
999
+ databaseUrl: projectDatabaseUrl(cwd, config, !hasEngineOverride(config)),
931
1000
  projectRef: config.project.name,
932
1001
  kongPort,
933
1002
  provider: "docker",
@@ -965,7 +1034,7 @@ export async function runDevCompose(cwd: string, config: SupatypeProjectConfig,
965
1034
  shutdownState.studioProc = studioProc
966
1035
  if (studioProc) {
967
1036
  console.log(
968
- `[supatype] Studio (overrides.studio) live reload proxied at http://localhost:${kongPort}/studio/`,
1037
+ `[supatype] Studio (overrides.studio): live reload proxied at http://localhost:${kongPort}/studio/`,
969
1038
  )
970
1039
  }
971
1040
  }
@@ -1053,6 +1122,6 @@ function grantAuthSchemaAccess(
1053
1122
  { cwd: composeDir, encoding: "utf8", timeout: 10_000 },
1054
1123
  )
1055
1124
  if (result.status !== 0) {
1056
- console.warn("[supatype] Could not grant service_role access to auth.users Studio relation preview may fail.")
1125
+ console.warn("[supatype] Could not grant service_role access to auth.users, Studio relation preview may fail.")
1057
1126
  }
1058
1127
  }
@@ -48,7 +48,7 @@ export function filterStackLogLine(line: string): boolean {
48
48
  return false
49
49
  }
50
50
 
51
- /** Drop docker noise only keep diff tables, push status, and command output. */
51
+ /** Drop docker noise only, keep diff tables, push status, and command output. */
52
52
  export function filterCommandLogLine(line: string): boolean {
53
53
  const t = stripAnsi(line).trim()
54
54
  if (!t) return false
package/src/dev-ports.ts CHANGED
@@ -60,7 +60,7 @@ async function promptPortConflict(
60
60
  export interface EnsureKongPortOptions {
61
61
  /** When false, fail fast instead of prompting (CI / scripts). */
62
62
  interactive?: boolean
63
- /** init wizard slightly different copy */
63
+ /** init wizard: slightly different copy */
64
64
  context?: "dev" | "init"
65
65
  }
66
66
 
@@ -102,7 +102,7 @@ export async function ensureKongPort(
102
102
  return port
103
103
  }
104
104
 
105
- /** Wizard / init pick a Kong port without writing `.env` (scaffold writes it). */
105
+ /** Wizard / init: pick a Kong port without writing `.env` (scaffold writes it). */
106
106
  export async function promptKongPortChoice(): Promise<number> {
107
107
  const freeDefault = (await isPortInUse(COMPOSE_DEV_KONG_PORT))
108
108
  ? await findNextFreePort(COMPOSE_DEV_KONG_PORT)
@@ -139,7 +139,7 @@ async function promptPortConflictWithoutPersist(
139
139
  const headline =
140
140
  reason === "init"
141
141
  ? `Port ${blockedPort} is already in use on this machine.`
142
- : `Port ${blockedPort} is in use another Supatype project or service may already be bound to it.`
142
+ : `Port ${blockedPort} is in use, another Supatype project or service may already be bound to it.`
143
143
 
144
144
  const choice = await p.select<"suggested" | "custom" | "cancel">({
145
145
  message: headline,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `supatype dev` output session Ink dashboard (default) or interleaved stream mode.
2
+ * `supatype dev` output session, Ink dashboard (default) or interleaved stream mode.
3
3
  */
4
4
 
5
5
  import { render, type Instance } from "ink"
@@ -32,7 +32,7 @@ export function beginDevSession(mode: DevUiMode): DevSession {
32
32
  return activeSession
33
33
  }
34
34
 
35
- /** @deprecated Ink starts in beginDevSession kept for callers that invoke late. */
35
+ /** @deprecated Ink starts in beginDevSession, kept for callers that invoke late. */
36
36
  export function startDevSession(): void {
37
37
  activeSession?.startInk()
38
38
  }
@@ -47,7 +47,7 @@ export function endDevSession(): void {
47
47
  activeSession = null
48
48
  }
49
49
 
50
- /** @deprecated Dev prompts render inside the Ink dashboard no suspend needed. */
50
+ /** @deprecated Dev prompts render inside the Ink dashboard, no suspend needed. */
51
51
  export function suspendDevSessionForPrompt(): void {
52
52
  prepareStdinForInteractivePrompt()
53
53
  }
@@ -58,12 +58,12 @@ export function prepareStdinForInteractivePrompt(): void {
58
58
  process.stdin.resume()
59
59
  }
60
60
 
61
- /** @deprecated Dev prompts render inside the Ink dashboard no resume needed. */
61
+ /** @deprecated Dev prompts render inside the Ink dashboard, no resume needed. */
62
62
  export function resumeDevSessionAfterPrompt(): void {
63
- // no-op prompts are Ink overlays
63
+ // no-op: prompts are Ink overlays
64
64
  }
65
65
 
66
- /** @deprecated Use Ink overlay prompts runs fn without tearing down the dashboard. */
66
+ /** @deprecated Use Ink overlay prompts, runs fn without tearing down the dashboard. */
67
67
  export async function withDevSessionSuspended<T>(fn: () => Promise<T>): Promise<T> {
68
68
  return fn()
69
69
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Graceful shutdown for `supatype dev` SIGINT, TUI Ctrl+C, terminal close,
2
+ * Graceful shutdown for `supatype dev`, SIGINT, TUI Ctrl+C, terminal close,
3
3
  * and a synchronous compose-down fallback on process exit.
4
4
  */
5
5
 
@@ -23,7 +23,7 @@ let forceQuitRequested = false
23
23
  let hooksRegistered = false
24
24
  let ignoreSigintUntil = 0
25
25
 
26
- /** SIGINT/SIGTERM hooks call as soon as `supatype dev` starts (before compose is up). */
26
+ /** SIGINT/SIGTERM hooks: call as soon as `supatype dev` starts (before compose is up). */
27
27
  export function ensureDevShutdownHooks(): void {
28
28
  if (hooksRegistered) return
29
29
  hooksRegistered = true
@@ -62,7 +62,7 @@ function syncComposeDownFallback(): void {
62
62
  { quiet: true },
63
63
  )
64
64
  } catch {
65
- // best-effort process is exiting
65
+ // best-effort: process is exiting
66
66
  }
67
67
  if (shutdownCwd) clearDevSessionLock(shutdownCwd)
68
68
  }
@@ -74,7 +74,7 @@ function onProcessExit(): void {
74
74
  export interface RegisterDevShutdownOptions {
75
75
  /** Sync `docker compose down` when async teardown cannot finish (terminal close, kill). */
76
76
  compose?: DevComposeShutdownFallback
77
- /** Project root clears `.supatype/dev-session.json` after shutdown. */
77
+ /** Project root: clears `.supatype/dev-session.json` after shutdown. */
78
78
  cwd?: string
79
79
  }
80
80
 
@@ -89,7 +89,7 @@ export function registerDevShutdown(
89
89
  ensureDevShutdownHooks()
90
90
  }
91
91
 
92
- /** TUI Ctrl+C do not re-emit SIGINT (avoids double-fire on Windows raw mode). */
92
+ /** TUI Ctrl+C: do not re-emit SIGINT (avoids double-fire on Windows raw mode). */
93
93
  export function requestDevShutdown(): void {
94
94
  ignoreSigintUntil = Date.now() + 400
95
95
  void runDevShutdown()
@@ -99,7 +99,7 @@ export function isDevShuttingDown(): boolean {
99
99
  return shuttingDown
100
100
  }
101
101
 
102
- /** @internal Tests reset module state between cases. */
102
+ /** @internal Tests: reset module state between cases. */
103
103
  export function resetDevShutdownForTests(): void {
104
104
  shutdownWork = null
105
105
  composeFallback = null
@@ -125,7 +125,7 @@ async function runDevShutdown(): Promise<void> {
125
125
  } catch {
126
126
  // best-effort terminal restore
127
127
  }
128
- process.stderr.write("\n[supatype] Forced quit Docker containers may still be running.\n")
128
+ process.stderr.write("\n[supatype] Forced quit: Docker containers may still be running.\n")
129
129
  process.stdout.write("\n")
130
130
  process.exit(130)
131
131
  }
@@ -145,7 +145,7 @@ async function runDevShutdown(): Promise<void> {
145
145
  } catch (err) {
146
146
  process.stderr.write(`[supatype] Shutdown failed: ${(err as Error).message}\n`)
147
147
  process.stderr.write(
148
- "[supatype] Docker containers may still be running try: supatype self-host compose down\n",
148
+ "[supatype] Docker containers may still be running, try: supatype self-host compose down\n",
149
149
  )
150
150
  syncComposeDownFallback()
151
151
  shutdownCompleted = true
@@ -30,7 +30,7 @@ export function levelColor(line: string): string | null {
30
30
  return null
31
31
  }
32
32
 
33
- /** Drop redundant prefix task pane is already labelled supatype. */
33
+ /** Drop redundant prefix: task pane is already labelled supatype. */
34
34
  export function normalizeStackLogLine(line: string): string {
35
35
  return line.replace(/^\[supatype\]\s*/, "")
36
36
  }