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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +208 -1
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/dist/app/proxy-dev-app.d.ts +13 -0
  5. package/dist/app/proxy-dev-app.d.ts.map +1 -0
  6. package/dist/app/proxy-dev-app.js +53 -0
  7. package/dist/app/proxy-dev-app.js.map +1 -0
  8. package/dist/app-config.d.ts +7 -0
  9. package/dist/app-config.d.ts.map +1 -0
  10. package/dist/app-config.js +113 -0
  11. package/dist/app-config.js.map +1 -0
  12. package/dist/augmentation-generator.d.ts +2 -0
  13. package/dist/augmentation-generator.d.ts.map +1 -0
  14. package/dist/augmentation-generator.js +111 -0
  15. package/dist/augmentation-generator.js.map +1 -0
  16. package/dist/binary-cache.d.ts +94 -0
  17. package/dist/binary-cache.d.ts.map +1 -0
  18. package/dist/binary-cache.js +669 -0
  19. package/dist/binary-cache.js.map +1 -0
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +13 -7
  22. package/dist/cli.js.map +1 -1
  23. package/dist/commands/admin.d.ts.map +1 -1
  24. package/dist/commands/admin.js +4 -3
  25. package/dist/commands/admin.js.map +1 -1
  26. package/dist/commands/app.d.ts.map +1 -1
  27. package/dist/commands/app.js +56 -209
  28. package/dist/commands/app.js.map +1 -1
  29. package/dist/commands/cache.d.ts +6 -0
  30. package/dist/commands/cache.d.ts.map +1 -0
  31. package/dist/commands/cache.js +105 -0
  32. package/dist/commands/cache.js.map +1 -0
  33. package/dist/commands/cloud.d.ts +20 -0
  34. package/dist/commands/cloud.d.ts.map +1 -1
  35. package/dist/commands/cloud.js +50 -52
  36. package/dist/commands/cloud.js.map +1 -1
  37. package/dist/commands/db.d.ts.map +1 -1
  38. package/dist/commands/db.js +47 -54
  39. package/dist/commands/db.js.map +1 -1
  40. package/dist/commands/deploy.d.ts +2 -1
  41. package/dist/commands/deploy.d.ts.map +1 -1
  42. package/dist/commands/deploy.js +79 -52
  43. package/dist/commands/deploy.js.map +1 -1
  44. package/dist/commands/dev.d.ts +11 -0
  45. package/dist/commands/dev.d.ts.map +1 -1
  46. package/dist/commands/dev.js +759 -385
  47. package/dist/commands/dev.js.map +1 -1
  48. package/dist/commands/diff.d.ts.map +1 -1
  49. package/dist/commands/diff.js +30 -15
  50. package/dist/commands/diff.js.map +1 -1
  51. package/dist/commands/engine.d.ts +1 -3
  52. package/dist/commands/engine.d.ts.map +1 -1
  53. package/dist/commands/engine.js +13 -85
  54. package/dist/commands/engine.js.map +1 -1
  55. package/dist/commands/functions.d.ts.map +1 -1
  56. package/dist/commands/functions.js +92 -105
  57. package/dist/commands/functions.js.map +1 -1
  58. package/dist/commands/generate.d.ts.map +1 -1
  59. package/dist/commands/generate.js +22 -12
  60. package/dist/commands/generate.js.map +1 -1
  61. package/dist/commands/init.d.ts +1 -1
  62. package/dist/commands/init.d.ts.map +1 -1
  63. package/dist/commands/init.js +137 -410
  64. package/dist/commands/init.js.map +1 -1
  65. package/dist/commands/migrate-from-v1.d.ts +5 -0
  66. package/dist/commands/migrate-from-v1.d.ts.map +1 -0
  67. package/dist/commands/migrate-from-v1.js +125 -0
  68. package/dist/commands/migrate-from-v1.js.map +1 -0
  69. package/dist/commands/migrate.d.ts.map +1 -1
  70. package/dist/commands/migrate.js +27 -23
  71. package/dist/commands/migrate.js.map +1 -1
  72. package/dist/commands/pg.d.ts +8 -0
  73. package/dist/commands/pg.d.ts.map +1 -0
  74. package/dist/commands/pg.js +102 -0
  75. package/dist/commands/pg.js.map +1 -0
  76. package/dist/commands/pull.d.ts.map +1 -1
  77. package/dist/commands/pull.js +5 -66
  78. package/dist/commands/pull.js.map +1 -1
  79. package/dist/commands/push.d.ts.map +1 -1
  80. package/dist/commands/push.js +128 -38
  81. package/dist/commands/push.js.map +1 -1
  82. package/dist/commands/seed.d.ts +2 -0
  83. package/dist/commands/seed.d.ts.map +1 -1
  84. package/dist/commands/seed.js +44 -11
  85. package/dist/commands/seed.js.map +1 -1
  86. package/dist/commands/self-host.d.ts +7 -1
  87. package/dist/commands/self-host.d.ts.map +1 -1
  88. package/dist/commands/self-host.js +272 -758
  89. package/dist/commands/self-host.js.map +1 -1
  90. package/dist/commands/self-update.d.ts +9 -0
  91. package/dist/commands/self-update.d.ts.map +1 -0
  92. package/dist/commands/self-update.js +33 -0
  93. package/dist/commands/self-update.js.map +1 -0
  94. package/dist/commands/status.d.ts.map +1 -1
  95. package/dist/commands/status.js +4 -3
  96. package/dist/commands/status.js.map +1 -1
  97. package/dist/commands/types.d.ts +3 -0
  98. package/dist/commands/types.d.ts.map +1 -0
  99. package/dist/commands/types.js +62 -0
  100. package/dist/commands/types.js.map +1 -0
  101. package/dist/commands/update.d.ts +7 -0
  102. package/dist/commands/update.d.ts.map +1 -0
  103. package/dist/commands/update.js +93 -0
  104. package/dist/commands/update.js.map +1 -0
  105. package/dist/components.d.ts +5 -0
  106. package/dist/components.d.ts.map +1 -0
  107. package/dist/components.js +3 -0
  108. package/dist/components.js.map +1 -0
  109. package/dist/config.d.ts +10 -51
  110. package/dist/config.d.ts.map +1 -1
  111. package/dist/config.js +101 -33
  112. package/dist/config.js.map +1 -1
  113. package/dist/dev-compose.d.ts +17 -0
  114. package/dist/dev-compose.d.ts.map +1 -0
  115. package/dist/dev-compose.js +374 -0
  116. package/dist/dev-compose.js.map +1 -0
  117. package/dist/diff-output.d.ts +4 -0
  118. package/dist/diff-output.d.ts.map +1 -0
  119. package/dist/diff-output.js +12 -0
  120. package/dist/diff-output.js.map +1 -0
  121. package/dist/docker-postgres.d.ts +57 -0
  122. package/dist/docker-postgres.d.ts.map +1 -0
  123. package/dist/docker-postgres.js +208 -0
  124. package/dist/docker-postgres.js.map +1 -0
  125. package/dist/engine-client.d.ts +69 -0
  126. package/dist/engine-client.d.ts.map +1 -0
  127. package/dist/engine-client.js +157 -0
  128. package/dist/engine-client.js.map +1 -0
  129. package/dist/ensure-binary.d.ts +7 -0
  130. package/dist/ensure-binary.d.ts.map +1 -0
  131. package/dist/ensure-binary.js +17 -0
  132. package/dist/ensure-binary.js.map +1 -0
  133. package/dist/functions-router-gen.d.ts +14 -0
  134. package/dist/functions-router-gen.d.ts.map +1 -0
  135. package/dist/functions-router-gen.js +199 -0
  136. package/dist/functions-router-gen.js.map +1 -0
  137. package/dist/index.d.ts +4 -5
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +2 -3
  140. package/dist/index.js.map +1 -1
  141. package/dist/kong-config.d.ts +25 -0
  142. package/dist/kong-config.d.ts.map +1 -0
  143. package/dist/kong-config.js +71 -0
  144. package/dist/kong-config.js.map +1 -0
  145. package/dist/local-gateway.d.ts +7 -0
  146. package/dist/local-gateway.d.ts.map +1 -0
  147. package/dist/local-gateway.js +9 -0
  148. package/dist/local-gateway.js.map +1 -0
  149. package/dist/local-storage.d.ts +8 -0
  150. package/dist/local-storage.d.ts.map +1 -0
  151. package/dist/local-storage.js +14 -0
  152. package/dist/local-storage.js.map +1 -0
  153. package/dist/pgbouncer-userlist.d.ts +5 -0
  154. package/dist/pgbouncer-userlist.d.ts.map +1 -0
  155. package/dist/pgbouncer-userlist.js +14 -0
  156. package/dist/pgbouncer-userlist.js.map +1 -0
  157. package/dist/postgres-ctl.d.ts +44 -0
  158. package/dist/postgres-ctl.d.ts.map +1 -0
  159. package/dist/postgres-ctl.js +137 -0
  160. package/dist/postgres-ctl.js.map +1 -0
  161. package/dist/process-manager.d.ts +43 -0
  162. package/dist/process-manager.d.ts.map +1 -0
  163. package/dist/process-manager.js +135 -0
  164. package/dist/process-manager.js.map +1 -0
  165. package/dist/project-config.d.ts +235 -0
  166. package/dist/project-config.d.ts.map +1 -0
  167. package/dist/project-config.js +160 -0
  168. package/dist/project-config.js.map +1 -0
  169. package/dist/pull-utils.d.ts +15 -0
  170. package/dist/pull-utils.d.ts.map +1 -1
  171. package/dist/pull-utils.js +12 -0
  172. package/dist/pull-utils.js.map +1 -1
  173. package/dist/release-pins.d.ts +7 -0
  174. package/dist/release-pins.d.ts.map +1 -0
  175. package/dist/release-pins.js +27 -0
  176. package/dist/release-pins.js.map +1 -0
  177. package/dist/release-public-key.d.ts +8 -0
  178. package/dist/release-public-key.d.ts.map +1 -0
  179. package/dist/release-public-key.js +13 -0
  180. package/dist/release-public-key.js.map +1 -0
  181. package/dist/runtime-routes.d.ts +34 -0
  182. package/dist/runtime-routes.d.ts.map +1 -0
  183. package/dist/runtime-routes.js +252 -0
  184. package/dist/runtime-routes.js.map +1 -0
  185. package/dist/schema-ast-v2.d.ts +127 -0
  186. package/dist/schema-ast-v2.d.ts.map +1 -0
  187. package/dist/schema-ast-v2.js +226 -0
  188. package/dist/schema-ast-v2.js.map +1 -0
  189. package/dist/scripts/postinstall.d.ts +5 -6
  190. package/dist/scripts/postinstall.d.ts.map +1 -1
  191. package/dist/scripts/postinstall.js +36 -20
  192. package/dist/scripts/postinstall.js.map +1 -1
  193. package/dist/self-host-compose.d.ts +22 -0
  194. package/dist/self-host-compose.d.ts.map +1 -0
  195. package/dist/self-host-compose.js +347 -0
  196. package/dist/self-host-compose.js.map +1 -0
  197. package/dist/storage-provision.d.ts +24 -0
  198. package/dist/storage-provision.d.ts.map +1 -0
  199. package/dist/storage-provision.js +44 -0
  200. package/dist/storage-provision.js.map +1 -0
  201. package/dist/studio-admin-roles.d.ts +7 -0
  202. package/dist/studio-admin-roles.d.ts.map +1 -0
  203. package/dist/studio-admin-roles.js +14 -0
  204. package/dist/studio-admin-roles.js.map +1 -0
  205. package/dist/studio-dev-server.d.ts +22 -0
  206. package/dist/studio-dev-server.d.ts.map +1 -0
  207. package/dist/studio-dev-server.js +28 -0
  208. package/dist/studio-dev-server.js.map +1 -0
  209. package/dist/systemd.d.ts +26 -0
  210. package/dist/systemd.d.ts.map +1 -0
  211. package/dist/systemd.js +102 -0
  212. package/dist/systemd.js.map +1 -0
  213. package/dist/tsx-runner.d.ts.map +1 -1
  214. package/dist/tsx-runner.js +9 -2
  215. package/dist/tsx-runner.js.map +1 -1
  216. package/dist/type-extractor.d.ts +4 -0
  217. package/dist/type-extractor.d.ts.map +1 -0
  218. package/dist/type-extractor.js +1213 -0
  219. package/dist/type-extractor.js.map +1 -0
  220. package/dist/type-resolver.d.ts +33 -0
  221. package/dist/type-resolver.d.ts.map +1 -0
  222. package/dist/type-resolver.js +338 -0
  223. package/dist/type-resolver.js.map +1 -0
  224. package/package.json +4 -3
  225. package/releases/deno/VERSION +1 -0
  226. package/scripts/mirror-deno-release.sh +76 -0
  227. package/src/TYPE-RESOLUTION.md +294 -0
  228. package/src/app/proxy-dev-app.ts +67 -0
  229. package/src/app-config.ts +128 -0
  230. package/src/augmentation-generator.ts +126 -0
  231. package/src/binary-cache.ts +822 -0
  232. package/src/cli.ts +13 -8
  233. package/src/commands/admin.ts +4 -3
  234. package/src/commands/app.ts +67 -231
  235. package/src/commands/cache.ts +117 -0
  236. package/src/commands/cloud.ts +63 -64
  237. package/src/commands/db.ts +54 -63
  238. package/src/commands/deploy.ts +96 -62
  239. package/src/commands/dev.ts +933 -405
  240. package/src/commands/diff.ts +31 -29
  241. package/src/commands/engine.ts +13 -116
  242. package/src/commands/functions.ts +97 -115
  243. package/src/commands/generate.ts +23 -10
  244. package/src/commands/init.ts +149 -414
  245. package/src/commands/migrate-from-v1.ts +131 -0
  246. package/src/commands/migrate.ts +27 -23
  247. package/src/commands/pg.ts +133 -0
  248. package/src/commands/pull.ts +6 -85
  249. package/src/commands/push.ts +161 -56
  250. package/src/commands/seed.ts +54 -12
  251. package/src/commands/self-host.ts +312 -880
  252. package/src/commands/self-update.ts +45 -0
  253. package/src/commands/status.ts +4 -3
  254. package/src/commands/types.ts +76 -0
  255. package/src/commands/update.ts +109 -0
  256. package/src/components.ts +6 -0
  257. package/src/config.ts +127 -94
  258. package/src/dev-compose.ts +455 -0
  259. package/src/diff-output.ts +12 -0
  260. package/src/docker-postgres.ts +295 -0
  261. package/src/engine-client.ts +236 -0
  262. package/src/ensure-binary.ts +28 -0
  263. package/src/functions-router-gen.ts +224 -0
  264. package/src/index.ts +4 -12
  265. package/src/kong-config.ts +93 -0
  266. package/src/local-gateway.ts +9 -0
  267. package/src/local-storage.ts +14 -0
  268. package/src/pgbouncer-userlist.ts +15 -0
  269. package/src/postgres-ctl.ts +171 -0
  270. package/src/process-manager.ts +168 -0
  271. package/src/project-config.ts +386 -0
  272. package/src/pull-utils.ts +24 -0
  273. package/src/release-pins.ts +31 -0
  274. package/src/release-public-key.ts +12 -0
  275. package/src/runtime-routes.ts +291 -0
  276. package/src/schema-ast-v2.ts +324 -0
  277. package/src/scripts/postinstall.ts +36 -25
  278. package/src/self-host-compose.ts +389 -0
  279. package/src/storage-provision.ts +58 -0
  280. package/src/studio-admin-roles.ts +16 -0
  281. package/src/studio-dev-server.ts +53 -0
  282. package/src/systemd.ts +137 -0
  283. package/src/tsx-runner.ts +11 -1
  284. package/src/type-extractor.ts +1479 -0
  285. package/src/type-resolver.ts +457 -0
  286. package/tests/app-command.test.ts +54 -0
  287. package/tests/augmentation-generator.test.ts +59 -0
  288. package/tests/binary-cache-cloud-overrides.test.ts +123 -0
  289. package/tests/cached-artifact-format.test.ts +84 -0
  290. package/tests/cli-help.test.ts +40 -14
  291. package/tests/config.test.ts +171 -37
  292. package/tests/docker-postgres.test.ts +39 -0
  293. package/tests/engine-distribution.test.ts +3 -3
  294. package/tests/ensure-binary.test.ts +59 -0
  295. package/tests/init.test.ts +28 -86
  296. package/tests/migrate-from-v1.test.ts +29 -0
  297. package/tests/normalize-admin-config.test.ts +48 -0
  298. package/tests/pg-spawn-env.test.ts +18 -0
  299. package/tests/postgres-archive-tag.test.ts +9 -0
  300. package/tests/proxy-dev-app.test.ts +33 -0
  301. package/tests/pull-utils.test.ts +36 -1
  302. package/tests/release-pins.test.ts +28 -0
  303. package/tests/runtime-contract.test.ts +351 -0
  304. package/tests/seed-discover.test.ts +31 -0
  305. package/tests/studio-admin-roles.test.ts +27 -0
  306. package/tests/tsconfig.json +9 -0
  307. package/tests/type-extractor.test.ts +985 -0
  308. package/tests/type-resolver.test.ts +59 -0
  309. package/tsconfig.tsbuildinfo +1 -1
  310. package/vitest.config.ts +12 -0
  311. package/dist/engine/cache.d.ts +0 -37
  312. package/dist/engine/cache.d.ts.map +0 -1
  313. package/dist/engine/cache.js +0 -121
  314. package/dist/engine/cache.js.map +0 -1
  315. package/dist/engine/download.d.ts +0 -19
  316. package/dist/engine/download.d.ts.map +0 -1
  317. package/dist/engine/download.js +0 -108
  318. package/dist/engine/download.js.map +0 -1
  319. package/dist/engine/platform.d.ts +0 -24
  320. package/dist/engine/platform.d.ts.map +0 -1
  321. package/dist/engine/platform.js +0 -50
  322. package/dist/engine/platform.js.map +0 -1
  323. package/dist/engine/resolve.d.ts +0 -37
  324. package/dist/engine/resolve.d.ts.map +0 -1
  325. package/dist/engine/resolve.js +0 -133
  326. package/dist/engine/resolve.js.map +0 -1
  327. package/dist/engine/update-notify.d.ts +0 -11
  328. package/dist/engine/update-notify.d.ts.map +0 -1
  329. package/dist/engine/update-notify.js +0 -43
  330. package/dist/engine/update-notify.js.map +0 -1
  331. package/dist/engine/verify.d.ts +0 -50
  332. package/dist/engine/verify.d.ts.map +0 -1
  333. package/dist/engine/verify.js +0 -161
  334. package/dist/engine/verify.js.map +0 -1
  335. package/dist/engine-version.d.ts +0 -35
  336. package/dist/engine-version.d.ts.map +0 -1
  337. package/dist/engine-version.js +0 -35
  338. package/dist/engine-version.js.map +0 -1
  339. package/dist/engine.d.ts +0 -34
  340. package/dist/engine.d.ts.map +0 -1
  341. package/dist/engine.js +0 -76
  342. package/dist/engine.js.map +0 -1
  343. package/src/engine/cache.ts +0 -135
  344. package/src/engine/download.ts +0 -143
  345. package/src/engine/platform.ts +0 -66
  346. package/src/engine/resolve.ts +0 -197
  347. package/src/engine/update-notify.ts +0 -50
  348. package/src/engine/verify.ts +0 -206
  349. package/src/engine-version.ts +0 -39
  350. package/src/engine.ts +0 -99
@@ -1,14 +1,8 @@
1
1
  import type { Command } from "commander"
2
2
  import { loadConfig, loadSchemaAst } from "../config.js"
3
- import { ensureEngine, invokeEngine } from "../engine.js"
4
-
5
- interface DiffResult {
6
- operations: Array<{
7
- kind: string
8
- risk: "safe" | "cautious" | "destructive"
9
- description: string
10
- }>
11
- }
3
+ import { connectionString, schemaPathFromProject } from "../project-config.js"
4
+ import { ensureEngine, engineRequest, type DiffResult } from "../engine-client.js"
5
+ import { printDiffWarnings } from "../diff-output.js"
12
6
 
13
7
  export function registerDiff(program: Command): void {
14
8
  program
@@ -18,43 +12,51 @@ export function registerDiff(program: Command): void {
18
12
  .action(async (opts: { connection?: string }) => {
19
13
  const cwd = process.cwd()
20
14
  const config = loadConfig(cwd)
21
- const connection = opts.connection ?? config.connection
15
+ const connection = opts.connection ?? connectionString(config)
22
16
 
23
17
  await ensureEngine()
24
18
 
25
19
  console.log("Loading schema...")
26
- const ast = loadSchemaAst(config.schema, cwd)
27
-
28
- const result = invokeEngine(
29
- ["diff", "--connection", connection, "--format", "json"],
30
- JSON.stringify(ast),
31
- )
32
- if (result.exitCode !== 0) {
33
- console.error(result.stderr || result.stdout)
34
- process.exit(1)
35
- }
20
+ const ast = loadSchemaAst(schemaPathFromProject(config, cwd), cwd)
21
+
22
+ const diff = await engineRequest<DiffResult>("/diff", {
23
+ ast,
24
+ database_url: connection,
25
+ schema: "public",
26
+ })
36
27
 
37
- const diff = JSON.parse(result.stdout) as DiffResult
38
28
  const ops = diff.operations ?? []
29
+ printDiffWarnings(diff)
39
30
 
40
31
  if (ops.length === 0) {
41
32
  console.log("No changes.")
42
33
  return
43
34
  }
44
35
 
45
- const symbol = { safe: "+", cautious: "~", destructive: "!" }
46
- const legend = { safe: "safe", cautious: "cautious", destructive: "DESTRUCTIVE" }
36
+ const symbol: Record<NonNullable<DiffResult["operations"][number]["risk"]>, string> = {
37
+ safe: "+",
38
+ warn: "~",
39
+ cautious: "~",
40
+ danger: "!",
41
+ destructive: "!",
42
+ }
43
+ const legend: typeof symbol = {
44
+ safe: "safe",
45
+ warn: "caution",
46
+ cautious: "caution",
47
+ danger: "DANGER",
48
+ destructive: "DANGER",
49
+ }
47
50
 
48
51
  console.log(`\n${ops.length} change(s):\n`)
49
52
  for (const op of ops) {
50
- console.log(
51
- ` [${symbol[op.risk]}] ${op.description} (${legend[op.risk]})`,
52
- )
53
+ const r = op.risk ?? "safe"
54
+ console.log(` [${symbol[r]}] ${op.description} (${legend[r]})`)
53
55
  }
54
56
 
55
- const destructive = ops.filter((o) => o.risk === "destructive").length
56
- if (destructive > 0) {
57
- console.log(`\n ${destructive} destructive operation(s). Run with --yes to skip confirmation.`)
57
+ const dangerous = ops.filter((o) => o.risk === "danger").length
58
+ if (dangerous > 0) {
59
+ console.log(`\n ${dangerous} dangerous operation(s). Review before pushing.`)
58
60
  }
59
61
  console.log()
60
62
  })
@@ -1,133 +1,30 @@
1
1
  /**
2
2
  * Engine management commands:
3
- * supatype engine version show pinned, cached, and latest versions
4
- * supatype engine update-check — check for newer engine versions
5
- * supatype engine prune — remove old cached engine versions
3
+ * supatype engine status check if the engine container is reachable
6
4
  */
7
5
 
8
6
  import type { Command } from "commander"
9
- import { ENGINE_VERSION } from "../engine-version.js"
10
- import { detectPlatform } from "../engine/platform.js"
11
- import {
12
- hasCachedBinary,
13
- listCachedVersions,
14
- pruneCacheExcept,
15
- saveUpdateCheck,
16
- } from "../engine/cache.js"
17
- import { checkLatestVersion } from "../engine/resolve.js"
7
+ import { engineHealth } from "../engine-client.js"
18
8
 
19
9
  export function registerEngine(program: Command): void {
20
10
  const engine = program
21
11
  .command("engine")
22
- .description("Manage the Supatype engine binary")
12
+ .description("Manage the Supatype schema engine")
23
13
 
24
- // supatype engine version
25
14
  engine
26
- .command("version")
27
- .description("Show engine version information")
15
+ .command("status")
16
+ .description("Check if the schema engine container is reachable")
28
17
  .action(async () => {
29
- const platform = detectPlatform()
30
- const cached = hasCachedBinary(ENGINE_VERSION, platform)
31
- const cachedVersions = listCachedVersions()
18
+ const url = process.env["SUPATYPE_ENGINE_URL"] ?? "http://localhost:7500"
19
+ console.log(`Checking engine at ${url}...`)
32
20
 
33
- console.log(`Engine: v${ENGINE_VERSION} (pinned)`)
34
- console.log(
35
- `Cache: ${cached ? `v${ENGINE_VERSION} ✓` : "not downloaded"}`,
36
- )
37
-
38
- if (cachedVersions.length > 1) {
39
- const others = cachedVersions.filter((v) => v !== ENGINE_VERSION)
40
- console.log(`Other cached versions: ${others.join(", ")}`)
41
- }
42
-
43
- // Check latest
44
- try {
45
- const latest = await checkLatestVersion()
46
- if (latest) {
47
- await saveUpdateCheck(latest.version)
48
- if (latest.version !== ENGINE_VERSION) {
49
- console.log(
50
- `Latest: v${latest.version} — update available, run: npm update @supatype/cli`,
51
- )
52
- } else {
53
- console.log(`Latest: v${latest.version} (up to date)`)
54
- }
55
- }
56
- } catch {
57
- console.log("Latest: unable to check (offline?)")
58
- }
59
- })
60
-
61
- // supatype engine update-check
62
- engine
63
- .command("update-check")
64
- .description("Check if a newer engine version is available")
65
- .action(async () => {
66
- const latest = await checkLatestVersion()
67
-
68
- if (!latest) {
69
- console.error(
70
- "Could not check for updates. Check your internet connection.",
71
- )
72
- process.exitCode = 1
73
- return
74
- }
75
-
76
- await saveUpdateCheck(latest.version)
77
-
78
- if (latest.version !== ENGINE_VERSION) {
79
- console.log(
80
- `Supatype engine v${latest.version} is available (current: v${ENGINE_VERSION}).`,
81
- )
82
- console.log(`Run: npm update @supatype/cli`)
21
+ const healthy = await engineHealth()
22
+ if (healthy) {
23
+ console.log("Engine is reachable and healthy.")
83
24
  } else {
84
- console.log(`Engine v${ENGINE_VERSION} is up to date.`)
85
- }
86
- })
87
-
88
- // supatype engine prune
89
- engine
90
- .command("prune")
91
- .description("Remove all cached engine versions except the current one")
92
- .action(() => {
93
- const { removed, bytesFreed } = pruneCacheExcept(ENGINE_VERSION)
94
-
95
- if (removed.length === 0) {
96
- console.log("Nothing to prune — only the current version is cached.")
97
- return
98
- }
99
-
100
- const mb = (bytesFreed / (1024 * 1024)).toFixed(1)
101
- console.log(`Removed ${removed.length} cached version(s): ${removed.join(", ")}`)
102
- console.log(`Space reclaimed: ${mb}MB`)
103
- })
104
-
105
- // supatype engine versions (list all released versions)
106
- engine
107
- .command("versions")
108
- .description("List all released engine versions")
109
- .action(async () => {
110
- const { fetchJson } = await import("../engine/download.js")
111
- const { CDN_BASE_URL } = await import("../engine-version.js")
112
-
113
- interface VersionEntry {
114
- version: string
115
- date: string
116
- }
117
-
118
- const versions = await fetchJson<VersionEntry[]>(
119
- `${CDN_BASE_URL}/versions.json`,
120
- )
121
-
122
- if (!versions || versions.length === 0) {
123
- console.log("No released versions found.")
124
- return
125
- }
126
-
127
- console.log("Released engine versions:")
128
- for (const v of versions) {
129
- const current = v.version === ENGINE_VERSION ? " (current)" : ""
130
- console.log(` v${v.version} ${v.date}${current}`)
25
+ console.error("Engine is not reachable.")
26
+ console.error("Make sure the engine container is running (supatype dev or docker compose up).")
27
+ process.exitCode = 1
131
28
  }
132
29
  })
133
30
  }
@@ -8,12 +8,23 @@ import {
8
8
  writeFileSync,
9
9
  unlinkSync,
10
10
  } from "node:fs"
11
- import { resolve, join, basename, relative } from "node:path"
11
+ import { resolve, join, basename, relative, isAbsolute } from "node:path"
12
12
  import { spawnSync, execSync } from "node:child_process"
13
+ import { localKongBaseUrl } from "../local-gateway.js"
14
+ import { loadConfig } from "../config.js"
15
+ import { ensureBinary } from "../ensure-binary.js"
16
+ import {
17
+ functionsPathCandidatesFromProject,
18
+ preferredFunctionsPathFromProject,
19
+ } from "../project-config.js"
20
+ import {
21
+ discoverTsFunctionsInDir,
22
+ generateFunctionsRouterSource,
23
+ } from "../functions-router-gen.js"
24
+ import { selfHostComposePaths } from "../self-host-compose.js"
13
25
 
14
26
  // ─── Constants ───────────────────────────────────────────────────────────────
15
27
 
16
- const FUNCTIONS_DIR = "supatype/functions"
17
28
  const SHARED_DIR = "_shared"
18
29
  const ENV_LOCAL = ".env.local"
19
30
  const ENV_PRODUCTION = ".env.production"
@@ -36,9 +47,9 @@ export function registerFunctions(program: Command): void {
36
47
  .command("serve")
37
48
  .description("Start a local Deno server that serves all functions with hot reload")
38
49
  .option("--port <port>", "Port to serve on", "54321")
39
- .option("--env-file <path>", "Path to env file", `${FUNCTIONS_DIR}/${ENV_LOCAL}`)
40
- .action((opts: { port: string; envFile: string }) => {
41
- serve(process.cwd(), opts)
50
+ .option("--env-file <path>", "Path to env file", ENV_LOCAL)
51
+ .action(async (opts: { port: string; envFile: string }) => {
52
+ await serve(process.cwd(), opts)
42
53
  })
43
54
 
44
55
  fnCmd
@@ -111,7 +122,8 @@ export function registerFunctions(program: Command): void {
111
122
  // ─── Scaffold ────────────────────────────────────────────────────────────────
112
123
 
113
124
  function scaffoldFunction(cwd: string, name: string): void {
114
- const fnDir = resolve(cwd, FUNCTIONS_DIR, name)
125
+ const functionsDir = resolveFunctionsDir(cwd, "write")
126
+ const fnDir = resolve(functionsDir, name)
115
127
  if (existsSync(fnDir)) {
116
128
  console.error(`Function "${name}" already exists at ${relative(cwd, fnDir)}`)
117
129
  process.exit(1)
@@ -120,7 +132,7 @@ function scaffoldFunction(cwd: string, name: string): void {
120
132
  mkdirSync(fnDir, { recursive: true })
121
133
 
122
134
  const indexContent = `// ${name} — Supatype Edge Function
123
- // Docs: https://supatype.dev/docs/edge-functions
135
+ // Docs: https://supatype.com/docs/edge-functions
124
136
 
125
137
  export default async function handler(req: Request): Promise<Response> {
126
138
  const { method, url } = req
@@ -144,7 +156,7 @@ export default async function handler(req: Request): Promise<Response> {
144
156
  writeFileSync(join(fnDir, "index.ts"), indexContent, "utf8")
145
157
 
146
158
  // Ensure _shared directory exists
147
- const sharedDir = resolve(cwd, FUNCTIONS_DIR, SHARED_DIR)
159
+ const sharedDir = resolve(functionsDir, SHARED_DIR)
148
160
  if (!existsSync(sharedDir)) {
149
161
  mkdirSync(sharedDir, { recursive: true })
150
162
  writeFileSync(
@@ -155,7 +167,7 @@ export default async function handler(req: Request): Promise<Response> {
155
167
  }
156
168
 
157
169
  // Ensure .env.local exists
158
- const envLocalPath = resolve(cwd, FUNCTIONS_DIR, ENV_LOCAL)
170
+ const envLocalPath = resolve(functionsDir, ENV_LOCAL)
159
171
  if (!existsSync(envLocalPath)) {
160
172
  writeFileSync(
161
173
  envLocalPath,
@@ -164,7 +176,8 @@ export default async function handler(req: Request): Promise<Response> {
164
176
  )
165
177
  }
166
178
 
167
- console.log(`Created function: ${FUNCTIONS_DIR}/${name}/index.ts`)
179
+ const functionsDirLabel = relativeFunctionsDir(cwd, functionsDir)
180
+ console.log(`Created function: ${functionsDirLabel}/${name}/index.ts`)
168
181
  console.log()
169
182
  console.log(" Local dev: npx supatype functions serve")
170
183
  console.log(` Invoke: npx supatype functions invoke ${name}`)
@@ -179,8 +192,36 @@ interface DiscoveredFunction {
179
192
  absPath: string
180
193
  }
181
194
 
195
+ function resolveFunctionsDir(cwd: string, mode: "read" | "write"): string {
196
+ try {
197
+ const cfg = loadConfig(cwd)
198
+ if (mode === "write") {
199
+ return preferredFunctionsPathFromProject(cfg, cwd)
200
+ }
201
+ const candidates = functionsPathCandidatesFromProject(cfg, cwd)
202
+ return candidates.find(dir => existsSync(dir)) ?? candidates[0] ?? resolve(cwd, "functions")
203
+ } catch {
204
+ // Keep commands usable even if config cannot be loaded yet.
205
+ const modern = resolve(cwd, "functions")
206
+ const legacy = resolve(cwd, "supatype/functions")
207
+ if (mode === "write") return existsSync(legacy) ? legacy : modern
208
+ return existsSync(modern) ? modern : legacy
209
+ }
210
+ }
211
+
212
+ function relativeFunctionsDir(cwd: string, functionsDir: string): string {
213
+ const rel = relative(cwd, functionsDir)
214
+ return rel.length > 0 ? rel : "."
215
+ }
216
+
217
+ function resolveEnvFilePath(cwd: string, functionsDir: string, envFile: string): string {
218
+ if (isAbsolute(envFile)) return envFile
219
+ if (envFile.includes("/") || envFile.includes("\\")) return resolve(cwd, envFile)
220
+ return resolve(functionsDir, envFile)
221
+ }
222
+
182
223
  function discoverFunctions(cwd: string): DiscoveredFunction[] {
183
- const functionsDir = resolve(cwd, FUNCTIONS_DIR)
224
+ const functionsDir = resolveFunctionsDir(cwd, "read")
184
225
  if (!existsSync(functionsDir)) return []
185
226
 
186
227
  const entries = readdirSync(functionsDir)
@@ -210,26 +251,29 @@ function discoverFunctions(cwd: string): DiscoveredFunction[] {
210
251
 
211
252
  // ─── Serve (local dev) ──────────────────────────────────────────────────────
212
253
 
213
- function serve(cwd: string, opts: { port: string; envFile: string }): void {
214
- const fns = discoverFunctions(cwd)
215
- if (fns.length === 0) {
216
- console.error(`No functions found in ${FUNCTIONS_DIR}/`)
254
+ async function serve(cwd: string, opts: { port: string; envFile: string }): Promise<void> {
255
+ const config = loadConfig(cwd)
256
+ const functionsDir = resolveFunctionsDir(cwd, "read")
257
+ const functionsDirLabel = relativeFunctionsDir(cwd, functionsDir)
258
+ const routes = discoverTsFunctionsInDir(functionsDir)
259
+ if (routes.length === 0) {
260
+ console.error(`No functions found in ${functionsDirLabel}/`)
217
261
  console.error("Create one with: npx supatype functions new <name>")
218
262
  process.exit(1)
219
263
  }
220
264
 
221
- console.log(`Discovered ${fns.length} function(s):`)
222
- for (const fn of fns) {
265
+ console.log(`Discovered ${routes.length} function(s):`)
266
+ for (const fn of routes) {
223
267
  console.log(` /${fn.name} → ${relative(cwd, fn.entrypoint)}`)
224
268
  }
225
269
  console.log()
226
270
 
227
271
  // Generate a Deno entry script that routes requests to the correct function
228
- const routerScript = generateLocalRouter(fns, cwd)
229
- const routerPath = resolve(cwd, FUNCTIONS_DIR, ".serve-router.ts")
272
+ const routerPath = resolve(functionsDir, ".serve-router.ts")
273
+ const routerScript = generateFunctionsRouterSource(routerPath, routes)
230
274
  writeFileSync(routerPath, routerScript, "utf8")
231
275
 
232
- const envFilePath = resolve(cwd, opts.envFile)
276
+ const envFilePath = resolveEnvFilePath(cwd, functionsDir, opts.envFile)
233
277
  const envArgs: string[] = []
234
278
  if (existsSync(envFilePath)) {
235
279
  envArgs.push("--env-file", envFilePath)
@@ -238,8 +282,16 @@ function serve(cwd: string, opts: { port: string; envFile: string }): void {
238
282
  console.log(`Serving functions at http://localhost:${opts.port}/functions/v1/`)
239
283
  console.log("Watching for changes...\n")
240
284
 
285
+ let denoBin: string
286
+ try {
287
+ denoBin = await ensureBinary("deno", config)
288
+ } catch (err) {
289
+ console.error(`[supatype] Could not provision Deno v${config.versions.deno}: ${(err as Error).message}`)
290
+ process.exit(1)
291
+ }
292
+
241
293
  const result = spawnSync(
242
- "deno",
294
+ denoBin,
243
295
  [
244
296
  "run",
245
297
  "--allow-net",
@@ -255,7 +307,9 @@ function serve(cwd: string, opts: { port: string; envFile: string }): void {
255
307
  env: {
256
308
  ...process.env,
257
309
  PORT: opts.port,
258
- SUPATYPE_URL: process.env["SUPATYPE_URL"] ?? `http://localhost:8000`,
310
+ SUPATYPE_DENO_FUNCTIONS_DIR: functionsDir,
311
+ SUPATYPE_SHARED_ENV_FILE: resolve(functionsDir, ENV_LOCAL),
312
+ SUPATYPE_URL: process.env["SUPATYPE_URL"] ?? localKongBaseUrl(),
259
313
  SUPATYPE_ANON_KEY: process.env["SUPATYPE_ANON_KEY"] ?? "",
260
314
  SUPATYPE_SERVICE_ROLE_KEY: process.env["SUPATYPE_SERVICE_ROLE_KEY"] ?? "",
261
315
  },
@@ -267,61 +321,10 @@ function serve(cwd: string, opts: { port: string; envFile: string }): void {
267
321
 
268
322
  if (result.status !== 0) {
269
323
  console.error("Function server exited with errors.")
270
- console.error("Make sure Deno is installed: https://deno.land/manual/getting_started/installation")
271
324
  process.exit(result.status ?? 1)
272
325
  }
273
326
  }
274
327
 
275
- function generateLocalRouter(fns: DiscoveredFunction[], cwd: string): string {
276
- const imports = fns.map(
277
- (fn, i) => `import handler_${i} from "./${relative(resolve(cwd, FUNCTIONS_DIR), fn.entrypoint).replace(/\\/g, "/")}"`,
278
- )
279
-
280
- const routes = fns.map(
281
- (fn, i) => ` "${fn.name}": handler_${i},`,
282
- )
283
-
284
- return `// Auto-generated local function router — do not edit
285
- ${imports.join("\n")}
286
-
287
- const handlers: Record<string, (req: Request) => Response | Promise<Response>> = {
288
- ${routes.join("\n")}
289
- }
290
-
291
- const port = parseInt(Deno.env.get("PORT") ?? "54321", 10)
292
-
293
- Deno.serve({ port }, async (req: Request): Promise<Response> => {
294
- const url = new URL(req.url)
295
- const pathParts = url.pathname.replace(/^\\/functions\\/v1\\//, "").split("/")
296
- const fnName = pathParts[0] ?? ""
297
-
298
- if (!fnName || !handlers[fnName]) {
299
- return new Response(JSON.stringify({
300
- error: "not_found",
301
- message: fnName ? \`Function "\${fnName}" not found\` : "No function specified",
302
- available: Object.keys(handlers),
303
- }), { status: 404, headers: { "Content-Type": "application/json" } })
304
- }
305
-
306
- try {
307
- const start = performance.now()
308
- const response = await handlers[fnName]!(req)
309
- const duration = (performance.now() - start).toFixed(1)
310
- console.log(\`\${req.method} /functions/v1/\${fnName} → \${response.status} (\${duration}ms)\`)
311
- return response
312
- } catch (err) {
313
- console.error(\`Error in function "\${fnName}":\`, err)
314
- return new Response(JSON.stringify({
315
- error: "function_error",
316
- message: err instanceof Error ? err.message : "Unknown error",
317
- }), { status: 500, headers: { "Content-Type": "application/json" } })
318
- }
319
- })
320
-
321
- console.log(\`Edge function server running on http://localhost:\${port}/functions/v1/\`)
322
- `
323
- }
324
-
325
328
  // ─── Deploy ──────────────────────────────────────────────────────────────────
326
329
 
327
330
  async function deploy(cwd: string, opts: { only?: string; dryRun?: boolean }): Promise<void> {
@@ -331,10 +334,12 @@ async function deploy(cwd: string, opts: { only?: string; dryRun?: boolean }): P
331
334
  : allFns
332
335
 
333
336
  if (fns.length === 0) {
337
+ const functionsDir = resolveFunctionsDir(cwd, "read")
338
+ const functionsDirLabel = relativeFunctionsDir(cwd, functionsDir)
334
339
  if (opts.only) {
335
- console.error(`Function "${opts.only}" not found in ${FUNCTIONS_DIR}/`)
340
+ console.error(`Function "${opts.only}" not found in ${functionsDirLabel}/`)
336
341
  } else {
337
- console.error(`No functions found in ${FUNCTIONS_DIR}/`)
342
+ console.error(`No functions found in ${functionsDirLabel}/`)
338
343
  }
339
344
  process.exit(1)
340
345
  }
@@ -348,50 +353,27 @@ async function deploy(cwd: string, opts: { only?: string; dryRun?: boolean }): P
348
353
  return
349
354
  }
350
355
 
351
- // Check if this is a self-hosted deployment or cloud
352
- const isSelfHosted = detectSelfHosted(cwd)
353
-
354
- if (isSelfHosted) {
356
+ const composePath = selfHostComposePaths(cwd).composePath
357
+ if (existsSync(composePath)) {
355
358
  await deploySelfHosted(cwd, fns)
356
- } else {
357
- await deployCloud(cwd, fns)
359
+ return
358
360
  }
359
- }
360
361
 
361
- function detectSelfHosted(cwd: string): boolean {
362
- return existsSync(resolve(cwd, "deploy/docker-compose.yml"))
362
+ await deployCloud(cwd, fns)
363
363
  }
364
364
 
365
365
  async function deploySelfHosted(cwd: string, fns: DiscoveredFunction[]): Promise<void> {
366
- console.log("Self-hosted deployment detected.\n")
367
- console.log("Bundling functions...\n")
368
-
369
- const bundleDir = resolve(cwd, "deploy/functions")
370
- mkdirSync(bundleDir, { recursive: true })
366
+ console.log("Self-host Compose deployment.\n")
367
+ console.log("Functions are served from your project functions/ directory (no bundle step).\n")
371
368
 
372
369
  for (const fn of fns) {
373
- const start = Date.now()
374
- const outFile = join(bundleDir, `${fn.name}.js`)
375
-
376
- // Bundle with Deno
377
- const result = spawnSync("deno", ["bundle", fn.entrypoint, outFile], {
378
- stdio: "pipe",
379
- cwd,
380
- })
381
-
382
- if (result.status !== 0) {
383
- const stderr = result.stderr?.toString() ?? ""
384
- console.error(` ${fn.name} ✗ bundle failed`)
385
- if (stderr) console.error(` ${stderr.trim()}`)
386
- continue
387
- }
388
-
389
- const duration = Date.now() - start
390
- console.log(` ${fn.name} ✓ deployed (${duration}ms)`)
370
+ console.log(` ${fn.name} → ${relative(cwd, fn.entrypoint)}`)
391
371
  }
392
372
 
393
- console.log(`\nDeployed ${fns.length} function(s) to deploy/functions/`)
394
- console.log("The supatype-functions container will pick up changes automatically.")
373
+ console.log(`\n${fns.length} function(s) ready on disk.`)
374
+ console.log("Restart the functions-worker container to load changes:")
375
+ console.log(" supatype self-host compose restart functions-worker")
376
+ console.log("\nKong → supatype-server → functions-worker (per-project worker).")
395
377
  }
396
378
 
397
379
  async function deployCloud(cwd: string, fns: DiscoveredFunction[]): Promise<void> {
@@ -450,7 +432,7 @@ async function deployCloud(cwd: string, fns: DiscoveredFunction[]): Promise<void
450
432
  }
451
433
 
452
434
  console.log(`\nDeployed ${fns.length} function(s)`)
453
- console.log(`Invoke: https://${linked.ref}.supatype.io/functions/v1/<name>`)
435
+ console.log(`Invoke: https://${linked.ref}.supatype.dev/functions/v1/<name>`)
454
436
  }
455
437
 
456
438
  function readFunctionSource(fn: DiscoveredFunction): string {
@@ -642,7 +624,7 @@ async function invoke(
642
624
  const { getLinkedProject, getCloudToken } = await loadCloudHelpers()
643
625
  const linked = getLinkedProject(cwd)
644
626
  if (linked) {
645
- url = `https://${linked.ref}.supatype.io/functions/v1/${name}`
627
+ url = `https://${linked.ref}.supatype.dev/functions/v1/${name}`
646
628
  const token = getCloudToken()
647
629
  if (token && opts.auth) {
648
630
  headers["Authorization"] = `Bearer ${token}`
@@ -708,7 +690,7 @@ async function envList(cwd: string): Promise<void> {
708
690
 
709
691
  if (!linked) {
710
692
  // Show local env vars
711
- const envPath = resolve(cwd, FUNCTIONS_DIR, ENV_LOCAL)
693
+ const envPath = resolve(resolveFunctionsDir(cwd, "read"), ENV_LOCAL)
712
694
  if (!existsSync(envPath)) {
713
695
  console.log("No environment variables configured.")
714
696
  return
@@ -780,7 +762,7 @@ async function envSet(cwd: string, keyvalue: string): Promise<void> {
780
762
 
781
763
  if (!linked) {
782
764
  // Set in local env file
783
- const envPath = resolve(cwd, FUNCTIONS_DIR, ENV_LOCAL)
765
+ const envPath = resolve(resolveFunctionsDir(cwd, "write"), ENV_LOCAL)
784
766
  let content = existsSync(envPath) ? readFileSync(envPath, "utf8") : ""
785
767
 
786
768
  // Replace existing or append
@@ -832,7 +814,7 @@ async function envUnset(cwd: string, key: string): Promise<void> {
832
814
  const linked = getLinkedProject(cwd)
833
815
 
834
816
  if (!linked) {
835
- const envPath = resolve(cwd, FUNCTIONS_DIR, ENV_LOCAL)
817
+ const envPath = resolve(resolveFunctionsDir(cwd, "read"), ENV_LOCAL)
836
818
  if (!existsSync(envPath)) {
837
819
  console.error("No local env file found.")
838
820
  process.exit(1)
@@ -913,7 +895,7 @@ async function loadCloudHelpers(): Promise<CloudHelpers> {
913
895
  },
914
896
 
915
897
  getCloudApiUrl(): string {
916
- return process.env["SUPATYPE_API_URL"] ?? "https://api.supatype.io"
898
+ return process.env["SUPATYPE_API_URL"] ?? "https://api.supatype.com"
917
899
  },
918
900
  }
919
901
  }
@@ -1,6 +1,10 @@
1
1
  import type { Command } from "commander"
2
+ import { mkdirSync, writeFileSync } from "node:fs"
3
+ import { resolve, dirname } from "node:path"
2
4
  import { loadConfig, loadSchemaAst } from "../config.js"
3
- import { ensureEngine, invokeEngine } from "../engine.js"
5
+ import { schemaPathFromProject } from "../project-config.js"
6
+ import { ensureEngine, engineRequest } from "../engine-client.js"
7
+ import { generateClientAugmentation } from "../augmentation-generator.js"
4
8
 
5
9
  export function registerGenerate(program: Command): void {
6
10
  program
@@ -10,22 +14,31 @@ export function registerGenerate(program: Command): void {
10
14
  .action(async (opts: { connection?: string }) => {
11
15
  const cwd = process.cwd()
12
16
  const config = loadConfig(cwd)
13
- const connection = opts.connection ?? config.connection
17
+ const schemaPath = schemaPathFromProject(config, cwd)
18
+ const outputTypesPath = config.output?.types ?? "types/database.ts"
19
+ const outputClientPath = config.output?.client ?? "supatype/generated/index.d.ts"
14
20
 
15
21
  await ensureEngine()
16
22
  console.log("Loading schema...")
17
- const ast = loadSchemaAst(config.schema, cwd)
23
+ const ast = loadSchemaAst(schemaPath, cwd)
18
24
 
19
- const args = ["generate", "--connection", connection]
20
- if (config.output?.types) args.push("--types", config.output.types)
21
- if (config.output?.client) args.push("--client", config.output.client)
25
+ const result = await engineRequest<{ code?: string; message?: string }>("/generate", { ast, lang: "typescript" })
22
26
 
23
- const result = invokeEngine(args, JSON.stringify(ast))
24
- if (result.exitCode !== 0) {
25
- console.error(result.stderr || result.stdout)
27
+ const typesCode = result.code ?? result.message
28
+ if (typesCode === undefined) {
29
+ console.error("Engine returned no output.")
26
30
  process.exit(1)
27
31
  }
28
32
 
29
- console.log(result.stdout || "Types generated.")
33
+ const outPath = resolve(cwd, outputTypesPath)
34
+ mkdirSync(dirname(outPath), { recursive: true })
35
+ writeFileSync(outPath, typesCode, "utf8")
36
+ console.log(`Types written to ${outputTypesPath}`)
37
+
38
+ const augmentationOutPath = resolve(cwd, outputClientPath)
39
+ const augmentationCode = generateClientAugmentation(ast)
40
+ mkdirSync(dirname(augmentationOutPath), { recursive: true })
41
+ writeFileSync(augmentationOutPath, augmentationCode, "utf8")
42
+ console.log(`Client augmentation written to ${outputClientPath}`)
30
43
  })
31
44
  }