@supatype/cli 0.1.0-alpha.9 → 0.1.0

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 (383) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/.turbo/turbo-test.log +270 -65
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/assets/supatype-logo-wordmark.ascii.txt +6 -0
  5. package/bin/dev-entry.ts +2 -1
  6. package/dist/app/framework.js +1 -3
  7. package/dist/app/framework.js.map +1 -1
  8. package/dist/app/proxy-dev-app.d.ts +14 -0
  9. package/dist/app/proxy-dev-app.d.ts.map +1 -1
  10. package/dist/app/proxy-dev-app.js +110 -6
  11. package/dist/app/proxy-dev-app.js.map +1 -1
  12. package/dist/app-config.d.ts +10 -0
  13. package/dist/app-config.d.ts.map +1 -1
  14. package/dist/app-config.js +72 -0
  15. package/dist/app-config.js.map +1 -1
  16. package/dist/assets/supatype-logo-wordmark.ascii.txt +6 -0
  17. package/dist/binary-cache.d.ts +19 -7
  18. package/dist/binary-cache.d.ts.map +1 -1
  19. package/dist/binary-cache.js +92 -46
  20. package/dist/binary-cache.js.map +1 -1
  21. package/dist/cli.d.ts +1 -1
  22. package/dist/cli.d.ts.map +1 -1
  23. package/dist/cli.js +17 -2
  24. package/dist/cli.js.map +1 -1
  25. package/dist/commands/add.d.ts +3 -0
  26. package/dist/commands/add.d.ts.map +1 -0
  27. package/dist/commands/add.js +86 -0
  28. package/dist/commands/add.js.map +1 -0
  29. package/dist/commands/admin.d.ts.map +1 -1
  30. package/dist/commands/admin.js +39 -53
  31. package/dist/commands/admin.js.map +1 -1
  32. package/dist/commands/adopt.d.ts +3 -0
  33. package/dist/commands/adopt.d.ts.map +1 -0
  34. package/dist/commands/adopt.js +55 -0
  35. package/dist/commands/adopt.js.map +1 -0
  36. package/dist/commands/app.d.ts.map +1 -1
  37. package/dist/commands/app.js +20 -17
  38. package/dist/commands/app.js.map +1 -1
  39. package/dist/commands/cache.d.ts.map +1 -1
  40. package/dist/commands/cache.js +11 -10
  41. package/dist/commands/cache.js.map +1 -1
  42. package/dist/commands/cloud.d.ts +4 -9
  43. package/dist/commands/cloud.d.ts.map +1 -1
  44. package/dist/commands/cloud.js +75 -125
  45. package/dist/commands/cloud.js.map +1 -1
  46. package/dist/commands/db.d.ts.map +1 -1
  47. package/dist/commands/db.js +37 -58
  48. package/dist/commands/db.js.map +1 -1
  49. package/dist/commands/deploy.d.ts.map +1 -1
  50. package/dist/commands/deploy.js +140 -96
  51. package/dist/commands/deploy.js.map +1 -1
  52. package/dist/commands/dev.d.ts.map +1 -1
  53. package/dist/commands/dev.js +72 -39
  54. package/dist/commands/dev.js.map +1 -1
  55. package/dist/commands/diff.d.ts.map +1 -1
  56. package/dist/commands/diff.js +39 -39
  57. package/dist/commands/diff.js.map +1 -1
  58. package/dist/commands/doctor.d.ts +3 -0
  59. package/dist/commands/doctor.d.ts.map +1 -0
  60. package/dist/commands/doctor.js +78 -0
  61. package/dist/commands/doctor.js.map +1 -0
  62. package/dist/commands/engine.d.ts.map +1 -1
  63. package/dist/commands/engine.js +5 -4
  64. package/dist/commands/engine.js.map +1 -1
  65. package/dist/commands/functions.d.ts.map +1 -1
  66. package/dist/commands/functions.js +172 -119
  67. package/dist/commands/functions.js.map +1 -1
  68. package/dist/commands/generate.d.ts.map +1 -1
  69. package/dist/commands/generate.js +5 -4
  70. package/dist/commands/generate.js.map +1 -1
  71. package/dist/commands/init.d.ts +30 -1
  72. package/dist/commands/init.d.ts.map +1 -1
  73. package/dist/commands/init.js +814 -107
  74. package/dist/commands/init.js.map +1 -1
  75. package/dist/commands/introspect.d.ts +3 -0
  76. package/dist/commands/introspect.d.ts.map +1 -0
  77. package/dist/commands/introspect.js +35 -0
  78. package/dist/commands/introspect.js.map +1 -0
  79. package/dist/commands/keys.d.ts +15 -1
  80. package/dist/commands/keys.d.ts.map +1 -1
  81. package/dist/commands/keys.js +46 -10
  82. package/dist/commands/keys.js.map +1 -1
  83. package/dist/commands/link-helpers.d.ts +15 -0
  84. package/dist/commands/link-helpers.d.ts.map +1 -0
  85. package/dist/commands/link-helpers.js +225 -0
  86. package/dist/commands/link-helpers.js.map +1 -0
  87. package/dist/commands/logs.d.ts.map +1 -1
  88. package/dist/commands/logs.js +5 -4
  89. package/dist/commands/logs.js.map +1 -1
  90. package/dist/commands/migrate-from-v1.d.ts.map +1 -1
  91. package/dist/commands/migrate-from-v1.js +3 -2
  92. package/dist/commands/migrate-from-v1.js.map +1 -1
  93. package/dist/commands/migrate.d.ts.map +1 -1
  94. package/dist/commands/migrate.js +119 -26
  95. package/dist/commands/migrate.js.map +1 -1
  96. package/dist/commands/pg.d.ts.map +1 -1
  97. package/dist/commands/pg.js +11 -12
  98. package/dist/commands/pg.js.map +1 -1
  99. package/dist/commands/plugins.d.ts.map +1 -1
  100. package/dist/commands/plugins.js +55 -46
  101. package/dist/commands/plugins.js.map +1 -1
  102. package/dist/commands/pull.d.ts.map +1 -1
  103. package/dist/commands/pull.js +33 -5
  104. package/dist/commands/pull.js.map +1 -1
  105. package/dist/commands/push.d.ts.map +1 -1
  106. package/dist/commands/push.js +110 -137
  107. package/dist/commands/push.js.map +1 -1
  108. package/dist/commands/seed.d.ts.map +1 -1
  109. package/dist/commands/seed.js +4 -3
  110. package/dist/commands/seed.js.map +1 -1
  111. package/dist/commands/self-host.d.ts +2 -2
  112. package/dist/commands/self-host.d.ts.map +1 -1
  113. package/dist/commands/self-host.js +65 -50
  114. package/dist/commands/self-host.js.map +1 -1
  115. package/dist/commands/self-update.d.ts.map +1 -1
  116. package/dist/commands/self-update.js +3 -2
  117. package/dist/commands/self-update.js.map +1 -1
  118. package/dist/commands/status.d.ts +1 -1
  119. package/dist/commands/status.d.ts.map +1 -1
  120. package/dist/commands/status.js +95 -29
  121. package/dist/commands/status.js.map +1 -1
  122. package/dist/commands/types.d.ts.map +1 -1
  123. package/dist/commands/types.js +3 -2
  124. package/dist/commands/types.js.map +1 -1
  125. package/dist/commands/update.d.ts.map +1 -1
  126. package/dist/commands/update.js +54 -21
  127. package/dist/commands/update.js.map +1 -1
  128. package/dist/config.d.ts +2 -1
  129. package/dist/config.d.ts.map +1 -1
  130. package/dist/config.js.map +1 -1
  131. package/dist/dev-compose.d.ts +26 -0
  132. package/dist/dev-compose.d.ts.map +1 -1
  133. package/dist/dev-compose.js +328 -34
  134. package/dist/dev-compose.js.map +1 -1
  135. package/dist/dev-log-bus.d.ts +30 -0
  136. package/dist/dev-log-bus.d.ts.map +1 -0
  137. package/dist/dev-log-bus.js +87 -0
  138. package/dist/dev-log-bus.js.map +1 -0
  139. package/dist/dev-log-filter.d.ts +10 -0
  140. package/dist/dev-log-filter.d.ts.map +1 -0
  141. package/dist/dev-log-filter.js +36 -0
  142. package/dist/dev-log-filter.js.map +1 -0
  143. package/dist/dev-logo.d.ts +12 -0
  144. package/dist/dev-logo.d.ts.map +1 -0
  145. package/dist/dev-logo.js +56 -0
  146. package/dist/dev-logo.js.map +1 -0
  147. package/dist/dev-session.d.ts +26 -0
  148. package/dist/dev-session.d.ts.map +1 -0
  149. package/dist/dev-session.js +106 -0
  150. package/dist/dev-session.js.map +1 -0
  151. package/dist/dev-shutdown.d.ts +9 -0
  152. package/dist/dev-shutdown.d.ts.map +1 -0
  153. package/dist/dev-shutdown.js +50 -0
  154. package/dist/dev-shutdown.js.map +1 -0
  155. package/dist/dev-task-colors.d.ts +13 -0
  156. package/dist/dev-task-colors.d.ts.map +1 -0
  157. package/dist/dev-task-colors.js +43 -0
  158. package/dist/dev-task-colors.js.map +1 -0
  159. package/dist/dev-tui.d.ts +24 -0
  160. package/dist/dev-tui.d.ts.map +1 -0
  161. package/dist/dev-tui.js +188 -0
  162. package/dist/dev-tui.js.map +1 -0
  163. package/dist/diff-output.d.ts +5 -1
  164. package/dist/diff-output.d.ts.map +1 -1
  165. package/dist/diff-output.js +69 -0
  166. package/dist/diff-output.js.map +1 -1
  167. package/dist/docker-runtime.d.ts +30 -0
  168. package/dist/docker-runtime.d.ts.map +1 -0
  169. package/dist/docker-runtime.js +118 -0
  170. package/dist/docker-runtime.js.map +1 -0
  171. package/dist/engine-client.d.ts +10 -1
  172. package/dist/engine-client.d.ts.map +1 -1
  173. package/dist/engine-client.js +76 -17
  174. package/dist/engine-client.js.map +1 -1
  175. package/dist/engine-push-output.d.ts +17 -0
  176. package/dist/engine-push-output.d.ts.map +1 -0
  177. package/dist/engine-push-output.js +64 -0
  178. package/dist/engine-push-output.js.map +1 -0
  179. package/dist/ensure-binary.js +2 -2
  180. package/dist/ensure-binary.js.map +1 -1
  181. package/dist/gitignore.d.ts +8 -0
  182. package/dist/gitignore.d.ts.map +1 -0
  183. package/dist/gitignore.js +41 -0
  184. package/dist/gitignore.js.map +1 -0
  185. package/dist/kong-config.d.ts +9 -0
  186. package/dist/kong-config.d.ts.map +1 -1
  187. package/dist/kong-config.js +18 -1
  188. package/dist/kong-config.js.map +1 -1
  189. package/dist/link.d.ts +66 -0
  190. package/dist/link.d.ts.map +1 -0
  191. package/dist/link.js +160 -0
  192. package/dist/link.js.map +1 -0
  193. package/dist/process-manager.d.ts +8 -0
  194. package/dist/process-manager.d.ts.map +1 -1
  195. package/dist/process-manager.js +53 -9
  196. package/dist/process-manager.js.map +1 -1
  197. package/dist/project-config.d.ts +30 -3
  198. package/dist/project-config.d.ts.map +1 -1
  199. package/dist/project-config.js +37 -4
  200. package/dist/project-config.js.map +1 -1
  201. package/dist/prompts.d.ts +3 -0
  202. package/dist/prompts.d.ts.map +1 -0
  203. package/dist/prompts.js +3 -0
  204. package/dist/prompts.js.map +1 -0
  205. package/dist/pull-utils.d.ts +50 -14
  206. package/dist/pull-utils.d.ts.map +1 -1
  207. package/dist/pull-utils.js +152 -12
  208. package/dist/pull-utils.js.map +1 -1
  209. package/dist/resolve-target.d.ts +86 -0
  210. package/dist/resolve-target.d.ts.map +1 -0
  211. package/dist/resolve-target.js +291 -0
  212. package/dist/resolve-target.js.map +1 -0
  213. package/dist/restore-system-relation-targets.d.ts +3 -0
  214. package/dist/restore-system-relation-targets.d.ts.map +1 -0
  215. package/dist/restore-system-relation-targets.js +45 -0
  216. package/dist/restore-system-relation-targets.js.map +1 -0
  217. package/dist/runtime-routes.d.ts.map +1 -1
  218. package/dist/runtime-routes.js +7 -0
  219. package/dist/runtime-routes.js.map +1 -1
  220. package/dist/schema-ast-v2.d.ts +1 -1
  221. package/dist/schema-ast-v2.d.ts.map +1 -1
  222. package/dist/schema-ast-v2.js +2 -2
  223. package/dist/schema-ast-v2.js.map +1 -1
  224. package/dist/schema-sources.d.ts +40 -0
  225. package/dist/schema-sources.d.ts.map +1 -0
  226. package/dist/schema-sources.js +183 -0
  227. package/dist/schema-sources.js.map +1 -0
  228. package/dist/scripts/postinstall.js +5 -1
  229. package/dist/scripts/postinstall.js.map +1 -1
  230. package/dist/self-host-compose.d.ts +37 -1
  231. package/dist/self-host-compose.d.ts.map +1 -1
  232. package/dist/self-host-compose.js +233 -43
  233. package/dist/self-host-compose.js.map +1 -1
  234. package/dist/storage-provision.d.ts +4 -0
  235. package/dist/storage-provision.d.ts.map +1 -1
  236. package/dist/storage-provision.js +24 -2
  237. package/dist/storage-provision.js.map +1 -1
  238. package/dist/supatype-eval-1781522769253.d.mts +2 -0
  239. package/dist/supatype-eval-1781522769253.d.mts.map +1 -0
  240. package/dist/supatype-eval-1781522769253.mjs +3 -0
  241. package/dist/supatype-eval-1781522769253.mjs.map +1 -0
  242. package/dist/systemd.js +2 -2
  243. package/dist/systemd.js.map +1 -1
  244. package/dist/target-client.d.ts +10 -0
  245. package/dist/target-client.d.ts.map +1 -0
  246. package/dist/target-client.js +22 -0
  247. package/dist/target-client.js.map +1 -0
  248. package/dist/type-extractor.d.ts +11 -0
  249. package/dist/type-extractor.d.ts.map +1 -1
  250. package/dist/type-extractor.js +95 -8
  251. package/dist/type-extractor.js.map +1 -1
  252. package/dist/ui/brand.d.ts +9 -0
  253. package/dist/ui/brand.d.ts.map +1 -0
  254. package/dist/ui/brand.js +11 -0
  255. package/dist/ui/brand.js.map +1 -0
  256. package/dist/ui/confirm.d.ts +12 -0
  257. package/dist/ui/confirm.d.ts.map +1 -0
  258. package/dist/ui/confirm.js +28 -0
  259. package/dist/ui/confirm.js.map +1 -0
  260. package/dist/ui/fatal.d.ts +10 -0
  261. package/dist/ui/fatal.d.ts.map +1 -0
  262. package/dist/ui/fatal.js +34 -0
  263. package/dist/ui/fatal.js.map +1 -0
  264. package/dist/ui/index.d.ts +9 -0
  265. package/dist/ui/index.d.ts.map +1 -0
  266. package/dist/ui/index.js +9 -0
  267. package/dist/ui/index.js.map +1 -0
  268. package/dist/ui/interactive.d.ts +3 -0
  269. package/dist/ui/interactive.d.ts.map +1 -0
  270. package/dist/ui/interactive.js +5 -0
  271. package/dist/ui/interactive.js.map +1 -0
  272. package/dist/ui/messages.d.ts +10 -0
  273. package/dist/ui/messages.d.ts.map +1 -0
  274. package/dist/ui/messages.js +35 -0
  275. package/dist/ui/messages.js.map +1 -0
  276. package/dist/ui/next-steps.d.ts +3 -0
  277. package/dist/ui/next-steps.d.ts.map +1 -0
  278. package/dist/ui/next-steps.js +10 -0
  279. package/dist/ui/next-steps.js.map +1 -0
  280. package/dist/ui/progress.d.ts +5 -0
  281. package/dist/ui/progress.d.ts.map +1 -0
  282. package/dist/ui/progress.js +24 -0
  283. package/dist/ui/progress.js.map +1 -0
  284. package/dist/ui/prompts.d.ts +14 -0
  285. package/dist/ui/prompts.d.ts.map +1 -0
  286. package/dist/ui/prompts.js +34 -0
  287. package/dist/ui/prompts.js.map +1 -0
  288. package/package.json +3 -2
  289. package/src/app/framework.ts +1 -3
  290. package/src/app/proxy-dev-app.ts +114 -6
  291. package/src/app-config.ts +80 -0
  292. package/src/binary-cache.ts +102 -52
  293. package/src/cli.ts +16 -2
  294. package/src/commands/add.ts +97 -0
  295. package/src/commands/admin.ts +39 -73
  296. package/src/commands/adopt.ts +82 -0
  297. package/src/commands/app.ts +20 -17
  298. package/src/commands/cache.ts +11 -10
  299. package/src/commands/cloud.ts +91 -142
  300. package/src/commands/db.ts +40 -63
  301. package/src/commands/deploy.ts +186 -126
  302. package/src/commands/dev.ts +95 -55
  303. package/src/commands/diff.ts +52 -43
  304. package/src/commands/doctor.ts +103 -0
  305. package/src/commands/engine.ts +5 -4
  306. package/src/commands/functions.ts +187 -123
  307. package/src/commands/generate.ts +5 -4
  308. package/src/commands/init.ts +996 -105
  309. package/src/commands/introspect.ts +48 -0
  310. package/src/commands/keys.ts +56 -14
  311. package/src/commands/link-helpers.ts +273 -0
  312. package/src/commands/logs.ts +5 -4
  313. package/src/commands/migrate-from-v1.ts +3 -2
  314. package/src/commands/migrate.ts +167 -27
  315. package/src/commands/pg.ts +13 -18
  316. package/src/commands/plugins.ts +55 -46
  317. package/src/commands/pull.ts +38 -9
  318. package/src/commands/push.ts +147 -174
  319. package/src/commands/seed.ts +5 -4
  320. package/src/commands/self-host.ts +85 -54
  321. package/src/commands/self-update.ts +3 -2
  322. package/src/commands/status.ts +102 -33
  323. package/src/commands/types.ts +3 -2
  324. package/src/commands/update.ts +59 -23
  325. package/src/config.ts +2 -1
  326. package/src/dev-compose.ts +426 -34
  327. package/src/dev-log-bus.ts +101 -0
  328. package/src/dev-log-filter.ts +32 -0
  329. package/src/dev-logo.ts +61 -0
  330. package/src/dev-session.ts +130 -0
  331. package/src/dev-shutdown.ts +54 -0
  332. package/src/dev-task-colors.ts +47 -0
  333. package/src/dev-tui.ts +232 -0
  334. package/src/diff-output.ts +79 -1
  335. package/src/docker-runtime.ts +151 -0
  336. package/src/engine-client.ts +81 -17
  337. package/src/engine-push-output.ts +75 -0
  338. package/src/ensure-binary.ts +2 -2
  339. package/src/gitignore.ts +48 -0
  340. package/src/kong-config.ts +24 -1
  341. package/src/link.ts +243 -0
  342. package/src/process-manager.ts +66 -10
  343. package/src/project-config.ts +62 -7
  344. package/src/prompts.ts +2 -0
  345. package/src/pull-utils.ts +217 -23
  346. package/src/resolve-target.ts +419 -0
  347. package/src/restore-system-relation-targets.ts +45 -0
  348. package/src/runtime-routes.ts +7 -0
  349. package/src/schema-ast-v2.ts +2 -1
  350. package/src/schema-sources.ts +248 -0
  351. package/src/scripts/postinstall.ts +7 -1
  352. package/src/self-host-compose.ts +261 -46
  353. package/src/storage-provision.ts +33 -1
  354. package/src/supatype-eval-1781522769253.mts +1 -0
  355. package/src/systemd.ts +2 -2
  356. package/src/target-client.ts +40 -0
  357. package/src/type-extractor.ts +124 -11
  358. package/src/ui/README.md +17 -0
  359. package/src/ui/brand.ts +12 -0
  360. package/src/ui/confirm.ts +38 -0
  361. package/src/ui/fatal.ts +43 -0
  362. package/src/ui/index.ts +8 -0
  363. package/src/ui/interactive.ts +4 -0
  364. package/src/ui/messages.ts +43 -0
  365. package/src/ui/next-steps.ts +10 -0
  366. package/src/ui/progress.ts +28 -0
  367. package/src/ui/prompts.ts +40 -0
  368. package/tests/cli-help.test.ts +27 -2
  369. package/tests/config.test.ts +29 -2
  370. package/tests/dev-ui.test.ts +139 -0
  371. package/tests/docker-runtime.test.ts +236 -0
  372. package/tests/engine-push-output.test.ts +67 -0
  373. package/tests/init.test.ts +197 -18
  374. package/tests/link.test.ts +148 -0
  375. package/tests/minisign.test.ts +102 -0
  376. package/tests/proxy-dev-app.test.ts +45 -1
  377. package/tests/pull-utils.test.ts +5 -4
  378. package/tests/runtime-contract.test.ts +186 -2
  379. package/tests/schema-sources.test.ts +119 -0
  380. package/tests/storage-provision.test.ts +100 -0
  381. package/tests/ui-confirm.test.ts +41 -0
  382. package/tests/ui-messages.test.ts +66 -0
  383. package/tsconfig.tsbuildinfo +1 -1
@@ -1,17 +1,34 @@
1
1
  import type { Command } from "commander"
2
2
  import { mkdirSync, writeFileSync } from "node:fs"
3
- import { createInterface } from "node:readline"
4
3
  import { join } from "node:path"
5
4
  import { loadConfig, loadSchemaAst } from "../config.js"
6
- import { connectionString, resolveRuntimeProvider, schemaPathFromProject, serverBaseUrl } from "../project-config.js"
7
- import { isCloudLinked, pushSchemaToLinkedProject } from "./cloud.js"
8
- import { ensureEngine, engineRequest, type DiffResult, type Operation } from "../engine-client.js"
9
- import { printDiffWarnings } from "../diff-output.js"
5
+ import { resolveRuntimeProvider, schemaPathFromProject, serverBaseUrl } from "../project-config.js"
6
+ import { ensureEngine, engineRequest, type DiffResult } from "../engine-client.js"
7
+ import { printDiffOperations, printDiffWarnings } from "../diff-output.js"
10
8
  import { signJwt } from "../jwt.js"
11
- import { provisionBuckets } from "../storage-provision.js"
9
+ import { provisionBucketsFromAst } from "../storage-provision.js"
10
+ import type { ExtractedSchemaAstV2 } from "../schema-ast-v2.js"
12
11
  import { promptFirstAdminUser } from "./admin.js"
13
12
  import { withAdminRoles } from "../studio-admin-roles.js"
13
+ import { restoreSystemRelationTargets } from "../restore-system-relation-targets.js"
14
14
  import type { SupatypeProjectConfig } from "../project-config.js"
15
+ import {
16
+ resolveTarget,
17
+ targetSchemaDiff,
18
+ targetSchemaPush,
19
+ schemaPgSchema,
20
+ type DeployTarget,
21
+ } from "../resolve-target.js"
22
+ import { loadProjectLink } from "../link.js"
23
+ import {
24
+ buildSchemaSourcesPayload,
25
+ cacheSchemaSourcesLocally,
26
+ resolvePushedBy,
27
+ } from "../schema-sources.js"
28
+ import { confirm, logSkippedConfirm } from "../ui/confirm.js"
29
+ import { info, plain } from "../ui/messages.js"
30
+ import { withSpinner } from "../ui/progress.js"
31
+ import { isInteractive } from "../ui/interactive.js"
15
32
 
16
33
  const DEV_JWT_SECRET = "super-secret-jwt-token-with-at-least-32-characters-long"
17
34
 
@@ -23,202 +40,158 @@ export function registerPush(program: Command): void {
23
40
  )
24
41
  .option("--yes", "Skip confirmation prompts for destructive changes")
25
42
  .option("--connection <url>", "Database connection URL (overrides config)")
26
- .action(async (opts: { yes?: boolean; connection?: string }) => {
43
+ .option("--env <name>", "Target environment when linked")
44
+ .option("--direct", "Use local engine subprocess (skip control plane)")
45
+ .option("--local", "Alias for --direct")
46
+ .action(async (opts: {
47
+ yes?: boolean
48
+ connection?: string
49
+ env?: string
50
+ direct?: boolean
51
+ local?: boolean
52
+ }) => {
27
53
  const cwd = process.cwd()
28
-
29
- if (isCloudLinked(cwd)) {
30
- if (opts.connection) {
31
- console.error("--connection is not allowed when linked to a cloud project (credentials stay server-side).")
32
- process.exit(1)
33
- }
34
- await pushSchemaToLinkedProject(cwd, { force: opts.yes ?? true })
35
- return
36
- }
37
-
38
54
  const config = loadConfig(cwd)
39
-
40
- // Docker provider: the compose Postgres isn't published to the host, so
41
- // apply the schema through the in-compose schema-engine (unless the user
42
- // gave an explicit --connection to a reachable database).
43
- if (!opts.connection && resolveRuntimeProvider(config) === "docker") {
44
- const { pushSchemaDocker } = await import("../dev-compose.js")
45
- await pushSchemaDocker(cwd, config)
46
- return
47
- }
48
-
49
- const connection = opts.connection ?? connectionString(config)
50
-
51
- await ensureEngine()
52
-
53
- console.log("Loading schema...")
55
+ const pgSchema = schemaPgSchema(cwd)
54
56
  const ast = loadSchemaAst(schemaPathFromProject(config, cwd), cwd)
55
57
 
56
- console.log("Diffing against database...")
57
- const diff = await engineRequest<DiffResult>("/diff", {
58
- ast,
59
- database_url: connection,
60
- schema: "public",
61
- })
62
-
63
- const ops = diff.operations ?? []
64
- printDiffWarnings(diff)
65
-
66
- if (ops.length === 0) {
67
- console.log(
68
- "Schema matches the database (no DDL). Syncing Studio metadata...",
69
- )
70
- } else {
71
- printDiff(ops)
72
-
73
- const risky = ops.filter(
74
- (o) => o.risk === "cautious" || o.risk === "destructive" || o.risk === "warn" || o.risk === "danger",
75
- )
76
- if (risky.length > 0 && !opts.yes) {
77
- const confirmed = await confirm(
78
- `\n${risky.length} risky operation(s) above (type changes or data loss). Proceed? [y/N] `,
79
- )
80
- if (!confirmed) {
81
- console.log("Aborted.")
82
- return
83
- }
84
- }
85
- }
86
-
87
- console.log(ops.length > 0 ? "\nApplying migration..." : "\nSyncing with engine...")
88
- const pushResult = await engineRequest<{
89
- message?: string
90
- status?: string
91
- admin_refreshed?: boolean
92
- }>("/push", {
93
- ast,
94
- database_url: connection,
95
- schema: "public",
96
- force: true,
97
- })
98
- if (pushResult.status === "up_to_date") {
99
- console.log(
100
- pushResult.admin_refreshed
101
- ? "Database schema unchanged — Studio metadata synced."
102
- : "Schema is up to date.",
103
- )
104
- } else {
105
- console.log(pushResult.message ?? "Migration applied.")
106
- }
107
-
108
- await writeLocalAdminConfig(ast, config)
58
+ const linked = loadProjectLink(cwd)
59
+ const useDirect = opts.direct || opts.local || Boolean(opts.connection)
109
60
 
110
- // After a DDL migration, check if this is the first push and offer to create an
111
- // admin user if none exist (Gap Appendices task 48).
112
- if (ops.length > 0) {
113
- await promptFirstAdminUser(connection)
61
+ if (linked && !useDirect && !opts.connection) {
62
+ const target = resolveTarget(cwd, { env: opts.env })
63
+ await pushViaTarget(cwd, config, target, ast, pgSchema, opts.yes ?? false)
64
+ return
114
65
  }
115
66
 
116
- // Provision storage buckets declared in the schema.
117
- const baseUrl = serverBaseUrl(config)
118
- const serviceRoleKey =
119
- process.env["SUPATYPE_SERVICE_ROLE_KEY"] ??
120
- (config.server.mode === "dev"
121
- ? signJwt({ role: "service_role", iss: "supatype", iat: Math.floor(Date.now() / 1000) }, DEV_JWT_SECRET)
122
- : undefined)
123
-
124
- if (baseUrl && serviceRoleKey) {
125
- const parsedAst = await engineRequest<{
126
- storageBuckets?: Array<{
127
- id: string
128
- public: boolean
129
- accessMode?: "public" | "private" | "custom"
130
- allowedMimeTypes?: string[]
131
- fileSizeLimit?: number
132
- s3BucketPolicy?: string
133
- }>
134
- }>("/parse", { ast })
135
- const buckets = (parsedAst.storageBuckets ?? []).map((b) => ({
136
- id: b.id,
137
- public: b.public,
138
- ...(b.accessMode !== undefined && { access_mode: b.accessMode }),
139
- ...(b.allowedMimeTypes != null && { allowed_mime_types: b.allowedMimeTypes }),
140
- ...(b.fileSizeLimit != null && { file_size_limit: b.fileSizeLimit }),
141
- ...(b.s3BucketPolicy != null &&
142
- b.s3BucketPolicy !== "" && { s3_bucket_policy: b.s3BucketPolicy }),
143
- }))
144
- if (buckets.length > 0) {
145
- console.log("Provisioning storage buckets...")
146
- await provisionBuckets(`${baseUrl}/storage/v1`, serviceRoleKey, buckets)
67
+ if (!opts.connection && !useDirect && resolveRuntimeProvider(config) === "docker") {
68
+ const localTarget = resolveTarget(cwd, { env: opts.env })
69
+ if (localTarget.mode === "local" && localTarget.token) {
70
+ await pushViaTarget(cwd, config, localTarget, ast, pgSchema, opts.yes ?? false)
71
+ return
147
72
  }
73
+ const { pushSchemaDocker } = await import("../dev-compose.js")
74
+ await withSpinner("Applying schema via Docker Compose", () => pushSchemaDocker(cwd, config))
75
+ return
148
76
  }
149
77
 
150
- if (config.output?.types ?? config.output?.client) {
151
- console.log("Generating types...")
152
- const genBody: Record<string, unknown> = { ast, lang: "typescript" }
153
- if (config.output?.types) genBody["types_path"] = config.output.types
154
- if (config.output?.client) genBody["client_path"] = config.output.client
155
-
156
- const genResult = await engineRequest<{ code?: string; message?: string }>("/generate", genBody)
157
- console.log(genResult.message ?? "Types generated.")
158
- }
159
-
160
- const studioBase = baseUrl?.replace(/\/$/, "") ?? ""
161
- if (studioBase) {
162
- console.log(`\nStudio: ${studioBase}/studio/ — sign in with the admin user you created.`)
163
- } else {
164
- console.log("\nDone.")
165
- }
78
+ const target = resolveTarget(cwd, {
79
+ env: opts.env,
80
+ direct: true,
81
+ connection: opts.connection,
82
+ })
83
+ await pushViaTarget(cwd, config, target, ast, pgSchema, opts.yes ?? false)
166
84
  })
167
85
  }
168
86
 
169
- function printDiff(ops: Operation[]): void {
170
- const symbol: Record<string, string> = {
171
- safe: "+",
172
- warn: "~",
173
- cautious: "~",
174
- danger: "!",
175
- destructive: "!",
176
- }
177
- console.log(`\n${ops.length} change(s) planned:\n`)
178
- for (const op of ops) {
179
- const riskKey = op.risk ?? "safe"
180
- const s = symbol[riskKey] ?? "?"
181
- const label = op.warning ?? op.description ?? formatOperation(op)
182
- console.log(` [${s}] ${label}`)
87
+ async function pushViaTarget(
88
+ cwd: string,
89
+ config: SupatypeProjectConfig,
90
+ target: DeployTarget,
91
+ ast: unknown,
92
+ pgSchema: string,
93
+ skipConfirm: boolean,
94
+ ): Promise<void> {
95
+ const diff = await withSpinner("Diffing against database", () =>
96
+ targetSchemaDiff(target, ast, { schema: pgSchema }),
97
+ )
98
+ const ops = diff.operations ?? []
99
+ printDiffWarnings(diff)
100
+
101
+ if (ops.length === 0) {
102
+ info("Schema matches the database (no DDL). Syncing Studio metadata...")
103
+ } else {
104
+ printDiffOperations({ operations: ops })
105
+ const risky = ops.filter(
106
+ (o) => o.risk === "cautious" || o.risk === "destructive" || o.risk === "warn" || o.risk === "danger",
107
+ )
108
+ if (risky.length > 0 && !skipConfirm) {
109
+ if (!isInteractive()) {
110
+ logSkippedConfirm(`${risky.length} risky operation(s) require confirmation`)
111
+ plain("Aborted.")
112
+ return
113
+ }
114
+ const confirmed = await confirm(
115
+ `${risky.length} risky operation(s) above. Proceed?`,
116
+ { default: false },
117
+ )
118
+ if (!confirmed) {
119
+ plain("Aborted.")
120
+ return
121
+ }
122
+ }
183
123
  }
184
- }
185
124
 
186
- function formatOperation(op: Operation): string {
187
- if (typeof op.description === "string" && op.description.trim().length > 0) {
188
- return op.description
125
+ const pushResult = await withSpinner(
126
+ ops.length > 0 ? "Applying migration" : "Syncing with engine",
127
+ () =>
128
+ targetSchemaPush(target, ast, {
129
+ force: true,
130
+ schema: pgSchema,
131
+ schemaSources: buildSchemaSourcesPayload(cwd, resolvePushedBy()),
132
+ }),
133
+ )
134
+
135
+ if ((pushResult as { status?: string }).status === "up_to_date") {
136
+ info("Schema is up to date.")
137
+ } else {
138
+ info((pushResult as { message?: string }).message ?? "Migration applied.")
139
+ const migrationName = (pushResult as { name?: string }).name
140
+ const schemaSources = buildSchemaSourcesPayload(cwd, resolvePushedBy())
141
+ if (migrationName && schemaSources) {
142
+ cacheSchemaSourcesLocally(cwd, migrationName, schemaSources.gz)
143
+ }
189
144
  }
190
145
 
191
- const kind = typeof op.kind === "string" ? op.kind : "operation"
192
- const raw = op as unknown as Record<string, unknown>
193
- const table = raw["table"]
194
- const column = raw["column"]
195
-
196
- if (typeof table === "string" && typeof column === "string") {
197
- return `${kind} ${table}.${column}`
146
+ if (target.mode === "direct" || target.mode === "local") {
147
+ await writeLocalAdminConfig(ast, config)
148
+ if (ops.length > 0 && target.databaseUrl) {
149
+ await promptFirstAdminUser(target.databaseUrl)
150
+ }
151
+ await generateTypesLocal(ast, config)
152
+ await provisionLocalStorage(ast, config)
153
+ } else {
154
+ info(`Pushed to ${target.mode} (${target.environment}).`)
198
155
  }
199
- if (typeof table === "string") {
200
- return `${kind} ${table}`
156
+
157
+ const baseUrl = (serverBaseUrl(config) ?? "").replace(/\/$/, "")
158
+ if (baseUrl) {
159
+ plain(`\nStudio: ${baseUrl}/studio/`)
201
160
  }
161
+ }
202
162
 
203
- // Last resort: show operation kind with compact payload.
204
- return `${kind} ${JSON.stringify(op)}`
163
+ async function generateTypesLocal(ast: unknown, config: SupatypeProjectConfig): Promise<void> {
164
+ if (!config.output?.types && !config.output?.client) return
165
+ await withSpinner("Generating types", async () => {
166
+ await ensureEngine()
167
+ const genBody: Record<string, unknown> = { ast, lang: "typescript" }
168
+ if (config.output?.types) genBody["types_path"] = config.output.types
169
+ if (config.output?.client) genBody["client_path"] = config.output.client
170
+ const genResult = await engineRequest<{ message?: string }>("/generate", genBody)
171
+ return genResult.message ?? "Types generated."
172
+ }).then((msg) => info(msg))
205
173
  }
206
174
 
207
- async function confirm(prompt: string): Promise<boolean> {
208
- const rl = createInterface({ input: process.stdin, output: process.stdout })
209
- return new Promise((resolve) => {
210
- rl.question(prompt, (answer) => {
211
- rl.close()
212
- resolve(answer.toLowerCase() === "y")
213
- })
214
- })
175
+ async function provisionLocalStorage(ast: unknown, config: SupatypeProjectConfig): Promise<void> {
176
+ const baseUrl = serverBaseUrl(config)
177
+ const serviceRoleKey =
178
+ process.env["SUPATYPE_SERVICE_ROLE_KEY"] ??
179
+ process.env["SERVICE_ROLE_KEY"] ??
180
+ (config.server.mode === "dev"
181
+ ? signJwt({ role: "service_role", iss: "supatype", iat: Math.floor(Date.now() / 1000) }, DEV_JWT_SECRET)
182
+ : undefined)
183
+ if (!baseUrl || !serviceRoleKey) return
184
+ await ensureEngine()
185
+ const parsedAst = await engineRequest<Pick<ExtractedSchemaAstV2, "storageBuckets">>("/parse", { ast })
186
+ await provisionBucketsFromAst(parsedAst, `${baseUrl}/storage/v1`, serviceRoleKey)
215
187
  }
216
188
 
217
- /** Write `.supatype/admin-config.json` for local Studio (same layout as `supatype dev`). */
218
189
  async function writeLocalAdminConfig(ast: unknown, config: SupatypeProjectConfig): Promise<void> {
219
190
  const cwd = process.cwd()
220
191
  const dir = join(cwd, ".supatype")
221
192
  mkdirSync(dir, { recursive: true })
193
+ await ensureEngine()
222
194
  const admin = withAdminRoles(await engineRequest<unknown>("/admin", { ast }), config)
195
+ restoreSystemRelationTargets(admin, ast)
223
196
  writeFileSync(join(dir, "admin-config.json"), `${JSON.stringify(admin, null, 2)}\n`)
224
197
  }
@@ -5,6 +5,7 @@ import { isLinkedToCloudProject } from "../binary-cache.js"
5
5
  import { loadConfig } from "../config.js"
6
6
  import { projectRootFromConfig } from "../project-config.js"
7
7
  import { runTsFile } from "../tsx-runner.js"
8
+ import { error, info } from "../ui/messages.js"
8
9
 
9
10
  const SEED_EXT = /\.(ts|mts|tsx)$/
10
11
 
@@ -31,8 +32,8 @@ export function registerSeed(program: Command): void {
31
32
  const cwd = process.cwd()
32
33
  const config = loadConfig(cwd)
33
34
  if (isLinkedToCloudProject(cwd, config) && !opts.force) {
34
- console.error(
35
- "[supatype] This project is linked to Supatype Cloud. Refusing to run seeds locally.\n" +
35
+ error(
36
+ "This project is linked to Supatype Cloud. Refusing to run seeds locally.\n" +
36
37
  " Pass --force only if you intend to target this linked project (advanced).",
37
38
  )
38
39
  process.exit(1)
@@ -53,12 +54,12 @@ export function registerSeed(program: Command): void {
53
54
 
54
55
  const missing = paths.filter((p) => !existsSync(p))
55
56
  if (missing.length > 0) {
56
- console.error(`Seed file(s) not found:\n ${missing.join("\n ")}`)
57
+ error(`Seed file(s) not found:\n ${missing.join("\n ")}`)
57
58
  process.exit(1)
58
59
  }
59
60
 
60
61
  for (const seedFile of paths) {
61
- console.log(`[supatype] Running ${seedFile}...`)
62
+ info(`Running ${seedFile}...`)
62
63
  const result = runTsFile(seedFile, { cwd, stdio: "inherit" })
63
64
  if (result.exitCode !== 0) {
64
65
  process.exit(result.exitCode)