@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,45 @@
1
+ /**
2
+ * supatype self-update — Phase 10.6C8.
3
+ *
4
+ * npm-installed CLI: instruct to use `npm update -g`.
5
+ * Standalone / future curl|sh installs: CDN-published CLI binary replacement is not wired yet.
6
+ */
7
+
8
+ import type { Command } from "commander"
9
+ import { sep } from "node:path"
10
+
11
+ function looksLikeNpmOrWorkspaceCLI(): boolean {
12
+ const main = process.argv[1] ?? ""
13
+ return (
14
+ main.includes("node_modules") ||
15
+ main.includes(`${sep}dist${sep}cli`) ||
16
+ main.includes(`${sep}bin${sep}supatype.js`) ||
17
+ Boolean(process.env["npm_execpath"]) ||
18
+ Boolean(process.env["npm_lifecycle_event"])
19
+ )
20
+ }
21
+
22
+ export function registerSelfUpdate(program: Command): void {
23
+ program
24
+ .command("self-update")
25
+ .description(
26
+ "Update the supatype CLI (npm: use npm update; standalone binary swap from CDN is not available yet)",
27
+ )
28
+ .action(() => {
29
+ if (looksLikeNpmOrWorkspaceCLI()) {
30
+ console.log(
31
+ "This CLI was installed via npm (or runs from the package workspace).\n" +
32
+ "Update with:\n\n npm update -g @supatype/cli\n\n" +
33
+ "To bump engine/server/postgres/deno pinned in supatype.config.ts, use:\n\n supatype update\n",
34
+ )
35
+ return
36
+ }
37
+
38
+ console.error(
39
+ "Standalone CLI self-update (replace binary from CDN) is not published yet.\n\n" +
40
+ "Install or upgrade via npm:\n npm install -g @supatype/cli\n\n" +
41
+ "Component binaries (engine, server, postgres, deno):\n supatype update\n",
42
+ )
43
+ process.exit(1)
44
+ })
45
+ }
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import type { Command } from "commander"
5
5
  import { spawnSync } from "node:child_process"
6
+ import { LOCAL_KONG_HOST_PORT, localKongBaseUrl } from "../local-gateway.js"
6
7
 
7
8
  interface ServiceStatus {
8
9
  name: string
@@ -21,7 +22,7 @@ export function registerStatus(program: Command): void {
21
22
  { name: "Postgres", container: "supatype-postgres", port: 5432 },
22
23
  { name: "PostgREST", container: "supatype-postgrest", port: 3000 },
23
24
  { name: "GoTrue", container: "supatype-gotrue", port: 9999 },
24
- { name: "Kong", container: "supatype-kong", port: 8000 },
25
+ { name: "Kong", container: "supatype-kong", port: LOCAL_KONG_HOST_PORT },
25
26
  { name: "MinIO", container: "supatype-minio", port: 9000 },
26
27
  { name: "Realtime", container: "supatype-realtime", port: 4000 },
27
28
  { name: "Studio", container: "supatype-studio", port: 3100 },
@@ -46,9 +47,9 @@ export function registerStatus(program: Command): void {
46
47
  console.log(`\n${running.length}/${services.length} services running`)
47
48
 
48
49
  if (running.length > 0) {
49
- console.log(`\nAPI URL: http://localhost:8000`)
50
+ console.log(`\nAPI URL: ${localKongBaseUrl()}`)
50
51
  console.log(`Studio: http://localhost:3100`)
51
- console.log(`Database: postgresql://postgres:postgres@localhost:5432/postgres`)
52
+ console.log(`Database: postgresql://supatype_admin:postgres@localhost:5432/postgres`)
52
53
  }
53
54
  })
54
55
  }
@@ -0,0 +1,76 @@
1
+ import type { Command } from "commander"
2
+ import { existsSync, readFileSync } from "node:fs"
3
+ import { resolve, relative } from "node:path"
4
+ import ts from "typescript"
5
+ import { loadConfig } from "../config.js"
6
+
7
+ export function registerTypes(program: Command): void {
8
+ const types = program.command("types").description("Type generation and validation utilities")
9
+
10
+ types
11
+ .command("check")
12
+ .description("Validate generated client augmentation wiring")
13
+ .action(() => {
14
+ const cwd = process.cwd()
15
+ const config = loadConfig(cwd)
16
+ const augmentationPath = resolve(cwd, config.output?.client ?? "supatype/generated/index.d.ts")
17
+
18
+ const errors: string[] = []
19
+
20
+ if (!existsSync(augmentationPath)) {
21
+ errors.push(
22
+ `Missing generated augmentation file: ${relative(cwd, augmentationPath)}.\nRun: supatype generate`,
23
+ )
24
+ }
25
+
26
+ const tsconfigPath = resolve(cwd, "tsconfig.json")
27
+ if (!existsSync(tsconfigPath)) {
28
+ errors.push("Missing tsconfig.json in project root.")
29
+ } else {
30
+ const tsconfigRaw = readFileSync(tsconfigPath, "utf8")
31
+ const parsed = ts.parseConfigFileTextToJson(tsconfigPath, tsconfigRaw)
32
+ const cfg = (parsed.config ?? {}) as { include?: unknown; files?: unknown }
33
+ const include = Array.isArray(cfg.include) ? cfg.include.map(String) : []
34
+ const files = Array.isArray(cfg.files) ? cfg.files.map(String) : []
35
+ const relAug = toPosix(relative(cwd, augmentationPath))
36
+ const coveredByFiles = files.includes(relAug)
37
+ const coveredByInclude = include.some((entry) => {
38
+ if (entry.includes("**")) return relAug.startsWith(entry.split("**")[0] ?? "")
39
+ if (entry.endsWith("*.ts") || entry.endsWith("*.d.ts")) {
40
+ return relAug.startsWith(entry.replace(/\*\.d?ts$/, ""))
41
+ }
42
+ return relAug === entry || relAug.startsWith(entry.replace(/\/$/, "") + "/")
43
+ })
44
+ if (!coveredByFiles && !coveredByInclude) {
45
+ errors.push(
46
+ `tsconfig.json does not include ${relAug}. Add it to "include" or "files" so module augmentation is visible to TypeScript.`,
47
+ )
48
+ }
49
+ }
50
+
51
+ const packageJsonPath = resolve(cwd, "package.json")
52
+ if (existsSync(packageJsonPath)) {
53
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8")) as {
54
+ dependencies?: Record<string, string>
55
+ devDependencies?: Record<string, string>
56
+ }
57
+ const hasClient =
58
+ (pkg.dependencies && "@supatype/client" in pkg.dependencies) ||
59
+ (pkg.devDependencies && "@supatype/client" in pkg.devDependencies)
60
+ if (!hasClient) {
61
+ errors.push('package.json is missing "@supatype/client" dependency.')
62
+ }
63
+ }
64
+
65
+ if (errors.length > 0) {
66
+ for (const err of errors) console.error(`- ${err}`)
67
+ process.exit(1)
68
+ }
69
+
70
+ console.log("types check passed")
71
+ })
72
+ }
73
+
74
+ function toPosix(path: string): string {
75
+ return path.replace(/\\/g, "/")
76
+ }
@@ -0,0 +1,109 @@
1
+ /**
2
+ * supatype update — bump component versions in supatype.config.ts
3
+ * and download the new binaries.
4
+ */
5
+
6
+ import type { Command } from "commander"
7
+ import { existsSync, readFileSync, writeFileSync } from "node:fs"
8
+ import { basename, resolve } from "node:path"
9
+ import { loadConfig } from "../config.js"
10
+ import { resolveRuntimeProvider } from "../project-config.js"
11
+ import { runDockerCompose, writeSelfHostCompose } from "../self-host-compose.js"
12
+ import { download, currentPlatform, fetchAllLatestVersions, type Component } from "../binary-cache.js"
13
+
14
+ const CONFIG_CANDIDATES = ["supatype.config.ts", "supatype.config.js", "supatype.config.mjs"]
15
+
16
+ function resolveConfigFile(cwd: string): string | null {
17
+ for (const name of CONFIG_CANDIDATES) {
18
+ const p = resolve(cwd, name)
19
+ if (existsSync(p)) return p
20
+ }
21
+ return null
22
+ }
23
+
24
+ export function registerUpdate(program: Command): void {
25
+ program
26
+ .command("update")
27
+ .description(
28
+ "Download the latest component binaries and update versions in supatype.config.ts",
29
+ )
30
+ .option("--check", "Print available updates without downloading", false)
31
+ .action(async (opts: { check: boolean }) => {
32
+ const cwd = process.cwd()
33
+ const config = loadConfig(cwd)
34
+ const provider = resolveRuntimeProvider(config)
35
+
36
+ if (provider === "docker") {
37
+ if (opts.check) {
38
+ console.log("Docker provider: run without --check to pull compose images (supatype self-host compose pull).")
39
+ return
40
+ }
41
+ const paths = writeSelfHostCompose(cwd, config, { devLocal: true })
42
+ console.log("Pulling self-host compose images...")
43
+ const status = runDockerCompose(paths.composePath, ["pull"], cwd)
44
+ if (status !== 0) process.exit(status)
45
+ console.log("Compose images updated.")
46
+ return
47
+ }
48
+
49
+ const platform = currentPlatform()
50
+
51
+ const components: Component[] = ["engine", "server", "postgres", "deno"]
52
+ const updates: Array<{ component: Component; from: string; to: string }> = []
53
+
54
+ console.log("Fetching latest component versions from CDN...")
55
+ const latestVersions = await fetchAllLatestVersions()
56
+
57
+ for (const component of components) {
58
+ const current = config.versions[component]
59
+ if (current === "local") continue
60
+ const latest = latestVersions[component]
61
+ if (current !== latest) {
62
+ updates.push({ component, from: current, to: latest })
63
+ }
64
+ }
65
+
66
+ if (updates.length === 0) {
67
+ console.log("All components are up to date.")
68
+ return
69
+ }
70
+
71
+ console.log("Available updates:")
72
+ for (const { component, from, to } of updates) {
73
+ console.log(` ${component} ${from} → ${to}`)
74
+ }
75
+
76
+ if (opts.check) return
77
+
78
+ // Download updated binaries.
79
+ for (const { component, to } of updates) {
80
+ console.log(`\nDownloading ${component} v${to}...`)
81
+ try {
82
+ await download(component, to, platform)
83
+ } catch (err) {
84
+ console.error(` Failed: ${(err as Error).message}`)
85
+ continue
86
+ }
87
+ console.log(` ${component} v${to} downloaded.`)
88
+ }
89
+
90
+ const configPath = resolveConfigFile(cwd)
91
+ if (configPath === null) {
92
+ console.error("No supatype.config.ts (or .js/.mjs) found to patch versions.")
93
+ process.exit(1)
94
+ }
95
+
96
+ let text = readFileSync(configPath, "utf8")
97
+ for (const { component, to } of updates) {
98
+ const key = component
99
+ // engine: "0.4.1" or engine: '0.4.1'
100
+ text = text.replace(
101
+ new RegExp(`(${key}\\s*:\\s*['"])[^'"]*(['"])`),
102
+ `$1${to}$2`,
103
+ )
104
+ }
105
+
106
+ writeFileSync(configPath, text, "utf8")
107
+ console.log(`\n${basename(configPath)} updated.`)
108
+ })
109
+ }
@@ -0,0 +1,6 @@
1
+ /** CDN-cached binaries resolved by the CLI (`engine`, `server`, `postgres`, `deno`). */
2
+ export const BINARY_COMPONENTS = ["engine", "server", "postgres", "deno"] as const
3
+
4
+ export type Component = (typeof BINARY_COMPONENTS)[number]
5
+
6
+ export type ComponentVersions = Record<Component, string>
package/src/config.ts CHANGED
@@ -1,6 +1,19 @@
1
- import { existsSync } from "node:fs"
1
+ import { existsSync, readFileSync, writeFileSync, unlinkSync } from "node:fs"
2
2
  import { resolve } from "node:path"
3
+ import { tmpdir } from "node:os"
4
+ import { join } from "node:path"
3
5
  import { evalTsSnippet } from "./tsx-runner.js"
6
+ import {
7
+ mergeProjectConfig,
8
+ validateProjectConfig,
9
+ type SupatypeProjectConfig,
10
+ } from "./project-config.js"
11
+ import { extractSchemaAstFromTypes } from "./type-extractor.js"
12
+
13
+ export type { SupatypeProjectConfig } from "./project-config.js"
14
+
15
+ /** Canonical project configuration shape (alias for clarity at call sites). */
16
+ export type SupatypeConfig = SupatypeProjectConfig
4
17
 
5
18
  export interface ServiceVersionPin {
6
19
  /** Docker image tag to pin this service to (e.g. "v1.2.3"). When set, `self-host upgrade` skips this service. */
@@ -27,12 +40,6 @@ export interface SelfHostConfig {
27
40
  * Pin specific services to fixed Docker image versions.
28
41
  * When a service is pinned, `self-host upgrade` will skip it.
29
42
  * Omit a service or set to `undefined` to allow automatic upgrades.
30
- *
31
- * @example
32
- * services: {
33
- * db: { version: "17-latest" },
34
- * postgrest: { version: "v12.2.8" },
35
- * }
36
43
  */
37
44
  services?: {
38
45
  db?: ServiceVersionPin
@@ -63,97 +70,136 @@ export interface AppConfig {
63
70
  headers?: Record<string, string>
64
71
  }
65
72
 
66
- export interface SupatypeConfig {
67
- /** Database connection string. */
68
- connection: string
69
- /**
70
- * Path (or glob) to the schema entry point.
71
- * Must export model definitions as named exports.
72
- * @example "./schema/index.ts"
73
- */
74
- schema: string
75
- output?: {
76
- /** Path for generated TypeScript types. */
77
- types?: string
78
- /** Path for generated client helpers. */
79
- client?: string
80
- }
81
- /** Self-hosted production deployment configuration. */
82
- selfHost?: SelfHostConfig
83
- /** Cloud project reference (set by `supatype link --project <ref>`). */
84
- projectRef?: string
85
- /** Cloud API URL override. */
86
- apiUrl?: string
87
- /** Cloud access token (prefer SUPATYPE_ACCESS_TOKEN env var). */
88
- accessToken?: string
89
- /** CORS configuration. */
90
- cors?: {
91
- /** Allowed origins. Defaults to ['*'] in development. */
92
- allowedOrigins?: string[]
93
- }
94
- /** Static site hosting configuration. */
95
- app?: AppConfig
96
- /** Registered plugins (provider, field, composite, widget). */
97
- plugins?: Array<unknown> | undefined
98
- /** Admin panel configuration (see Gap Appendices tasks 47–50). */
99
- admin?: {
100
- /**
101
- * Roles from {ref}_auth.users that grant admin panel access.
102
- * Checked against `app_metadata.role` in the project JWT.
103
- * @default ["admin"]
104
- */
105
- roles?: string[]
106
- }
107
- }
108
-
109
73
  /** Identity helper — provides type inference for config files. */
110
- export function defineConfig(config: SupatypeConfig): SupatypeConfig {
74
+ export function defineConfig(config: SupatypeProjectConfig): SupatypeProjectConfig {
111
75
  return config
112
76
  }
113
77
 
114
- const CONFIG_CANDIDATES = [
78
+ const LEGACY_TOML = "supatype.config.toml"
79
+
80
+ const MAIN_CONFIG_CANDIDATES = [
115
81
  "supatype.config.ts",
116
82
  "supatype.config.js",
117
83
  "supatype.config.mjs",
118
84
  ]
119
85
 
120
- /** Load and evaluate supatype.config.ts from the given directory. */
121
- export function loadConfig(cwd: string = process.cwd()): SupatypeConfig {
122
- for (const candidate of CONFIG_CANDIDATES) {
86
+ const LOCAL_CONFIG_CANDIDATES = [
87
+ "supatype.local.config.ts",
88
+ "supatype.local.config.js",
89
+ "supatype.local.config.mjs",
90
+ ]
91
+
92
+ /**
93
+ * Normalize a config object parsed from JSON (e.g. shorthand `schema: "./x"`).
94
+ */
95
+ function normalizeProjectJson(raw: unknown): unknown {
96
+ if (typeof raw !== "object" || raw === null) return raw
97
+ const o = { ...(raw as Record<string, unknown>) }
98
+ const sch = o["schema"]
99
+ if (typeof sch === "string") {
100
+ o["schema"] = {
101
+ path: sch,
102
+ pg_schema: typeof o["pg_schema"] === "string" ? o["pg_schema"] : "public",
103
+ }
104
+ delete o["pg_schema"]
105
+ }
106
+ return o
107
+ }
108
+
109
+ /**
110
+ * Load project config from `supatype.config.ts` (or .js/.mjs), merged with
111
+ * optional `supatype.local.config.*` (gitignored overrides).
112
+ */
113
+ export function loadConfig(cwd: string = process.cwd()): SupatypeProjectConfig {
114
+ if (existsSync(resolve(cwd, LEGACY_TOML))) {
115
+ throw new Error(
116
+ `Found ${LEGACY_TOML}, which is no longer supported.\n` +
117
+ "Move settings into supatype.config.ts (export default { project, database, server, app, versions, … }).\n" +
118
+ "Run `supatype init` in a new folder for a fresh template.",
119
+ )
120
+ }
121
+
122
+ const baseRaw = loadFirstTsConfig(cwd, MAIN_CONFIG_CANDIDATES)
123
+ if (baseRaw === null) {
124
+ throw new Error(
125
+ "No supatype.config.ts (or .js/.mjs) found in the current directory.\n" +
126
+ "Run: supatype init",
127
+ )
128
+ }
129
+
130
+ const baseNorm = normalizeProjectJson(baseRaw)
131
+ const base = validateProjectConfig(baseNorm, "supatype.config.ts")
132
+
133
+ const localRaw = loadFirstTsConfig(cwd, LOCAL_CONFIG_CANDIDATES)
134
+ if (localRaw === null) return base
135
+
136
+ const localNorm = normalizeProjectJson(localRaw) as Partial<SupatypeProjectConfig>
137
+ return mergeProjectConfig(base, localNorm)
138
+ }
139
+
140
+ function loadFirstTsConfig(
141
+ cwd: string,
142
+ candidates: string[],
143
+ ): Record<string, unknown> | null {
144
+ for (const candidate of candidates) {
123
145
  const configPath = resolve(cwd, candidate)
124
146
  if (!existsSync(configPath)) continue
125
147
 
126
148
  const urlPath = "file:///" + configPath.replace(/\\/g, "/")
127
-
128
- // Use dynamic import so we can always access .default —
129
- // files without a parent package.json are treated as CJS by tsx,
130
- // meaning export default becomes module.exports.default rather than
131
- // the namespace default. Dynamic import + fallback handles both.
132
149
  const snippet = `
133
150
  const mod = await import(${JSON.stringify(urlPath)})
134
151
  const config = mod.default ?? mod
135
152
  process.stdout.write(JSON.stringify(config))
136
153
  `
137
154
  const result = evalTsSnippet(snippet, { cwd })
138
- if (result.exitCode !== 0) {
139
- throw new Error(
140
- `Failed to load ${candidate}:\n${result.stderr || result.stdout}`,
141
- )
155
+ if (result.exitCode === 0) {
156
+ return JSON.parse(result.stdout) as Record<string, unknown>
142
157
  }
143
158
 
144
- const parsed = JSON.parse(result.stdout) as SupatypeConfig
145
- if (!parsed.connection || !parsed.schema) {
146
- throw new Error(
147
- `${candidate} must export { connection, schema } via defineConfig()`,
148
- )
159
+ const failure = result.stderr || result.stdout
160
+ if (!failure.includes("ERR_PACKAGE_PATH_NOT_EXPORTED")) {
161
+ throw new Error(`Failed to load ${candidate}:\n${failure}`)
149
162
  }
150
- return parsed
163
+
164
+ const fallback = loadTsConfigWithoutCliImport(configPath, cwd)
165
+ if (fallback !== null) return fallback
166
+ throw new Error(`Failed to load ${candidate}:\n${failure}`)
151
167
  }
168
+ return null
169
+ }
152
170
 
153
- throw new Error(
154
- "No supatype.config.ts found in the current directory.\n" +
155
- "Run: supatype init",
156
- )
171
+ function loadTsConfigWithoutCliImport(
172
+ configPath: string,
173
+ cwd: string,
174
+ ): Record<string, unknown> | null {
175
+ const original = readFileSync(configPath, "utf8")
176
+ const patched = original
177
+ .replace(/^import\s+type\s+\{[^}]*\}\s+from\s+["']@supatype\/cli["'];?\s*$/gm, "")
178
+ .replace(/^import\s+\{[^}]*defineConfig[^}]*\}\s+from\s+["']@supatype\/cli["'];?\s*$/gm, "")
179
+
180
+ // If the file didn't import from @supatype/cli, this fallback won't help.
181
+ if (patched === original) return null
182
+
183
+ const tmpPath = join(tmpdir(), `supatype-config-fallback-${Date.now()}.mts`)
184
+ const wrapper = `const defineConfig = (config) => config\n${patched}`
185
+ writeFileSync(tmpPath, wrapper, "utf8")
186
+ try {
187
+ const urlPath = "file:///" + tmpPath.replace(/\\/g, "/")
188
+ const snippet = `
189
+ const mod = await import(${JSON.stringify(urlPath)})
190
+ const config = mod.default ?? mod
191
+ process.stdout.write(JSON.stringify(config))
192
+ `
193
+ const result = evalTsSnippet(snippet, { cwd })
194
+ if (result.exitCode !== 0) return null
195
+ return JSON.parse(result.stdout) as Record<string, unknown>
196
+ } finally {
197
+ try {
198
+ unlinkSync(tmpPath)
199
+ } catch {
200
+ // ignore cleanup errors
201
+ }
202
+ }
157
203
  }
158
204
 
159
205
  /** Load schema AST by evaluating the user's schema entry point via tsx. */
@@ -161,30 +207,17 @@ export function loadSchemaAst(
161
207
  schemaPath: string,
162
208
  cwd: string = process.cwd(),
163
209
  ): unknown {
210
+ const extracted = extractSchemaAstFromTypes(schemaPath, cwd)
211
+ if (extracted !== null) return extracted
212
+
164
213
  const absPath = resolve(cwd, schemaPath)
165
214
  if (!existsSync(absPath)) {
166
215
  throw new Error(`Schema file not found: ${absPath}`)
167
216
  }
168
217
 
169
- const urlPath = "file:///" + absPath.replace(/\\/g, "/")
170
-
171
- const snippet = `
172
- import { serialiseSchema } from "@supatype/schema"
173
- const mod = await import(${JSON.stringify(urlPath)})
174
- const { default: _default, ...named } = mod
175
- const models = Object.fromEntries(
176
- Object.entries(named).filter(([, v]) =>
177
- v != null && typeof v === "object" && "__modelMeta" in (v as object)
218
+ throw new Error(
219
+ "Runtime model() schemas are no longer supported.\n" +
220
+ `Could not extract type-based models from: ${absPath}\n` +
221
+ "Migrate this file to @supatype/types Model<> definitions (or run `supatype migrate-from-v1`).",
178
222
  )
179
- )
180
- process.stdout.write(JSON.stringify(serialiseSchema(models)))
181
- `
182
- const result = evalTsSnippet(snippet, { cwd })
183
- if (result.exitCode !== 0) {
184
- throw new Error(
185
- `Failed to load schema from ${absPath}:\n${result.stderr || result.stdout}`,
186
- )
187
- }
188
-
189
- return JSON.parse(result.stdout)
190
223
  }