@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
package/src/cli.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { Command } from "commander"
2
- import { ENGINE_VERSION } from "./engine-version.js"
3
2
  import { registerInit } from "./commands/init.js"
4
3
  import { registerDev } from "./commands/dev.js"
4
+ import { registerCache } from "./commands/cache.js"
5
+ import { registerUpdate } from "./commands/update.js"
6
+ import { registerPg } from "./commands/pg.js"
5
7
  import { registerPush } from "./commands/push.js"
6
8
  import { registerDiff } from "./commands/diff.js"
7
9
  import { registerPull } from "./commands/pull.js"
@@ -20,16 +22,22 @@ import { registerLogs } from "./commands/logs.js"
20
22
  import { registerAdmin } from "./commands/admin.js"
21
23
  import { registerFunctions } from "./commands/functions.js"
22
24
  import { registerPlugins } from "./commands/plugins.js"
23
- import { showUpdateNotification } from "./engine/update-notify.js"
25
+ import { registerTypes } from "./commands/types.js"
26
+ import { registerMigrateFromV1 } from "./commands/migrate-from-v1.js"
27
+ import { registerSelfUpdate } from "./commands/self-update.js"
24
28
 
25
29
  export function run(): void {
26
30
  const program = new Command()
27
31
  .name("supatype")
28
32
  .description("Supatype — schema-first Postgres API")
29
- .version(ENGINE_VERSION)
33
+ .version("0.1.0")
30
34
 
31
35
  registerInit(program)
32
36
  registerDev(program)
37
+ registerCache(program)
38
+ registerSelfUpdate(program)
39
+ registerUpdate(program)
40
+ registerPg(program)
33
41
  registerPush(program)
34
42
  registerDiff(program)
35
43
  registerPull(program)
@@ -48,11 +56,8 @@ export function run(): void {
48
56
  registerAdmin(program)
49
57
  registerFunctions(program)
50
58
  registerPlugins(program)
51
-
52
- // After command execution, show update notification (non-blocking)
53
- program.hook("postAction", async () => {
54
- await showUpdateNotification()
55
- })
59
+ registerTypes(program)
60
+ registerMigrateFromV1(program)
56
61
 
57
62
  program.parse()
58
63
  }
@@ -8,6 +8,7 @@ import { createInterface } from "node:readline"
8
8
  import { randomBytes, scrypt } from "node:crypto"
9
9
  import { promisify } from "node:util"
10
10
  import { loadConfig } from "../config.js"
11
+ import { connectionString } from "../project-config.js"
11
12
  import { signJwt } from "../jwt.js"
12
13
 
13
14
  const scryptAsync = promisify(scrypt)
@@ -33,7 +34,7 @@ export function registerAdmin(program: Command): void {
33
34
  }) => {
34
35
  const cwd = process.cwd()
35
36
  const config = loadConfig(cwd)
36
- const connection = opts.connection ?? config.connection
37
+ const connection = opts.connection ?? connectionString(config)
37
38
 
38
39
  const email = opts.email ?? (await prompt("Admin email: "))
39
40
  if (!email || !email.includes("@")) {
@@ -146,7 +147,7 @@ export function registerAdmin(program: Command): void {
146
147
  async (opts: { email: string; role: string; connection?: string }) => {
147
148
  const cwd = process.cwd()
148
149
  const config = loadConfig(cwd)
149
- const connection = opts.connection ?? config.connection
150
+ const connection = opts.connection ?? connectionString(config)
150
151
 
151
152
  const pg = await importPg()
152
153
  const pool = new pg.Pool({ connectionString: connection, max: 2 })
@@ -194,7 +195,7 @@ export function registerAdmin(program: Command): void {
194
195
  .action(async (opts: { connection?: string }) => {
195
196
  const cwd = process.cwd()
196
197
  const config = loadConfig(cwd)
197
- const connection = opts.connection ?? config.connection
198
+ const connection = opts.connection ?? connectionString(config)
198
199
 
199
200
  const pg = await importPg()
200
201
  const pool = new pg.Pool({ connectionString: connection, max: 2 })
@@ -1,25 +1,45 @@
1
1
  import type { Command } from "commander"
2
- import { readFileSync, writeFileSync, existsSync } from "node:fs"
2
+ import { existsSync, mkdirSync } from "node:fs"
3
3
  import { resolve } from "node:path"
4
- import { APP_COMPOSE_MARKER, KONG_APP_MARKER } from "./init.js"
4
+ import { localKongBaseUrl } from "../local-gateway.js"
5
+ import { updateAppConfigInProject } from "../app-config.js"
5
6
 
6
7
  export function registerApp(program: Command): void {
7
8
  const appCmd = program
8
9
  .command("app")
9
- .description("Manage your application container in the Supatype stack")
10
+ .description("Manage application routing intent in supatype.config.ts")
10
11
 
11
12
  appCmd
12
- .command("add")
13
- .description("Add your application to the docker-compose stack at /")
14
- .option("--dockerfile <path>", "Path to your Dockerfile", "./Dockerfile")
15
- .option("--port <port>", "Port your app listens on", "3000")
16
- .action((opts: { dockerfile: string; port: string }) => {
17
- addApp(process.cwd(), opts.dockerfile, opts.port)
18
- })
13
+ .command("add [dir]")
14
+ .description("Configure app routing: --static for a built site, or proxy to a dev server")
15
+ .option("--static", "Serve a static directory at / (default: ./public, or [dir] argument)")
16
+ .option("--port <port>", "Port your app listens on (proxy mode)", "3000")
17
+ .option("--upstream <url>", "Explicit upstream URL (proxy mode; defaults to localhost:<port>)")
18
+ .option("--dockerfile <path>", "(deprecated) ignored — use supatype.config.ts")
19
+ .action(
20
+ (
21
+ dir: string | undefined,
22
+ opts: {
23
+ static?: boolean
24
+ port: string
25
+ upstream?: string
26
+ dockerfile?: string
27
+ },
28
+ ) => {
29
+ if (opts.static) {
30
+ addStaticApp(process.cwd(), resolveStaticDir(dir))
31
+ return
32
+ }
33
+ if (opts.dockerfile) {
34
+ console.warn("[supatype] --dockerfile is deprecated and ignored.")
35
+ }
36
+ addProxyApp(process.cwd(), opts.port, opts.upstream)
37
+ },
38
+ )
19
39
 
20
40
  appCmd
21
41
  .command("remove")
22
- .description("Remove your application from the docker-compose stack")
42
+ .description("Set app.mode=none in supatype.config.ts")
23
43
  .action(() => {
24
44
  removeApp(process.cwd())
25
45
  })
@@ -27,235 +47,51 @@ export function registerApp(program: Command): void {
27
47
 
28
48
  // ─── Implementation ───────────────────────────────────────────────────────────
29
49
 
30
- function addApp(cwd: string, dockerfile: string, port: string): void {
31
- const composePath = resolve(cwd, "docker-compose.yml")
32
- if (!existsSync(composePath)) {
33
- console.error("docker-compose.yml not found. Run: supatype init")
34
- process.exit(1)
35
- }
36
-
37
- let compose = readFileSync(composePath, "utf8")
38
- if (!compose.includes(APP_COMPOSE_MARKER)) {
39
- console.error("App service slot not found in docker-compose.yml. Is this a supatype project?")
40
- process.exit(1)
41
- }
42
-
43
- if (isAppActive(compose)) {
44
- console.error("App service is already configured. Run: supatype app remove first.")
45
- process.exit(1)
46
- }
47
-
48
- compose = uncommentServiceBlock(compose, APP_COMPOSE_MARKER, { dockerfile, port })
49
- writeFileSync(composePath, compose, "utf8")
50
- console.log(" updated docker-compose.yml")
51
-
52
- const kongPath = resolve(cwd, ".supatype/kong.yml")
53
- if (existsSync(kongPath)) {
54
- let kong = readFileSync(kongPath, "utf8")
55
- if (kong.includes(KONG_APP_MARKER)) {
56
- kong = uncommentKongBlock(kong, KONG_APP_MARKER, port)
57
- writeFileSync(kongPath, kong, "utf8")
58
- console.log(" updated .supatype/kong.yml")
59
- }
60
- }
61
-
62
- console.log(`\nApp service added (port ${port}). Your app will be available at http://localhost:8000/\n`)
63
- console.log("Run: supatype dev")
50
+ function resolveStaticDir(dir?: string): string {
51
+ const trimmed = dir?.trim()
52
+ return trimmed && trimmed.length > 0 ? trimmed : "./public"
64
53
  }
65
54
 
66
- function removeApp(cwd: string): void {
67
- const composePath = resolve(cwd, "docker-compose.yml")
68
- if (!existsSync(composePath)) {
69
- console.error("docker-compose.yml not found.")
70
- process.exit(1)
55
+ function addStaticApp(cwd: string, staticDir: string): void {
56
+ const abs = resolve(cwd, staticDir)
57
+ if (!existsSync(abs)) {
58
+ mkdirSync(abs, { recursive: true })
59
+ console.log(` created ${staticDir}/`)
71
60
  }
72
-
73
- let compose = readFileSync(composePath, "utf8")
74
- if (!isAppActive(compose)) {
75
- console.error("No active app service found.")
61
+ try {
62
+ 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`)
69
+ } catch (err) {
70
+ console.error((err as Error).message)
76
71
  process.exit(1)
77
72
  }
78
-
79
- compose = recommentServiceBlock(compose, APP_COMPOSE_MARKER)
80
- writeFileSync(composePath, compose, "utf8")
81
- console.log(" updated docker-compose.yml")
82
-
83
- const kongPath = resolve(cwd, ".supatype/kong.yml")
84
- if (existsSync(kongPath)) {
85
- let kong = readFileSync(kongPath, "utf8")
86
- if (!kong.includes(KONG_APP_MARKER)) {
87
- // Active route — re-comment it
88
- kong = recommentKongBlock(kong)
89
- }
90
- writeFileSync(kongPath, kong, "utf8")
91
- console.log(" updated .supatype/kong.yml")
92
- }
93
-
94
- console.log("\nApp service removed.\n")
95
- }
96
-
97
- // ─── Block manipulation helpers ───────────────────────────────────────────────
98
-
99
- /** Returns true if the docker-compose has an active (uncommented) app: service. */
100
- function isAppActive(compose: string): boolean {
101
- return /^ app:/m.test(compose)
102
- }
103
-
104
- /**
105
- * Finds the commented app service block after the marker line and uncomments it,
106
- * substituting the dockerfile path and port.
107
- */
108
- function uncommentServiceBlock(
109
- compose: string,
110
- marker: string,
111
- opts: { dockerfile: string; port: string },
112
- ): string {
113
- const lines = compose.split("\n")
114
- const markerIdx = lines.findIndex((l) => l === marker)
115
- if (markerIdx === -1) return compose
116
-
117
- const result: string[] = []
118
- let i = 0
119
-
120
- while (i < lines.length) {
121
- if (i === markerIdx) {
122
- // Skip the marker line itself, then uncomment the block
123
- i++
124
- while (i < lines.length) {
125
- const line = lines[i]!
126
- // End of block: empty line followed by a non-commented service-level line
127
- if (line === "" && i + 1 < lines.length && !/^ #/.test(lines[i + 1]!)) {
128
- result.push(line)
129
- i++
130
- break
131
- }
132
- if (/^ # /.test(line)) {
133
- // Uncomment: replace " # " prefix with " "
134
- let uncommented = line.replace(/^ # /, " ")
135
- // Substitute placeholders
136
- uncommented = uncommented.replace("./Dockerfile", opts.dockerfile)
137
- uncommented = uncommented.replace(/- "3000:3000"/, `- "${opts.port}:${opts.port}"`)
138
- result.push(uncommented)
139
- } else if (line === "" || /^ #─/.test(line)) {
140
- // Skip remaining marker-style comment lines
141
- } else {
142
- result.push(line)
143
- }
144
- i++
145
- }
146
- } else {
147
- result.push(lines[i]!)
148
- i++
149
- }
150
- }
151
-
152
- return result.join("\n")
153
- }
154
-
155
- /**
156
- * Finds the active app: service block and re-comments it, restoring the marker.
157
- */
158
- function recommentServiceBlock(compose: string, marker: string): string {
159
- const lines = compose.split("\n")
160
- const appIdx = lines.findIndex((l) => l === " app:")
161
- if (appIdx === -1) return compose
162
-
163
- const result: string[] = []
164
- let i = 0
165
-
166
- while (i < lines.length) {
167
- if (i === appIdx) {
168
- result.push(marker)
169
- // Re-comment lines until we hit an empty line or the volumes: section
170
- while (i < lines.length) {
171
- const line = lines[i]!
172
- if (line === "" || /^volumes:/.test(line) || /^ \w/.test(line)) {
173
- result.push(line)
174
- i++
175
- break
176
- }
177
- // Re-comment: " X..." → " # X..."
178
- result.push(line.replace(/^ /, " # "))
179
- i++
180
- }
181
- } else {
182
- result.push(lines[i]!)
183
- i++
184
- }
185
- }
186
-
187
- return result.join("\n")
188
73
  }
189
74
 
190
- /**
191
- * Uncomments the Kong app route block after the marker.
192
- */
193
- function uncommentKongBlock(kong: string, marker: string, port: string): string {
194
- const lines = kong.split("\n")
195
- const markerIdx = lines.findIndex((l) => l === marker)
196
- if (markerIdx === -1) return kong
197
-
198
- const result: string[] = []
199
- let i = 0
200
-
201
- while (i < lines.length) {
202
- if (i === markerIdx) {
203
- i++ // skip marker
204
- while (i < lines.length) {
205
- const line = lines[i]!
206
- if (line === "" && (i + 1 >= lines.length || !/^ #/.test(lines[i + 1]!))) {
207
- result.push(line)
208
- i++
209
- break
210
- }
211
- if (/^ # /.test(line)) {
212
- let uncommented = line.replace(/^ # /, " ")
213
- uncommented = uncommented.replace(":3000", `:${port}`)
214
- result.push(uncommented)
215
- } else {
216
- result.push(line)
217
- }
218
- i++
219
- }
220
- } else {
221
- result.push(lines[i]!)
222
- i++
223
- }
75
+ function addProxyApp(cwd: string, port: string, upstream?: string): void {
76
+ const upstreamUrl = upstream?.trim() || `http://localhost:${port}`
77
+ try {
78
+ 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
+ } catch (err) {
83
+ console.error((err as Error).message)
84
+ process.exit(1)
224
85
  }
225
-
226
- return result.join("\n")
227
86
  }
228
87
 
229
- /**
230
- * Finds the active Kong app route and re-comments it, restoring the marker.
231
- */
232
- function recommentKongBlock(kong: string): string {
233
- const lines = kong.split("\n")
234
- // Find " - name: app" (the active route)
235
- const appIdx = lines.findIndex((l) => /^ - name: app$/.test(l))
236
- if (appIdx === -1) return kong
237
-
238
- const result: string[] = []
239
- let i = 0
240
-
241
- while (i < lines.length) {
242
- if (i === appIdx) {
243
- result.push(KONG_APP_MARKER)
244
- while (i < lines.length) {
245
- const line = lines[i]!
246
- if (line === "" || (i > appIdx && /^ - /.test(line))) {
247
- result.push(line)
248
- i++
249
- break
250
- }
251
- result.push(line.replace(/^ /, " # "))
252
- i++
253
- }
254
- } else {
255
- result.push(lines[i]!)
256
- i++
257
- }
88
+ function removeApp(cwd: string): void {
89
+ try {
90
+ const configPath = updateAppConfigInProject(cwd, { mode: "none" })
91
+ console.log(` updated ${configPath}`)
92
+ console.log("\nApp routing disabled (app.mode=none).\n")
93
+ } catch (err) {
94
+ console.error((err as Error).message)
95
+ process.exit(1)
258
96
  }
259
-
260
- return result.join("\n")
261
97
  }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * supatype cache — list and clean cached component binaries.
3
+ */
4
+
5
+ import type { Command } from "commander"
6
+ import { existsSync, readdirSync, rmSync, statSync } from "node:fs"
7
+ import { join } from "node:path"
8
+ import { cacheRoot, type Component } from "../binary-cache.js"
9
+
10
+ const COMPONENTS: Component[] = ["engine", "server", "postgres", "deno"]
11
+
12
+ export function registerCache(program: Command): void {
13
+ const cache = program
14
+ .command("cache")
15
+ .description("Manage cached component binaries")
16
+
17
+ cache
18
+ .command("list")
19
+ .description("List cached component binaries and their sizes")
20
+ .action(() => {
21
+ const root = cacheRoot()
22
+ if (!existsSync(root)) {
23
+ console.log("Cache is empty.")
24
+ return
25
+ }
26
+
27
+ let totalBytes = 0
28
+ let found = false
29
+
30
+ for (const component of COMPONENTS) {
31
+ const compDir = join(root, component)
32
+ if (!existsSync(compDir)) continue
33
+
34
+ const versions = readdirSync(compDir).filter(
35
+ (v) => statSync(join(compDir, v)).isDirectory(),
36
+ )
37
+ for (const version of versions) {
38
+ const vDir = join(compDir, version)
39
+ const size = dirSize(vDir)
40
+ totalBytes += size
41
+ found = true
42
+ console.log(` ${component}@${version} ${formatBytes(size)}`)
43
+ }
44
+ }
45
+
46
+ if (!found) {
47
+ console.log("Cache is empty.")
48
+ return
49
+ }
50
+
51
+ console.log(`\nTotal: ${formatBytes(totalBytes)}`)
52
+ console.log(`Cache root: ${root}`)
53
+ })
54
+
55
+ cache
56
+ .command("clean [component] [version]")
57
+ .description(
58
+ "Remove cached binaries. Optionally specify a component and/or version.\n" +
59
+ "Examples:\n" +
60
+ " supatype cache clean # remove everything\n" +
61
+ " supatype cache clean engine # remove all engine versions\n" +
62
+ " supatype cache clean engine 0.4.2",
63
+ )
64
+ .action((component?: string, version?: string) => {
65
+ const root = cacheRoot()
66
+ if (!existsSync(root)) {
67
+ console.log("Cache is already empty.")
68
+ return
69
+ }
70
+
71
+ const targets = component ? [component as Component] : COMPONENTS
72
+
73
+ for (const comp of targets) {
74
+ const compDir = join(root, comp)
75
+ if (!existsSync(compDir)) continue
76
+
77
+ if (version) {
78
+ const vDir = join(compDir, version)
79
+ if (!existsSync(vDir)) {
80
+ console.log(` ${comp}@${version} not cached.`)
81
+ continue
82
+ }
83
+ rmSync(vDir, { recursive: true, force: true })
84
+ console.log(` removed ${comp}@${version}`)
85
+ } else {
86
+ rmSync(compDir, { recursive: true, force: true })
87
+ console.log(` removed ${comp} (all versions)`)
88
+ }
89
+ }
90
+
91
+ console.log("Done.")
92
+ })
93
+ }
94
+
95
+ function dirSize(dir: string): number {
96
+ let total = 0
97
+ try {
98
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
99
+ const full = join(dir, entry.name)
100
+ if (entry.isDirectory()) {
101
+ total += dirSize(full)
102
+ } else {
103
+ total += statSync(full).size
104
+ }
105
+ }
106
+ } catch {
107
+ // Skip unreadable entries.
108
+ }
109
+ return total
110
+ }
111
+
112
+ function formatBytes(bytes: number): string {
113
+ if (bytes < 1024) return `${bytes} B`
114
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
115
+ if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
116
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
117
+ }