@supatype/cli 0.1.0-alpha.10

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 (416) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-test.log +221 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/assets/supatype-logo-wordmark.ascii.txt +6 -0
  5. package/bin/dev-entry.ts +2 -0
  6. package/bin/supatype.js +5 -0
  7. package/dist/app/framework.d.ts +44 -0
  8. package/dist/app/framework.d.ts.map +1 -0
  9. package/dist/app/framework.js +200 -0
  10. package/dist/app/framework.js.map +1 -0
  11. package/dist/app/proxy-dev-app.d.ts +13 -0
  12. package/dist/app/proxy-dev-app.d.ts.map +1 -0
  13. package/dist/app/proxy-dev-app.js +54 -0
  14. package/dist/app/proxy-dev-app.js.map +1 -0
  15. package/dist/app-config.d.ts +7 -0
  16. package/dist/app-config.d.ts.map +1 -0
  17. package/dist/app-config.js +113 -0
  18. package/dist/app-config.js.map +1 -0
  19. package/dist/assets/supatype-logo-wordmark.ascii.txt +6 -0
  20. package/dist/augmentation-generator.d.ts +2 -0
  21. package/dist/augmentation-generator.d.ts.map +1 -0
  22. package/dist/augmentation-generator.js +111 -0
  23. package/dist/augmentation-generator.js.map +1 -0
  24. package/dist/binary-cache.d.ts +98 -0
  25. package/dist/binary-cache.d.ts.map +1 -0
  26. package/dist/binary-cache.js +687 -0
  27. package/dist/binary-cache.js.map +1 -0
  28. package/dist/cli.d.ts +2 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +61 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/commands/admin.d.ts +4 -0
  33. package/dist/commands/admin.d.ts.map +1 -0
  34. package/dist/commands/admin.js +271 -0
  35. package/dist/commands/admin.js.map +1 -0
  36. package/dist/commands/app.d.ts +3 -0
  37. package/dist/commands/app.d.ts.map +1 -0
  38. package/dist/commands/app.js +82 -0
  39. package/dist/commands/app.js.map +1 -0
  40. package/dist/commands/cache.d.ts +6 -0
  41. package/dist/commands/cache.d.ts.map +1 -0
  42. package/dist/commands/cache.js +105 -0
  43. package/dist/commands/cache.js.map +1 -0
  44. package/dist/commands/cloud.d.ts +23 -0
  45. package/dist/commands/cloud.d.ts.map +1 -0
  46. package/dist/commands/cloud.js +254 -0
  47. package/dist/commands/cloud.js.map +1 -0
  48. package/dist/commands/db.d.ts +8 -0
  49. package/dist/commands/db.d.ts.map +1 -0
  50. package/dist/commands/db.js +116 -0
  51. package/dist/commands/db.js.map +1 -0
  52. package/dist/commands/deploy-types.d.ts +14 -0
  53. package/dist/commands/deploy-types.d.ts.map +1 -0
  54. package/dist/commands/deploy-types.js +38 -0
  55. package/dist/commands/deploy-types.js.map +1 -0
  56. package/dist/commands/deploy.d.ts +15 -0
  57. package/dist/commands/deploy.d.ts.map +1 -0
  58. package/dist/commands/deploy.js +322 -0
  59. package/dist/commands/deploy.js.map +1 -0
  60. package/dist/commands/dev.d.ts +14 -0
  61. package/dist/commands/dev.d.ts.map +1 -0
  62. package/dist/commands/dev.js +806 -0
  63. package/dist/commands/dev.js.map +1 -0
  64. package/dist/commands/diff.d.ts +3 -0
  65. package/dist/commands/diff.d.ts.map +1 -0
  66. package/dist/commands/diff.js +54 -0
  67. package/dist/commands/diff.js.map +1 -0
  68. package/dist/commands/engine.d.ts +7 -0
  69. package/dist/commands/engine.d.ts.map +1 -0
  70. package/dist/commands/engine.js +27 -0
  71. package/dist/commands/engine.js.map +1 -0
  72. package/dist/commands/functions.d.ts +3 -0
  73. package/dist/commands/functions.d.ts.map +1 -0
  74. package/dist/commands/functions.js +749 -0
  75. package/dist/commands/functions.js.map +1 -0
  76. package/dist/commands/generate.d.ts +3 -0
  77. package/dist/commands/generate.d.ts.map +1 -0
  78. package/dist/commands/generate.js +38 -0
  79. package/dist/commands/generate.js.map +1 -0
  80. package/dist/commands/init.d.ts +7 -0
  81. package/dist/commands/init.d.ts.map +1 -0
  82. package/dist/commands/init.js +228 -0
  83. package/dist/commands/init.js.map +1 -0
  84. package/dist/commands/keys.d.ts +4 -0
  85. package/dist/commands/keys.d.ts.map +1 -0
  86. package/dist/commands/keys.js +57 -0
  87. package/dist/commands/keys.js.map +1 -0
  88. package/dist/commands/logs.d.ts +6 -0
  89. package/dist/commands/logs.d.ts.map +1 -0
  90. package/dist/commands/logs.js +52 -0
  91. package/dist/commands/logs.js.map +1 -0
  92. package/dist/commands/migrate-from-v1.d.ts +5 -0
  93. package/dist/commands/migrate-from-v1.d.ts.map +1 -0
  94. package/dist/commands/migrate-from-v1.js +125 -0
  95. package/dist/commands/migrate-from-v1.js.map +1 -0
  96. package/dist/commands/migrate.d.ts +3 -0
  97. package/dist/commands/migrate.d.ts.map +1 -0
  98. package/dist/commands/migrate.js +75 -0
  99. package/dist/commands/migrate.js.map +1 -0
  100. package/dist/commands/pg.d.ts +8 -0
  101. package/dist/commands/pg.d.ts.map +1 -0
  102. package/dist/commands/pg.js +102 -0
  103. package/dist/commands/pg.js.map +1 -0
  104. package/dist/commands/plugins.d.ts +3 -0
  105. package/dist/commands/plugins.d.ts.map +1 -0
  106. package/dist/commands/plugins.js +431 -0
  107. package/dist/commands/plugins.js.map +1 -0
  108. package/dist/commands/pull.d.ts +3 -0
  109. package/dist/commands/pull.d.ts.map +1 -0
  110. package/dist/commands/pull.js +12 -0
  111. package/dist/commands/pull.js.map +1 -0
  112. package/dist/commands/push.d.ts +3 -0
  113. package/dist/commands/push.d.ts.map +1 -0
  114. package/dist/commands/push.js +179 -0
  115. package/dist/commands/push.js.map +1 -0
  116. package/dist/commands/seed.d.ts +5 -0
  117. package/dist/commands/seed.d.ts.map +1 -0
  118. package/dist/commands/seed.js +55 -0
  119. package/dist/commands/seed.js.map +1 -0
  120. package/dist/commands/self-host.d.ts +9 -0
  121. package/dist/commands/self-host.d.ts.map +1 -0
  122. package/dist/commands/self-host.js +310 -0
  123. package/dist/commands/self-host.js.map +1 -0
  124. package/dist/commands/self-update.d.ts +9 -0
  125. package/dist/commands/self-update.d.ts.map +1 -0
  126. package/dist/commands/self-update.js +33 -0
  127. package/dist/commands/self-update.js.map +1 -0
  128. package/dist/commands/status.d.ts +6 -0
  129. package/dist/commands/status.d.ts.map +1 -0
  130. package/dist/commands/status.js +70 -0
  131. package/dist/commands/status.js.map +1 -0
  132. package/dist/commands/types.d.ts +3 -0
  133. package/dist/commands/types.d.ts.map +1 -0
  134. package/dist/commands/types.js +62 -0
  135. package/dist/commands/types.js.map +1 -0
  136. package/dist/commands/update.d.ts +7 -0
  137. package/dist/commands/update.d.ts.map +1 -0
  138. package/dist/commands/update.js +118 -0
  139. package/dist/commands/update.js.map +1 -0
  140. package/dist/components.d.ts +5 -0
  141. package/dist/components.d.ts.map +1 -0
  142. package/dist/components.js +3 -0
  143. package/dist/components.js.map +1 -0
  144. package/dist/config.d.ts +65 -0
  145. package/dist/config.d.ts.map +1 -0
  146. package/dist/config.js +134 -0
  147. package/dist/config.js.map +1 -0
  148. package/dist/dev-compose.d.ts +19 -0
  149. package/dist/dev-compose.d.ts.map +1 -0
  150. package/dist/dev-compose.js +468 -0
  151. package/dist/dev-compose.js.map +1 -0
  152. package/dist/dev-log-bus.d.ts +30 -0
  153. package/dist/dev-log-bus.d.ts.map +1 -0
  154. package/dist/dev-log-bus.js +87 -0
  155. package/dist/dev-log-bus.js.map +1 -0
  156. package/dist/dev-log-filter.d.ts +10 -0
  157. package/dist/dev-log-filter.d.ts.map +1 -0
  158. package/dist/dev-log-filter.js +36 -0
  159. package/dist/dev-log-filter.js.map +1 -0
  160. package/dist/dev-logo.d.ts +12 -0
  161. package/dist/dev-logo.d.ts.map +1 -0
  162. package/dist/dev-logo.js +57 -0
  163. package/dist/dev-logo.js.map +1 -0
  164. package/dist/dev-session.d.ts +26 -0
  165. package/dist/dev-session.d.ts.map +1 -0
  166. package/dist/dev-session.js +106 -0
  167. package/dist/dev-session.js.map +1 -0
  168. package/dist/dev-shutdown.d.ts +9 -0
  169. package/dist/dev-shutdown.d.ts.map +1 -0
  170. package/dist/dev-shutdown.js +50 -0
  171. package/dist/dev-shutdown.js.map +1 -0
  172. package/dist/dev-task-colors.d.ts +14 -0
  173. package/dist/dev-task-colors.d.ts.map +1 -0
  174. package/dist/dev-task-colors.js +44 -0
  175. package/dist/dev-task-colors.js.map +1 -0
  176. package/dist/dev-tui.d.ts +24 -0
  177. package/dist/dev-tui.d.ts.map +1 -0
  178. package/dist/dev-tui.js +188 -0
  179. package/dist/dev-tui.js.map +1 -0
  180. package/dist/diff-output.d.ts +4 -0
  181. package/dist/diff-output.d.ts.map +1 -0
  182. package/dist/diff-output.js +12 -0
  183. package/dist/diff-output.js.map +1 -0
  184. package/dist/docker-postgres.d.ts +57 -0
  185. package/dist/docker-postgres.d.ts.map +1 -0
  186. package/dist/docker-postgres.js +208 -0
  187. package/dist/docker-postgres.js.map +1 -0
  188. package/dist/engine-client.d.ts +69 -0
  189. package/dist/engine-client.d.ts.map +1 -0
  190. package/dist/engine-client.js +157 -0
  191. package/dist/engine-client.js.map +1 -0
  192. package/dist/engine-push-output.d.ts +16 -0
  193. package/dist/engine-push-output.d.ts.map +1 -0
  194. package/dist/engine-push-output.js +61 -0
  195. package/dist/engine-push-output.js.map +1 -0
  196. package/dist/ensure-binary.d.ts +7 -0
  197. package/dist/ensure-binary.d.ts.map +1 -0
  198. package/dist/ensure-binary.js +17 -0
  199. package/dist/ensure-binary.js.map +1 -0
  200. package/dist/functions-router-gen.d.ts +14 -0
  201. package/dist/functions-router-gen.d.ts.map +1 -0
  202. package/dist/functions-router-gen.js +199 -0
  203. package/dist/functions-router-gen.js.map +1 -0
  204. package/dist/index.d.ts +11 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +9 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/jwt.d.ts +3 -0
  209. package/dist/jwt.d.ts.map +1 -0
  210. package/dist/jwt.js +13 -0
  211. package/dist/jwt.js.map +1 -0
  212. package/dist/kong-config.d.ts +25 -0
  213. package/dist/kong-config.d.ts.map +1 -0
  214. package/dist/kong-config.js +71 -0
  215. package/dist/kong-config.js.map +1 -0
  216. package/dist/local-gateway.d.ts +7 -0
  217. package/dist/local-gateway.d.ts.map +1 -0
  218. package/dist/local-gateway.js +9 -0
  219. package/dist/local-gateway.js.map +1 -0
  220. package/dist/local-storage.d.ts +8 -0
  221. package/dist/local-storage.d.ts.map +1 -0
  222. package/dist/local-storage.js +14 -0
  223. package/dist/local-storage.js.map +1 -0
  224. package/dist/pgbouncer-userlist.d.ts +5 -0
  225. package/dist/pgbouncer-userlist.d.ts.map +1 -0
  226. package/dist/pgbouncer-userlist.js +14 -0
  227. package/dist/pgbouncer-userlist.js.map +1 -0
  228. package/dist/postgres-ctl.d.ts +44 -0
  229. package/dist/postgres-ctl.d.ts.map +1 -0
  230. package/dist/postgres-ctl.js +137 -0
  231. package/dist/postgres-ctl.js.map +1 -0
  232. package/dist/process-manager.d.ts +49 -0
  233. package/dist/process-manager.d.ts.map +1 -0
  234. package/dist/process-manager.js +177 -0
  235. package/dist/process-manager.js.map +1 -0
  236. package/dist/project-config.d.ts +238 -0
  237. package/dist/project-config.d.ts.map +1 -0
  238. package/dist/project-config.js +159 -0
  239. package/dist/project-config.js.map +1 -0
  240. package/dist/pull-utils.d.ts +31 -0
  241. package/dist/pull-utils.d.ts.map +1 -0
  242. package/dist/pull-utils.js +77 -0
  243. package/dist/pull-utils.js.map +1 -0
  244. package/dist/release-pins.d.ts +7 -0
  245. package/dist/release-pins.d.ts.map +1 -0
  246. package/dist/release-pins.js +27 -0
  247. package/dist/release-pins.js.map +1 -0
  248. package/dist/release-public-key.d.ts +8 -0
  249. package/dist/release-public-key.d.ts.map +1 -0
  250. package/dist/release-public-key.js +13 -0
  251. package/dist/release-public-key.js.map +1 -0
  252. package/dist/restore-system-relation-targets.d.ts +3 -0
  253. package/dist/restore-system-relation-targets.d.ts.map +1 -0
  254. package/dist/restore-system-relation-targets.js +45 -0
  255. package/dist/restore-system-relation-targets.js.map +1 -0
  256. package/dist/runtime-routes.d.ts +34 -0
  257. package/dist/runtime-routes.d.ts.map +1 -0
  258. package/dist/runtime-routes.js +252 -0
  259. package/dist/runtime-routes.js.map +1 -0
  260. package/dist/schema-ast-v2.d.ts +127 -0
  261. package/dist/schema-ast-v2.d.ts.map +1 -0
  262. package/dist/schema-ast-v2.js +226 -0
  263. package/dist/schema-ast-v2.js.map +1 -0
  264. package/dist/scripts/postinstall.d.ts +11 -0
  265. package/dist/scripts/postinstall.d.ts.map +1 -0
  266. package/dist/scripts/postinstall.js +47 -0
  267. package/dist/scripts/postinstall.js.map +1 -0
  268. package/dist/seed.d.ts +8 -0
  269. package/dist/seed.d.ts.map +1 -0
  270. package/dist/seed.js +32 -0
  271. package/dist/seed.js.map +1 -0
  272. package/dist/self-host-compose.d.ts +43 -0
  273. package/dist/self-host-compose.d.ts.map +1 -0
  274. package/dist/self-host-compose.js +400 -0
  275. package/dist/self-host-compose.js.map +1 -0
  276. package/dist/storage-provision.d.ts +24 -0
  277. package/dist/storage-provision.d.ts.map +1 -0
  278. package/dist/storage-provision.js +44 -0
  279. package/dist/storage-provision.js.map +1 -0
  280. package/dist/studio-admin-roles.d.ts +7 -0
  281. package/dist/studio-admin-roles.d.ts.map +1 -0
  282. package/dist/studio-admin-roles.js +14 -0
  283. package/dist/studio-admin-roles.js.map +1 -0
  284. package/dist/studio-dev-server.d.ts +22 -0
  285. package/dist/studio-dev-server.d.ts.map +1 -0
  286. package/dist/studio-dev-server.js +28 -0
  287. package/dist/studio-dev-server.js.map +1 -0
  288. package/dist/supatype-eval-1781522769253.d.mts +2 -0
  289. package/dist/supatype-eval-1781522769253.d.mts.map +1 -0
  290. package/dist/supatype-eval-1781522769253.mjs +3 -0
  291. package/dist/supatype-eval-1781522769253.mjs.map +1 -0
  292. package/dist/systemd.d.ts +26 -0
  293. package/dist/systemd.d.ts.map +1 -0
  294. package/dist/systemd.js +102 -0
  295. package/dist/systemd.js.map +1 -0
  296. package/dist/tsx-runner.d.ts +18 -0
  297. package/dist/tsx-runner.d.ts.map +1 -0
  298. package/dist/tsx-runner.js +69 -0
  299. package/dist/tsx-runner.js.map +1 -0
  300. package/dist/type-extractor.d.ts +4 -0
  301. package/dist/type-extractor.d.ts.map +1 -0
  302. package/dist/type-extractor.js +1213 -0
  303. package/dist/type-extractor.js.map +1 -0
  304. package/dist/type-resolver.d.ts +33 -0
  305. package/dist/type-resolver.d.ts.map +1 -0
  306. package/dist/type-resolver.js +338 -0
  307. package/dist/type-resolver.js.map +1 -0
  308. package/package.json +41 -0
  309. package/releases/deno/VERSION +1 -0
  310. package/scripts/mirror-deno-release.sh +76 -0
  311. package/src/TYPE-RESOLUTION.md +294 -0
  312. package/src/app/framework.ts +249 -0
  313. package/src/app/proxy-dev-app.ts +68 -0
  314. package/src/app-config.ts +128 -0
  315. package/src/augmentation-generator.ts +126 -0
  316. package/src/binary-cache.ts +845 -0
  317. package/src/cli.ts +63 -0
  318. package/src/commands/admin.ts +372 -0
  319. package/src/commands/app.ts +97 -0
  320. package/src/commands/cache.ts +117 -0
  321. package/src/commands/cloud.ts +325 -0
  322. package/src/commands/db.ts +136 -0
  323. package/src/commands/deploy-types.ts +49 -0
  324. package/src/commands/deploy.ts +400 -0
  325. package/src/commands/dev.ts +1009 -0
  326. package/src/commands/diff.ts +63 -0
  327. package/src/commands/engine.ts +30 -0
  328. package/src/commands/functions.ts +901 -0
  329. package/src/commands/generate.ts +44 -0
  330. package/src/commands/init.ts +253 -0
  331. package/src/commands/keys.ts +66 -0
  332. package/src/commands/logs.ts +58 -0
  333. package/src/commands/migrate-from-v1.ts +131 -0
  334. package/src/commands/migrate.ts +87 -0
  335. package/src/commands/pg.ts +133 -0
  336. package/src/commands/plugins.ts +508 -0
  337. package/src/commands/pull.ts +17 -0
  338. package/src/commands/push.ts +226 -0
  339. package/src/commands/seed.ts +68 -0
  340. package/src/commands/self-host.ts +364 -0
  341. package/src/commands/self-update.ts +45 -0
  342. package/src/commands/status.ts +84 -0
  343. package/src/commands/types.ts +76 -0
  344. package/src/commands/update.ts +136 -0
  345. package/src/components.ts +6 -0
  346. package/src/config.ts +223 -0
  347. package/src/dev-compose.ts +583 -0
  348. package/src/dev-log-bus.ts +101 -0
  349. package/src/dev-log-filter.ts +32 -0
  350. package/src/dev-logo.ts +62 -0
  351. package/src/dev-session.ts +130 -0
  352. package/src/dev-shutdown.ts +54 -0
  353. package/src/dev-task-colors.ts +47 -0
  354. package/src/dev-tui.ts +232 -0
  355. package/src/diff-output.ts +12 -0
  356. package/src/docker-postgres.ts +295 -0
  357. package/src/engine-client.ts +236 -0
  358. package/src/engine-push-output.ts +71 -0
  359. package/src/ensure-binary.ts +28 -0
  360. package/src/functions-router-gen.ts +224 -0
  361. package/src/index.ts +11 -0
  362. package/src/jwt.ts +14 -0
  363. package/src/kong-config.ts +93 -0
  364. package/src/local-gateway.ts +9 -0
  365. package/src/local-storage.ts +14 -0
  366. package/src/pgbouncer-userlist.ts +15 -0
  367. package/src/postgres-ctl.ts +171 -0
  368. package/src/process-manager.ts +220 -0
  369. package/src/project-config.ts +388 -0
  370. package/src/pull-utils.ts +81 -0
  371. package/src/release-pins.ts +31 -0
  372. package/src/release-public-key.ts +12 -0
  373. package/src/restore-system-relation-targets.ts +45 -0
  374. package/src/runtime-routes.ts +291 -0
  375. package/src/schema-ast-v2.ts +324 -0
  376. package/src/scripts/postinstall.ts +51 -0
  377. package/src/seed.ts +43 -0
  378. package/src/self-host-compose.ts +452 -0
  379. package/src/storage-provision.ts +58 -0
  380. package/src/studio-admin-roles.ts +16 -0
  381. package/src/studio-dev-server.ts +53 -0
  382. package/src/supatype-eval-1781522769253.mts +1 -0
  383. package/src/systemd.ts +137 -0
  384. package/src/tsx-runner.ts +89 -0
  385. package/src/type-extractor.ts +1479 -0
  386. package/src/type-resolver.ts +457 -0
  387. package/tests/app-command.test.ts +54 -0
  388. package/tests/augmentation-generator.test.ts +59 -0
  389. package/tests/binary-cache-cloud-overrides.test.ts +123 -0
  390. package/tests/cached-artifact-format.test.ts +84 -0
  391. package/tests/cli-help.test.ts +133 -0
  392. package/tests/config.test.ts +252 -0
  393. package/tests/dev-ui.test.ts +139 -0
  394. package/tests/docker-postgres.test.ts +39 -0
  395. package/tests/engine-distribution.test.ts +418 -0
  396. package/tests/engine-push-output.test.ts +67 -0
  397. package/tests/ensure-binary.test.ts +59 -0
  398. package/tests/init.test.ts +127 -0
  399. package/tests/keys.test.ts +160 -0
  400. package/tests/migrate-from-v1.test.ts +29 -0
  401. package/tests/normalize-admin-config.test.ts +48 -0
  402. package/tests/pg-spawn-env.test.ts +18 -0
  403. package/tests/postgres-archive-tag.test.ts +9 -0
  404. package/tests/proxy-dev-app.test.ts +33 -0
  405. package/tests/pull-utils.test.ts +150 -0
  406. package/tests/release-pins.test.ts +28 -0
  407. package/tests/runtime-contract.test.ts +370 -0
  408. package/tests/seed-discover.test.ts +31 -0
  409. package/tests/studio-admin-roles.test.ts +27 -0
  410. package/tests/tsconfig.json +9 -0
  411. package/tests/tsx-runner.test.ts +66 -0
  412. package/tests/type-extractor.test.ts +985 -0
  413. package/tests/type-resolver.test.ts +59 -0
  414. package/tsconfig.json +10 -0
  415. package/tsconfig.tsbuildinfo +1 -0
  416. package/vitest.config.ts +12 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Postinstall script — downloads component binaries on first install.
3
+ *
4
+ * Components: supatype-engine, supatype-server, supatype-pg (Postgres), deno.
5
+ * Binaries are cached in ~/.supatype/cache/{component}/{version}/.
6
+ *
7
+ * Failures are non-fatal: an installation message is printed and the user
8
+ * can run `supatype update` manually to retry.
9
+ */
10
+
11
+ import { download, currentPlatform, fetchAllLatestVersions, type Component } from "../binary-cache.js"
12
+
13
+ async function main() {
14
+ const platform = currentPlatform()
15
+
16
+ let versions: Record<Component, string>
17
+ try {
18
+ console.log("[supatype] Fetching latest component versions...")
19
+ versions = await fetchAllLatestVersions()
20
+ } catch (err) {
21
+ console.error(`[supatype] Failed to fetch latest versions: ${(err as Error).message}`)
22
+ console.error("[supatype] Run 'supatype update' to download component binaries.")
23
+ return
24
+ }
25
+
26
+ console.log(`[supatype] Downloading component binaries for ${platform.os}/${platform.arch}...`)
27
+
28
+ const components = Object.entries(versions) as [Component, string][]
29
+
30
+ let anyFailed = false
31
+ for (const [component, version] of components) {
32
+ try {
33
+ await download(component, version, platform)
34
+ } catch (err) {
35
+ console.error(`[supatype] Failed to download ${component} v${version}: ${(err as Error).message}`)
36
+ anyFailed = true
37
+ }
38
+ }
39
+
40
+ if (anyFailed) {
41
+ console.error("[supatype] Some downloads failed. Run 'supatype update' to retry.")
42
+ } else {
43
+ console.log("[supatype] All component binaries downloaded successfully.")
44
+ }
45
+ }
46
+
47
+ main().catch((err) => {
48
+ // Non-fatal — postinstall failures should not break npm install.
49
+ console.error("[supatype] Postinstall failed:", err)
50
+ process.exit(0)
51
+ })
package/src/seed.ts ADDED
@@ -0,0 +1,43 @@
1
+ import pg from "pg"
2
+
3
+ export interface SeedSql {
4
+ (strings: TemplateStringsArray, ...values: unknown[]): Promise<pg.QueryResult>
5
+ end(): Promise<void>
6
+ }
7
+
8
+ /** Lightweight tagged-template SQL helper for project `seed.ts` scripts. */
9
+ export function sql(connectionString: string): SeedSql {
10
+ const client = new pg.Client({ connectionString })
11
+ let connected = false
12
+
13
+ const ensureConnected = async (): Promise<void> => {
14
+ if (!connected) {
15
+ await client.connect()
16
+ connected = true
17
+ }
18
+ }
19
+
20
+ const tag = async (
21
+ strings: TemplateStringsArray,
22
+ ...values: unknown[]
23
+ ): Promise<pg.QueryResult> => {
24
+ await ensureConnected()
25
+ let text = ""
26
+ for (let i = 0; i < strings.length; i++) {
27
+ text += strings[i]
28
+ if (i < values.length) {
29
+ text += `$${i + 1}`
30
+ }
31
+ }
32
+ return client.query(text, values)
33
+ }
34
+
35
+ return Object.assign(tag, {
36
+ end: async (): Promise<void> => {
37
+ if (connected) {
38
+ await client.end()
39
+ connected = false
40
+ }
41
+ },
42
+ })
43
+ }
@@ -0,0 +1,452 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs"
2
+ import { dirname, join, relative, resolve } from "node:path"
3
+ import { spawnSync } from "node:child_process"
4
+ import { preferredFunctionsPathFromProject, type SupatypeProjectConfig } from "./project-config.js"
5
+ import { hasEngineOverride, hasStudioOverride, pinnedVersion, fetchLatestVersion, VERSION_PIN_LOCAL } from "./binary-cache.js"
6
+ import { buildKongDeclarative } from "./kong-config.js"
7
+
8
+ /** Env keys written when `versions` pins exist in supatype.config.ts. */
9
+ export const COMPOSE_PINNED_IMAGE_ENV_KEYS = [
10
+ "SUPATYPE_ENGINE_IMAGE",
11
+ "SUPATYPE_SERVER_IMAGE",
12
+ "SUPATYPE_POSTGRES_IMAGE",
13
+ ] as const
14
+
15
+ type DockerPinComponent = "engine" | "server" | "postgres"
16
+
17
+ /** Map a config version pin to a Docker Hub image reference. */
18
+ export function dockerImageRef(
19
+ component: DockerPinComponent,
20
+ version: string,
21
+ config?: SupatypeProjectConfig,
22
+ ): string {
23
+ const trimmed = version.trim()
24
+ switch (component) {
25
+ case "engine":
26
+ return `supatype/schema-engine:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
27
+ case "server":
28
+ return `supatype/server:${trimmed.startsWith("v") ? trimmed : `v${trimmed}`}`
29
+ case "postgres": {
30
+ const override = config?.database?.image?.trim()
31
+ if (override) return override
32
+ if (trimmed.includes("-latest")) return `supatype/postgres:${trimmed}`
33
+ const major = trimmed.split(".")[0]
34
+ return `supatype/postgres:${major}-latest`
35
+ }
36
+ }
37
+ }
38
+
39
+ /**
40
+ * When the user pins `versions` in config, sync matching SUPATYPE_*_IMAGE vars for Compose.
41
+ * Unpinned components are omitted so compose falls back to :latest defaults.
42
+ */
43
+ export function composeDockerImageEnv(config: SupatypeProjectConfig): Record<string, string> {
44
+ const env: Record<string, string> = {}
45
+ const versions = config.versions
46
+ if (!versions) return env
47
+
48
+ if (versions.engine && versions.engine !== VERSION_PIN_LOCAL) {
49
+ env.SUPATYPE_ENGINE_IMAGE = dockerImageRef("engine", versions.engine)
50
+ }
51
+ if (versions.server && versions.server !== VERSION_PIN_LOCAL) {
52
+ env.SUPATYPE_SERVER_IMAGE = dockerImageRef("server", versions.server)
53
+ }
54
+ if (versions.postgres && versions.postgres !== VERSION_PIN_LOCAL) {
55
+ env.SUPATYPE_POSTGRES_IMAGE = dockerImageRef("postgres", versions.postgres, config)
56
+ }
57
+ return env
58
+ }
59
+
60
+ /**
61
+ * Schema-engine image for a one-off `docker compose run` when pushing schema.
62
+ * Uses config pin when set; otherwise CDN engine semver (Docker Hub `:latest` can lag).
63
+ * Does not touch `.env` — server/postgres still use compose `:latest` defaults.
64
+ */
65
+ export async function schemaEngineImageForPush(
66
+ config: SupatypeProjectConfig,
67
+ ): Promise<string | undefined> {
68
+ const pinned = pinnedVersion("engine", config)
69
+ if (pinned === VERSION_PIN_LOCAL) return undefined
70
+ if (pinned) return dockerImageRef("engine", pinned)
71
+ const version = await fetchLatestVersion("engine")
72
+ return dockerImageRef("engine", version)
73
+ }
74
+
75
+ export interface SelfHostComposePaths {
76
+ dir: string
77
+ composePath: string
78
+ kongPath: string
79
+ nginxPath: string
80
+ }
81
+
82
+ export function selfHostComposePaths(cwd: string): SelfHostComposePaths {
83
+ const dir = resolve(cwd, ".supatype", "self-host")
84
+ return {
85
+ dir,
86
+ composePath: join(dir, "docker-compose.yml"),
87
+ kongPath: join(dir, "kong.yml"),
88
+ nginxPath: join(dir, "nginx.conf"),
89
+ }
90
+ }
91
+
92
+ export function appUpstreamForCompose(config: SupatypeProjectConfig): string | undefined {
93
+ if (config.app.mode !== "proxy") return undefined
94
+ const upstream = config.app.upstream?.trim()
95
+ return upstream && upstream.length > 0 ? upstream : undefined
96
+ }
97
+
98
+ export function staticDirForCompose(config: SupatypeProjectConfig): string | undefined {
99
+ if (config.app.mode !== "static") return undefined
100
+ const dir = config.app.static_dir?.trim()
101
+ return dir && dir.length > 0 ? dir : "./public"
102
+ }
103
+
104
+ /**
105
+ * Bind-mount source for `/project` in generated compose files.
106
+ * Paths are resolved from `--project-directory` (always the project root in `runDockerCompose`),
107
+ * not from the compose file directory — use `.` not `../..`.
108
+ */
109
+ function projectMountPath(_cwd: string): string {
110
+ return "."
111
+ }
112
+
113
+ /** Paths in generated compose are resolved from `--project-directory` (project root). */
114
+ function relativeFromProjectRoot(cwd: string, target: string): string {
115
+ let rel = relative(resolve(cwd), resolve(target)).replace(/\\/g, "/")
116
+ if (!rel.startsWith(".") && !rel.startsWith("/")) {
117
+ rel = `./${rel}`
118
+ }
119
+ return rel
120
+ }
121
+
122
+ function kongMountPath(_cwd: string): string {
123
+ return ".supatype/self-host/kong.yml"
124
+ }
125
+
126
+ /** Host Vite dev server as seen from Kong inside Docker Compose. */
127
+ export const COMPOSE_STUDIO_HOST_URL = "http://host.docker.internal:3002"
128
+
129
+ /** Studio container — always Docker Hub unless SUPATYPE_STUDIO_IMAGE is set in .env. */
130
+ function studioServiceBlock(): string {
131
+ return ` image: \${SUPATYPE_STUDIO_IMAGE:-supatype/studio:latest}`
132
+ }
133
+
134
+ /** Host dev app (Astro/Vite on the machine) as seen from inside compose services. */
135
+ function proxyUpstreamForCompose(upstream: string, devLocal: boolean): string {
136
+ const trimmed = upstream.trim()
137
+ if (!devLocal) return trimmed
138
+ try {
139
+ const url = new URL(trimmed)
140
+ if (url.hostname === "localhost" || url.hostname === "127.0.0.1") {
141
+ url.hostname = "host.docker.internal"
142
+ return url.toString()
143
+ }
144
+ } catch {
145
+ // keep literal upstream when not a URL
146
+ }
147
+ return trimmed
148
+ }
149
+
150
+ function serverAppEnvForCompose(config: SupatypeProjectConfig, devLocal: boolean): string {
151
+ const mode = config.app.mode ?? "none"
152
+ const lines = [` SUPATYPE_APP_MODE: ${mode}`]
153
+ if (mode === "static") {
154
+ const dir = staticDirForCompose(config) ?? "./public"
155
+ lines.push(` SUPATYPE_APP_STATIC_DIR: /project/${dir.replace(/^\.\//, "")}`)
156
+ } else if (mode === "proxy" && config.app.upstream?.trim()) {
157
+ lines.push(` SUPATYPE_APP_UPSTREAM: ${proxyUpstreamForCompose(config.app.upstream, devLocal)}`)
158
+ }
159
+ return lines.join("\n")
160
+ }
161
+
162
+ export interface SelfHostComposeOptions {
163
+ /** `supatype dev` with provider docker: internal-only db/server; Kong on host :18473. */
164
+ devLocal?: boolean
165
+ }
166
+
167
+ export function renderSelfHostCompose(
168
+ config: SupatypeProjectConfig,
169
+ cwd: string = process.cwd(),
170
+ options?: SelfHostComposeOptions,
171
+ ): string {
172
+ const projectMount = projectMountPath(cwd)
173
+ const kongMount = kongMountPath(cwd)
174
+ const devLocal = options?.devLocal === true
175
+ const studioHostDev = devLocal && hasStudioOverride(config)
176
+ const appEnv = serverAppEnvForCompose(config, devLocal)
177
+ const studioService = studioServiceBlock()
178
+ const studioBlock = studioHostDev
179
+ ? ""
180
+ : `
181
+ studio:
182
+ ${studioService}
183
+ environment:
184
+ SUPATYPE_CLOUD_JSON: '{"url":"\${API_EXTERNAL_URL:-http://localhost:18473}","anonKey":"\${ANON_KEY:-}"}'
185
+ expose:
186
+ - "3002"
187
+ `
188
+ const kongDependsOn = studioHostDev
189
+ ? ` - server`
190
+ : ` - server
191
+ - studio`
192
+ const publishDbToHost = !devLocal || hasEngineOverride(config)
193
+ const dbPorts = publishDbToHost
194
+ ? devLocal
195
+ ? ` ports:
196
+ - "127.0.0.1:\${SUPATYPE_DEV_DB_PORT:-54329}:5432"
197
+ `
198
+ : ` ports:
199
+ - "5432:5432"
200
+ `
201
+ : ""
202
+ const serverPorts = devLocal
203
+ ? ""
204
+ : ` ports:
205
+ - "9999:9999"
206
+ `
207
+ const minioPorts = devLocal
208
+ ? ""
209
+ : ` ports:
210
+ - "9000:9000"
211
+ - "9001:9001"
212
+ `
213
+
214
+ return `# Generated by supatype self-host compose
215
+ # Kong → supatype-server (unified gateway) → internal PostgREST / storage / etc.
216
+ services:
217
+ db:
218
+ image: \${SUPATYPE_POSTGRES_IMAGE:-supatype/postgres:latest}
219
+ environment:
220
+ POSTGRES_USER: \${POSTGRES_USER:-supatype_admin}
221
+ POSTGRES_PASSWORD: \${POSTGRES_PASSWORD:-postgres}
222
+ POSTGRES_DB: \${POSTGRES_DB:-supatype}
223
+ ${dbPorts} volumes:
224
+ - db-data:/var/lib/postgresql/data
225
+ healthcheck:
226
+ test: ["CMD-SHELL", "pg_isready -U \${POSTGRES_USER:-supatype_admin}"]
227
+ interval: 5s
228
+ timeout: 5s
229
+ retries: 20
230
+
231
+ postgrest:
232
+ image: postgrest/postgrest:v12.2.8
233
+ expose:
234
+ - "3000"
235
+ environment:
236
+ PGRST_DB_URI: postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}
237
+ PGRST_DB_SCHEMA: "public, supatype, graphql_public, auth"
238
+ PGRST_DB_ANON_ROLE: anon
239
+ PGRST_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
240
+ PGRST_DB_EXTRA_SEARCH_PATH: public,extensions
241
+ PGRST_DB_POOL: 3
242
+ depends_on:
243
+ db:
244
+ condition: service_healthy
245
+
246
+ storage:
247
+ image: \${SUPATYPE_STORAGE_IMAGE:-supatype/storage:latest}
248
+ expose:
249
+ - "5000"
250
+ environment:
251
+ PORT: 5000
252
+ DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
253
+ JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
254
+ S3_ENDPOINT: http://minio:9000
255
+ S3_REGION: us-east-1
256
+ S3_ACCESS_KEY: supatype
257
+ S3_SECRET_KEY: supatype-secret
258
+ S3_FORCE_PATH_STYLE: "true"
259
+ depends_on:
260
+ db:
261
+ condition: service_healthy
262
+
263
+ functions-worker:
264
+ image: \${SUPATYPE_FUNCTIONS_WORKER_IMAGE:-supatype/functions-worker:latest}
265
+ expose:
266
+ - "8001"
267
+ volumes:
268
+ - ${projectMount}:/project:ro
269
+ environment:
270
+ SUPATYPE_FUNCTIONS_ROOT: /project/functions
271
+ SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
272
+ PORT: "8001"
273
+ SUPATYPE_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
274
+ SUPATYPE_ANON_KEY: \${ANON_KEY:-}
275
+ SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
276
+ STRIPE_SECRET_KEY: \${STRIPE_SECRET_KEY:-}
277
+ STRIPE_WEBHOOK_SECRET: \${STRIPE_WEBHOOK_SECRET:-}
278
+ SITE_URL: \${SITE_URL:-\${API_EXTERNAL_URL:-http://localhost:18473}}
279
+ depends_on:
280
+ db:
281
+ condition: service_healthy
282
+
283
+ server:
284
+ image: \${SUPATYPE_SERVER_IMAGE:-\${SUPATYPE_AUTH_IMAGE:-supatype/server:latest}}
285
+ ${serverPorts} volumes:
286
+ - ${projectMount}:/project:ro
287
+ working_dir: /project
288
+ environment:
289
+ SUPATYPE_MODE: ${devLocal ? "dev" : "standalone"}
290
+ SUPATYPE_MANIFEST_PATH: .supatype/manifest.json
291
+ SUPATYPE_ADMIN_CONFIG_PATH: .supatype/admin-config.json
292
+ SUPATYPE_API_CONFIG_PATH: .supatype/api-config.json
293
+ SUPATYPE_POSTGREST_URL: http://postgrest:3000
294
+ SUPATYPE_GRAPHQL_URL: http://postgrest:3000
295
+ SUPATYPE_STORAGE_URL: http://storage:5000
296
+ SUPATYPE_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
297
+ SUPATYPE_ANON_KEY: \${ANON_KEY:-}
298
+ SUPATYPE_SERVICE_ROLE_KEY: \${SERVICE_ROLE_KEY:-}
299
+ SUPATYPE_SQL_DATABASE_URL: "postgresql://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}"
300
+ SUPATYPE_DENO_FUNCTIONS_DIR: /project/functions
301
+ SUPATYPE_FUNCTIONS_WORKER_URL: http://functions-worker:8001
302
+ ${appEnv}
303
+ GOTRUE_API_HOST: 0.0.0.0
304
+ GOTRUE_API_PORT: 9999
305
+ API_EXTERNAL_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
306
+ GOTRUE_API_EXTERNAL_URL: \${API_EXTERNAL_URL:-http://localhost:18473}
307
+ GOTRUE_DB_DRIVER: postgres
308
+ GOTRUE_DB_DATABASE_URL: "postgres://\${POSTGRES_USER:-supatype_admin}:\${POSTGRES_PASSWORD:-postgres}@db:5432/\${POSTGRES_DB:-supatype}?search_path=auth"
309
+ GOTRUE_SITE_URL: \${SITE_URL:-http://localhost:3000}
310
+ GOTRUE_JWT_SECRET: \${JWT_SECRET:-super-secret-jwt-token-change-in-production}
311
+ GOTRUE_JWT_EXP: 3600
312
+ GOTRUE_JWT_AUD: authenticated
313
+ GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated
314
+ GOTRUE_JWT_ADMIN_ROLES: service_role,supatype_admin
315
+ GOTRUE_MAILER_AUTOCONFIRM: \${GOTRUE_MAILER_AUTOCONFIRM:-true}
316
+ GOTRUE_DISABLE_SIGNUP: \${DISABLE_SIGNUP:-false}
317
+ ${devLocal ? " STUDIO_OPEN_DEV: \"1\"\n" : ""}
318
+ depends_on:
319
+ db:
320
+ condition: service_healthy
321
+ postgrest:
322
+ condition: service_started
323
+ storage:
324
+ condition: service_started
325
+ functions-worker:
326
+ condition: service_started
327
+
328
+ minio:
329
+ image: minio/minio:RELEASE.2024-11-07T00-52-20Z
330
+ command: server /data --console-address ":9001"
331
+ environment:
332
+ MINIO_ROOT_USER: supatype
333
+ MINIO_ROOT_PASSWORD: supatype-secret
334
+ ${minioPorts} volumes:
335
+ - minio-data:/data
336
+
337
+ schema-engine:
338
+ image: \${SUPATYPE_ENGINE_IMAGE:-supatype/schema-engine:latest}
339
+ profiles: ["tools"]
340
+ entrypoint: ["supatype-engine"]
341
+ volumes:
342
+ - ${projectMount}:/project
343
+ working_dir: /project
344
+ depends_on:
345
+ db:
346
+ condition: service_healthy
347
+ ${studioBlock}
348
+ kong:
349
+ image: kong:3.6
350
+ environment:
351
+ KONG_DATABASE: "off"
352
+ KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
353
+ KONG_PROXY_ACCESS_LOG: /dev/stdout
354
+ KONG_ADMIN_ACCESS_LOG: /dev/stdout
355
+ KONG_PROXY_ERROR_LOG: /dev/stderr
356
+ KONG_ADMIN_ERROR_LOG: /dev/stderr
357
+ volumes:
358
+ - ${kongMount}:/etc/kong/kong.yml:ro
359
+ ports:
360
+ - "\${SUPATYPE_KONG_PORT:-18473}:8000"
361
+ depends_on:
362
+ ${kongDependsOn}
363
+
364
+ volumes:
365
+ db-data:
366
+ minio-data:
367
+ `
368
+ }
369
+
370
+ function ensureComposeManifest(cwd: string): void {
371
+ const manifestPath = join(cwd, ".supatype", "manifest.json")
372
+ if (existsSync(manifestPath)) return
373
+ mkdirSync(dirname(manifestPath), { recursive: true })
374
+ const manifest = {
375
+ schema: "public",
376
+ postgrest_url: "http://postgrest:3000",
377
+ storage_url: "http://storage:5000",
378
+ realtime_enabled: true,
379
+ functions_enabled: false,
380
+ }
381
+ writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8")
382
+ }
383
+
384
+ function ensureProjectFunctionsDir(cwd: string, config: SupatypeProjectConfig): void {
385
+ mkdirSync(preferredFunctionsPathFromProject(config, cwd), { recursive: true })
386
+ }
387
+
388
+ export function writeSelfHostCompose(
389
+ cwd: string,
390
+ config: SupatypeProjectConfig,
391
+ options?: SelfHostComposeOptions,
392
+ ): SelfHostComposePaths {
393
+ const paths = selfHostComposePaths(cwd)
394
+ mkdirSync(paths.dir, { recursive: true })
395
+ ensureProjectFunctionsDir(cwd, config)
396
+ ensureComposeManifest(cwd)
397
+ writeFileSync(paths.composePath, renderSelfHostCompose(config, cwd, options), "utf8")
398
+ const studioHostDev = options?.devLocal === true && hasStudioOverride(config)
399
+ writeFileSync(
400
+ paths.kongPath,
401
+ buildKongDeclarative({
402
+ unifiedGateway: true,
403
+ ...(studioHostDev && {
404
+ studioServiceUrl: COMPOSE_STUDIO_HOST_URL,
405
+ studioStripPath: false,
406
+ }),
407
+ }),
408
+ "utf8",
409
+ )
410
+ return paths
411
+ }
412
+
413
+ export interface RunDockerComposeOptions {
414
+ /** Suppress docker compose progress UI (container status lines). */
415
+ quiet?: boolean
416
+ }
417
+
418
+ export function runDockerCompose(
419
+ composePath: string,
420
+ args: string[],
421
+ projectRoot: string = process.cwd(),
422
+ composeProject?: string,
423
+ options?: RunDockerComposeOptions,
424
+ ): number {
425
+ const envFile = resolve(projectRoot, ".env")
426
+ const composeArgs = ["compose"]
427
+ if (options?.quiet) {
428
+ composeArgs.push("--progress", "quiet")
429
+ }
430
+ // Per-project name isolates containers/volumes/network so multiple Supatype
431
+ // projects on one machine never share a database (default would be the
432
+ // ".supatype/self-host" dir name, identical for every project).
433
+ if (composeProject) composeArgs.push("-p", composeProject)
434
+ // Resolve ${VAR} in compose.yml from the project root .env (not .supatype/self-host/).
435
+ composeArgs.push("--project-directory", projectRoot)
436
+ composeArgs.push("-f", composePath)
437
+ if (existsSync(envFile)) {
438
+ composeArgs.push("--env-file", envFile)
439
+ }
440
+ composeArgs.push(...args)
441
+ const env: NodeJS.ProcessEnv = options?.quiet
442
+ ? { ...process.env, COMPOSE_PROGRESS: "quiet" }
443
+ : process.env
444
+ const result = spawnSync("docker", composeArgs, { stdio: "inherit", cwd: projectRoot, env })
445
+ return result.status ?? 1
446
+ }
447
+
448
+ /** Compose project name for a Supatype project — isolates docker state per project. */
449
+ export function composeProjectName(projectName: string): string {
450
+ const slug = projectName.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "")
451
+ return `supatype-${slug || "project"}`
452
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Provision storage buckets declared in a schema AST via the storage server API.
3
+ *
4
+ * The storage server is the authority on bucket existence — going through the API
5
+ * ensures it creates any backing resources (directories, S3 buckets, etc.).
6
+ * Buckets already registered return 409 Conflict, which is treated as success.
7
+ */
8
+
9
+ export interface BucketSpec {
10
+ id: string
11
+ public: boolean
12
+ allowed_mime_types?: string[] | null
13
+ file_size_limit?: number | null
14
+ access_mode?: "public" | "private" | "custom"
15
+ s3_bucket_policy?: string | null
16
+ }
17
+
18
+ /**
19
+ * Ensure all declared buckets exist in the storage server.
20
+ *
21
+ * @param storageApiUrl Base URL of the storage API, e.g. "http://localhost:54321/storage/v1"
22
+ * @param serviceRoleKey A service_role JWT for the storage server
23
+ * @param buckets Buckets to provision (from the resolved AST)
24
+ */
25
+ export async function provisionBuckets(
26
+ storageApiUrl: string,
27
+ serviceRoleKey: string,
28
+ buckets: BucketSpec[],
29
+ ): Promise<void> {
30
+ const base = storageApiUrl.replace(/\/$/, "")
31
+ const headers = {
32
+ "Authorization": `Bearer ${serviceRoleKey}`,
33
+ "Content-Type": "application/json",
34
+ }
35
+
36
+ for (const bucket of buckets) {
37
+ const body = JSON.stringify({
38
+ id: bucket.id,
39
+ name: bucket.id,
40
+ public: bucket.public,
41
+ ...(bucket.allowed_mime_types != null && { allowed_mime_types: bucket.allowed_mime_types }),
42
+ ...(bucket.file_size_limit != null && { file_size_limit: bucket.file_size_limit }),
43
+ ...(bucket.access_mode != null && { access_mode: bucket.access_mode }),
44
+ ...(bucket.s3_bucket_policy != null &&
45
+ bucket.s3_bucket_policy !== "" && { s3_bucket_policy: bucket.s3_bucket_policy }),
46
+ })
47
+
48
+ const res = await fetch(`${base}/bucket`, { method: "POST", headers, body })
49
+ .catch(() => null)
50
+
51
+ if (res === null) continue // server not reachable — skip silently
52
+ if (res.status === 409) continue // already exists — fine
53
+ if (!res.ok) {
54
+ const msg = await res.text().catch(() => res.statusText)
55
+ console.warn(`[storage] Failed to provision bucket "${bucket.id}": ${msg}`)
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,16 @@
1
+ import type { SupatypeProjectConfig } from "./project-config.js"
2
+
3
+ export const DEFAULT_STUDIO_ADMIN_ROLES = ["admin", "supatype_admin"] as const
4
+
5
+ /** Studio admin roles from `supatype.config.ts` `admin.roles` or defaults. */
6
+ export function studioAdminRoles(cfg: SupatypeProjectConfig): string[] {
7
+ const roles = cfg.admin?.roles
8
+ if (roles !== undefined && roles.length > 0) return roles
9
+ return [...DEFAULT_STUDIO_ADMIN_ROLES]
10
+ }
11
+
12
+ /** Merge `adminRoles` into engine admin-config JSON for Studio and supatype-server. */
13
+ export function withAdminRoles(admin: unknown, cfg: SupatypeProjectConfig): Record<string, unknown> {
14
+ const base = typeof admin === "object" && admin !== null ? (admin as Record<string, unknown>) : {}
15
+ return { ...base, adminRoles: studioAdminRoles(cfg) }
16
+ }
@@ -0,0 +1,53 @@
1
+ import { existsSync } from "node:fs"
2
+ import { join, resolve } from "node:path"
3
+ import { ProcessManager } from "./process-manager.js"
4
+
5
+ const STUDIO_PORT = 3002
6
+
7
+ export interface StudioDevServerOptions {
8
+ cwd: string
9
+ studioOverride: string
10
+ pidDir: string
11
+ serviceRoleKey: string
12
+ /**
13
+ * Where Vite proxies API requests (Kong gateway port for compose dev, or
14
+ * supatype-server port for native `supatype dev`).
15
+ */
16
+ proxyTarget: string
17
+ /**
18
+ * Public Supatype URL the browser uses. Compose dev: Kong on the host.
19
+ * Native dev: Vite dev server (same origin as Studio).
20
+ */
21
+ viteSupatypeUrl: string
22
+ /** Vite `base` — `/studio/` when behind Kong at `/studio/`; `/` for native dev on :3002. */
23
+ basePath?: string
24
+ }
25
+
26
+ /** Start @supatype/studio Vite dev server when `overrides.studio` is set. */
27
+ export function startStudioViteDevServer(opts: StudioDevServerOptions): ProcessManager | null {
28
+ const studioDir = resolve(opts.cwd, opts.studioOverride)
29
+ const viteJs = join(studioDir, "node_modules", "vite", "bin", "vite.js")
30
+ if (!existsSync(viteJs)) {
31
+ console.warn(`[supatype] ⚠ Studio override set but vite not found at ${viteJs}. Run: pnpm install`)
32
+ return null
33
+ }
34
+
35
+ const basePath = opts.basePath ?? "/"
36
+ return new ProcessManager(
37
+ process.execPath,
38
+ [viteJs, "--port", String(STUDIO_PORT), "--strictPort", "--host"],
39
+ {
40
+ label: "studio",
41
+ pidDir: opts.pidDir,
42
+ cwd: studioDir,
43
+ colour: "\x1b[35m",
44
+ env: {
45
+ VITE_SUPATYPE_URL: opts.viteSupatypeUrl,
46
+ SUPATYPE_PROXY_TARGET: opts.proxyTarget,
47
+ VITE_SUPATYPE_ANON_KEY: opts.serviceRoleKey,
48
+ VITE_SUPATYPE_SERVICE_ROLE_KEY: opts.serviceRoleKey,
49
+ VITE_BASE_PATH: basePath,
50
+ },
51
+ },
52
+ )
53
+ }
@@ -0,0 +1 @@
1
+ process.stdout.write("hello from tsx")