@supatype/cli 0.1.0-alpha.6 → 0.1.0-alpha.8

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 (350) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +208 -1
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/dist/app/proxy-dev-app.d.ts +13 -0
  5. package/dist/app/proxy-dev-app.d.ts.map +1 -0
  6. package/dist/app/proxy-dev-app.js +53 -0
  7. package/dist/app/proxy-dev-app.js.map +1 -0
  8. package/dist/app-config.d.ts +7 -0
  9. package/dist/app-config.d.ts.map +1 -0
  10. package/dist/app-config.js +113 -0
  11. package/dist/app-config.js.map +1 -0
  12. package/dist/augmentation-generator.d.ts +2 -0
  13. package/dist/augmentation-generator.d.ts.map +1 -0
  14. package/dist/augmentation-generator.js +111 -0
  15. package/dist/augmentation-generator.js.map +1 -0
  16. package/dist/binary-cache.d.ts +94 -0
  17. package/dist/binary-cache.d.ts.map +1 -0
  18. package/dist/binary-cache.js +669 -0
  19. package/dist/binary-cache.js.map +1 -0
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +13 -7
  22. package/dist/cli.js.map +1 -1
  23. package/dist/commands/admin.d.ts.map +1 -1
  24. package/dist/commands/admin.js +4 -3
  25. package/dist/commands/admin.js.map +1 -1
  26. package/dist/commands/app.d.ts.map +1 -1
  27. package/dist/commands/app.js +56 -209
  28. package/dist/commands/app.js.map +1 -1
  29. package/dist/commands/cache.d.ts +6 -0
  30. package/dist/commands/cache.d.ts.map +1 -0
  31. package/dist/commands/cache.js +105 -0
  32. package/dist/commands/cache.js.map +1 -0
  33. package/dist/commands/cloud.d.ts +20 -0
  34. package/dist/commands/cloud.d.ts.map +1 -1
  35. package/dist/commands/cloud.js +50 -52
  36. package/dist/commands/cloud.js.map +1 -1
  37. package/dist/commands/db.d.ts.map +1 -1
  38. package/dist/commands/db.js +47 -54
  39. package/dist/commands/db.js.map +1 -1
  40. package/dist/commands/deploy.d.ts +2 -1
  41. package/dist/commands/deploy.d.ts.map +1 -1
  42. package/dist/commands/deploy.js +79 -52
  43. package/dist/commands/deploy.js.map +1 -1
  44. package/dist/commands/dev.d.ts +11 -0
  45. package/dist/commands/dev.d.ts.map +1 -1
  46. package/dist/commands/dev.js +759 -385
  47. package/dist/commands/dev.js.map +1 -1
  48. package/dist/commands/diff.d.ts.map +1 -1
  49. package/dist/commands/diff.js +30 -15
  50. package/dist/commands/diff.js.map +1 -1
  51. package/dist/commands/engine.d.ts +1 -3
  52. package/dist/commands/engine.d.ts.map +1 -1
  53. package/dist/commands/engine.js +13 -85
  54. package/dist/commands/engine.js.map +1 -1
  55. package/dist/commands/functions.d.ts.map +1 -1
  56. package/dist/commands/functions.js +92 -105
  57. package/dist/commands/functions.js.map +1 -1
  58. package/dist/commands/generate.d.ts.map +1 -1
  59. package/dist/commands/generate.js +22 -12
  60. package/dist/commands/generate.js.map +1 -1
  61. package/dist/commands/init.d.ts +1 -1
  62. package/dist/commands/init.d.ts.map +1 -1
  63. package/dist/commands/init.js +137 -410
  64. package/dist/commands/init.js.map +1 -1
  65. package/dist/commands/migrate-from-v1.d.ts +5 -0
  66. package/dist/commands/migrate-from-v1.d.ts.map +1 -0
  67. package/dist/commands/migrate-from-v1.js +125 -0
  68. package/dist/commands/migrate-from-v1.js.map +1 -0
  69. package/dist/commands/migrate.d.ts.map +1 -1
  70. package/dist/commands/migrate.js +27 -23
  71. package/dist/commands/migrate.js.map +1 -1
  72. package/dist/commands/pg.d.ts +8 -0
  73. package/dist/commands/pg.d.ts.map +1 -0
  74. package/dist/commands/pg.js +102 -0
  75. package/dist/commands/pg.js.map +1 -0
  76. package/dist/commands/pull.d.ts.map +1 -1
  77. package/dist/commands/pull.js +5 -66
  78. package/dist/commands/pull.js.map +1 -1
  79. package/dist/commands/push.d.ts.map +1 -1
  80. package/dist/commands/push.js +128 -38
  81. package/dist/commands/push.js.map +1 -1
  82. package/dist/commands/seed.d.ts +2 -0
  83. package/dist/commands/seed.d.ts.map +1 -1
  84. package/dist/commands/seed.js +44 -11
  85. package/dist/commands/seed.js.map +1 -1
  86. package/dist/commands/self-host.d.ts +7 -1
  87. package/dist/commands/self-host.d.ts.map +1 -1
  88. package/dist/commands/self-host.js +272 -758
  89. package/dist/commands/self-host.js.map +1 -1
  90. package/dist/commands/self-update.d.ts +9 -0
  91. package/dist/commands/self-update.d.ts.map +1 -0
  92. package/dist/commands/self-update.js +33 -0
  93. package/dist/commands/self-update.js.map +1 -0
  94. package/dist/commands/status.d.ts.map +1 -1
  95. package/dist/commands/status.js +4 -3
  96. package/dist/commands/status.js.map +1 -1
  97. package/dist/commands/types.d.ts +3 -0
  98. package/dist/commands/types.d.ts.map +1 -0
  99. package/dist/commands/types.js +62 -0
  100. package/dist/commands/types.js.map +1 -0
  101. package/dist/commands/update.d.ts +7 -0
  102. package/dist/commands/update.d.ts.map +1 -0
  103. package/dist/commands/update.js +93 -0
  104. package/dist/commands/update.js.map +1 -0
  105. package/dist/components.d.ts +5 -0
  106. package/dist/components.d.ts.map +1 -0
  107. package/dist/components.js +3 -0
  108. package/dist/components.js.map +1 -0
  109. package/dist/config.d.ts +10 -51
  110. package/dist/config.d.ts.map +1 -1
  111. package/dist/config.js +101 -33
  112. package/dist/config.js.map +1 -1
  113. package/dist/dev-compose.d.ts +17 -0
  114. package/dist/dev-compose.d.ts.map +1 -0
  115. package/dist/dev-compose.js +374 -0
  116. package/dist/dev-compose.js.map +1 -0
  117. package/dist/diff-output.d.ts +4 -0
  118. package/dist/diff-output.d.ts.map +1 -0
  119. package/dist/diff-output.js +12 -0
  120. package/dist/diff-output.js.map +1 -0
  121. package/dist/docker-postgres.d.ts +57 -0
  122. package/dist/docker-postgres.d.ts.map +1 -0
  123. package/dist/docker-postgres.js +208 -0
  124. package/dist/docker-postgres.js.map +1 -0
  125. package/dist/engine-client.d.ts +69 -0
  126. package/dist/engine-client.d.ts.map +1 -0
  127. package/dist/engine-client.js +157 -0
  128. package/dist/engine-client.js.map +1 -0
  129. package/dist/ensure-binary.d.ts +7 -0
  130. package/dist/ensure-binary.d.ts.map +1 -0
  131. package/dist/ensure-binary.js +17 -0
  132. package/dist/ensure-binary.js.map +1 -0
  133. package/dist/functions-router-gen.d.ts +14 -0
  134. package/dist/functions-router-gen.d.ts.map +1 -0
  135. package/dist/functions-router-gen.js +199 -0
  136. package/dist/functions-router-gen.js.map +1 -0
  137. package/dist/index.d.ts +4 -5
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +2 -3
  140. package/dist/index.js.map +1 -1
  141. package/dist/kong-config.d.ts +25 -0
  142. package/dist/kong-config.d.ts.map +1 -0
  143. package/dist/kong-config.js +71 -0
  144. package/dist/kong-config.js.map +1 -0
  145. package/dist/local-gateway.d.ts +7 -0
  146. package/dist/local-gateway.d.ts.map +1 -0
  147. package/dist/local-gateway.js +9 -0
  148. package/dist/local-gateway.js.map +1 -0
  149. package/dist/local-storage.d.ts +8 -0
  150. package/dist/local-storage.d.ts.map +1 -0
  151. package/dist/local-storage.js +14 -0
  152. package/dist/local-storage.js.map +1 -0
  153. package/dist/pgbouncer-userlist.d.ts +5 -0
  154. package/dist/pgbouncer-userlist.d.ts.map +1 -0
  155. package/dist/pgbouncer-userlist.js +14 -0
  156. package/dist/pgbouncer-userlist.js.map +1 -0
  157. package/dist/postgres-ctl.d.ts +44 -0
  158. package/dist/postgres-ctl.d.ts.map +1 -0
  159. package/dist/postgres-ctl.js +137 -0
  160. package/dist/postgres-ctl.js.map +1 -0
  161. package/dist/process-manager.d.ts +43 -0
  162. package/dist/process-manager.d.ts.map +1 -0
  163. package/dist/process-manager.js +135 -0
  164. package/dist/process-manager.js.map +1 -0
  165. package/dist/project-config.d.ts +235 -0
  166. package/dist/project-config.d.ts.map +1 -0
  167. package/dist/project-config.js +160 -0
  168. package/dist/project-config.js.map +1 -0
  169. package/dist/pull-utils.d.ts +15 -0
  170. package/dist/pull-utils.d.ts.map +1 -1
  171. package/dist/pull-utils.js +12 -0
  172. package/dist/pull-utils.js.map +1 -1
  173. package/dist/release-pins.d.ts +7 -0
  174. package/dist/release-pins.d.ts.map +1 -0
  175. package/dist/release-pins.js +27 -0
  176. package/dist/release-pins.js.map +1 -0
  177. package/dist/release-public-key.d.ts +8 -0
  178. package/dist/release-public-key.d.ts.map +1 -0
  179. package/dist/release-public-key.js +13 -0
  180. package/dist/release-public-key.js.map +1 -0
  181. package/dist/runtime-routes.d.ts +34 -0
  182. package/dist/runtime-routes.d.ts.map +1 -0
  183. package/dist/runtime-routes.js +252 -0
  184. package/dist/runtime-routes.js.map +1 -0
  185. package/dist/schema-ast-v2.d.ts +127 -0
  186. package/dist/schema-ast-v2.d.ts.map +1 -0
  187. package/dist/schema-ast-v2.js +226 -0
  188. package/dist/schema-ast-v2.js.map +1 -0
  189. package/dist/scripts/postinstall.d.ts +5 -6
  190. package/dist/scripts/postinstall.d.ts.map +1 -1
  191. package/dist/scripts/postinstall.js +36 -20
  192. package/dist/scripts/postinstall.js.map +1 -1
  193. package/dist/self-host-compose.d.ts +22 -0
  194. package/dist/self-host-compose.d.ts.map +1 -0
  195. package/dist/self-host-compose.js +347 -0
  196. package/dist/self-host-compose.js.map +1 -0
  197. package/dist/storage-provision.d.ts +24 -0
  198. package/dist/storage-provision.d.ts.map +1 -0
  199. package/dist/storage-provision.js +44 -0
  200. package/dist/storage-provision.js.map +1 -0
  201. package/dist/studio-admin-roles.d.ts +7 -0
  202. package/dist/studio-admin-roles.d.ts.map +1 -0
  203. package/dist/studio-admin-roles.js +14 -0
  204. package/dist/studio-admin-roles.js.map +1 -0
  205. package/dist/studio-dev-server.d.ts +22 -0
  206. package/dist/studio-dev-server.d.ts.map +1 -0
  207. package/dist/studio-dev-server.js +28 -0
  208. package/dist/studio-dev-server.js.map +1 -0
  209. package/dist/systemd.d.ts +26 -0
  210. package/dist/systemd.d.ts.map +1 -0
  211. package/dist/systemd.js +102 -0
  212. package/dist/systemd.js.map +1 -0
  213. package/dist/tsx-runner.d.ts.map +1 -1
  214. package/dist/tsx-runner.js +9 -2
  215. package/dist/tsx-runner.js.map +1 -1
  216. package/dist/type-extractor.d.ts +4 -0
  217. package/dist/type-extractor.d.ts.map +1 -0
  218. package/dist/type-extractor.js +1213 -0
  219. package/dist/type-extractor.js.map +1 -0
  220. package/dist/type-resolver.d.ts +33 -0
  221. package/dist/type-resolver.d.ts.map +1 -0
  222. package/dist/type-resolver.js +338 -0
  223. package/dist/type-resolver.js.map +1 -0
  224. package/package.json +4 -3
  225. package/releases/deno/VERSION +1 -0
  226. package/scripts/mirror-deno-release.sh +76 -0
  227. package/src/TYPE-RESOLUTION.md +294 -0
  228. package/src/app/proxy-dev-app.ts +67 -0
  229. package/src/app-config.ts +128 -0
  230. package/src/augmentation-generator.ts +126 -0
  231. package/src/binary-cache.ts +822 -0
  232. package/src/cli.ts +13 -8
  233. package/src/commands/admin.ts +4 -3
  234. package/src/commands/app.ts +67 -231
  235. package/src/commands/cache.ts +117 -0
  236. package/src/commands/cloud.ts +63 -64
  237. package/src/commands/db.ts +54 -63
  238. package/src/commands/deploy.ts +96 -62
  239. package/src/commands/dev.ts +933 -405
  240. package/src/commands/diff.ts +31 -29
  241. package/src/commands/engine.ts +13 -116
  242. package/src/commands/functions.ts +97 -115
  243. package/src/commands/generate.ts +23 -10
  244. package/src/commands/init.ts +149 -414
  245. package/src/commands/migrate-from-v1.ts +131 -0
  246. package/src/commands/migrate.ts +27 -23
  247. package/src/commands/pg.ts +133 -0
  248. package/src/commands/pull.ts +6 -85
  249. package/src/commands/push.ts +161 -56
  250. package/src/commands/seed.ts +54 -12
  251. package/src/commands/self-host.ts +312 -880
  252. package/src/commands/self-update.ts +45 -0
  253. package/src/commands/status.ts +4 -3
  254. package/src/commands/types.ts +76 -0
  255. package/src/commands/update.ts +109 -0
  256. package/src/components.ts +6 -0
  257. package/src/config.ts +127 -94
  258. package/src/dev-compose.ts +455 -0
  259. package/src/diff-output.ts +12 -0
  260. package/src/docker-postgres.ts +295 -0
  261. package/src/engine-client.ts +236 -0
  262. package/src/ensure-binary.ts +28 -0
  263. package/src/functions-router-gen.ts +224 -0
  264. package/src/index.ts +4 -12
  265. package/src/kong-config.ts +93 -0
  266. package/src/local-gateway.ts +9 -0
  267. package/src/local-storage.ts +14 -0
  268. package/src/pgbouncer-userlist.ts +15 -0
  269. package/src/postgres-ctl.ts +171 -0
  270. package/src/process-manager.ts +168 -0
  271. package/src/project-config.ts +386 -0
  272. package/src/pull-utils.ts +24 -0
  273. package/src/release-pins.ts +31 -0
  274. package/src/release-public-key.ts +12 -0
  275. package/src/runtime-routes.ts +291 -0
  276. package/src/schema-ast-v2.ts +324 -0
  277. package/src/scripts/postinstall.ts +36 -25
  278. package/src/self-host-compose.ts +389 -0
  279. package/src/storage-provision.ts +58 -0
  280. package/src/studio-admin-roles.ts +16 -0
  281. package/src/studio-dev-server.ts +53 -0
  282. package/src/systemd.ts +137 -0
  283. package/src/tsx-runner.ts +11 -1
  284. package/src/type-extractor.ts +1479 -0
  285. package/src/type-resolver.ts +457 -0
  286. package/tests/app-command.test.ts +54 -0
  287. package/tests/augmentation-generator.test.ts +59 -0
  288. package/tests/binary-cache-cloud-overrides.test.ts +123 -0
  289. package/tests/cached-artifact-format.test.ts +84 -0
  290. package/tests/cli-help.test.ts +40 -14
  291. package/tests/config.test.ts +171 -37
  292. package/tests/docker-postgres.test.ts +39 -0
  293. package/tests/engine-distribution.test.ts +3 -3
  294. package/tests/ensure-binary.test.ts +59 -0
  295. package/tests/init.test.ts +28 -86
  296. package/tests/migrate-from-v1.test.ts +29 -0
  297. package/tests/normalize-admin-config.test.ts +48 -0
  298. package/tests/pg-spawn-env.test.ts +18 -0
  299. package/tests/postgres-archive-tag.test.ts +9 -0
  300. package/tests/proxy-dev-app.test.ts +33 -0
  301. package/tests/pull-utils.test.ts +36 -1
  302. package/tests/release-pins.test.ts +28 -0
  303. package/tests/runtime-contract.test.ts +351 -0
  304. package/tests/seed-discover.test.ts +31 -0
  305. package/tests/studio-admin-roles.test.ts +27 -0
  306. package/tests/tsconfig.json +9 -0
  307. package/tests/type-extractor.test.ts +985 -0
  308. package/tests/type-resolver.test.ts +59 -0
  309. package/tsconfig.tsbuildinfo +1 -1
  310. package/vitest.config.ts +12 -0
  311. package/dist/engine/cache.d.ts +0 -37
  312. package/dist/engine/cache.d.ts.map +0 -1
  313. package/dist/engine/cache.js +0 -121
  314. package/dist/engine/cache.js.map +0 -1
  315. package/dist/engine/download.d.ts +0 -19
  316. package/dist/engine/download.d.ts.map +0 -1
  317. package/dist/engine/download.js +0 -108
  318. package/dist/engine/download.js.map +0 -1
  319. package/dist/engine/platform.d.ts +0 -24
  320. package/dist/engine/platform.d.ts.map +0 -1
  321. package/dist/engine/platform.js +0 -50
  322. package/dist/engine/platform.js.map +0 -1
  323. package/dist/engine/resolve.d.ts +0 -37
  324. package/dist/engine/resolve.d.ts.map +0 -1
  325. package/dist/engine/resolve.js +0 -133
  326. package/dist/engine/resolve.js.map +0 -1
  327. package/dist/engine/update-notify.d.ts +0 -11
  328. package/dist/engine/update-notify.d.ts.map +0 -1
  329. package/dist/engine/update-notify.js +0 -43
  330. package/dist/engine/update-notify.js.map +0 -1
  331. package/dist/engine/verify.d.ts +0 -50
  332. package/dist/engine/verify.d.ts.map +0 -1
  333. package/dist/engine/verify.js +0 -161
  334. package/dist/engine/verify.js.map +0 -1
  335. package/dist/engine-version.d.ts +0 -35
  336. package/dist/engine-version.d.ts.map +0 -1
  337. package/dist/engine-version.js +0 -35
  338. package/dist/engine-version.js.map +0 -1
  339. package/dist/engine.d.ts +0 -34
  340. package/dist/engine.d.ts.map +0 -1
  341. package/dist/engine.js +0 -76
  342. package/dist/engine.js.map +0 -1
  343. package/src/engine/cache.ts +0 -135
  344. package/src/engine/download.ts +0 -143
  345. package/src/engine/platform.ts +0 -66
  346. package/src/engine/resolve.ts +0 -197
  347. package/src/engine/update-notify.ts +0 -50
  348. package/src/engine/verify.ts +0 -206
  349. package/src/engine-version.ts +0 -39
  350. package/src/engine.ts +0 -99
@@ -0,0 +1,291 @@
1
+ export interface RuntimeRoute {
2
+ name: string
3
+ serviceName: string
4
+ serviceUrl: string
5
+ paths: string[]
6
+ stripPath?: boolean
7
+ protocols?: string[]
8
+ engineProtected?: boolean
9
+ /** Route /graphql/v1 to PostgREST /rpc/graphql with graphql_public Content-Profile. */
10
+ graphqlPostgrest?: boolean
11
+ }
12
+
13
+ export interface RuntimeRouteOptions {
14
+ appUpstream?: string
15
+ staticAppServiceUrl?: string
16
+ /** Compose self-host: supatype-server container (functions proxy). */
17
+ functionsServiceUrl?: string
18
+ /**
19
+ * Self-host Compose: Kong forwards API traffic to supatype-server (unified gateway),
20
+ * which proxies to internal services — same model as `supatype dev`.
21
+ */
22
+ unifiedGateway?: boolean
23
+ /** Studio UI upstream (default: in-compose `studio:3002`). */
24
+ studioServiceUrl?: string
25
+ /**
26
+ * Strip `/studio/` before proxying to the Studio upstream.
27
+ * False for host Vite dev (`host.docker.internal`) where `base` is `/studio/`.
28
+ */
29
+ studioStripPath?: boolean
30
+ }
31
+
32
+ const DEFAULT_STUDIO_SERVICE_URL = "http://studio:3002"
33
+
34
+ function studioServiceUrl(opts: RuntimeRouteOptions): string {
35
+ const url = opts.studioServiceUrl?.trim()
36
+ return url && url.length > 0 ? url : DEFAULT_STUDIO_SERVICE_URL
37
+ }
38
+
39
+ function studioStripPath(opts: RuntimeRouteOptions): boolean {
40
+ return opts.studioStripPath !== false
41
+ }
42
+
43
+ const SERVER_GATEWAY = "http://server:9999"
44
+
45
+ /**
46
+ * Kong routes when self-host uses supatype-server as the single API gateway.
47
+ */
48
+ function runtimeRouteSpecUnified(opts: RuntimeRouteOptions): RuntimeRoute[] {
49
+ const studioUrl = studioServiceUrl(opts)
50
+ const stripStudio = studioStripPath(opts)
51
+ return [
52
+ {
53
+ name: "rest-v1",
54
+ serviceName: "supatype-server-rest",
55
+ serviceUrl: SERVER_GATEWAY,
56
+ paths: ["/rest/v1/"],
57
+ stripPath: false,
58
+ },
59
+ {
60
+ name: "auth-v1",
61
+ serviceName: "supatype-server-auth",
62
+ serviceUrl: SERVER_GATEWAY,
63
+ paths: ["/auth/v1/"],
64
+ stripPath: false,
65
+ },
66
+ {
67
+ name: "admin-v1",
68
+ serviceName: "supatype-server-admin",
69
+ serviceUrl: SERVER_GATEWAY,
70
+ paths: ["/admin/v1/"],
71
+ stripPath: false,
72
+ },
73
+ {
74
+ name: "storage-v1",
75
+ serviceName: "supatype-server-storage",
76
+ serviceUrl: SERVER_GATEWAY,
77
+ paths: ["/storage/v1/"],
78
+ stripPath: false,
79
+ },
80
+ {
81
+ name: "realtime-v1",
82
+ serviceName: "supatype-server-realtime",
83
+ serviceUrl: SERVER_GATEWAY,
84
+ paths: ["/realtime/v1/"],
85
+ stripPath: false,
86
+ protocols: ["http", "https"],
87
+ },
88
+ {
89
+ name: "functions-v1",
90
+ serviceName: "supatype-server-functions",
91
+ serviceUrl: SERVER_GATEWAY,
92
+ paths: ["/functions/v1/"],
93
+ stripPath: false,
94
+ },
95
+ {
96
+ name: "graphql-v1",
97
+ serviceName: "postgrest-graphql",
98
+ serviceUrl: "http://postgrest:3000/rpc/graphql",
99
+ paths: ["/graphql/v1"],
100
+ stripPath: true,
101
+ graphqlPostgrest: true,
102
+ },
103
+ {
104
+ name: "studio-config-route",
105
+ serviceName: "supatype-server-studio-config",
106
+ serviceUrl: SERVER_GATEWAY,
107
+ paths: ["/studio-config"],
108
+ stripPath: false,
109
+ },
110
+ {
111
+ name: "sql-route",
112
+ serviceName: "supatype-server-sql",
113
+ serviceUrl: SERVER_GATEWAY,
114
+ paths: ["/sql"],
115
+ stripPath: false,
116
+ },
117
+ {
118
+ name: "studio-auth",
119
+ serviceName: "supatype-server-studio-auth",
120
+ serviceUrl: SERVER_GATEWAY,
121
+ paths: ["/studio/auth/"],
122
+ stripPath: false,
123
+ },
124
+ {
125
+ name: "studio-proxy",
126
+ serviceName: "supatype-server-studio-proxy",
127
+ serviceUrl: SERVER_GATEWAY,
128
+ paths: ["/studio/proxy/"],
129
+ stripPath: false,
130
+ },
131
+ {
132
+ name: "studio-exact",
133
+ serviceName: "studio-exact",
134
+ serviceUrl: studioUrl,
135
+ paths: ["~/studio$"],
136
+ stripPath: stripStudio,
137
+ },
138
+ {
139
+ name: "studio",
140
+ serviceName: "studio",
141
+ serviceUrl: studioUrl,
142
+ paths: ["/studio/"],
143
+ stripPath: stripStudio,
144
+ },
145
+ {
146
+ name: "app-root",
147
+ serviceName: "supatype-server-app",
148
+ serviceUrl: SERVER_GATEWAY,
149
+ paths: ["/"],
150
+ stripPath: false,
151
+ },
152
+ ]
153
+ }
154
+
155
+ /**
156
+ * Legacy split-stack routes (PostgREST/storage/realtime directly from Kong).
157
+ * Kept for tests or explicit opt-out only — self-host uses unifiedGateway.
158
+ */
159
+ function runtimeRouteSpecSplit(opts: RuntimeRouteOptions): RuntimeRoute[] {
160
+ const studioUrl = studioServiceUrl(opts)
161
+ const stripStudio = studioStripPath(opts)
162
+ const routes: RuntimeRoute[] = [
163
+ {
164
+ name: "rest-v1",
165
+ serviceName: "rest-v1",
166
+ serviceUrl: "http://postgrest:3000",
167
+ paths: ["/rest/v1/"],
168
+ stripPath: true,
169
+ },
170
+ {
171
+ name: "auth-v1",
172
+ serviceName: "auth-v1",
173
+ serviceUrl: "http://server:9999",
174
+ paths: ["/auth/v1/"],
175
+ stripPath: true,
176
+ },
177
+ {
178
+ name: "admin-v1",
179
+ serviceName: "admin-v1",
180
+ serviceUrl: "http://server:9999",
181
+ paths: ["/admin/v1/"],
182
+ stripPath: false,
183
+ },
184
+ {
185
+ name: "storage-v1",
186
+ serviceName: "storage-v1",
187
+ serviceUrl: "http://storage:5000",
188
+ paths: ["/storage/v1/"],
189
+ stripPath: true,
190
+ },
191
+ {
192
+ name: "realtime-v1",
193
+ serviceName: "realtime-v1",
194
+ serviceUrl: "http://realtime:4000",
195
+ paths: ["/realtime/v1/"],
196
+ stripPath: true,
197
+ protocols: ["http", "https"],
198
+ },
199
+ {
200
+ name: "functions-v1",
201
+ serviceName: "functions-v1",
202
+ serviceUrl: opts.functionsServiceUrl?.trim() || "http://server:9999",
203
+ paths: ["/functions/v1/"],
204
+ stripPath: false,
205
+ },
206
+ {
207
+ name: "graphql-v1",
208
+ serviceName: "postgrest-graphql",
209
+ serviceUrl: "http://postgrest:3000/rpc/graphql",
210
+ paths: ["/graphql/v1"],
211
+ stripPath: true,
212
+ graphqlPostgrest: true,
213
+ },
214
+ {
215
+ name: "studio-auth",
216
+ serviceName: "auth-v1",
217
+ serviceUrl: "http://server:9999",
218
+ paths: ["/studio/auth/"],
219
+ stripPath: false,
220
+ },
221
+ {
222
+ name: "studio-proxy",
223
+ serviceName: "auth-v1",
224
+ serviceUrl: "http://server:9999",
225
+ paths: ["/studio/proxy/"],
226
+ stripPath: false,
227
+ },
228
+ {
229
+ name: "studio-exact",
230
+ serviceName: "studio-exact",
231
+ serviceUrl: studioUrl,
232
+ paths: ["~/studio$"],
233
+ stripPath: stripStudio,
234
+ },
235
+ {
236
+ name: "studio",
237
+ serviceName: "studio",
238
+ serviceUrl: studioUrl,
239
+ paths: ["/studio/"],
240
+ stripPath: stripStudio,
241
+ },
242
+ {
243
+ name: "studio-config-route",
244
+ serviceName: "engine-studio-config",
245
+ serviceUrl: "http://engine:7500",
246
+ paths: ["/studio-config"],
247
+ engineProtected: true,
248
+ },
249
+ {
250
+ name: "sql-route",
251
+ serviceName: "engine-sql",
252
+ serviceUrl: "http://engine:7500",
253
+ paths: ["/sql"],
254
+ engineProtected: true,
255
+ },
256
+ ]
257
+
258
+ const staticServiceUrl = opts.staticAppServiceUrl?.trim()
259
+ if (staticServiceUrl && staticServiceUrl.length > 0) {
260
+ routes.push({
261
+ name: "app-root",
262
+ serviceName: "app-root",
263
+ serviceUrl: staticServiceUrl,
264
+ paths: ["/"],
265
+ stripPath: false,
266
+ })
267
+ return routes
268
+ }
269
+
270
+ if (opts.appUpstream && opts.appUpstream.trim().length > 0) {
271
+ routes.push({
272
+ name: "app-root",
273
+ serviceName: "app-root",
274
+ serviceUrl: opts.appUpstream.trim(),
275
+ paths: ["/"],
276
+ stripPath: false,
277
+ })
278
+ }
279
+
280
+ return routes
281
+ }
282
+
283
+ /**
284
+ * Shared route contract used by local/self-host renderers.
285
+ */
286
+ export function runtimeRouteSpec(opts: RuntimeRouteOptions = {}): RuntimeRoute[] {
287
+ if (opts.unifiedGateway) {
288
+ return runtimeRouteSpecUnified(opts)
289
+ }
290
+ return runtimeRouteSpecSplit(opts)
291
+ }
@@ -0,0 +1,324 @@
1
+ /**
2
+ * AST v2 wire format — canonical types and emitters.
3
+ * Parsers build {@link ParsedField}; only `emitField` / `emitModel` / `emitSchema` produce JSON.
4
+ */
5
+
6
+ export const AST_VERSION = 2 as const
7
+
8
+ export type DefaultAst =
9
+ | { kind: "value"; value: string | number | boolean | null }
10
+ | { kind: "now" }
11
+ | { kind: "genRandomUuid" }
12
+ | { kind: "expression"; expr: string }
13
+
14
+ export interface DbFieldAnnotations {
15
+ pgType?: string
16
+ unique?: boolean
17
+ index?: boolean
18
+ foreignKey?: string
19
+ serverGenerated?: boolean
20
+ elementType?: string
21
+ }
22
+
23
+ export interface PlatformFieldAnnotations {
24
+ editor?: string
25
+ readOnly?: boolean
26
+ }
27
+
28
+ export interface FieldAnnotations {
29
+ db?: DbFieldAnnotations
30
+ platform?: PlatformFieldAnnotations
31
+ }
32
+
33
+ /** Kernel facts only — never db/platform keys at this layer. */
34
+ export interface KernelFieldFacts {
35
+ required?: boolean
36
+ primaryKey?: boolean
37
+ default?: DefaultAst
38
+ localized?: boolean
39
+ cardinality?: string
40
+ target?: string
41
+ values?: string[]
42
+ from?: string
43
+ sources?: string[]
44
+ template?: string
45
+ bucket?: string
46
+ accessMode?: string
47
+ geoType?: string
48
+ srid?: number
49
+ dimensions?: number
50
+ blocks?: BlockDefinitionAst[]
51
+ check?: string
52
+ precision?: number
53
+ scale?: number
54
+ references?: string
55
+ through?: string
56
+ onDelete?: string
57
+ onUpdate?: string
58
+ uniqueFk?: boolean
59
+ plugin?: string
60
+ fieldType?: string
61
+ tsType?: string
62
+ index?: boolean
63
+ }
64
+
65
+ /** Internal parse result — not serialized. */
66
+ export interface ParsedField {
67
+ kind: string
68
+ kernel: KernelFieldFacts
69
+ db: DbFieldAnnotations
70
+ platform: PlatformFieldAnnotations
71
+ }
72
+
73
+ export type FieldAstV2 = {
74
+ kind: string
75
+ annotations?: FieldAnnotations
76
+ } & Record<string, unknown>
77
+
78
+ export interface BlockDefinitionAst {
79
+ name: string
80
+ label?: string
81
+ icon?: string
82
+ fields: Record<string, FieldAstV2>
83
+ }
84
+
85
+ export interface ModelAstV2 {
86
+ name: string
87
+ fields: Record<string, FieldAstV2>
88
+ options: Record<string, unknown>
89
+ annotations: {
90
+ db: { tableName: string; indexes: unknown[] }
91
+ platform: { access: Record<string, unknown> }
92
+ }
93
+ }
94
+
95
+ export interface ExtractedStorageBucketAst {
96
+ id: string
97
+ public: boolean
98
+ accessMode?: "public" | "private" | "custom"
99
+ allowedMimeTypes?: string[]
100
+ fileSizeLimit?: number
101
+ access?: Record<string, unknown>
102
+ s3BucketPolicy?: string
103
+ }
104
+
105
+ export interface ExtractedSchemaAstV2 {
106
+ astVersion: typeof AST_VERSION
107
+ models: ModelAstV2[]
108
+ storageBuckets?: ExtractedStorageBucketAst[]
109
+ locales?: string[]
110
+ defaultLocale?: string
111
+ }
112
+
113
+ const DEFAULT_DB_BY_KIND: Record<string, Partial<DbFieldAnnotations>> = {
114
+ text: { pgType: "TEXT" },
115
+ richText: { pgType: "JSONB" },
116
+ integer: { pgType: "INTEGER" },
117
+ smallInt: { pgType: "SMALLINT" },
118
+ bigInt: { pgType: "BIGINT" },
119
+ float: { pgType: "DOUBLE PRECISION" },
120
+ boolean: { pgType: "BOOLEAN" },
121
+ datetime: { pgType: "TIMESTAMPTZ" },
122
+ date: { pgType: "DATE" },
123
+ timestamp: { pgType: "TIMESTAMP WITH TIME ZONE" },
124
+ uuid: { pgType: "UUID" },
125
+ email: { pgType: "TEXT" },
126
+ url: { pgType: "TEXT" },
127
+ slug: { pgType: "TEXT" },
128
+ enum: { pgType: "TEXT" },
129
+ json: { pgType: "JSONB" },
130
+ decimal: { pgType: "TEXT" },
131
+ bytes: { pgType: "BYTEA" },
132
+ serial: { pgType: "SERIAL" },
133
+ bigSerial: { pgType: "BIGSERIAL" },
134
+ money: { pgType: "TEXT" },
135
+ ip: { pgType: "TEXT" },
136
+ cidr: { pgType: "TEXT" },
137
+ macaddr: { pgType: "TEXT" },
138
+ xml: { pgType: "TEXT" },
139
+ tsQuery: { pgType: "TEXT" },
140
+ tsVector: { pgType: "TEXT" },
141
+ color: { pgType: "TEXT" },
142
+ array: { pgType: "ARRAY" },
143
+ image: { pgType: "JSONB" },
144
+ file: { pgType: "JSONB" },
145
+ geo: { pgType: "GEOGRAPHY" },
146
+ vector: { pgType: "VECTOR" },
147
+ blocks: { pgType: "JSONB" },
148
+ }
149
+
150
+ const DEFAULT_PLATFORM_BY_KIND: Record<string, Partial<PlatformFieldAnnotations>> = {
151
+ richText: { editor: "rich" },
152
+ }
153
+
154
+ const COMPOSITE_KINDS = new Set(["timestamps", "publishable", "softDelete"])
155
+
156
+ function hasKeys(obj: Record<string, unknown>): boolean {
157
+ return Object.keys(obj).length > 0
158
+ }
159
+
160
+ function stripUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {
161
+ const out: Record<string, unknown> = {}
162
+ for (const [k, v] of Object.entries(obj)) {
163
+ if (v !== undefined) out[k] = v
164
+ }
165
+ return out as Partial<T>
166
+ }
167
+
168
+ /** Start a parsed field with kind defaults for db/platform namespaces. */
169
+ export function defaultPgTypeForKind(kind: string): string {
170
+ return DEFAULT_DB_BY_KIND[kind]?.pgType ?? "TEXT"
171
+ }
172
+
173
+ /** Flat wire shape for fields nested inside `blocks` definitions (engine FieldAst serde). */
174
+ export function emitBlockNestedField(field: FieldAstV2): FieldAstV2 {
175
+ const annotations = (field.annotations ?? {}) as FieldAnnotations
176
+ const db = annotations.db ?? {}
177
+ const platform = annotations.platform ?? {}
178
+
179
+ const wire: FieldAstV2 = {
180
+ kind: field.kind,
181
+ pgType: db.pgType ?? defaultPgTypeForKind(String(field.kind)),
182
+ required: field.required ?? false,
183
+ unique: db.unique ?? false,
184
+ localized: field.localized ?? false,
185
+ }
186
+
187
+ if (platform.readOnly) wire.readOnly = true
188
+ if (field.primaryKey) wire.primaryKey = true
189
+ if (field.default !== undefined) wire.default = field.default
190
+ if (field.from !== undefined) wire.from = field.from
191
+ if (field.values !== undefined) wire.values = field.values
192
+ if (field.bucket !== undefined) wire.bucket = field.bucket
193
+ if (field.accessMode !== undefined) wire.accessMode = field.accessMode
194
+ if (field.geoType !== undefined) wire.geoType = field.geoType
195
+ if (field.srid !== undefined) wire.srid = field.srid
196
+ if (field.dimensions !== undefined) wire.dimensions = field.dimensions
197
+ if (field.check !== undefined) wire.check = field.check
198
+ if (field.precision !== undefined) wire.precision = field.precision
199
+ if (field.scale !== undefined) wire.scale = field.scale
200
+ if (field.sources !== undefined) wire.sources = field.sources
201
+ if (field.template !== undefined) wire.template = field.template
202
+ if (field.plugin !== undefined) wire.plugin = field.plugin
203
+ if (field.fieldType !== undefined) wire.fieldType = field.fieldType
204
+ if (field.tsType !== undefined) wire.tsType = field.tsType
205
+
206
+ return wire
207
+ }
208
+
209
+ export function scalar(
210
+ kind: string,
211
+ extra?: {
212
+ kernel?: Partial<KernelFieldFacts>
213
+ db?: Partial<DbFieldAnnotations>
214
+ platform?: Partial<PlatformFieldAnnotations>
215
+ },
216
+ ): ParsedField {
217
+ return {
218
+ kind,
219
+ kernel: { ...(extra?.kernel ?? {}) },
220
+ db: { ...DEFAULT_DB_BY_KIND[kind], ...stripUndefined(extra?.db ?? {}) },
221
+ platform: { ...DEFAULT_PLATFORM_BY_KIND[kind], ...stripUndefined(extra?.platform ?? {}) },
222
+ }
223
+ }
224
+
225
+ export function emitField(parsed: ParsedField): FieldAstV2 {
226
+ if (COMPOSITE_KINDS.has(parsed.kind)) {
227
+ return { kind: parsed.kind }
228
+ }
229
+
230
+ const db = stripUndefined({
231
+ ...DEFAULT_DB_BY_KIND[parsed.kind],
232
+ ...parsed.db,
233
+ }) as DbFieldAnnotations
234
+
235
+ const platform = stripUndefined({
236
+ ...DEFAULT_PLATFORM_BY_KIND[parsed.kind],
237
+ ...parsed.platform,
238
+ }) as PlatformFieldAnnotations
239
+
240
+ const wire: FieldAstV2 = { kind: parsed.kind }
241
+
242
+ const kernel = parsed.kernel
243
+ if (kernel.required !== undefined) wire.required = kernel.required
244
+ if (kernel.primaryKey) wire.primaryKey = true
245
+ if (kernel.default !== undefined) wire.default = kernel.default
246
+ if (kernel.localized) wire.localized = true
247
+ if (kernel.cardinality !== undefined) wire.cardinality = kernel.cardinality
248
+ if (kernel.target !== undefined) wire.target = kernel.target
249
+ if (kernel.values !== undefined) wire.values = kernel.values
250
+ if (kernel.from !== undefined) wire.from = kernel.from
251
+ if (kernel.sources !== undefined && kernel.sources.length > 0) wire.sources = kernel.sources
252
+ if (kernel.template !== undefined) wire.template = kernel.template
253
+ if (kernel.bucket !== undefined) wire.bucket = kernel.bucket
254
+ if (kernel.accessMode !== undefined) wire.accessMode = kernel.accessMode
255
+ if (kernel.geoType !== undefined) wire.geoType = kernel.geoType
256
+ if (kernel.srid !== undefined) wire.srid = kernel.srid
257
+ if (kernel.dimensions !== undefined) wire.dimensions = kernel.dimensions
258
+ if (kernel.blocks !== undefined) {
259
+ wire.blocks = kernel.blocks.map((blockDef) => ({
260
+ ...blockDef,
261
+ fields: Object.fromEntries(
262
+ Object.entries(blockDef.fields).map(([name, nested]) => [
263
+ name,
264
+ emitBlockNestedField(nested),
265
+ ]),
266
+ ),
267
+ }))
268
+ }
269
+ if (kernel.check !== undefined) wire.check = kernel.check
270
+ if (kernel.precision !== undefined) wire.precision = kernel.precision
271
+ if (kernel.scale !== undefined) wire.scale = kernel.scale
272
+ if (kernel.references !== undefined) wire.references = kernel.references
273
+ if (kernel.through !== undefined) wire.through = kernel.through
274
+ if (kernel.onDelete !== undefined) wire.onDelete = kernel.onDelete
275
+ if (kernel.onUpdate !== undefined) wire.onUpdate = kernel.onUpdate
276
+ if (kernel.uniqueFk) wire.uniqueFk = true
277
+ if (kernel.plugin !== undefined) wire.plugin = kernel.plugin
278
+ if (kernel.fieldType !== undefined) wire.fieldType = kernel.fieldType
279
+ if (kernel.tsType !== undefined) wire.tsType = kernel.tsType
280
+ if (parsed.kind === "blocks" && kernel.index !== undefined) wire.index = kernel.index
281
+
282
+ const annotations: FieldAnnotations = {}
283
+ if (hasKeys(db as Record<string, unknown>)) annotations.db = db
284
+ if (hasKeys(platform as Record<string, unknown>)) annotations.platform = platform
285
+ if (hasKeys(annotations as Record<string, unknown>)) wire.annotations = annotations
286
+
287
+ return wire
288
+ }
289
+
290
+ export function emitModel(
291
+ name: string,
292
+ fields: Record<string, FieldAstV2>,
293
+ options: Record<string, unknown>,
294
+ tableName: string,
295
+ access: Record<string, unknown>,
296
+ ): ModelAstV2 {
297
+ return {
298
+ name,
299
+ fields,
300
+ options,
301
+ annotations: {
302
+ db: { tableName, indexes: [] },
303
+ platform: { access },
304
+ },
305
+ }
306
+ }
307
+
308
+ export function emitSchema(
309
+ models: ModelAstV2[],
310
+ extras?: {
311
+ storageBuckets?: ExtractedSchemaAstV2["storageBuckets"]
312
+ locales?: string[]
313
+ defaultLocale?: string
314
+ },
315
+ ): ExtractedSchemaAstV2 {
316
+ return {
317
+ astVersion: AST_VERSION,
318
+ models,
319
+ ...(extras?.storageBuckets !== undefined &&
320
+ extras.storageBuckets.length > 0 && { storageBuckets: extras.storageBuckets }),
321
+ ...(extras?.locales !== undefined && extras.locales.length > 0 && { locales: extras.locales }),
322
+ ...(extras?.defaultLocale !== undefined && { defaultLocale: extras.defaultLocale }),
323
+ }
324
+ }
@@ -1,40 +1,51 @@
1
1
  /**
2
- * Postinstall script — downloads the correct engine binary for the current
3
- * platform and caches it at ~/.supatype/engine/{version}/supatype-engine[.exe].
2
+ * Postinstall script — downloads component binaries on first install.
4
3
  *
5
- * Pattern: same as Prisma, esbuild, SWC, Turbo.
4
+ * Components: supatype-engine, supatype-server, supatype-pg (Postgres), deno.
5
+ * Binaries are cached in ~/.supatype/cache/{component}/{version}/.
6
6
  *
7
- * The binary is verified via:
8
- * 1. Minisign signature on checksums.sha256 (proves checksum file is authentic)
9
- * 2. SHA256 checksum of binary (proves binary matches signed checksum)
7
+ * Failures are non-fatal: an installation message is printed and the user
8
+ * can run `supatype update` manually to retry.
10
9
  */
11
10
 
12
- import { ENGINE_VERSION } from "../engine-version.js"
13
- import { detectPlatform } from "../engine/platform.js"
14
- import { hasCachedBinary } from "../engine/cache.js"
15
- import { resolveEngine } from "../engine/resolve.js"
11
+ import { download, currentPlatform, fetchAllLatestVersions, type Component } from "../binary-cache.js"
16
12
 
17
- async function main(): Promise<void> {
18
- const platform = detectPlatform()
13
+ async function main() {
14
+ const platform = currentPlatform()
19
15
 
20
- // Skip if already cached at the right version
21
- if (hasCachedBinary(ENGINE_VERSION, platform)) {
22
- console.log(`[supatype] Engine v${ENGINE_VERSION} already cached.`)
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
23
  return
24
24
  }
25
25
 
26
- console.log(
27
- `[supatype] Downloading engine v${ENGINE_VERSION} for ${platform.os}-${platform.arch}...`,
28
- )
26
+ console.log(`[supatype] Downloading component binaries for ${platform.os}/${platform.arch}...`)
29
27
 
30
- const result = await resolveEngine(ENGINE_VERSION)
31
- console.log(`[supatype] Engine installed at ${result.binaryPath}`)
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
+ }
32
45
  }
33
46
 
34
47
  main().catch((err) => {
35
- console.error("[supatype] Engine download failed:", err.message)
36
- console.error(
37
- "[supatype] You can still use the CLI — the engine will be downloaded on first use.",
38
- )
39
- // Don't exit(1) — let npm install succeed even if binary download fails.
48
+ // Non-fatal postinstall failures should not break npm install.
49
+ console.error("[supatype] Postinstall failed:", err)
50
+ process.exit(0)
40
51
  })