@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
@@ -0,0 +1,82 @@
1
+ import type { Command } from "commander"
2
+ import { loadConfig, loadSchemaAst } from "../config.js"
3
+ import { schemaPathFromProject } from "../project-config.js"
4
+ import { loadProjectLink } from "../link.js"
5
+ import { resolveTarget, targetSchemaAdopt, schemaPgSchema } from "../resolve-target.js"
6
+ import { confirm } from "../ui/confirm.js"
7
+ import { info, plain } from "../ui/messages.js"
8
+ import { withSpinner } from "../ui/progress.js"
9
+
10
+ interface AdoptPreview {
11
+ status: string
12
+ stampStatements?: string[]
13
+ doctor?: {
14
+ missing: unknown[]
15
+ staleManaged: unknown[]
16
+ unmanagedDrift: unknown[]
17
+ }
18
+ }
19
+
20
+ export function registerAdopt(program: Command): void {
21
+ program
22
+ .command("adopt")
23
+ .description("Stamp Supatype-managed comments on DB objects matching the schema (adoption ceremony)")
24
+ .option("--connection <url>", "Database connection URL (overrides config)")
25
+ .option("--env <name>", "Target environment when linked")
26
+ .option("--direct", "Use local engine subprocess")
27
+ .option("--yes", "Apply stamps without interactive confirmation")
28
+ .option("--no-cache", "Force full database introspection")
29
+ .action(async (opts: {
30
+ connection?: string
31
+ env?: string
32
+ direct?: boolean
33
+ yes?: boolean
34
+ noCache?: boolean
35
+ }) => {
36
+ const cwd = process.cwd()
37
+ const config = loadConfig(cwd)
38
+ const pgSchema = schemaPgSchema(cwd)
39
+
40
+ const ast = await withSpinner("Loading schema", async () =>
41
+ loadSchemaAst(schemaPathFromProject(config, cwd), cwd),
42
+ )
43
+
44
+ const linked = loadProjectLink(cwd)
45
+ const target = linked && !opts.direct && !opts.connection
46
+ ? resolveTarget(cwd, { env: opts.env })
47
+ : resolveTarget(cwd, { env: opts.env, direct: true, connection: opts.connection })
48
+
49
+ const preview = (await targetSchemaAdopt(target, ast, {
50
+ schema: pgSchema,
51
+ noCache: opts.noCache ?? false,
52
+ yes: false,
53
+ })) as AdoptPreview
54
+
55
+ const statements = preview.stampStatements ?? []
56
+ if (statements.length === 0) {
57
+ info("Nothing to stamp — matching objects are already managed or absent.")
58
+ return
59
+ }
60
+
61
+ plain(`\nWill stamp ${statements.length} object(s):\n`)
62
+ for (const sql of statements) {
63
+ plain(` ${sql}`)
64
+ }
65
+
66
+ if (!opts.yes) {
67
+ const ok = await confirm("Apply adoption stamps?", { default: false })
68
+ if (!ok) {
69
+ plain("Adoption cancelled.")
70
+ return
71
+ }
72
+ }
73
+
74
+ const result = (await targetSchemaAdopt(target, ast, {
75
+ schema: pgSchema,
76
+ noCache: opts.noCache ?? false,
77
+ yes: true,
78
+ })) as { status: string; stamped?: number; name?: string }
79
+
80
+ info(`Adopted: ${result.stamped ?? 0} object(s) stamped (${result.name ?? "ok"}).`)
81
+ })
82
+ }
@@ -3,6 +3,8 @@ import { existsSync, mkdirSync } from "node:fs"
3
3
  import { resolve } from "node:path"
4
4
  import { localKongBaseUrl } from "../local-gateway.js"
5
5
  import { updateAppConfigInProject } from "../app-config.js"
6
+ import { error, file, info, warn } from "../ui/messages.js"
7
+ import { nextSteps } from "../ui/next-steps.js"
6
8
 
7
9
  export function registerApp(program: Command): void {
8
10
  const appCmd = program
@@ -14,7 +16,7 @@ export function registerApp(program: Command): void {
14
16
  .description("Configure app routing: --static for a built site, or proxy to a dev server")
15
17
  .option("--static", "Serve a static directory at / (default: ./public, or [dir] argument)")
16
18
  .option("--port <port>", "Port your app listens on (proxy mode)", "3000")
17
- .option("--upstream <url>", "Explicit upstream URL (proxy mode; defaults to localhost:<port>)")
19
+ .option("--upstream <url>", "URL of your running dev server (proxy mode; defaults to localhost:<port>)")
18
20
  .option("--dockerfile <path>", "(deprecated) ignored — use supatype.config.ts")
19
21
  .action(
20
22
  (
@@ -31,7 +33,7 @@ export function registerApp(program: Command): void {
31
33
  return
32
34
  }
33
35
  if (opts.dockerfile) {
34
- console.warn("[supatype] --dockerfile is deprecated and ignored.")
36
+ warn("--dockerfile is deprecated and ignored.")
35
37
  }
36
38
  addProxyApp(process.cwd(), opts.port, opts.upstream)
37
39
  },
@@ -56,18 +58,19 @@ function addStaticApp(cwd: string, staticDir: string): void {
56
58
  const abs = resolve(cwd, staticDir)
57
59
  if (!existsSync(abs)) {
58
60
  mkdirSync(abs, { recursive: true })
59
- console.log(` created ${staticDir}/`)
61
+ file("created", `${staticDir}/`)
60
62
  }
61
63
  try {
62
64
  const configPath = updateAppConfigInProject(cwd, { mode: "static", staticDir })
63
- console.log(` updated ${configPath}`)
64
- console.log(`\nStatic app directory: ${staticDir}`)
65
- console.log(`Build your frontend into ${staticDir}/, then:`)
66
- console.log(` supatype self-host compose render`)
67
- console.log(` supatype self-host compose up -d`)
68
- console.log(`\nYour app will be served at ${localKongBaseUrl()}/\n`)
65
+ file("updated", configPath)
66
+ info(`Static app directory: ${staticDir}`)
67
+ nextSteps("Build your frontend, then:", [
68
+ "supatype self-host compose render",
69
+ "supatype self-host compose up -d",
70
+ `App URL: ${localKongBaseUrl()}/`,
71
+ ])
69
72
  } catch (err) {
70
- console.error((err as Error).message)
73
+ error((err as Error).message)
71
74
  process.exit(1)
72
75
  }
73
76
  }
@@ -76,11 +79,11 @@ function addProxyApp(cwd: string, port: string, upstream?: string): void {
76
79
  const upstreamUrl = upstream?.trim() || `http://localhost:${port}`
77
80
  try {
78
81
  const configPath = updateAppConfigInProject(cwd, { mode: "proxy", upstream: upstreamUrl })
79
- console.log(` updated ${configPath}`)
80
- console.log(`\nApp upstream set to ${upstreamUrl}. The app will be available at ${localKongBaseUrl()}/\n`)
81
- console.log("Run: supatype self-host compose render")
82
+ file("updated", configPath)
83
+ info(`Forwarding to ${upstreamUrl} app at ${localKongBaseUrl()}/`)
84
+ nextSteps("Next:", ["supatype self-host compose render"])
82
85
  } catch (err) {
83
- console.error((err as Error).message)
86
+ error((err as Error).message)
84
87
  process.exit(1)
85
88
  }
86
89
  }
@@ -88,10 +91,10 @@ function addProxyApp(cwd: string, port: string, upstream?: string): void {
88
91
  function removeApp(cwd: string): void {
89
92
  try {
90
93
  const configPath = updateAppConfigInProject(cwd, { mode: "none" })
91
- console.log(` updated ${configPath}`)
92
- console.log("\nApp routing disabled (app.mode=none).\n")
94
+ file("updated", configPath)
95
+ info("App routing disabled (app.mode=none).")
93
96
  } catch (err) {
94
- console.error((err as Error).message)
97
+ error((err as Error).message)
95
98
  process.exit(1)
96
99
  }
97
100
  }
@@ -6,6 +6,7 @@ import type { Command } from "commander"
6
6
  import { existsSync, readdirSync, rmSync, statSync } from "node:fs"
7
7
  import { join } from "node:path"
8
8
  import { cacheRoot, type Component } from "../binary-cache.js"
9
+ import { info, plain } from "../ui/messages.js"
9
10
 
10
11
  const COMPONENTS: Component[] = ["engine", "server", "postgres", "deno"]
11
12
 
@@ -20,7 +21,7 @@ export function registerCache(program: Command): void {
20
21
  .action(() => {
21
22
  const root = cacheRoot()
22
23
  if (!existsSync(root)) {
23
- console.log("Cache is empty.")
24
+ info("Cache is empty.")
24
25
  return
25
26
  }
26
27
 
@@ -39,17 +40,17 @@ export function registerCache(program: Command): void {
39
40
  const size = dirSize(vDir)
40
41
  totalBytes += size
41
42
  found = true
42
- console.log(` ${component}@${version} ${formatBytes(size)}`)
43
+ plain(` ${component}@${version} ${formatBytes(size)}`)
43
44
  }
44
45
  }
45
46
 
46
47
  if (!found) {
47
- console.log("Cache is empty.")
48
+ info("Cache is empty.")
48
49
  return
49
50
  }
50
51
 
51
- console.log(`\nTotal: ${formatBytes(totalBytes)}`)
52
- console.log(`Cache root: ${root}`)
52
+ plain(`\nTotal: ${formatBytes(totalBytes)}`)
53
+ info(`Cache root: ${root}`)
53
54
  })
54
55
 
55
56
  cache
@@ -64,7 +65,7 @@ export function registerCache(program: Command): void {
64
65
  .action((component?: string, version?: string) => {
65
66
  const root = cacheRoot()
66
67
  if (!existsSync(root)) {
67
- console.log("Cache is already empty.")
68
+ info("Cache is already empty.")
68
69
  return
69
70
  }
70
71
 
@@ -77,18 +78,18 @@ export function registerCache(program: Command): void {
77
78
  if (version) {
78
79
  const vDir = join(compDir, version)
79
80
  if (!existsSync(vDir)) {
80
- console.log(` ${comp}@${version} not cached.`)
81
+ info(`${comp}@${version} not cached.`)
81
82
  continue
82
83
  }
83
84
  rmSync(vDir, { recursive: true, force: true })
84
- console.log(` removed ${comp}@${version}`)
85
+ plain(` removed ${comp}@${version}`)
85
86
  } else {
86
87
  rmSync(compDir, { recursive: true, force: true })
87
- console.log(` removed ${comp} (all versions)`)
88
+ plain(` removed ${comp} (all versions)`)
88
89
  }
89
90
  }
90
91
 
91
- console.log("Done.")
92
+ info("Done.")
92
93
  })
93
94
  }
94
95
 
@@ -1,20 +1,37 @@
1
1
  import type { Command } from "commander"
2
2
  import { readFileSync, writeFileSync, existsSync } from "node:fs"
3
3
  import { resolve } from "node:path"
4
- import { createInterface } from "node:readline"
4
+ import { loadProjectLink, migrateLegacyLinkFiles } from "../link.js"
5
+ import { targetFetch } from "../target-client.js"
6
+ import { registerEnvs, registerLinkOptions, runLinkAction } from "./link-helpers.js"
7
+ import { resolveTarget, targetSchemaPush, schemaPgSchema } from "../resolve-target.js"
8
+ import { loadConfig, loadSchemaAst } from "../config.js"
9
+ import { schemaPathFromProject } from "../project-config.js"
10
+ import { error, info, plain } from "../ui/messages.js"
11
+ import { nextSteps } from "../ui/next-steps.js"
5
12
 
6
13
  interface CloudConfig {
7
14
  apiUrl: string
8
15
  token: string
9
16
  projectSlug?: string
10
- /** Organisation UUID — required for schema routes (`X-Org-Id`). */
11
- orgId?: string
17
+ orgId?: string | undefined
12
18
  }
13
19
 
20
+ /** @deprecated Prefer loadProjectLink */
14
21
  export function loadCloudConfig(cwd: string): CloudConfig | null {
15
- const configPath = resolve(cwd, ".supatype/cloud.json")
16
- if (!existsSync(configPath)) return null
17
- return JSON.parse(readFileSync(configPath, "utf8")) as CloudConfig
22
+ migrateLegacyLinkFiles(cwd)
23
+ const link = loadProjectLink(cwd)
24
+ if (!link || link.kind !== "cloud") return null
25
+ const legacyPath = resolve(cwd, ".supatype/cloud.json")
26
+ if (existsSync(legacyPath)) {
27
+ return JSON.parse(readFileSync(legacyPath, "utf8")) as CloudConfig
28
+ }
29
+ return {
30
+ apiUrl: link.cloudApiUrl ?? "https://api.supatype.com",
31
+ token: link.token ?? "",
32
+ projectSlug: link.projectRef,
33
+ ...(link.orgId !== undefined ? { orgId: link.orgId } : {}),
34
+ }
18
35
  }
19
36
 
20
37
  function saveCloudConfig(cwd: string, config: CloudConfig): void {
@@ -27,135 +44,66 @@ function saveCloudConfig(cwd: string, config: CloudConfig): void {
27
44
  }
28
45
 
29
46
  async function cloudFetch<T>(config: CloudConfig, method: string, path: string, body?: unknown): Promise<T> {
30
- const headers: Record<string, string> = {
31
- "Content-Type": "application/json",
32
- Authorization: `Bearer ${config.token}`,
33
- }
34
- if (config.orgId) {
35
- headers["X-Org-Id"] = config.orgId
36
- }
37
- const res = await fetch(`${config.apiUrl}/api/v1${path}`, {
47
+ return targetFetch<T>(config.apiUrl, "/api/v1", {
38
48
  method,
39
- headers,
40
- ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
49
+ path,
50
+ body,
51
+ token: config.token,
52
+ orgId: config.orgId,
41
53
  })
42
-
43
- const json = await res.json() as { data?: T; error?: string; message?: string }
44
- if (!res.ok) {
45
- throw new Error(json.message ?? json.error ?? `API error: ${res.status}`)
46
- }
47
- return json.data as T
48
54
  }
49
55
 
50
- /** True when `.supatype/cloud.json` exists with a linked project slug. */
51
56
  export function isCloudLinked(cwd: string): boolean {
52
- const cfg = loadCloudConfig(cwd)
53
- return Boolean(cfg?.projectSlug && cfg.token)
57
+ migrateLegacyLinkFiles(cwd)
58
+ const link = loadProjectLink(cwd)
59
+ return Boolean(link?.kind === "cloud" && link.projectRef && link.token)
54
60
  }
55
61
 
56
- /**
57
- * Push schema AST to the linked cloud project (`POST /api/v1/projects/:ref/schema/push`).
58
- * Credentials stay server-side; only AST is sent.
59
- */
60
- export async function pushSchemaToLinkedProject(cwd: string, opts?: { force?: boolean }): Promise<void> {
61
- const config = loadCloudConfig(cwd)
62
- if (!config?.projectSlug) {
63
- console.error("Not linked to a cloud project. Run: supatype link")
62
+ export async function pushSchemaToLinkedProject(
63
+ cwd: string,
64
+ opts?: { force?: boolean; env?: string },
65
+ ): Promise<void> {
66
+ const config = loadConfig(cwd)
67
+ const target = resolveTarget(cwd, { env: opts?.env })
68
+ if (target.mode !== "cloud") {
69
+ error("Not linked to a cloud project. Run: supatype link --project <slug>")
64
70
  process.exit(1)
65
71
  }
66
- if (!config.orgId) {
67
- console.error(
68
- "Missing orgId in .supatype/cloud.json. Re-run: supatype link --project <slug> (after cloud login).",
69
- )
70
- process.exit(1)
71
- }
72
-
73
- const { loadConfig: loadAppConfig, loadSchemaAst } = await import("../config.js")
74
- const { schemaPathFromProject } = await import("../project-config.js")
75
-
76
- const appConfig = loadAppConfig(cwd)
77
- const ast = loadSchemaAst(schemaPathFromProject(appConfig, cwd), cwd)
78
72
 
79
- console.log(`Pushing schema to cloud project ${config.projectSlug}...`)
73
+ const ast = loadSchemaAst(schemaPathFromProject(config, cwd), cwd)
74
+ info(`Pushing schema to ${target.mode} project ${target.projectRef} (${target.environment})...`)
80
75
 
81
- const result = await cloudFetch<{ message?: string }>(config, "POST", `/projects/${config.projectSlug}/schema/push`, {
82
- ast,
76
+ const result = await targetSchemaPush(target, ast, {
83
77
  force: opts?.force ?? true,
78
+ schema: schemaPgSchema(cwd),
84
79
  })
85
80
 
86
- console.log(result.message ?? "Schema push completed.")
81
+ info((result as { message?: string }).message ?? "Schema push completed.")
87
82
  }
88
83
 
89
- /** @deprecated Use pushSchemaToLinkedProject kept for deploy command alias */
90
- export async function deploySchemaToLinkedProject(cwd: string, _environment: string): Promise<void> {
91
- await pushSchemaToLinkedProject(cwd)
84
+ export async function deploySchemaToLinkedProject(cwd: string, environment: string): Promise<void> {
85
+ await pushSchemaToLinkedProject(cwd, { force: true, env: environment })
92
86
  }
93
87
 
94
- function prompt(question: string): Promise<string> {
95
- const rl = createInterface({ input: process.stdin, output: process.stdout })
96
- return new Promise((resolve) => {
97
- rl.question(question, (answer) => {
98
- rl.close()
99
- resolve(answer.trim())
100
- })
101
- })
102
- }
103
-
104
- // ─── Registration ──────────────────────────────────────────────────────────────
105
-
106
88
  export function registerCloud(program: Command): void {
107
- // ── Link ───────────────────────────────────────────────────────────────────
108
- program
109
- .command("link")
110
- .description("Link this local project to a Supatype cloud project")
111
- .option("--project <slug>", "Project slug to link to")
112
- .option("--api-url <url>", "Control plane API URL", "https://api.supatype.com")
113
- .option("--token <token>", "Authentication token")
114
- .action(async (opts: { project?: string; apiUrl: string; token?: string }) => {
115
- const cwd = process.cwd()
116
- const token = opts.token ?? process.env["SUPATYPE_TOKEN"]
117
- if (!token) {
118
- console.error("Authentication required. Set SUPATYPE_TOKEN or pass --token.")
119
- process.exit(1)
120
- }
121
-
122
- const config: CloudConfig = { apiUrl: opts.apiUrl, token }
89
+ registerEnvs(program)
123
90
 
124
- if (opts.project) {
125
- config.projectSlug = opts.project
126
- const one = await cloudFetch<{ slug: string; orgId: string }>(config, "GET", `/projects/${opts.project}`)
127
- config.orgId = one.orgId
128
- } else {
129
- const projects = await cloudFetch<Array<{ slug: string; name: string; status: string; tier: string; orgId: string }>>(
130
- config, "GET", "/projects",
131
- )
132
- if (projects.length === 0) {
133
- console.error("No projects found. Create one with: supatype projects create <name>")
134
- process.exit(1)
135
- }
136
-
137
- console.log("\nAvailable projects:\n")
138
- projects.forEach((p, i) => {
139
- console.log(` ${i + 1}. ${p.name} (${p.slug}) [${p.tier}] — ${p.status}`)
140
- })
141
-
142
- const answer = await prompt(`\nSelect project (1-${projects.length}): `)
143
- const idx = parseInt(answer, 10) - 1
144
- if (isNaN(idx) || idx < 0 || idx >= projects.length) {
145
- console.error("Invalid selection.")
146
- process.exit(1)
147
- }
148
- const picked = projects[idx]!
149
- config.projectSlug = picked.slug
150
- config.orgId = picked.orgId
151
- }
152
-
153
- saveCloudConfig(cwd, config)
154
- console.log(`\nLinked to project: ${config.projectSlug}`)
155
- console.log(`Config saved to .supatype/cloud.json\n`)
156
- })
91
+ const linkCmd = program
92
+ .command("link")
93
+ .description("Link this project to cloud or self-host (unified .supatype/link.json)")
94
+ registerLinkOptions(linkCmd)
95
+ linkCmd.action(async (opts: {
96
+ project?: string
97
+ url?: string
98
+ apiUrl: string
99
+ token?: string
100
+ serviceRoleKey?: string
101
+ env?: string
102
+ fixGitignore?: boolean
103
+ }) => {
104
+ await runLinkAction(opts)
105
+ })
157
106
 
158
- // ── Projects ───────────────────────────────────────────────────────────────
159
107
  const projectsCmd = program
160
108
  .command("projects")
161
109
  .description("Manage cloud projects")
@@ -171,18 +119,18 @@ export function registerCloud(program: Command): void {
171
119
  }>>(config, "GET", "/projects")
172
120
 
173
121
  if (projects.length === 0) {
174
- console.log("No projects. Create one with: supatype projects create <name>")
122
+ info("No projects. Create one with: supatype projects create <name>")
175
123
  return
176
124
  }
177
125
 
178
- console.log("\n Name Slug Tier Region Status")
179
- console.log(" " + "─".repeat(80))
126
+ plain("\n Name Slug Tier Region Status")
127
+ plain(" " + "─".repeat(80))
180
128
  for (const p of projects) {
181
- console.log(
129
+ plain(
182
130
  ` ${p.name.padEnd(24)}${p.slug.padEnd(25)}${p.tier.padEnd(8)}${p.region.padEnd(10)}${p.status}`,
183
131
  )
184
132
  }
185
- console.log()
133
+ plain()
186
134
  })
187
135
 
188
136
  projectsCmd
@@ -193,16 +141,16 @@ export function registerCloud(program: Command): void {
193
141
  .action(async (name: string, opts: { tier: string; region: string }) => {
194
142
  const config = getCloudConfigOrExit()
195
143
 
196
- console.log(`Creating project "${name}" (${opts.tier}, ${opts.region})...`)
144
+ info(`Creating project "${name}" (${opts.tier}, ${opts.region})...`)
197
145
 
198
146
  const project = await cloudFetch<{ slug: string; name: string; status: string }>(
199
147
  config, "POST", "/projects",
200
148
  { name, tier: opts.tier, region: opts.region },
201
149
  )
202
150
 
203
- console.log(`\nProject created: ${project.name} (${project.slug})`)
204
- console.log(`Status: ${project.status}`)
205
- console.log(`\nTo link this project: supatype link --project ${project.slug}\n`)
151
+ info(`Project created: ${project.name} (${project.slug})`)
152
+ info(`Status: ${project.status}`)
153
+ nextSteps("To link this project:", [`supatype link --project ${project.slug}`])
206
154
  })
207
155
 
208
156
  projectsCmd
@@ -211,7 +159,7 @@ export function registerCloud(program: Command): void {
211
159
  .action(async (slug: string) => {
212
160
  const config = getCloudConfigOrExit()
213
161
  await cloudFetch(config, "POST", `/projects/${slug}/pause`)
214
- console.log(`Project ${slug} paused.`)
162
+ info(`Project ${slug} paused.`)
215
163
  })
216
164
 
217
165
  projectsCmd
@@ -220,10 +168,9 @@ export function registerCloud(program: Command): void {
220
168
  .action(async (slug: string) => {
221
169
  const config = getCloudConfigOrExit()
222
170
  await cloudFetch(config, "POST", `/projects/${slug}/resume`)
223
- console.log(`Project ${slug} resumed.`)
171
+ info(`Project ${slug} resumed.`)
224
172
  })
225
173
 
226
- // ── Domains ────────────────────────────────────────────────────────────────
227
174
  const domainsCmd = program
228
175
  .command("domains")
229
176
  .description("Manage custom domains for a project")
@@ -234,7 +181,7 @@ export function registerCloud(program: Command): void {
234
181
  .action(async () => {
235
182
  const config = getCloudConfigOrExit()
236
183
  if (!config.projectSlug) {
237
- console.error("Not linked to a project. Run: supatype link")
184
+ error("Not linked to a project. Run: supatype link")
238
185
  process.exit(1)
239
186
  }
240
187
 
@@ -243,18 +190,18 @@ export function registerCloud(program: Command): void {
243
190
  }>>(config, "GET", `/projects/${config.projectSlug}/domains`)
244
191
 
245
192
  if (domains.length === 0) {
246
- console.log("No custom domains configured.")
193
+ info("No custom domains configured.")
247
194
  return
248
195
  }
249
196
 
250
- console.log("\n Domain Status CNAME Target")
251
- console.log(" " + "─".repeat(80))
197
+ plain("\n Domain Status CNAME Target")
198
+ plain(" " + "─".repeat(80))
252
199
  for (const d of domains) {
253
- console.log(
200
+ plain(
254
201
  ` ${d.domain.padEnd(34)}${d.status.padEnd(21)}${d.cnameTarget}`,
255
202
  )
256
203
  }
257
- console.log()
204
+ plain()
258
205
  })
259
206
 
260
207
  domainsCmd
@@ -263,7 +210,7 @@ export function registerCloud(program: Command): void {
263
210
  .action(async (domain: string) => {
264
211
  const config = getCloudConfigOrExit()
265
212
  if (!config.projectSlug) {
266
- console.error("Not linked to a project. Run: supatype link")
213
+ error("Not linked to a project. Run: supatype link")
267
214
  process.exit(1)
268
215
  }
269
216
 
@@ -272,9 +219,9 @@ export function registerCloud(program: Command): void {
272
219
  { domain },
273
220
  )
274
221
 
275
- console.log(`\nDomain added: ${result.domain}`)
276
- console.log(`\n${result.instructions}`)
277
- console.log(`\nAfter adding the CNAME record, verify with: supatype domains verify ${domain}\n`)
222
+ info(`Domain added: ${result.domain}`)
223
+ plain(`\n${result.instructions}`)
224
+ info(`After adding the CNAME record, verify with: supatype domains verify ${domain}`)
278
225
  })
279
226
 
280
227
  domainsCmd
@@ -283,12 +230,12 @@ export function registerCloud(program: Command): void {
283
230
  .action(async (domainId: string) => {
284
231
  const config = getCloudConfigOrExit()
285
232
  if (!config.projectSlug) {
286
- console.error("Not linked to a project. Run: supatype link")
233
+ error("Not linked to a project. Run: supatype link")
287
234
  process.exit(1)
288
235
  }
289
236
 
290
237
  await cloudFetch(config, "DELETE", `/projects/${config.projectSlug}/domains/${domainId}`)
291
- console.log("Domain removed.")
238
+ info("Domain removed.")
292
239
  })
293
240
 
294
241
  domainsCmd
@@ -297,7 +244,7 @@ export function registerCloud(program: Command): void {
297
244
  .action(async (domainId: string) => {
298
245
  const config = getCloudConfigOrExit()
299
246
  if (!config.projectSlug) {
300
- console.error("Not linked to a project. Run: supatype link")
247
+ error("Not linked to a project. Run: supatype link")
301
248
  process.exit(1)
302
249
  }
303
250
 
@@ -305,7 +252,7 @@ export function registerCloud(program: Command): void {
305
252
  config, "POST", `/projects/${config.projectSlug}/domains/${domainId}/verify`,
306
253
  )
307
254
 
308
- console.log(`Domain ${result.domain}: ${result.status}`)
255
+ info(`Domain ${result.domain}: ${result.status}`)
309
256
  })
310
257
  }
311
258
 
@@ -313,10 +260,12 @@ function getCloudConfigOrExit(): CloudConfig {
313
260
  const cwd = process.cwd()
314
261
  let config = loadCloudConfig(cwd)
315
262
  if (!config) {
316
- const token = process.env["SUPATYPE_TOKEN"]
263
+ const token =
264
+ process.env["SUPATYPE_ACCESS_TOKEN"] ??
265
+ process.env["SUPATYPE_TOKEN"]
317
266
  const apiUrl = process.env["SUPATYPE_API_URL"] ?? "https://api.supatype.com"
318
267
  if (!token) {
319
- console.error("Not connected to Supatype Cloud. Run: supatype link, or set SUPATYPE_TOKEN.")
268
+ error("Not connected to Supatype Cloud. Run: supatype link, or set SUPATYPE_ACCESS_TOKEN.")
320
269
  process.exit(1)
321
270
  }
322
271
  config = { apiUrl, token }