@supatype/cli 0.1.0-alpha.9 → 0.1.1

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 (407) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/.turbo/turbo-test.log +285 -69
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/assets/supatype-logo-wordmark.ascii.txt +6 -0
  5. package/bin/dev-entry.ts +2 -1
  6. package/dist/app/framework.js +1 -3
  7. package/dist/app/framework.js.map +1 -1
  8. package/dist/app/proxy-dev-app.d.ts +14 -0
  9. package/dist/app/proxy-dev-app.d.ts.map +1 -1
  10. package/dist/app/proxy-dev-app.js +110 -6
  11. package/dist/app/proxy-dev-app.js.map +1 -1
  12. package/dist/app-config.d.ts +10 -0
  13. package/dist/app-config.d.ts.map +1 -1
  14. package/dist/app-config.js +72 -0
  15. package/dist/app-config.js.map +1 -1
  16. package/dist/assets/supatype-logo-wordmark.ascii.txt +6 -0
  17. package/dist/binary-cache.d.ts +19 -7
  18. package/dist/binary-cache.d.ts.map +1 -1
  19. package/dist/binary-cache.js +92 -46
  20. package/dist/binary-cache.js.map +1 -1
  21. package/dist/cli.d.ts +1 -1
  22. package/dist/cli.d.ts.map +1 -1
  23. package/dist/cli.js +17 -2
  24. package/dist/cli.js.map +1 -1
  25. package/dist/commands/add.d.ts +3 -0
  26. package/dist/commands/add.d.ts.map +1 -0
  27. package/dist/commands/add.js +86 -0
  28. package/dist/commands/add.js.map +1 -0
  29. package/dist/commands/admin.d.ts +28 -1
  30. package/dist/commands/admin.d.ts.map +1 -1
  31. package/dist/commands/admin.js +297 -149
  32. package/dist/commands/admin.js.map +1 -1
  33. package/dist/commands/adopt.d.ts +3 -0
  34. package/dist/commands/adopt.d.ts.map +1 -0
  35. package/dist/commands/adopt.js +55 -0
  36. package/dist/commands/adopt.js.map +1 -0
  37. package/dist/commands/app.d.ts.map +1 -1
  38. package/dist/commands/app.js +20 -17
  39. package/dist/commands/app.js.map +1 -1
  40. package/dist/commands/cache.d.ts.map +1 -1
  41. package/dist/commands/cache.js +11 -10
  42. package/dist/commands/cache.js.map +1 -1
  43. package/dist/commands/cloud.d.ts +4 -9
  44. package/dist/commands/cloud.d.ts.map +1 -1
  45. package/dist/commands/cloud.js +75 -125
  46. package/dist/commands/cloud.js.map +1 -1
  47. package/dist/commands/db.d.ts.map +1 -1
  48. package/dist/commands/db.js +37 -58
  49. package/dist/commands/db.js.map +1 -1
  50. package/dist/commands/deploy.d.ts.map +1 -1
  51. package/dist/commands/deploy.js +140 -96
  52. package/dist/commands/deploy.js.map +1 -1
  53. package/dist/commands/dev.d.ts.map +1 -1
  54. package/dist/commands/dev.js +74 -39
  55. package/dist/commands/dev.js.map +1 -1
  56. package/dist/commands/diff.d.ts.map +1 -1
  57. package/dist/commands/diff.js +39 -39
  58. package/dist/commands/diff.js.map +1 -1
  59. package/dist/commands/doctor.d.ts +3 -0
  60. package/dist/commands/doctor.d.ts.map +1 -0
  61. package/dist/commands/doctor.js +78 -0
  62. package/dist/commands/doctor.js.map +1 -0
  63. package/dist/commands/engine.d.ts.map +1 -1
  64. package/dist/commands/engine.js +5 -4
  65. package/dist/commands/engine.js.map +1 -1
  66. package/dist/commands/functions.d.ts.map +1 -1
  67. package/dist/commands/functions.js +172 -119
  68. package/dist/commands/functions.js.map +1 -1
  69. package/dist/commands/generate.d.ts.map +1 -1
  70. package/dist/commands/generate.js +5 -4
  71. package/dist/commands/generate.js.map +1 -1
  72. package/dist/commands/init.d.ts +35 -1
  73. package/dist/commands/init.d.ts.map +1 -1
  74. package/dist/commands/init.js +883 -107
  75. package/dist/commands/init.js.map +1 -1
  76. package/dist/commands/introspect.d.ts +3 -0
  77. package/dist/commands/introspect.d.ts.map +1 -0
  78. package/dist/commands/introspect.js +35 -0
  79. package/dist/commands/introspect.js.map +1 -0
  80. package/dist/commands/keys.d.ts +15 -1
  81. package/dist/commands/keys.d.ts.map +1 -1
  82. package/dist/commands/keys.js +46 -10
  83. package/dist/commands/keys.js.map +1 -1
  84. package/dist/commands/link-helpers.d.ts +15 -0
  85. package/dist/commands/link-helpers.d.ts.map +1 -0
  86. package/dist/commands/link-helpers.js +225 -0
  87. package/dist/commands/link-helpers.js.map +1 -0
  88. package/dist/commands/logs.d.ts.map +1 -1
  89. package/dist/commands/logs.js +5 -4
  90. package/dist/commands/logs.js.map +1 -1
  91. package/dist/commands/migrate-from-v1.d.ts.map +1 -1
  92. package/dist/commands/migrate-from-v1.js +3 -2
  93. package/dist/commands/migrate-from-v1.js.map +1 -1
  94. package/dist/commands/migrate.d.ts.map +1 -1
  95. package/dist/commands/migrate.js +119 -26
  96. package/dist/commands/migrate.js.map +1 -1
  97. package/dist/commands/pg.d.ts.map +1 -1
  98. package/dist/commands/pg.js +11 -12
  99. package/dist/commands/pg.js.map +1 -1
  100. package/dist/commands/plugins.d.ts.map +1 -1
  101. package/dist/commands/plugins.js +55 -46
  102. package/dist/commands/plugins.js.map +1 -1
  103. package/dist/commands/pull.d.ts.map +1 -1
  104. package/dist/commands/pull.js +33 -5
  105. package/dist/commands/pull.js.map +1 -1
  106. package/dist/commands/push.d.ts.map +1 -1
  107. package/dist/commands/push.js +111 -138
  108. package/dist/commands/push.js.map +1 -1
  109. package/dist/commands/seed.d.ts.map +1 -1
  110. package/dist/commands/seed.js +4 -3
  111. package/dist/commands/seed.js.map +1 -1
  112. package/dist/commands/self-host.d.ts +2 -2
  113. package/dist/commands/self-host.d.ts.map +1 -1
  114. package/dist/commands/self-host.js +65 -50
  115. package/dist/commands/self-host.js.map +1 -1
  116. package/dist/commands/self-update.d.ts.map +1 -1
  117. package/dist/commands/self-update.js +3 -2
  118. package/dist/commands/self-update.js.map +1 -1
  119. package/dist/commands/status.d.ts +1 -1
  120. package/dist/commands/status.d.ts.map +1 -1
  121. package/dist/commands/status.js +95 -29
  122. package/dist/commands/status.js.map +1 -1
  123. package/dist/commands/types.d.ts.map +1 -1
  124. package/dist/commands/types.js +3 -2
  125. package/dist/commands/types.js.map +1 -1
  126. package/dist/commands/update.d.ts.map +1 -1
  127. package/dist/commands/update.js +54 -21
  128. package/dist/commands/update.js.map +1 -1
  129. package/dist/compose-rename.d.ts +10 -0
  130. package/dist/compose-rename.d.ts.map +1 -0
  131. package/dist/compose-rename.js +67 -0
  132. package/dist/compose-rename.js.map +1 -0
  133. package/dist/config.d.ts +2 -1
  134. package/dist/config.d.ts.map +1 -1
  135. package/dist/config.js.map +1 -1
  136. package/dist/dev-compose.d.ts +26 -0
  137. package/dist/dev-compose.d.ts.map +1 -1
  138. package/dist/dev-compose.js +357 -79
  139. package/dist/dev-compose.js.map +1 -1
  140. package/dist/dev-log-bus.d.ts +30 -0
  141. package/dist/dev-log-bus.d.ts.map +1 -0
  142. package/dist/dev-log-bus.js +87 -0
  143. package/dist/dev-log-bus.js.map +1 -0
  144. package/dist/dev-log-filter.d.ts +10 -0
  145. package/dist/dev-log-filter.d.ts.map +1 -0
  146. package/dist/dev-log-filter.js +36 -0
  147. package/dist/dev-log-filter.js.map +1 -0
  148. package/dist/dev-logo.d.ts +12 -0
  149. package/dist/dev-logo.d.ts.map +1 -0
  150. package/dist/dev-logo.js +56 -0
  151. package/dist/dev-logo.js.map +1 -0
  152. package/dist/dev-ports.d.ts +27 -0
  153. package/dist/dev-ports.d.ts.map +1 -0
  154. package/dist/dev-ports.js +171 -0
  155. package/dist/dev-ports.js.map +1 -0
  156. package/dist/dev-session-lock.d.ts +25 -0
  157. package/dist/dev-session-lock.d.ts.map +1 -0
  158. package/dist/dev-session-lock.js +81 -0
  159. package/dist/dev-session-lock.js.map +1 -0
  160. package/dist/dev-session.d.ts +26 -0
  161. package/dist/dev-session.d.ts.map +1 -0
  162. package/dist/dev-session.js +106 -0
  163. package/dist/dev-session.js.map +1 -0
  164. package/dist/dev-shutdown.d.ts +25 -0
  165. package/dist/dev-shutdown.d.ts.map +1 -0
  166. package/dist/dev-shutdown.js +114 -0
  167. package/dist/dev-shutdown.js.map +1 -0
  168. package/dist/dev-task-colors.d.ts +13 -0
  169. package/dist/dev-task-colors.d.ts.map +1 -0
  170. package/dist/dev-task-colors.js +43 -0
  171. package/dist/dev-task-colors.js.map +1 -0
  172. package/dist/dev-tui.d.ts +24 -0
  173. package/dist/dev-tui.d.ts.map +1 -0
  174. package/dist/dev-tui.js +188 -0
  175. package/dist/dev-tui.js.map +1 -0
  176. package/dist/diff-output.d.ts +5 -1
  177. package/dist/diff-output.d.ts.map +1 -1
  178. package/dist/diff-output.js +69 -0
  179. package/dist/diff-output.js.map +1 -1
  180. package/dist/docker-runtime.d.ts +30 -0
  181. package/dist/docker-runtime.d.ts.map +1 -0
  182. package/dist/docker-runtime.js +118 -0
  183. package/dist/docker-runtime.js.map +1 -0
  184. package/dist/engine-client.d.ts +10 -1
  185. package/dist/engine-client.d.ts.map +1 -1
  186. package/dist/engine-client.js +76 -17
  187. package/dist/engine-client.js.map +1 -1
  188. package/dist/engine-push-output.d.ts +17 -0
  189. package/dist/engine-push-output.d.ts.map +1 -0
  190. package/dist/engine-push-output.js +64 -0
  191. package/dist/engine-push-output.js.map +1 -0
  192. package/dist/ensure-binary.js +2 -2
  193. package/dist/ensure-binary.js.map +1 -1
  194. package/dist/env-file.d.ts +5 -0
  195. package/dist/env-file.d.ts.map +1 -0
  196. package/dist/env-file.js +33 -0
  197. package/dist/env-file.js.map +1 -0
  198. package/dist/gitignore.d.ts +8 -0
  199. package/dist/gitignore.d.ts.map +1 -0
  200. package/dist/gitignore.js +41 -0
  201. package/dist/gitignore.js.map +1 -0
  202. package/dist/kong-config.d.ts +9 -0
  203. package/dist/kong-config.d.ts.map +1 -1
  204. package/dist/kong-config.js +18 -1
  205. package/dist/kong-config.js.map +1 -1
  206. package/dist/link.d.ts +66 -0
  207. package/dist/link.d.ts.map +1 -0
  208. package/dist/link.js +160 -0
  209. package/dist/link.js.map +1 -0
  210. package/dist/process-manager.d.ts +8 -0
  211. package/dist/process-manager.d.ts.map +1 -1
  212. package/dist/process-manager.js +53 -9
  213. package/dist/process-manager.js.map +1 -1
  214. package/dist/project-config.d.ts +30 -3
  215. package/dist/project-config.d.ts.map +1 -1
  216. package/dist/project-config.js +37 -4
  217. package/dist/project-config.js.map +1 -1
  218. package/dist/prompts.d.ts +3 -0
  219. package/dist/prompts.d.ts.map +1 -0
  220. package/dist/prompts.js +3 -0
  221. package/dist/prompts.js.map +1 -0
  222. package/dist/pull-utils.d.ts +50 -14
  223. package/dist/pull-utils.d.ts.map +1 -1
  224. package/dist/pull-utils.js +152 -12
  225. package/dist/pull-utils.js.map +1 -1
  226. package/dist/resolve-target.d.ts +86 -0
  227. package/dist/resolve-target.d.ts.map +1 -0
  228. package/dist/resolve-target.js +291 -0
  229. package/dist/resolve-target.js.map +1 -0
  230. package/dist/restore-system-relation-targets.d.ts +3 -0
  231. package/dist/restore-system-relation-targets.d.ts.map +1 -0
  232. package/dist/restore-system-relation-targets.js +45 -0
  233. package/dist/restore-system-relation-targets.js.map +1 -0
  234. package/dist/runtime-routes.d.ts.map +1 -1
  235. package/dist/runtime-routes.js +7 -0
  236. package/dist/runtime-routes.js.map +1 -1
  237. package/dist/schema-ast-v2.d.ts +1 -1
  238. package/dist/schema-ast-v2.d.ts.map +1 -1
  239. package/dist/schema-ast-v2.js +2 -2
  240. package/dist/schema-ast-v2.js.map +1 -1
  241. package/dist/schema-sources.d.ts +40 -0
  242. package/dist/schema-sources.d.ts.map +1 -0
  243. package/dist/schema-sources.js +183 -0
  244. package/dist/schema-sources.js.map +1 -0
  245. package/dist/scripts/postinstall.js +5 -1
  246. package/dist/scripts/postinstall.js.map +1 -1
  247. package/dist/self-host-compose.d.ts +37 -1
  248. package/dist/self-host-compose.d.ts.map +1 -1
  249. package/dist/self-host-compose.js +234 -43
  250. package/dist/self-host-compose.js.map +1 -1
  251. package/dist/storage-provision.d.ts +4 -0
  252. package/dist/storage-provision.d.ts.map +1 -1
  253. package/dist/storage-provision.js +24 -2
  254. package/dist/storage-provision.js.map +1 -1
  255. package/dist/supatype-eval-1781522769253.d.mts +2 -0
  256. package/dist/supatype-eval-1781522769253.d.mts.map +1 -0
  257. package/dist/supatype-eval-1781522769253.mjs +3 -0
  258. package/dist/supatype-eval-1781522769253.mjs.map +1 -0
  259. package/dist/systemd.js +2 -2
  260. package/dist/systemd.js.map +1 -1
  261. package/dist/target-client.d.ts +10 -0
  262. package/dist/target-client.d.ts.map +1 -0
  263. package/dist/target-client.js +22 -0
  264. package/dist/target-client.js.map +1 -0
  265. package/dist/type-extractor.d.ts +11 -0
  266. package/dist/type-extractor.d.ts.map +1 -1
  267. package/dist/type-extractor.js +95 -8
  268. package/dist/type-extractor.js.map +1 -1
  269. package/dist/ui/brand.d.ts +9 -0
  270. package/dist/ui/brand.d.ts.map +1 -0
  271. package/dist/ui/brand.js +11 -0
  272. package/dist/ui/brand.js.map +1 -0
  273. package/dist/ui/confirm.d.ts +12 -0
  274. package/dist/ui/confirm.d.ts.map +1 -0
  275. package/dist/ui/confirm.js +28 -0
  276. package/dist/ui/confirm.js.map +1 -0
  277. package/dist/ui/fatal.d.ts +10 -0
  278. package/dist/ui/fatal.d.ts.map +1 -0
  279. package/dist/ui/fatal.js +34 -0
  280. package/dist/ui/fatal.js.map +1 -0
  281. package/dist/ui/index.d.ts +9 -0
  282. package/dist/ui/index.d.ts.map +1 -0
  283. package/dist/ui/index.js +9 -0
  284. package/dist/ui/index.js.map +1 -0
  285. package/dist/ui/interactive.d.ts +3 -0
  286. package/dist/ui/interactive.d.ts.map +1 -0
  287. package/dist/ui/interactive.js +5 -0
  288. package/dist/ui/interactive.js.map +1 -0
  289. package/dist/ui/messages.d.ts +10 -0
  290. package/dist/ui/messages.d.ts.map +1 -0
  291. package/dist/ui/messages.js +35 -0
  292. package/dist/ui/messages.js.map +1 -0
  293. package/dist/ui/next-steps.d.ts +3 -0
  294. package/dist/ui/next-steps.d.ts.map +1 -0
  295. package/dist/ui/next-steps.js +10 -0
  296. package/dist/ui/next-steps.js.map +1 -0
  297. package/dist/ui/progress.d.ts +5 -0
  298. package/dist/ui/progress.d.ts.map +1 -0
  299. package/dist/ui/progress.js +24 -0
  300. package/dist/ui/progress.js.map +1 -0
  301. package/dist/ui/prompts.d.ts +14 -0
  302. package/dist/ui/prompts.d.ts.map +1 -0
  303. package/dist/ui/prompts.js +34 -0
  304. package/dist/ui/prompts.js.map +1 -0
  305. package/package.json +5 -2
  306. package/src/app/framework.ts +1 -3
  307. package/src/app/proxy-dev-app.ts +114 -6
  308. package/src/app-config.ts +80 -0
  309. package/src/binary-cache.ts +102 -52
  310. package/src/cli.ts +16 -2
  311. package/src/commands/add.ts +97 -0
  312. package/src/commands/admin.ts +381 -190
  313. package/src/commands/adopt.ts +82 -0
  314. package/src/commands/app.ts +20 -17
  315. package/src/commands/cache.ts +11 -10
  316. package/src/commands/cloud.ts +91 -142
  317. package/src/commands/db.ts +40 -63
  318. package/src/commands/deploy.ts +186 -126
  319. package/src/commands/dev.ts +98 -55
  320. package/src/commands/diff.ts +52 -43
  321. package/src/commands/doctor.ts +103 -0
  322. package/src/commands/engine.ts +5 -4
  323. package/src/commands/functions.ts +187 -123
  324. package/src/commands/generate.ts +5 -4
  325. package/src/commands/init.ts +1087 -104
  326. package/src/commands/introspect.ts +48 -0
  327. package/src/commands/keys.ts +56 -14
  328. package/src/commands/link-helpers.ts +273 -0
  329. package/src/commands/logs.ts +5 -4
  330. package/src/commands/migrate-from-v1.ts +3 -2
  331. package/src/commands/migrate.ts +167 -27
  332. package/src/commands/pg.ts +13 -18
  333. package/src/commands/plugins.ts +55 -46
  334. package/src/commands/pull.ts +38 -9
  335. package/src/commands/push.ts +148 -175
  336. package/src/commands/seed.ts +5 -4
  337. package/src/commands/self-host.ts +85 -54
  338. package/src/commands/self-update.ts +3 -2
  339. package/src/commands/status.ts +102 -33
  340. package/src/commands/types.ts +3 -2
  341. package/src/commands/update.ts +59 -23
  342. package/src/compose-rename.ts +76 -0
  343. package/src/config.ts +2 -1
  344. package/src/dev-compose.ts +462 -76
  345. package/src/dev-log-bus.ts +101 -0
  346. package/src/dev-log-filter.ts +32 -0
  347. package/src/dev-logo.ts +61 -0
  348. package/src/dev-ports.ts +212 -0
  349. package/src/dev-session-lock.ts +101 -0
  350. package/src/dev-session.ts +130 -0
  351. package/src/dev-shutdown.ts +147 -0
  352. package/src/dev-task-colors.ts +47 -0
  353. package/src/dev-tui.ts +232 -0
  354. package/src/diff-output.ts +79 -1
  355. package/src/docker-runtime.ts +151 -0
  356. package/src/engine-client.ts +81 -17
  357. package/src/engine-push-output.ts +75 -0
  358. package/src/ensure-binary.ts +2 -2
  359. package/src/env-file.ts +37 -0
  360. package/src/gitignore.ts +48 -0
  361. package/src/kong-config.ts +24 -1
  362. package/src/link.ts +243 -0
  363. package/src/process-manager.ts +66 -10
  364. package/src/project-config.ts +62 -7
  365. package/src/prompts.ts +2 -0
  366. package/src/pull-utils.ts +217 -23
  367. package/src/resolve-target.ts +419 -0
  368. package/src/restore-system-relation-targets.ts +45 -0
  369. package/src/runtime-routes.ts +7 -0
  370. package/src/schema-ast-v2.ts +2 -1
  371. package/src/schema-sources.ts +248 -0
  372. package/src/scripts/postinstall.ts +7 -1
  373. package/src/self-host-compose.ts +262 -46
  374. package/src/storage-provision.ts +33 -1
  375. package/src/supatype-eval-1781522769253.mts +1 -0
  376. package/src/systemd.ts +2 -2
  377. package/src/target-client.ts +40 -0
  378. package/src/type-extractor.ts +124 -11
  379. package/src/ui/README.md +17 -0
  380. package/src/ui/brand.ts +12 -0
  381. package/src/ui/confirm.ts +38 -0
  382. package/src/ui/fatal.ts +43 -0
  383. package/src/ui/index.ts +8 -0
  384. package/src/ui/interactive.ts +4 -0
  385. package/src/ui/messages.ts +43 -0
  386. package/src/ui/next-steps.ts +10 -0
  387. package/src/ui/progress.ts +28 -0
  388. package/src/ui/prompts.ts +40 -0
  389. package/tests/admin-ensure.test.ts +59 -0
  390. package/tests/cli-help.test.ts +27 -2
  391. package/tests/config.test.ts +29 -2
  392. package/tests/dev-ports.test.ts +41 -0
  393. package/tests/dev-session-lock.test.ts +54 -0
  394. package/tests/dev-ui.test.ts +162 -0
  395. package/tests/docker-runtime.test.ts +236 -0
  396. package/tests/engine-push-output.test.ts +67 -0
  397. package/tests/init.test.ts +197 -18
  398. package/tests/link.test.ts +148 -0
  399. package/tests/minisign.test.ts +102 -0
  400. package/tests/proxy-dev-app.test.ts +45 -1
  401. package/tests/pull-utils.test.ts +5 -4
  402. package/tests/runtime-contract.test.ts +186 -2
  403. package/tests/schema-sources.test.ts +119 -0
  404. package/tests/storage-provision.test.ts +100 -0
  405. package/tests/ui-confirm.test.ts +41 -0
  406. package/tests/ui-messages.test.ts +66 -0
  407. package/tsconfig.tsbuildinfo +1 -1
@@ -1,10 +1,135 @@
1
- import { existsSync, mkdirSync, writeFileSync } from "node:fs"
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs"
2
2
  import { dirname, join, relative, resolve } from "node:path"
3
3
  import { spawnSync } from "node:child_process"
4
- import { preferredFunctionsPathFromProject, type SupatypeProjectConfig } from "./project-config.js"
5
- import { hasEngineOverride, hasStudioOverride } from "./binary-cache.js"
4
+ import { requireDockerDaemon, type DockerBrandOptions } from "./docker-runtime.js"
5
+ import { fatalError } from "./ui/fatal.js"
6
+ import { preferredFunctionsPathFromProject, selfHostTlsEnabled, type SupatypeProjectConfig } from "./project-config.js"
7
+ import { hasEngineOverride, hasStudioOverride, pinnedVersion, fetchLatestVersion, VERSION_PIN_LOCAL } from "./binary-cache.js"
6
8
  import { buildKongDeclarative } from "./kong-config.js"
7
9
 
10
+ /** Env keys written when `versions` pins exist in supatype.config.ts. */
11
+ export const COMPOSE_PINNED_IMAGE_ENV_KEYS = [
12
+ "SUPATYPE_ENGINE_IMAGE",
13
+ "SUPATYPE_SERVER_IMAGE",
14
+ "SUPATYPE_POSTGRES_IMAGE",
15
+ ] as const
16
+
17
+ /** Compose image env vars that may be overridden manually in `.env`. */
18
+ export const COMPOSE_IMAGE_ENV_KEYS = [
19
+ ...COMPOSE_PINNED_IMAGE_ENV_KEYS,
20
+ "SUPATYPE_CONTROL_PLANE_IMAGE",
21
+ "SUPATYPE_AUTH_IMAGE",
22
+ "SUPATYPE_STUDIO_IMAGE",
23
+ "SUPATYPE_STORAGE_IMAGE",
24
+ "SUPATYPE_FUNCTIONS_WORKER_IMAGE",
25
+ ] as const
26
+
27
+ type DockerPinComponent = "engine" | "server" | "postgres"
28
+
29
+ /** Map a config version pin to a Docker Hub image reference. */
30
+ export function dockerImageRef(
31
+ component: DockerPinComponent,
32
+ version: string,
33
+ config?: SupatypeProjectConfig,
34
+ ): string {
35
+ const trimmed = version.trim()
36
+ switch (component) {
37
+ case "engine":
38
+ return `supatype/schema-engine:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
39
+ case "server":
40
+ return `supatype/server:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
41
+ case "postgres": {
42
+ const override = config?.database?.image?.trim()
43
+ if (override) return override
44
+ if (trimmed.includes("-latest")) return `supatype/postgres:${trimmed}`
45
+ const major = trimmed.split(".")[0]
46
+ return `supatype/postgres:${major}-latest`
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * When the user pins `versions` in config, sync matching SUPATYPE_*_IMAGE vars for Compose.
53
+ * Unpinned components are omitted so compose falls back to :latest defaults.
54
+ */
55
+ export function composeDockerImageEnv(config: SupatypeProjectConfig): Record<string, string> {
56
+ const env: Record<string, string> = {}
57
+ const versions = config.versions
58
+ if (!versions) return env
59
+
60
+ if (versions.engine && versions.engine !== VERSION_PIN_LOCAL) {
61
+ env.SUPATYPE_ENGINE_IMAGE = dockerImageRef("engine", versions.engine)
62
+ }
63
+ if (versions.server && versions.server !== VERSION_PIN_LOCAL) {
64
+ env.SUPATYPE_SERVER_IMAGE = dockerImageRef("server", versions.server)
65
+ }
66
+ if (versions.postgres && versions.postgres !== VERSION_PIN_LOCAL) {
67
+ env.SUPATYPE_POSTGRES_IMAGE = dockerImageRef("postgres", versions.postgres, config)
68
+ }
69
+ return env
70
+ }
71
+
72
+ /** True when a Docker image tag is a semver/latest ref we expect `docker pull` to resolve. */
73
+ export function isRegistryPullableImageRef(ref: string): boolean {
74
+ const trimmed = ref.trim()
75
+ if (!trimmed) return true
76
+ const tag = trimmed.includes(":") ? trimmed.slice(trimmed.lastIndexOf(":") + 1) : "latest"
77
+ if (tag === "latest") return true
78
+ if (/^v?\d+\.\d+/.test(tag)) return true
79
+ if (/^\d+-latest$/.test(tag)) return true
80
+ return false
81
+ }
82
+
83
+ export function hasLocalVersionPins(config: SupatypeProjectConfig): boolean {
84
+ const versions = config.versions
85
+ if (!versions) return false
86
+ return (
87
+ versions.engine === VERSION_PIN_LOCAL ||
88
+ versions.server === VERSION_PIN_LOCAL ||
89
+ versions.postgres === VERSION_PIN_LOCAL ||
90
+ versions.deno === VERSION_PIN_LOCAL
91
+ )
92
+ }
93
+
94
+ function readComposeImageEnvValues(cwd: string): string[] {
95
+ const envPath = resolve(cwd, ".env")
96
+ if (!existsSync(envPath)) return []
97
+ const text = readFileSync(envPath, "utf8")
98
+ const values: string[] = []
99
+ for (const key of COMPOSE_IMAGE_ENV_KEYS) {
100
+ const match = text.match(new RegExp(`^${key}=(.+)$`, "m"))
101
+ if (match?.[1]) values.push(match[1].trim())
102
+ }
103
+ return values
104
+ }
105
+
106
+ /**
107
+ * Use `docker compose pull --ignore-pull-failures` only when the project may
108
+ * reference local-only images (config `versions: local` or custom `.env` tags).
109
+ */
110
+ export function composePullNeedsIgnoreFailures(
111
+ config: SupatypeProjectConfig,
112
+ cwd: string = process.cwd(),
113
+ ): boolean {
114
+ if (hasLocalVersionPins(config)) return true
115
+ return readComposeImageEnvValues(cwd).some((ref) => !isRegistryPullableImageRef(ref))
116
+ }
117
+
118
+ /**
119
+ * Schema-engine image for a one-off `docker compose run` when pushing schema.
120
+ * Uses config pin when set; otherwise CDN engine semver (Docker Hub `:latest` can lag).
121
+ * Does not touch `.env` — server/postgres still use compose `:latest` defaults.
122
+ */
123
+ export async function schemaEngineImageForPush(
124
+ config: SupatypeProjectConfig,
125
+ ): Promise<string | undefined> {
126
+ const pinned = pinnedVersion("engine", config)
127
+ if (pinned === VERSION_PIN_LOCAL) return undefined
128
+ if (pinned) return dockerImageRef("engine", pinned)
129
+ const version = await fetchLatestVersion("engine")
130
+ return dockerImageRef("engine", version)
131
+ }
132
+
8
133
  export interface SelfHostComposePaths {
9
134
  dir: string
10
135
  composePath: string
@@ -59,21 +184,9 @@ function kongMountPath(_cwd: string): string {
59
184
  /** Host Vite dev server as seen from Kong inside Docker Compose. */
60
185
  export const COMPOSE_STUDIO_HOST_URL = "http://host.docker.internal:3002"
61
186
 
62
- /** Local monorepo Studio image for `supatype dev` (dogfooding). */
63
- function studioServiceBlock(cwd: string, devLocal: boolean): string {
64
- if (!devLocal) {
65
- return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
66
- }
67
- const monorepoRoot = resolve(cwd, "..", "supatype")
68
- const studioDockerfile = join(monorepoRoot, "packages", "studio", "Dockerfile")
69
- if (!existsSync(studioDockerfile) || !existsSync(join(monorepoRoot, "pnpm-workspace.yaml"))) {
70
- return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
71
- }
72
- const context = relativeFromProjectRoot(cwd, monorepoRoot)
73
- return ` build:
74
- context: ${context}
75
- dockerfile: packages/studio/Dockerfile
76
- image: supatype/studio:dev-local`
187
+ /** Studio container always Docker Hub unless SUPATYPE_STUDIO_IMAGE is set in .env. */
188
+ function studioServiceBlock(): string {
189
+ return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
77
190
  }
78
191
 
79
192
  /** Host dev app (Astro/Vite on the machine) as seen from inside compose services. */
@@ -101,6 +214,11 @@ function serverAppEnvForCompose(config: SupatypeProjectConfig, devLocal: boolean
101
214
  } else if (mode === "proxy" && config.app.upstream?.trim()) {
102
215
  lines.push(` SUPATYPE_APP_UPSTREAM: ${proxyUpstreamForCompose(config.app.upstream, devLocal)}`)
103
216
  }
217
+ if (config.app.vite_dev_url?.trim()) {
218
+ lines.push(
219
+ ` SUPATYPE_VITE_DEV_URL: ${proxyUpstreamForCompose(config.app.vite_dev_url, devLocal)}`,
220
+ )
221
+ }
104
222
  return lines.join("\n")
105
223
  }
106
224
 
@@ -117,23 +235,32 @@ export function renderSelfHostCompose(
117
235
  const projectMount = projectMountPath(cwd)
118
236
  const kongMount = kongMountPath(cwd)
119
237
  const devLocal = options?.devLocal === true
238
+ const tlsEnabled = selfHostTlsEnabled(config, devLocal)
239
+ const domain = config.server.domain?.trim() ?? ""
240
+ // When TLS is on, default external URLs to https://<domain> so auth links/redirects use HTTPS.
241
+ const externalUrlFallback = tlsEnabled ? `https://${domain}` : "http://localhost:18473"
242
+ const siteUrlFallback = tlsEnabled ? `https://${domain}` : "http://localhost:3000"
120
243
  const studioHostDev = devLocal && hasStudioOverride(config)
121
244
  const appEnv = serverAppEnvForCompose(config, devLocal)
122
- const studioService = studioServiceBlock(cwd, devLocal)
245
+ const staticDir = staticDirForCompose(config) ?? "./dist"
246
+ const composeProject = composeProjectName(config.project.name)
247
+ const studioService = studioServiceBlock()
123
248
  const studioBlock = studioHostDev
124
249
  ? ""
125
250
  : `
126
251
  studio:
127
252
  ${studioService}
128
253
  environment:
129
- SUPATYPE_CLOUD_JSON: '{"url":"\${API_EXTERNAL_URL:-http://localhost:18473}","anonKey":"\${ANON_KEY:-}"}'
254
+ SUPATYPE_CLOUD_JSON: '{"url":"\${API_EXTERNAL_URL:-${externalUrlFallback}}","anonKey":"\${ANON_KEY:-}"}'
130
255
  expose:
131
256
  - "3002"
132
257
  `
133
258
  const kongDependsOn = studioHostDev
134
- ? ` - server`
259
+ ? ` - server
260
+ - control-plane`
135
261
  : ` - server
136
- - studio`
262
+ - studio
263
+ - control-plane`
137
264
  const publishDbToHost = !devLocal || hasEngineOverride(config)
138
265
  const dbPorts = publishDbToHost
139
266
  ? devLocal
@@ -155,6 +282,44 @@ ${studioService}
155
282
  - "9000:9000"
156
283
  - "9001:9001"
157
284
  `
285
+ const kongTlsEnv = tlsEnabled
286
+ ? ` KONG_PROXY_LISTEN: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
287
+ KONG_LUA_SSL_TRUSTED_CERTIFICATE: system
288
+ KONG_LUA_SSL_VERIFY_DEPTH: "2"
289
+ `
290
+ : ""
291
+ const kongPorts = tlsEnabled
292
+ ? ` - "80:8000"
293
+ - "443:8443"`
294
+ : ` - "\${SUPATYPE_KONG_PORT:-18473}:8000"`
295
+ const kongTlsDependsOn = tlsEnabled ? "\n - valkey" : ""
296
+ const valkeyBlock = tlsEnabled
297
+ ? `
298
+ valkey:
299
+ image: \${SUPATYPE_VALKEY_IMAGE:-valkey/valkey:8-alpine}
300
+ command: ["valkey-server", "--appendonly", "yes"]
301
+ expose:
302
+ - "6379"
303
+ volumes:
304
+ - valkey-data:/data
305
+ `
306
+ : ""
307
+ const tlsHintComment = tlsEnabled
308
+ ? ""
309
+ : ` # HTTPS is off. To enable automatic TLS (Let's Encrypt) for production, set in supatype.config.ts:
310
+ # server: { mode: "standalone", domain: "your.domain", tls: { email: "you@example.com" } }
311
+ # then re-run \`supatype self-host compose up -d\`. Kong publishes :80/:443 and provisions certs automatically.
312
+ `
313
+ const volumesBlock = tlsEnabled
314
+ ? `volumes:
315
+ db-data:
316
+ minio-data:
317
+ valkey-data:
318
+ `
319
+ : `volumes:
320
+ db-data:
321
+ minio-data:
322
+ `
158
323
 
159
324
  return `# Generated by supatype self-host compose
160
325
  # Kong → supatype-server (unified gateway) → internal PostgREST / storage / etc.
@@ -179,7 +344,7 @@ ${dbPorts} volumes:
179
344
  - "3000"
180
345
  environment:
181
346
  PGRST_DB_URI: postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}
182
- PGRST_DB_SCHEMA: "public, supatype, graphql_public"
347
+ PGRST_DB_SCHEMA: "public, supatype, graphql_public, auth"
183
348
  PGRST_DB_ANON_ROLE: anon
184
349
  PGRST_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
185
350
  PGRST_DB_EXTRA_SEARCH_PATH: public,extensions
@@ -215,12 +380,33 @@ ${dbPorts} volumes:
215
380
  SUPATYPE_FUNCTIONS_ROOT: /project/functions
216
381
  SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
217
382
  PORT: "8001"
218
- SUPATYPE_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
383
+ SUPATYPE_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
219
384
  SUPATYPE_ANON_KEY: \${ANON_KEY:-}
220
385
  SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
221
386
  STRIPE_SECRET_KEY: \${STRIPE_SECRET_KEY:-}
222
387
  STRIPE_WEBHOOK_SECRET: \${STRIPE_WEBHOOK_SECRET:-}
223
- SITE_URL: \${SITE_URL:-\${API_EXTERNAL_URL:-http://localhost:18473}}
388
+ SITE_URL: \${SITE_URL:-\${API_EXTERNAL_URL:-${externalUrlFallback}}}
389
+ depends_on:
390
+ db:
391
+ condition: service_healthy
392
+
393
+ control-plane:
394
+ image: \${SUPATYPE_CONTROL_PLANE_IMAGE:-supatype/control-plane:latest}
395
+ expose:
396
+ - "8080"
397
+ volumes:
398
+ - ${projectMount}:/project
399
+ - /var/run/docker.sock:/var/run/docker.sock
400
+ environment:
401
+ PORT: "8080"
402
+ SUPATYPE_PROJECT_REF: ${JSON.stringify(config.project.name)}
403
+ SUPATYPE_PROJECT_ROOT: /project
404
+ DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
405
+ SUPATYPE_FUNCTIONS_ROOT: /project/functions
406
+ SUPATYPE_STATIC_ROOT: /project/${staticDir.replace(/^\.\//, "")}
407
+ SUPATYPE_DEPLOYMENTS_DIR: /project/.supatype/deployments
408
+ COMPOSE_PROJECT_NAME: ${composeProject}
409
+ SUPATYPE_ENGINE_BIN: supatype-engine
224
410
  depends_on:
225
411
  db:
226
412
  condition: service_healthy
@@ -232,26 +418,27 @@ ${serverPorts} volumes:
232
418
  working_dir: /project
233
419
  environment:
234
420
  SUPATYPE_MODE: ${devLocal ? "dev" : "standalone"}
235
- SUPATYPE_MANIFEST_PATH: /project/.supatype/manifest.json
236
- SUPATYPE_ADMIN_CONFIG_PATH: /project/.supatype/admin-config.json
237
- SUPATYPE_API_CONFIG_PATH: /project/.supatype/api-config.json
421
+ SUPATYPE_MANIFEST_PATH: .supatype/manifest.json
422
+ SUPATYPE_ADMIN_CONFIG_PATH: .supatype/admin-config.json
423
+ SUPATYPE_API_CONFIG_PATH: .supatype/api-config.json
238
424
  SUPATYPE_POSTGREST_URL: http://postgrest:3000
239
425
  SUPATYPE_GRAPHQL_URL: http://postgrest:3000
240
426
  SUPATYPE_STORAGE_URL: http://storage:5000
241
- SUPATYPE_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
427
+ SUPATYPE_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
242
428
  SUPATYPE_ANON_KEY: \${ANON_KEY:-}
243
429
  SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
244
430
  SUPATYPE_SQL_DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
245
431
  SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
246
432
  SUPATYPE_FUNCTIONS_WORKER_URL: http://functions-worker:8001
433
+ SUPATYPE_CONTROL_PLANE_URL: http://control-plane:8080
247
434
  ${appEnv}
248
435
  GOTRUE_API_HOST: 0.0.0.0
249
436
  GOTRUE_API_PORT: 9999
250
- API_EXTERNAL_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
251
- GOTRUE_API_EXTERNAL_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
437
+ API_EXTERNAL_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
438
+ GOTRUE_API_EXTERNAL_URL: \${API_EXTERNAL_URL:-${externalUrlFallback}}
252
439
  GOTRUE_DB_DRIVER: postgres
253
440
  GOTRUE_DB_DATABASE_URL: "postgres://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}?search_path=auth"
254
- GOTRUE_SITE_URL: \${SITE_URL:-http://localhost:3000}
441
+ GOTRUE_SITE_URL: \${SITE_URL:-${siteUrlFallback}}
255
442
  GOTRUE_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
256
443
  GOTRUE_JWT_EXP: 3600
257
444
  GOTRUE_JWT_AUD: authenticated
@@ -269,6 +456,8 @@ ${devLocal ? " STUDIO_OPEN_DEV: \"1\"\n" : ""}
269
456
  condition: service_started
270
457
  functions-worker:
271
458
  condition: service_started
459
+ control-plane:
460
+ condition: service_started
272
461
 
273
462
  minio:
274
463
  image: minio/minio:RELEASE.2024-11-07T00-52-20Z
@@ -289,8 +478,7 @@ ${minioPorts} volumes:
289
478
  depends_on:
290
479
  db:
291
480
  condition: service_healthy
292
- ${studioBlock}
293
- kong:
481
+ ${studioBlock}${valkeyBlock}${tlsHintComment} kong:
294
482
  image: kong:3.6
295
483
  environment:
296
484
  KONG_DATABASE: "off"
@@ -299,17 +487,14 @@ ${studioBlock}
299
487
  KONG_ADMIN_ACCESS_LOG: /dev/stdout
300
488
  KONG_PROXY_ERROR_LOG: /dev/stderr
301
489
  KONG_ADMIN_ERROR_LOG: /dev/stderr
302
- volumes:
490
+ ${kongTlsEnv} volumes:
303
491
  - ${kongMount}:/etc/kong/kong.yml:ro
304
492
  ports:
305
- - "\${SUPATYPE_KONG_PORT:-18473}:8000"
493
+ ${kongPorts}
306
494
  depends_on:
307
- ${kongDependsOn}
495
+ ${kongDependsOn}${kongTlsDependsOn}
308
496
 
309
- volumes:
310
- db-data:
311
- minio-data:
312
- `
497
+ ${volumesBlock}`
313
498
  }
314
499
 
315
500
  function ensureComposeManifest(cwd: string): void {
@@ -341,6 +526,9 @@ export function writeSelfHostCompose(
341
526
  ensureComposeManifest(cwd)
342
527
  writeFileSync(paths.composePath, renderSelfHostCompose(config, cwd, options), "utf8")
343
528
  const studioHostDev = options?.devLocal === true && hasStudioOverride(config)
529
+ const tlsEnabled = selfHostTlsEnabled(config, options?.devLocal === true)
530
+ const domain = config.server.domain?.trim()
531
+ const acmeEmail = config.server.tls?.email?.trim()
344
532
  writeFileSync(
345
533
  paths.kongPath,
346
534
  buildKongDeclarative({
@@ -349,20 +537,48 @@ export function writeSelfHostCompose(
349
537
  studioServiceUrl: COMPOSE_STUDIO_HOST_URL,
350
538
  studioStripPath: false,
351
539
  }),
540
+ ...(tlsEnabled && domain && acmeEmail
541
+ ? { acme: { email: acmeEmail, domain, redisHost: "valkey" } }
542
+ : {}),
352
543
  }),
353
544
  "utf8",
354
545
  )
355
546
  return paths
356
547
  }
357
548
 
549
+ export interface RunDockerComposeOptions {
550
+ /** Suppress docker compose progress UI (container status lines). */
551
+ quiet?: boolean
552
+ /** Logo + Clack intro when Docker preflight fails (TTY). */
553
+ brand?: DockerBrandOptions
554
+ }
555
+
556
+ /** Exit with a friendly compose failure message. */
557
+ export function exitComposeFailed(
558
+ status: number,
559
+ context: string,
560
+ brand?: DockerBrandOptions,
561
+ ): never {
562
+ fatalError(
563
+ `docker compose failed (exit ${status}).`,
564
+ [context, "Check logs: supatype self-host compose logs"],
565
+ { ...(brand !== undefined && { brand }), exitCode: status === 0 ? 1 : status },
566
+ )
567
+ }
568
+
358
569
  export function runDockerCompose(
359
570
  composePath: string,
360
571
  args: string[],
361
572
  projectRoot: string = process.cwd(),
362
573
  composeProject?: string,
574
+ options?: RunDockerComposeOptions,
363
575
  ): number {
576
+ requireDockerDaemon(options?.brand !== undefined ? { brand: options.brand } : undefined)
364
577
  const envFile = resolve(projectRoot, ".env")
365
578
  const composeArgs = ["compose"]
579
+ if (options?.quiet) {
580
+ composeArgs.push("--progress", "quiet")
581
+ }
366
582
  // Per-project name isolates containers/volumes/network so multiple Supatype
367
583
  // projects on one machine never share a database (default would be the
368
584
  // ".supatype/self-host" dir name, identical for every project).
@@ -374,11 +590,11 @@ export function runDockerCompose(
374
590
  composeArgs.push("--env-file", envFile)
375
591
  }
376
592
  composeArgs.push(...args)
377
- const result = spawnSync(
378
- "docker",
379
- composeArgs,
380
- { stdio: "inherit", cwd: projectRoot },
381
- )
593
+ const env: NodeJS.ProcessEnv = options?.quiet
594
+ ? { ...process.env, COMPOSE_PROGRESS: "quiet" }
595
+ : process.env
596
+ const stdio = options?.quiet ? "pipe" : "inherit"
597
+ const result = spawnSync("docker", composeArgs, { stdio, cwd: projectRoot, env })
382
598
  return result.status ?? 1
383
599
  }
384
600
 
@@ -6,6 +6,10 @@
6
6
  * Buckets already registered return 409 Conflict, which is treated as success.
7
7
  */
8
8
 
9
+ import type { ExtractedSchemaAstV2 } from "./schema-ast-v2.js"
10
+
11
+ export type { ExtractedStorageBucketAst as SchemaStorageBucketAst } from "./schema-ast-v2.js"
12
+
9
13
  export interface BucketSpec {
10
14
  id: string
11
15
  public: boolean
@@ -15,6 +19,29 @@ export interface BucketSpec {
15
19
  s3_bucket_policy?: string | null
16
20
  }
17
21
 
22
+ export function bucketSpecsFromAst(ast: Pick<ExtractedSchemaAstV2, "storageBuckets">): BucketSpec[] {
23
+ return (ast.storageBuckets ?? []).map((b) => ({
24
+ id: b.id,
25
+ public: b.public,
26
+ ...(b.accessMode !== undefined && { access_mode: b.accessMode }),
27
+ ...(b.allowedMimeTypes != null && { allowed_mime_types: b.allowedMimeTypes }),
28
+ ...(b.fileSizeLimit != null && { file_size_limit: b.fileSizeLimit }),
29
+ ...(b.s3BucketPolicy != null &&
30
+ b.s3BucketPolicy !== "" && { s3_bucket_policy: b.s3BucketPolicy }),
31
+ }))
32
+ }
33
+
34
+ export async function provisionBucketsFromAst(
35
+ ast: Pick<ExtractedSchemaAstV2, "storageBuckets">,
36
+ storageApiUrl: string,
37
+ serviceRoleKey: string,
38
+ ): Promise<void> {
39
+ const buckets = bucketSpecsFromAst(ast)
40
+ if (buckets.length === 0) return
41
+ console.log("[supatype] Provisioning storage buckets...")
42
+ await provisionBuckets(storageApiUrl, serviceRoleKey, buckets)
43
+ }
44
+
18
45
  /**
19
46
  * Ensure all declared buckets exist in the storage server.
20
47
  *
@@ -48,11 +75,16 @@ export async function provisionBuckets(
48
75
  const res = await fetch(`${base}/bucket`, { method: "POST", headers, body })
49
76
  .catch(() => null)
50
77
 
51
- if (res === null) continue // server not reachable — skip silently
78
+ if (res === null) {
79
+ console.warn(`[storage] Storage API unreachable — skipped bucket "${bucket.id}"`)
80
+ continue
81
+ }
52
82
  if (res.status === 409) continue // already exists — fine
53
83
  if (!res.ok) {
54
84
  const msg = await res.text().catch(() => res.statusText)
55
85
  console.warn(`[storage] Failed to provision bucket "${bucket.id}": ${msg}`)
86
+ continue
56
87
  }
88
+ console.log(`[supatype] Storage bucket "${bucket.id}" ready.`)
57
89
  }
58
90
  }
@@ -0,0 +1 @@
1
+ process.stdout.write("hello from tsx")
package/src/systemd.ts CHANGED
@@ -62,7 +62,7 @@ function postgresUnit(
62
62
  ): string {
63
63
  const dataDir = config.database.data_dir ?? join(stateDir, "data")
64
64
  const logDir = join(stateDir, "logs")
65
- const pgBinDir = `%h/.supatype/cache/postgres/${config.versions.postgres}/bin`
65
+ const pgBinDir = `%h/.supatype/cache/postgres/${config.versions?.postgres ?? "latest"}/bin`
66
66
 
67
67
  return `[Unit]
68
68
  Description=Supatype Postgres (${config.project.name})
@@ -100,7 +100,7 @@ function serverUnit(
100
100
  envFile: string,
101
101
  ): string {
102
102
  const port = config.server.port ?? 54321
103
- const serverBin = `%h/.supatype/cache/server/${config.versions.server}/supatype-server`
103
+ const serverBin = `%h/.supatype/cache/server/${config.versions?.server ?? "latest"}/supatype-server`
104
104
  const logDir = join(stateDir, "logs")
105
105
 
106
106
  const extraArgs: string[] = [`--mode ${config.server.mode}`]
@@ -0,0 +1,40 @@
1
+ export interface TargetFetchOptions {
2
+ method: string
3
+ path: string
4
+ body?: unknown
5
+ token: string
6
+ orgId?: string | undefined
7
+ environment?: string | undefined
8
+ }
9
+
10
+ export async function targetFetch<T>(
11
+ baseUrl: string,
12
+ apiPrefix: "/api/v1" | "/platform/v1",
13
+ opts: TargetFetchOptions,
14
+ ): Promise<T> {
15
+ const headers: Record<string, string> = {
16
+ "Content-Type": "application/json",
17
+ Authorization: `Bearer ${opts.token}`,
18
+ }
19
+ if (opts.orgId) headers["X-Org-Id"] = opts.orgId
20
+ if (opts.environment) headers["X-Supatype-Environment"] = opts.environment
21
+
22
+ const url = `${baseUrl.replace(/\/$/, "")}${apiPrefix}${opts.path}`
23
+ const res = await fetch(url, {
24
+ method: opts.method,
25
+ headers,
26
+ ...(opts.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),
27
+ })
28
+
29
+ const json = (await res.json().catch(() => ({}))) as {
30
+ data?: T
31
+ error?: string
32
+ message?: string
33
+ }
34
+
35
+ if (!res.ok) {
36
+ throw new Error(json.message ?? json.error ?? `API error: ${res.status} ${url}`)
37
+ }
38
+
39
+ return (json.data !== undefined ? json.data : json) as T
40
+ }