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

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 (309) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +203 -1
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/dist/app-config.d.ts +7 -0
  5. package/dist/app-config.d.ts.map +1 -0
  6. package/dist/app-config.js +113 -0
  7. package/dist/app-config.js.map +1 -0
  8. package/dist/augmentation-generator.d.ts +2 -0
  9. package/dist/augmentation-generator.d.ts.map +1 -0
  10. package/dist/augmentation-generator.js +111 -0
  11. package/dist/augmentation-generator.js.map +1 -0
  12. package/dist/binary-cache.d.ts +89 -0
  13. package/dist/binary-cache.d.ts.map +1 -0
  14. package/dist/binary-cache.js +656 -0
  15. package/dist/binary-cache.js.map +1 -0
  16. package/dist/cli.d.ts.map +1 -1
  17. package/dist/cli.js +13 -7
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/admin.d.ts.map +1 -1
  20. package/dist/commands/admin.js +4 -3
  21. package/dist/commands/admin.js.map +1 -1
  22. package/dist/commands/app.d.ts.map +1 -1
  23. package/dist/commands/app.js +56 -209
  24. package/dist/commands/app.js.map +1 -1
  25. package/dist/commands/cache.d.ts +6 -0
  26. package/dist/commands/cache.d.ts.map +1 -0
  27. package/dist/commands/cache.js +105 -0
  28. package/dist/commands/cache.js.map +1 -0
  29. package/dist/commands/cloud.d.ts +12 -0
  30. package/dist/commands/cloud.d.ts.map +1 -1
  31. package/dist/commands/cloud.js +36 -46
  32. package/dist/commands/cloud.js.map +1 -1
  33. package/dist/commands/db.d.ts.map +1 -1
  34. package/dist/commands/db.js +47 -54
  35. package/dist/commands/db.js.map +1 -1
  36. package/dist/commands/deploy.d.ts +2 -1
  37. package/dist/commands/deploy.d.ts.map +1 -1
  38. package/dist/commands/deploy.js +92 -51
  39. package/dist/commands/deploy.js.map +1 -1
  40. package/dist/commands/dev.d.ts +11 -0
  41. package/dist/commands/dev.d.ts.map +1 -1
  42. package/dist/commands/dev.js +751 -384
  43. package/dist/commands/dev.js.map +1 -1
  44. package/dist/commands/diff.d.ts.map +1 -1
  45. package/dist/commands/diff.js +20 -15
  46. package/dist/commands/diff.js.map +1 -1
  47. package/dist/commands/engine.d.ts +1 -3
  48. package/dist/commands/engine.d.ts.map +1 -1
  49. package/dist/commands/engine.js +13 -85
  50. package/dist/commands/engine.js.map +1 -1
  51. package/dist/commands/functions.d.ts.map +1 -1
  52. package/dist/commands/functions.js +92 -105
  53. package/dist/commands/functions.js.map +1 -1
  54. package/dist/commands/generate.d.ts.map +1 -1
  55. package/dist/commands/generate.js +22 -12
  56. package/dist/commands/generate.js.map +1 -1
  57. package/dist/commands/init.d.ts +1 -1
  58. package/dist/commands/init.d.ts.map +1 -1
  59. package/dist/commands/init.js +124 -410
  60. package/dist/commands/init.js.map +1 -1
  61. package/dist/commands/migrate-from-v1.d.ts +5 -0
  62. package/dist/commands/migrate-from-v1.d.ts.map +1 -0
  63. package/dist/commands/migrate-from-v1.js +125 -0
  64. package/dist/commands/migrate-from-v1.js.map +1 -0
  65. package/dist/commands/migrate.d.ts.map +1 -1
  66. package/dist/commands/migrate.js +27 -23
  67. package/dist/commands/migrate.js.map +1 -1
  68. package/dist/commands/pg.d.ts +8 -0
  69. package/dist/commands/pg.d.ts.map +1 -0
  70. package/dist/commands/pg.js +102 -0
  71. package/dist/commands/pg.js.map +1 -0
  72. package/dist/commands/pull.d.ts.map +1 -1
  73. package/dist/commands/pull.js +5 -66
  74. package/dist/commands/pull.js.map +1 -1
  75. package/dist/commands/push.d.ts.map +1 -1
  76. package/dist/commands/push.js +99 -39
  77. package/dist/commands/push.js.map +1 -1
  78. package/dist/commands/seed.d.ts +2 -0
  79. package/dist/commands/seed.d.ts.map +1 -1
  80. package/dist/commands/seed.js +44 -11
  81. package/dist/commands/seed.js.map +1 -1
  82. package/dist/commands/self-host.d.ts +7 -1
  83. package/dist/commands/self-host.d.ts.map +1 -1
  84. package/dist/commands/self-host.js +272 -758
  85. package/dist/commands/self-host.js.map +1 -1
  86. package/dist/commands/self-update.d.ts +9 -0
  87. package/dist/commands/self-update.d.ts.map +1 -0
  88. package/dist/commands/self-update.js +33 -0
  89. package/dist/commands/self-update.js.map +1 -0
  90. package/dist/commands/status.d.ts.map +1 -1
  91. package/dist/commands/status.js +4 -3
  92. package/dist/commands/status.js.map +1 -1
  93. package/dist/commands/types.d.ts +3 -0
  94. package/dist/commands/types.d.ts.map +1 -0
  95. package/dist/commands/types.js +62 -0
  96. package/dist/commands/types.js.map +1 -0
  97. package/dist/commands/update.d.ts +7 -0
  98. package/dist/commands/update.d.ts.map +1 -0
  99. package/dist/commands/update.js +77 -0
  100. package/dist/commands/update.js.map +1 -0
  101. package/dist/components.d.ts +5 -0
  102. package/dist/components.d.ts.map +1 -0
  103. package/dist/components.js +3 -0
  104. package/dist/components.js.map +1 -0
  105. package/dist/config.d.ts +10 -51
  106. package/dist/config.d.ts.map +1 -1
  107. package/dist/config.js +101 -33
  108. package/dist/config.js.map +1 -1
  109. package/dist/docker-postgres.d.ts +39 -0
  110. package/dist/docker-postgres.d.ts.map +1 -0
  111. package/dist/docker-postgres.js +96 -0
  112. package/dist/docker-postgres.js.map +1 -0
  113. package/dist/engine-client.d.ts +67 -0
  114. package/dist/engine-client.d.ts.map +1 -0
  115. package/dist/engine-client.js +156 -0
  116. package/dist/engine-client.js.map +1 -0
  117. package/dist/ensure-binary.d.ts +7 -0
  118. package/dist/ensure-binary.d.ts.map +1 -0
  119. package/dist/ensure-binary.js +17 -0
  120. package/dist/ensure-binary.js.map +1 -0
  121. package/dist/functions-router-gen.d.ts +14 -0
  122. package/dist/functions-router-gen.d.ts.map +1 -0
  123. package/dist/functions-router-gen.js +199 -0
  124. package/dist/functions-router-gen.js.map +1 -0
  125. package/dist/index.d.ts +4 -5
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +2 -3
  128. package/dist/index.js.map +1 -1
  129. package/dist/kong-config.d.ts +21 -0
  130. package/dist/kong-config.d.ts.map +1 -0
  131. package/dist/kong-config.js +60 -0
  132. package/dist/kong-config.js.map +1 -0
  133. package/dist/local-gateway.d.ts +7 -0
  134. package/dist/local-gateway.d.ts.map +1 -0
  135. package/dist/local-gateway.js +9 -0
  136. package/dist/local-gateway.js.map +1 -0
  137. package/dist/local-storage.d.ts +8 -0
  138. package/dist/local-storage.d.ts.map +1 -0
  139. package/dist/local-storage.js +14 -0
  140. package/dist/local-storage.js.map +1 -0
  141. package/dist/pgbouncer-userlist.d.ts +5 -0
  142. package/dist/pgbouncer-userlist.d.ts.map +1 -0
  143. package/dist/pgbouncer-userlist.js +14 -0
  144. package/dist/pgbouncer-userlist.js.map +1 -0
  145. package/dist/postgres-ctl.d.ts +44 -0
  146. package/dist/postgres-ctl.d.ts.map +1 -0
  147. package/dist/postgres-ctl.js +137 -0
  148. package/dist/postgres-ctl.js.map +1 -0
  149. package/dist/process-manager.d.ts +41 -0
  150. package/dist/process-manager.d.ts.map +1 -0
  151. package/dist/process-manager.js +120 -0
  152. package/dist/process-manager.js.map +1 -0
  153. package/dist/project-config.d.ts +215 -0
  154. package/dist/project-config.d.ts.map +1 -0
  155. package/dist/project-config.js +145 -0
  156. package/dist/project-config.js.map +1 -0
  157. package/dist/pull-utils.d.ts +15 -0
  158. package/dist/pull-utils.d.ts.map +1 -1
  159. package/dist/pull-utils.js +12 -0
  160. package/dist/pull-utils.js.map +1 -1
  161. package/dist/release-pins.d.ts +7 -0
  162. package/dist/release-pins.d.ts.map +1 -0
  163. package/dist/release-pins.js +27 -0
  164. package/dist/release-pins.js.map +1 -0
  165. package/dist/release-public-key.d.ts +8 -0
  166. package/dist/release-public-key.d.ts.map +1 -0
  167. package/dist/release-public-key.js +13 -0
  168. package/dist/release-public-key.js.map +1 -0
  169. package/dist/runtime-routes.d.ts +25 -0
  170. package/dist/runtime-routes.d.ts.map +1 -0
  171. package/dist/runtime-routes.js +189 -0
  172. package/dist/runtime-routes.js.map +1 -0
  173. package/dist/scripts/postinstall.d.ts +5 -6
  174. package/dist/scripts/postinstall.d.ts.map +1 -1
  175. package/dist/scripts/postinstall.js +36 -20
  176. package/dist/scripts/postinstall.js.map +1 -1
  177. package/dist/self-host-compose.d.ts +14 -0
  178. package/dist/self-host-compose.d.ts.map +1 -0
  179. package/dist/self-host-compose.js +236 -0
  180. package/dist/self-host-compose.js.map +1 -0
  181. package/dist/storage-provision.d.ts +24 -0
  182. package/dist/storage-provision.d.ts.map +1 -0
  183. package/dist/storage-provision.js +44 -0
  184. package/dist/storage-provision.js.map +1 -0
  185. package/dist/systemd.d.ts +26 -0
  186. package/dist/systemd.d.ts.map +1 -0
  187. package/dist/systemd.js +102 -0
  188. package/dist/systemd.js.map +1 -0
  189. package/dist/tsx-runner.d.ts.map +1 -1
  190. package/dist/tsx-runner.js +9 -2
  191. package/dist/tsx-runner.js.map +1 -1
  192. package/dist/type-extractor.d.ts +31 -0
  193. package/dist/type-extractor.d.ts.map +1 -0
  194. package/dist/type-extractor.js +876 -0
  195. package/dist/type-extractor.js.map +1 -0
  196. package/package.json +4 -3
  197. package/releases/deno/VERSION +1 -0
  198. package/scripts/mirror-deno-release.sh +76 -0
  199. package/src/app-config.ts +128 -0
  200. package/src/augmentation-generator.ts +126 -0
  201. package/src/binary-cache.ts +802 -0
  202. package/src/cli.ts +13 -8
  203. package/src/commands/admin.ts +4 -3
  204. package/src/commands/app.ts +67 -231
  205. package/src/commands/cache.ts +117 -0
  206. package/src/commands/cloud.ts +46 -57
  207. package/src/commands/db.ts +54 -63
  208. package/src/commands/deploy.ts +110 -61
  209. package/src/commands/dev.ts +930 -405
  210. package/src/commands/diff.ts +21 -29
  211. package/src/commands/engine.ts +13 -116
  212. package/src/commands/functions.ts +97 -115
  213. package/src/commands/generate.ts +23 -10
  214. package/src/commands/init.ts +136 -414
  215. package/src/commands/migrate-from-v1.ts +131 -0
  216. package/src/commands/migrate.ts +27 -23
  217. package/src/commands/pg.ts +133 -0
  218. package/src/commands/pull.ts +6 -85
  219. package/src/commands/push.ts +128 -59
  220. package/src/commands/seed.ts +54 -12
  221. package/src/commands/self-host.ts +312 -880
  222. package/src/commands/self-update.ts +45 -0
  223. package/src/commands/status.ts +4 -3
  224. package/src/commands/types.ts +76 -0
  225. package/src/commands/update.ts +92 -0
  226. package/src/components.ts +6 -0
  227. package/src/config.ts +127 -94
  228. package/src/docker-postgres.ts +138 -0
  229. package/src/engine-client.ts +231 -0
  230. package/src/ensure-binary.ts +28 -0
  231. package/src/functions-router-gen.ts +224 -0
  232. package/src/index.ts +4 -12
  233. package/src/kong-config.ts +78 -0
  234. package/src/local-gateway.ts +9 -0
  235. package/src/local-storage.ts +14 -0
  236. package/src/pgbouncer-userlist.ts +15 -0
  237. package/src/postgres-ctl.ts +171 -0
  238. package/src/process-manager.ts +151 -0
  239. package/src/project-config.ts +353 -0
  240. package/src/pull-utils.ts +24 -0
  241. package/src/release-pins.ts +31 -0
  242. package/src/release-public-key.ts +12 -0
  243. package/src/runtime-routes.ts +216 -0
  244. package/src/scripts/postinstall.ts +36 -25
  245. package/src/self-host-compose.ts +257 -0
  246. package/src/storage-provision.ts +58 -0
  247. package/src/systemd.ts +137 -0
  248. package/src/tsx-runner.ts +11 -1
  249. package/src/type-extractor.ts +1016 -0
  250. package/tests/app-command.test.ts +54 -0
  251. package/tests/augmentation-generator.test.ts +59 -0
  252. package/tests/binary-cache-cloud-overrides.test.ts +123 -0
  253. package/tests/cached-artifact-format.test.ts +84 -0
  254. package/tests/cli-help.test.ts +40 -14
  255. package/tests/config.test.ts +140 -37
  256. package/tests/engine-distribution.test.ts +3 -3
  257. package/tests/ensure-binary.test.ts +59 -0
  258. package/tests/init.test.ts +28 -86
  259. package/tests/migrate-from-v1.test.ts +29 -0
  260. package/tests/pg-spawn-env.test.ts +18 -0
  261. package/tests/postgres-archive-tag.test.ts +9 -0
  262. package/tests/pull-utils.test.ts +36 -1
  263. package/tests/release-pins.test.ts +28 -0
  264. package/tests/runtime-contract.test.ts +236 -0
  265. package/tests/seed-discover.test.ts +31 -0
  266. package/tests/tsconfig.json +9 -0
  267. package/tests/type-extractor.test.ts +401 -0
  268. package/tsconfig.tsbuildinfo +1 -1
  269. package/vitest.config.ts +12 -0
  270. package/dist/engine/cache.d.ts +0 -37
  271. package/dist/engine/cache.d.ts.map +0 -1
  272. package/dist/engine/cache.js +0 -121
  273. package/dist/engine/cache.js.map +0 -1
  274. package/dist/engine/download.d.ts +0 -19
  275. package/dist/engine/download.d.ts.map +0 -1
  276. package/dist/engine/download.js +0 -108
  277. package/dist/engine/download.js.map +0 -1
  278. package/dist/engine/platform.d.ts +0 -24
  279. package/dist/engine/platform.d.ts.map +0 -1
  280. package/dist/engine/platform.js +0 -50
  281. package/dist/engine/platform.js.map +0 -1
  282. package/dist/engine/resolve.d.ts +0 -37
  283. package/dist/engine/resolve.d.ts.map +0 -1
  284. package/dist/engine/resolve.js +0 -133
  285. package/dist/engine/resolve.js.map +0 -1
  286. package/dist/engine/update-notify.d.ts +0 -11
  287. package/dist/engine/update-notify.d.ts.map +0 -1
  288. package/dist/engine/update-notify.js +0 -43
  289. package/dist/engine/update-notify.js.map +0 -1
  290. package/dist/engine/verify.d.ts +0 -50
  291. package/dist/engine/verify.d.ts.map +0 -1
  292. package/dist/engine/verify.js +0 -161
  293. package/dist/engine/verify.js.map +0 -1
  294. package/dist/engine-version.d.ts +0 -35
  295. package/dist/engine-version.d.ts.map +0 -1
  296. package/dist/engine-version.js +0 -35
  297. package/dist/engine-version.js.map +0 -1
  298. package/dist/engine.d.ts +0 -34
  299. package/dist/engine.d.ts.map +0 -1
  300. package/dist/engine.js +0 -76
  301. package/dist/engine.js.map +0 -1
  302. package/src/engine/cache.ts +0 -135
  303. package/src/engine/download.ts +0 -143
  304. package/src/engine/platform.ts +0 -66
  305. package/src/engine/resolve.ts +0 -197
  306. package/src/engine/update-notify.ts +0 -50
  307. package/src/engine/verify.ts +0 -206
  308. package/src/engine-version.ts +0 -39
  309. package/src/engine.ts +0 -99
@@ -6,6 +6,8 @@
6
6
 
7
7
  import type { Command } from "commander"
8
8
  import { loadConfig } from "../config.js"
9
+ import { connectionString } from "../project-config.js"
10
+ import { loadCloudConfig } from "./cloud.js"
9
11
 
10
12
  export function registerDb(program: Command): void {
11
13
  const db = program
@@ -21,16 +23,13 @@ export function registerDb(program: Command): void {
21
23
  .action(async (opts: { transaction?: boolean; env?: string }) => {
22
24
  const cwd = process.cwd()
23
25
  const config = loadConfig(cwd)
26
+ const cloudCfg = loadCloudConfig(cwd)
27
+ const localConn = connectionString(config)
24
28
 
25
- // The connection string is stored in the project config or fetched from cloud
26
- if (config.connection) {
27
- if (opts.transaction) {
28
- // Convert session URL to transaction pool URL (port 6432)
29
- const txUrl = config.connection.replace(/:5432\//, ":6432/")
30
- console.log(txUrl)
31
- } else {
32
- console.log(config.connection)
33
- }
29
+ // If no cloud project linked, show the local connection string.
30
+ if (!cloudCfg?.projectSlug) {
31
+ const connStr = opts.transaction ? localConn.replace(/:5432\//, ":6432/") : localConn
32
+ console.log(connStr)
34
33
  console.log()
35
34
  console.log("Session mode (port 5432): for interactive tools (psql, DataGrip, TablePlus)")
36
35
  console.log("Transaction mode (port 6432): for application servers and serverless functions")
@@ -38,58 +37,49 @@ export function registerDb(program: Command): void {
38
37
  }
39
38
 
40
39
  // If linked to a cloud project, fetch from the API
41
- if (config.projectRef) {
42
- const apiUrl = config.apiUrl || "https://api.supatype.io"
43
- const envName = opts.env || "production"
44
-
45
- try {
46
- const res = await fetch(
47
- `${apiUrl}/platform/v1/projects/${config.projectRef}/environments`,
48
- {
49
- headers: {
50
- Authorization: `Bearer ${config.accessToken || process.env["SUPATYPE_ACCESS_TOKEN"] || ""}`,
51
- },
40
+ const apiUrl = cloudCfg.apiUrl || "https://api.supatype.com"
41
+ const token = cloudCfg.token || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
42
+ const envName = opts.env || "production"
43
+
44
+ try {
45
+ const res = await fetch(
46
+ `${apiUrl}/platform/v1/projects/${cloudCfg.projectSlug}/environments`,
47
+ {
48
+ headers: {
49
+ Authorization: `Bearer ${token}`,
52
50
  },
53
- )
54
-
55
- if (!res.ok) {
56
- console.error(`Failed to fetch project info: ${res.status}`)
57
- process.exitCode = 1
58
- return
59
- }
60
-
61
- const { data } = (await res.json()) as { data: Array<{ name: string; databaseUrl?: string }> }
62
- const env = data.find((e) => e.name === envName)
63
-
64
- if (!env) {
65
- console.error(`Environment "${envName}" not found`)
66
- process.exitCode = 1
67
- return
68
- }
69
-
70
- const connStr = env.databaseUrl || "Connection string not available"
71
- if (opts.transaction) {
72
- console.log(connStr.replace(/:5432\//, ":6432/"))
73
- } else {
74
- console.log(connStr)
75
- }
76
-
77
- console.log()
78
- console.log("Session mode (port 5432): for interactive tools (psql, DataGrip, TablePlus)")
79
- console.log("Transaction mode (port 6432): for application servers and serverless functions")
80
- } catch (err) {
81
- console.error("Failed to fetch connection string:", (err as Error).message)
51
+ },
52
+ )
53
+
54
+ if (!res.ok) {
55
+ console.error(`Failed to fetch project info: ${res.status}`)
82
56
  process.exitCode = 1
57
+ return
83
58
  }
84
- return
85
- }
86
59
 
87
- console.error(
88
- "No connection configured. Either:\n" +
89
- " • Set 'connection' in supatype.config.ts\n" +
90
- " • Link to a cloud project: npx supatype link --project <ref>",
91
- )
92
- process.exitCode = 1
60
+ const { data } = (await res.json()) as { data: Array<{ name: string; databaseUrl?: string }> }
61
+ const env = data.find((e) => e.name === envName)
62
+
63
+ if (!env) {
64
+ console.error(`Environment "${envName}" not found`)
65
+ process.exitCode = 1
66
+ return
67
+ }
68
+
69
+ const connStr = env.databaseUrl || "Connection string not available"
70
+ if (opts.transaction) {
71
+ console.log(connStr.replace(/:5432\//, ":6432/"))
72
+ } else {
73
+ console.log(connStr)
74
+ }
75
+
76
+ console.log()
77
+ console.log("Session mode (port 5432): for interactive tools (psql, DataGrip, TablePlus)")
78
+ console.log("Transaction mode (port 6432): for application servers and serverless functions")
79
+ } catch (err) {
80
+ console.error("Failed to fetch connection string:", (err as Error).message)
81
+ process.exitCode = 1
82
+ }
93
83
  })
94
84
 
95
85
  // supatype db reset-password
@@ -99,24 +89,25 @@ export function registerDb(program: Command): void {
99
89
  .option("--env <name>", "Environment name", "production")
100
90
  .action(async (opts: { env?: string }) => {
101
91
  const cwd = process.cwd()
102
- const config = loadConfig(cwd)
92
+ const cloudCfg = loadCloudConfig(cwd)
103
93
 
104
- if (!config.projectRef) {
105
- console.error("Not linked to a cloud project. Run: npx supatype link --project <ref>")
94
+ if (!cloudCfg?.projectSlug) {
95
+ console.error("Not linked to a cloud project. Run: supatype link --project <ref>")
106
96
  process.exitCode = 1
107
97
  return
108
98
  }
109
99
 
110
- const apiUrl = config.apiUrl || "https://api.supatype.io"
100
+ const apiUrl = cloudCfg.apiUrl || "https://api.supatype.com"
101
+ const token = cloudCfg.token || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
111
102
  const envName = opts.env || "production"
112
103
 
113
104
  try {
114
105
  const res = await fetch(
115
- `${apiUrl}/platform/v1/projects/${config.projectRef}/environments/${envName}/reset-db-password`,
106
+ `${apiUrl}/platform/v1/projects/${cloudCfg.projectSlug}/environments/${envName}/reset-db-password`,
116
107
  {
117
108
  method: "POST",
118
109
  headers: {
119
- Authorization: `Bearer ${config.accessToken || process.env["SUPATYPE_ACCESS_TOKEN"] || ""}`,
110
+ Authorization: `Bearer ${token}`,
120
111
  "Content-Type": "application/json",
121
112
  },
122
113
  },
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Deploy commands:
3
- * supatype deploy — push schema + build & deploy static site
3
+ * supatype deploy — Supatype Cloud by default (linked via supatype link), else platform projectRef; use --local for engine + DB
4
+ * supatype deploy --local — push schema via local engine + optional static app to .supatype/static
4
5
  * supatype deploy --app-only — only build & deploy the static site
5
6
  * supatype deploy --schema-only — only push schema changes
6
7
  * supatype deploy --skip-build — deploy existing build output (no build step)
@@ -14,7 +15,9 @@ import type { Command } from "commander"
14
15
  import { existsSync, readdirSync, statSync, createReadStream } from "node:fs"
15
16
  import { join } from "node:path"
16
17
  import { loadConfig, loadSchemaAst } from "../config.js"
17
- import { ensureEngine, invokeEngine } from "../engine.js"
18
+ import { connectionString, schemaPathFromProject } from "../project-config.js"
19
+ import { deploySchemaToLinkedProject, loadCloudConfig } from "./cloud.js"
20
+ import { ensureEngine, engineRequest, type DiffResult } from "../engine-client.js"
18
21
  import { resolveAppConfig, validateStaticMode, validateBuildOutput, detectPackageManager } from "../app/framework.js"
19
22
  import { TIER_LIMITS, type Tier } from "./deploy-types.js"
20
23
  import { spawnSync } from "node:child_process"
@@ -22,13 +25,19 @@ import { spawnSync } from "node:child_process"
22
25
  export function registerDeploy(program: Command): void {
23
26
  const deploy = program
24
27
  .command("deploy")
25
- .description("Build and deploy your application")
28
+ .description(
29
+ "Deploy schema and app — Supatype Cloud by default when linked (`supatype link`); pass --local for engine + your database",
30
+ )
31
+ .option("--local", "Use local schema engine and database_url from config (skip cloud control plane)")
32
+ .option("--environment <name>", "Cloud environment when using linked project", "production")
26
33
  .option("--app-only", "Skip schema push, only deploy the static site")
27
34
  .option("--schema-only", "Skip app build, only push schema changes")
28
35
  .option("--skip-build", "Deploy existing build output without building")
29
36
  .option("--preview", "Deploy to a temporary preview URL")
30
37
  .option("--yes", "Skip confirmation prompts")
31
38
  .action(async (opts: {
39
+ local?: boolean
40
+ environment?: string
32
41
  appOnly?: boolean
33
42
  schemaOnly?: boolean
34
43
  skipBuild?: boolean
@@ -37,54 +46,92 @@ export function registerDeploy(program: Command): void {
37
46
  }) => {
38
47
  const cwd = process.cwd()
39
48
  const config = loadConfig(cwd)
40
-
41
- // Step 1: Schema push (unless --app-only or --skip-build)
42
- if (!opts.appOnly && !opts.skipBuild) {
43
- console.log("=== Schema Push ===")
44
- await ensureEngine()
45
-
46
- const ast = loadSchemaAst(config.schema, cwd)
47
- const diffResult = invokeEngine(
48
- ["diff", "--connection", config.connection, "--format", "json"],
49
- JSON.stringify(ast),
50
- )
51
- if (diffResult.exitCode !== 0) {
52
- console.error("Schema diff failed:", diffResult.stderr || diffResult.stdout)
53
- process.exit(1)
49
+ const cloudCfg = loadCloudConfig(cwd)
50
+
51
+ let schemaDone = false
52
+
53
+ // Default: cloud — .supatype/cloud.json → control plane schema deploy
54
+ if (
55
+ !opts.local &&
56
+ cloudCfg?.projectSlug &&
57
+ !opts.appOnly &&
58
+ !opts.skipBuild
59
+ ) {
60
+ await deploySchemaToLinkedProject(cwd, opts.environment ?? "production")
61
+ schemaDone = true
62
+ if (opts.schemaOnly) {
63
+ return
54
64
  }
65
+ }
55
66
 
56
- const diff = JSON.parse(diffResult.stdout)
57
- const ops = diff.operations ?? []
67
+ // Step 1: Schema push (unless --app-only or --skip-build, or already done via cloud.json)
68
+ if (!opts.appOnly && !opts.skipBuild && !schemaDone) {
69
+ const ast = loadSchemaAst(schemaPathFromProject(config, cwd), cwd)
58
70
 
59
- if (ops.length > 0) {
60
- console.log(`${ops.length} schema change(s) to apply.`)
61
- const migrateResult = invokeEngine(
62
- ["migrate", "--connection", config.connection],
63
- JSON.stringify(ast),
64
- )
65
- if (migrateResult.exitCode !== 0) {
66
- console.error("Migration failed:", migrateResult.stderr)
71
+ if (opts.local) {
72
+ console.log("=== Schema Push (local) ===")
73
+ await ensureEngine()
74
+
75
+ const diff = await engineRequest<DiffResult>("/diff", {
76
+ ast,
77
+ database_url: connectionString(config),
78
+ schema: "public",
79
+ })
80
+
81
+ const ops = diff.operations ?? []
82
+
83
+ if (ops.length > 0) {
84
+ console.log(`${ops.length} schema change(s) to apply.`)
85
+ await engineRequest("/push", {
86
+ ast,
87
+ database_url: connectionString(config),
88
+ schema: "public",
89
+ force: true,
90
+ })
91
+ console.log("Schema changes applied.")
92
+ } else {
93
+ console.log("Schema is up to date.")
94
+ }
95
+ } else if (cloudCfg?.projectSlug) {
96
+ console.log("=== Schema Push ===")
97
+ // Platform API — no local Docker needed
98
+ const apiUrl = cloudCfg.apiUrl || "https://api.supatype.com"
99
+ const token = cloudCfg.token || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
100
+
101
+ const res = await fetch(`${apiUrl}/platform/v1/projects/${cloudCfg.projectSlug}/schema/push`, {
102
+ method: "POST",
103
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
104
+ body: JSON.stringify({ ast }),
105
+ })
106
+ if (!res.ok) {
107
+ const body = await res.text()
108
+ console.error(`Schema push failed: ${res.status} ${body}`)
67
109
  process.exit(1)
68
110
  }
69
- console.log("Schema changes applied.")
111
+ const pushData = await res.json() as { operations?: unknown[]; message?: string }
112
+ console.log(pushData.message ?? `Schema changes applied (${pushData.operations?.length ?? 0} operations).`)
70
113
  } else {
71
- console.log("Schema is up to date.")
114
+ console.error(
115
+ "Not linked to Supatype Cloud. Run: supatype link\n" +
116
+ "Or deploy against your own database: supatype deploy --local",
117
+ )
118
+ process.exit(1)
72
119
  }
73
120
  }
74
121
 
75
122
  // Step 2: App build & deploy (unless --schema-only)
76
123
  if (!opts.schemaOnly) {
77
- if (!config.app) {
124
+ if (!config.build) {
78
125
  if (opts.appOnly) {
79
- console.error("No app configuration found in supatype.config.ts")
126
+ console.error("No build section found in supatype.config.ts")
80
127
  process.exit(1)
81
128
  }
82
- // No app config — just skip app deployment silently
129
+ // No build config — skip app deployment silently
83
130
  return
84
131
  }
85
132
 
86
133
  console.log("\n=== App Build & Deploy ===")
87
- const appConfig = resolveAppConfig(config.app, cwd)
134
+ const appConfig = resolveAppConfig(config.build, cwd)
88
135
 
89
136
  // Validate static mode
90
137
  const staticError = validateStaticMode(appConfig.framework, appConfig.directory)
@@ -107,10 +154,10 @@ export function registerDeploy(program: Command): void {
107
154
  }
108
155
 
109
156
  // Inject Supatype URLs if project is linked
110
- if (config.projectRef) {
111
- buildEnv["NEXT_PUBLIC_SUPATYPE_URL"] = config.apiUrl || `https://${config.projectRef}.supatype.io`
112
- buildEnv["VITE_SUPATYPE_URL"] = buildEnv["NEXT_PUBLIC_SUPATYPE_URL"]
113
- buildEnv["PUBLIC_SUPATYPE_URL"] = buildEnv["NEXT_PUBLIC_SUPATYPE_URL"]
157
+ if (cloudCfg?.projectSlug) {
158
+ buildEnv["NEXT_PUBLIC_SUPATYPE_URL"] = cloudCfg.apiUrl || `https://${cloudCfg.projectSlug}.supatype.dev`
159
+ buildEnv["VITE_SUPATYPE_URL"] = buildEnv["NEXT_PUBLIC_SUPATYPE_URL"]!
160
+ buildEnv["PUBLIC_SUPATYPE_URL"] = buildEnv["NEXT_PUBLIC_SUPATYPE_URL"]!
114
161
  // NEVER inject service_role key — only anon key is safe for client-side
115
162
  }
116
163
 
@@ -151,20 +198,22 @@ export function registerDeploy(program: Command): void {
151
198
  process.exit(1)
152
199
  }
153
200
 
154
- // Deploy
155
- if (config.projectRef) {
156
- // Cloud deployment — upload to API
157
- await deployToCloud(config, appConfig.outputDirectory, opts.preview ?? false)
201
+ // Deploy (--local never uploads to cloud, even if linked)
202
+ if (cloudCfg?.projectSlug && !opts.local) {
203
+ await deployToCloud(
204
+ { projectRef: cloudCfg.projectSlug, apiUrl: cloudCfg.apiUrl, accessToken: cloudCfg.token },
205
+ appConfig.outputDirectory,
206
+ opts.preview ?? false,
207
+ )
158
208
  } else {
159
- // Self-host — copy to serving directory
160
209
  deploySelfHost(appConfig.outputDirectory, cwd)
161
210
  }
162
211
 
163
212
  console.log("\nDeployment complete!")
164
- if (config.projectRef) {
213
+ if (cloudCfg?.projectSlug && !opts.local) {
165
214
  const url = opts.preview
166
- ? `https://preview-${Date.now().toString(36)}.${config.projectRef}.supatype.io`
167
- : `https://${config.projectRef}.supatype.io`
215
+ ? `https://preview-${Date.now().toString(36)}.${cloudCfg.projectSlug}.supatype.dev`
216
+ : `https://${cloudCfg.projectSlug}.supatype.dev`
168
217
  console.log(`URL: ${url}`)
169
218
  }
170
219
  }
@@ -175,16 +224,16 @@ export function registerDeploy(program: Command): void {
175
224
  .command("rollback")
176
225
  .description("Roll back to the previous static site deployment")
177
226
  .action(async () => {
178
- const config = loadConfig(process.cwd())
179
- if (!config.projectRef) {
227
+ const cloudCfg = loadCloudConfig(process.cwd())
228
+ if (!cloudCfg?.projectSlug) {
180
229
  console.error("Not linked to a cloud project. Rollback is only available for cloud deployments.")
181
230
  process.exit(1)
182
231
  }
183
232
 
184
- const apiUrl = config.apiUrl || "https://api.supatype.io"
185
- const token = config.accessToken || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
233
+ const apiUrl = cloudCfg.apiUrl || "https://api.supatype.com"
234
+ const token = cloudCfg.token || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
186
235
 
187
- const res = await fetch(`${apiUrl}/platform/v1/projects/${config.projectRef}/deployments/rollback`, {
236
+ const res = await fetch(`${apiUrl}/platform/v1/projects/${cloudCfg.projectSlug}/deployments/rollback`, {
188
237
  method: "POST",
189
238
  headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
190
239
  })
@@ -204,16 +253,16 @@ export function registerDeploy(program: Command): void {
204
253
  .command("status")
205
254
  .description("Show current deployment status")
206
255
  .action(async () => {
207
- const config = loadConfig(process.cwd())
208
- if (!config.projectRef) {
256
+ const cloudCfg = loadCloudConfig(process.cwd())
257
+ if (!cloudCfg?.projectSlug) {
209
258
  console.error("Not linked to a cloud project.")
210
259
  process.exit(1)
211
260
  }
212
261
 
213
- const apiUrl = config.apiUrl || "https://api.supatype.io"
214
- const token = config.accessToken || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
262
+ const apiUrl = cloudCfg.apiUrl || "https://api.supatype.com"
263
+ const token = cloudCfg.token || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
215
264
 
216
- const res = await fetch(`${apiUrl}/platform/v1/projects/${config.projectRef}/deployments/current`, {
265
+ const res = await fetch(`${apiUrl}/platform/v1/projects/${cloudCfg.projectSlug}/deployments/current`, {
217
266
  headers: { Authorization: `Bearer ${token}` },
218
267
  })
219
268
 
@@ -244,17 +293,17 @@ export function registerDeploy(program: Command): void {
244
293
  .command("logs [version]")
245
294
  .description("Show build logs for a deployment")
246
295
  .action(async (version?: string) => {
247
- const config = loadConfig(process.cwd())
248
- if (!config.projectRef) {
296
+ const cloudCfg = loadCloudConfig(process.cwd())
297
+ if (!cloudCfg?.projectSlug) {
249
298
  console.error("Not linked to a cloud project.")
250
299
  process.exit(1)
251
300
  }
252
301
 
253
- const apiUrl = config.apiUrl || "https://api.supatype.io"
254
- const token = config.accessToken || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
302
+ const apiUrl = cloudCfg.apiUrl || "https://api.supatype.com"
303
+ const token = cloudCfg.token || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
255
304
 
256
305
  const versionPath = version ? `/${version}` : "/current"
257
- const res = await fetch(`${apiUrl}/platform/v1/projects/${config.projectRef}/deployments${versionPath}/logs`, {
306
+ const res = await fetch(`${apiUrl}/platform/v1/projects/${cloudCfg.projectSlug}/deployments${versionPath}/logs`, {
258
307
  headers: { Authorization: `Bearer ${token}` },
259
308
  })
260
309
 
@@ -273,7 +322,7 @@ async function deployToCloud(
273
322
  outputDir: string,
274
323
  isPreview: boolean,
275
324
  ): Promise<void> {
276
- const apiUrl = config.apiUrl || "https://api.supatype.io"
325
+ const apiUrl = config.apiUrl || "https://api.supatype.com"
277
326
  const token = config.accessToken || process.env["SUPATYPE_ACCESS_TOKEN"] || ""
278
327
 
279
328
  console.log("Uploading build artifacts...")