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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +203 -1
  3. package/.turbo/turbo-typecheck.log +1 -1
  4. package/dist/app-config.d.ts +7 -0
  5. package/dist/app-config.d.ts.map +1 -0
  6. package/dist/app-config.js +113 -0
  7. package/dist/app-config.js.map +1 -0
  8. package/dist/augmentation-generator.d.ts +2 -0
  9. package/dist/augmentation-generator.d.ts.map +1 -0
  10. package/dist/augmentation-generator.js +111 -0
  11. package/dist/augmentation-generator.js.map +1 -0
  12. package/dist/binary-cache.d.ts +89 -0
  13. package/dist/binary-cache.d.ts.map +1 -0
  14. package/dist/binary-cache.js +656 -0
  15. package/dist/binary-cache.js.map +1 -0
  16. package/dist/cli.d.ts.map +1 -1
  17. package/dist/cli.js +13 -7
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/admin.d.ts.map +1 -1
  20. package/dist/commands/admin.js +4 -3
  21. package/dist/commands/admin.js.map +1 -1
  22. package/dist/commands/app.d.ts.map +1 -1
  23. package/dist/commands/app.js +56 -209
  24. package/dist/commands/app.js.map +1 -1
  25. package/dist/commands/cache.d.ts +6 -0
  26. package/dist/commands/cache.d.ts.map +1 -0
  27. package/dist/commands/cache.js +105 -0
  28. package/dist/commands/cache.js.map +1 -0
  29. package/dist/commands/cloud.d.ts +12 -0
  30. package/dist/commands/cloud.d.ts.map +1 -1
  31. package/dist/commands/cloud.js +36 -46
  32. package/dist/commands/cloud.js.map +1 -1
  33. package/dist/commands/db.d.ts.map +1 -1
  34. package/dist/commands/db.js +47 -54
  35. package/dist/commands/db.js.map +1 -1
  36. package/dist/commands/deploy.d.ts +2 -1
  37. package/dist/commands/deploy.d.ts.map +1 -1
  38. package/dist/commands/deploy.js +92 -51
  39. package/dist/commands/deploy.js.map +1 -1
  40. package/dist/commands/dev.d.ts +11 -0
  41. package/dist/commands/dev.d.ts.map +1 -1
  42. package/dist/commands/dev.js +751 -384
  43. package/dist/commands/dev.js.map +1 -1
  44. package/dist/commands/diff.d.ts.map +1 -1
  45. package/dist/commands/diff.js +20 -15
  46. package/dist/commands/diff.js.map +1 -1
  47. package/dist/commands/engine.d.ts +1 -3
  48. package/dist/commands/engine.d.ts.map +1 -1
  49. package/dist/commands/engine.js +13 -85
  50. package/dist/commands/engine.js.map +1 -1
  51. package/dist/commands/functions.d.ts.map +1 -1
  52. package/dist/commands/functions.js +92 -105
  53. package/dist/commands/functions.js.map +1 -1
  54. package/dist/commands/generate.d.ts.map +1 -1
  55. package/dist/commands/generate.js +22 -12
  56. package/dist/commands/generate.js.map +1 -1
  57. package/dist/commands/init.d.ts +1 -1
  58. package/dist/commands/init.d.ts.map +1 -1
  59. package/dist/commands/init.js +124 -410
  60. package/dist/commands/init.js.map +1 -1
  61. package/dist/commands/migrate-from-v1.d.ts +5 -0
  62. package/dist/commands/migrate-from-v1.d.ts.map +1 -0
  63. package/dist/commands/migrate-from-v1.js +125 -0
  64. package/dist/commands/migrate-from-v1.js.map +1 -0
  65. package/dist/commands/migrate.d.ts.map +1 -1
  66. package/dist/commands/migrate.js +27 -23
  67. package/dist/commands/migrate.js.map +1 -1
  68. package/dist/commands/pg.d.ts +8 -0
  69. package/dist/commands/pg.d.ts.map +1 -0
  70. package/dist/commands/pg.js +102 -0
  71. package/dist/commands/pg.js.map +1 -0
  72. package/dist/commands/pull.d.ts.map +1 -1
  73. package/dist/commands/pull.js +5 -66
  74. package/dist/commands/pull.js.map +1 -1
  75. package/dist/commands/push.d.ts.map +1 -1
  76. package/dist/commands/push.js +99 -39
  77. package/dist/commands/push.js.map +1 -1
  78. package/dist/commands/seed.d.ts +2 -0
  79. package/dist/commands/seed.d.ts.map +1 -1
  80. package/dist/commands/seed.js +44 -11
  81. package/dist/commands/seed.js.map +1 -1
  82. package/dist/commands/self-host.d.ts +7 -1
  83. package/dist/commands/self-host.d.ts.map +1 -1
  84. package/dist/commands/self-host.js +272 -758
  85. package/dist/commands/self-host.js.map +1 -1
  86. package/dist/commands/self-update.d.ts +9 -0
  87. package/dist/commands/self-update.d.ts.map +1 -0
  88. package/dist/commands/self-update.js +33 -0
  89. package/dist/commands/self-update.js.map +1 -0
  90. package/dist/commands/status.d.ts.map +1 -1
  91. package/dist/commands/status.js +4 -3
  92. package/dist/commands/status.js.map +1 -1
  93. package/dist/commands/types.d.ts +3 -0
  94. package/dist/commands/types.d.ts.map +1 -0
  95. package/dist/commands/types.js +62 -0
  96. package/dist/commands/types.js.map +1 -0
  97. package/dist/commands/update.d.ts +7 -0
  98. package/dist/commands/update.d.ts.map +1 -0
  99. package/dist/commands/update.js +77 -0
  100. package/dist/commands/update.js.map +1 -0
  101. package/dist/components.d.ts +5 -0
  102. package/dist/components.d.ts.map +1 -0
  103. package/dist/components.js +3 -0
  104. package/dist/components.js.map +1 -0
  105. package/dist/config.d.ts +10 -51
  106. package/dist/config.d.ts.map +1 -1
  107. package/dist/config.js +101 -33
  108. package/dist/config.js.map +1 -1
  109. package/dist/docker-postgres.d.ts +39 -0
  110. package/dist/docker-postgres.d.ts.map +1 -0
  111. package/dist/docker-postgres.js +96 -0
  112. package/dist/docker-postgres.js.map +1 -0
  113. package/dist/engine-client.d.ts +67 -0
  114. package/dist/engine-client.d.ts.map +1 -0
  115. package/dist/engine-client.js +156 -0
  116. package/dist/engine-client.js.map +1 -0
  117. package/dist/ensure-binary.d.ts +7 -0
  118. package/dist/ensure-binary.d.ts.map +1 -0
  119. package/dist/ensure-binary.js +17 -0
  120. package/dist/ensure-binary.js.map +1 -0
  121. package/dist/functions-router-gen.d.ts +14 -0
  122. package/dist/functions-router-gen.d.ts.map +1 -0
  123. package/dist/functions-router-gen.js +199 -0
  124. package/dist/functions-router-gen.js.map +1 -0
  125. package/dist/index.d.ts +4 -5
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +2 -3
  128. package/dist/index.js.map +1 -1
  129. package/dist/kong-config.d.ts +21 -0
  130. package/dist/kong-config.d.ts.map +1 -0
  131. package/dist/kong-config.js +60 -0
  132. package/dist/kong-config.js.map +1 -0
  133. package/dist/local-gateway.d.ts +7 -0
  134. package/dist/local-gateway.d.ts.map +1 -0
  135. package/dist/local-gateway.js +9 -0
  136. package/dist/local-gateway.js.map +1 -0
  137. package/dist/local-storage.d.ts +8 -0
  138. package/dist/local-storage.d.ts.map +1 -0
  139. package/dist/local-storage.js +14 -0
  140. package/dist/local-storage.js.map +1 -0
  141. package/dist/pgbouncer-userlist.d.ts +5 -0
  142. package/dist/pgbouncer-userlist.d.ts.map +1 -0
  143. package/dist/pgbouncer-userlist.js +14 -0
  144. package/dist/pgbouncer-userlist.js.map +1 -0
  145. package/dist/postgres-ctl.d.ts +44 -0
  146. package/dist/postgres-ctl.d.ts.map +1 -0
  147. package/dist/postgres-ctl.js +137 -0
  148. package/dist/postgres-ctl.js.map +1 -0
  149. package/dist/process-manager.d.ts +41 -0
  150. package/dist/process-manager.d.ts.map +1 -0
  151. package/dist/process-manager.js +120 -0
  152. package/dist/process-manager.js.map +1 -0
  153. package/dist/project-config.d.ts +215 -0
  154. package/dist/project-config.d.ts.map +1 -0
  155. package/dist/project-config.js +145 -0
  156. package/dist/project-config.js.map +1 -0
  157. package/dist/pull-utils.d.ts +15 -0
  158. package/dist/pull-utils.d.ts.map +1 -1
  159. package/dist/pull-utils.js +12 -0
  160. package/dist/pull-utils.js.map +1 -1
  161. package/dist/release-pins.d.ts +7 -0
  162. package/dist/release-pins.d.ts.map +1 -0
  163. package/dist/release-pins.js +27 -0
  164. package/dist/release-pins.js.map +1 -0
  165. package/dist/release-public-key.d.ts +8 -0
  166. package/dist/release-public-key.d.ts.map +1 -0
  167. package/dist/release-public-key.js +13 -0
  168. package/dist/release-public-key.js.map +1 -0
  169. package/dist/runtime-routes.d.ts +25 -0
  170. package/dist/runtime-routes.d.ts.map +1 -0
  171. package/dist/runtime-routes.js +189 -0
  172. package/dist/runtime-routes.js.map +1 -0
  173. package/dist/scripts/postinstall.d.ts +5 -6
  174. package/dist/scripts/postinstall.d.ts.map +1 -1
  175. package/dist/scripts/postinstall.js +36 -20
  176. package/dist/scripts/postinstall.js.map +1 -1
  177. package/dist/self-host-compose.d.ts +14 -0
  178. package/dist/self-host-compose.d.ts.map +1 -0
  179. package/dist/self-host-compose.js +236 -0
  180. package/dist/self-host-compose.js.map +1 -0
  181. package/dist/storage-provision.d.ts +24 -0
  182. package/dist/storage-provision.d.ts.map +1 -0
  183. package/dist/storage-provision.js +44 -0
  184. package/dist/storage-provision.js.map +1 -0
  185. package/dist/systemd.d.ts +26 -0
  186. package/dist/systemd.d.ts.map +1 -0
  187. package/dist/systemd.js +102 -0
  188. package/dist/systemd.js.map +1 -0
  189. package/dist/tsx-runner.d.ts.map +1 -1
  190. package/dist/tsx-runner.js +9 -2
  191. package/dist/tsx-runner.js.map +1 -1
  192. package/dist/type-extractor.d.ts +31 -0
  193. package/dist/type-extractor.d.ts.map +1 -0
  194. package/dist/type-extractor.js +876 -0
  195. package/dist/type-extractor.js.map +1 -0
  196. package/package.json +4 -3
  197. package/releases/deno/VERSION +1 -0
  198. package/scripts/mirror-deno-release.sh +76 -0
  199. package/src/app-config.ts +128 -0
  200. package/src/augmentation-generator.ts +126 -0
  201. package/src/binary-cache.ts +802 -0
  202. package/src/cli.ts +13 -8
  203. package/src/commands/admin.ts +4 -3
  204. package/src/commands/app.ts +67 -231
  205. package/src/commands/cache.ts +117 -0
  206. package/src/commands/cloud.ts +46 -57
  207. package/src/commands/db.ts +54 -63
  208. package/src/commands/deploy.ts +110 -61
  209. package/src/commands/dev.ts +930 -405
  210. package/src/commands/diff.ts +21 -29
  211. package/src/commands/engine.ts +13 -116
  212. package/src/commands/functions.ts +97 -115
  213. package/src/commands/generate.ts +23 -10
  214. package/src/commands/init.ts +136 -414
  215. package/src/commands/migrate-from-v1.ts +131 -0
  216. package/src/commands/migrate.ts +27 -23
  217. package/src/commands/pg.ts +133 -0
  218. package/src/commands/pull.ts +6 -85
  219. package/src/commands/push.ts +128 -59
  220. package/src/commands/seed.ts +54 -12
  221. package/src/commands/self-host.ts +312 -880
  222. package/src/commands/self-update.ts +45 -0
  223. package/src/commands/status.ts +4 -3
  224. package/src/commands/types.ts +76 -0
  225. package/src/commands/update.ts +92 -0
  226. package/src/components.ts +6 -0
  227. package/src/config.ts +127 -94
  228. package/src/docker-postgres.ts +138 -0
  229. package/src/engine-client.ts +231 -0
  230. package/src/ensure-binary.ts +28 -0
  231. package/src/functions-router-gen.ts +224 -0
  232. package/src/index.ts +4 -12
  233. package/src/kong-config.ts +78 -0
  234. package/src/local-gateway.ts +9 -0
  235. package/src/local-storage.ts +14 -0
  236. package/src/pgbouncer-userlist.ts +15 -0
  237. package/src/postgres-ctl.ts +171 -0
  238. package/src/process-manager.ts +151 -0
  239. package/src/project-config.ts +353 -0
  240. package/src/pull-utils.ts +24 -0
  241. package/src/release-pins.ts +31 -0
  242. package/src/release-public-key.ts +12 -0
  243. package/src/runtime-routes.ts +216 -0
  244. package/src/scripts/postinstall.ts +36 -25
  245. package/src/self-host-compose.ts +257 -0
  246. package/src/storage-provision.ts +58 -0
  247. package/src/systemd.ts +137 -0
  248. package/src/tsx-runner.ts +11 -1
  249. package/src/type-extractor.ts +1016 -0
  250. package/tests/app-command.test.ts +54 -0
  251. package/tests/augmentation-generator.test.ts +59 -0
  252. package/tests/binary-cache-cloud-overrides.test.ts +123 -0
  253. package/tests/cached-artifact-format.test.ts +84 -0
  254. package/tests/cli-help.test.ts +40 -14
  255. package/tests/config.test.ts +140 -37
  256. package/tests/engine-distribution.test.ts +3 -3
  257. package/tests/ensure-binary.test.ts +59 -0
  258. package/tests/init.test.ts +28 -86
  259. package/tests/migrate-from-v1.test.ts +29 -0
  260. package/tests/pg-spawn-env.test.ts +18 -0
  261. package/tests/postgres-archive-tag.test.ts +9 -0
  262. package/tests/pull-utils.test.ts +36 -1
  263. package/tests/release-pins.test.ts +28 -0
  264. package/tests/runtime-contract.test.ts +236 -0
  265. package/tests/seed-discover.test.ts +31 -0
  266. package/tests/tsconfig.json +9 -0
  267. package/tests/type-extractor.test.ts +401 -0
  268. package/tsconfig.tsbuildinfo +1 -1
  269. package/vitest.config.ts +12 -0
  270. package/dist/engine/cache.d.ts +0 -37
  271. package/dist/engine/cache.d.ts.map +0 -1
  272. package/dist/engine/cache.js +0 -121
  273. package/dist/engine/cache.js.map +0 -1
  274. package/dist/engine/download.d.ts +0 -19
  275. package/dist/engine/download.d.ts.map +0 -1
  276. package/dist/engine/download.js +0 -108
  277. package/dist/engine/download.js.map +0 -1
  278. package/dist/engine/platform.d.ts +0 -24
  279. package/dist/engine/platform.d.ts.map +0 -1
  280. package/dist/engine/platform.js +0 -50
  281. package/dist/engine/platform.js.map +0 -1
  282. package/dist/engine/resolve.d.ts +0 -37
  283. package/dist/engine/resolve.d.ts.map +0 -1
  284. package/dist/engine/resolve.js +0 -133
  285. package/dist/engine/resolve.js.map +0 -1
  286. package/dist/engine/update-notify.d.ts +0 -11
  287. package/dist/engine/update-notify.d.ts.map +0 -1
  288. package/dist/engine/update-notify.js +0 -43
  289. package/dist/engine/update-notify.js.map +0 -1
  290. package/dist/engine/verify.d.ts +0 -50
  291. package/dist/engine/verify.d.ts.map +0 -1
  292. package/dist/engine/verify.js +0 -161
  293. package/dist/engine/verify.js.map +0 -1
  294. package/dist/engine-version.d.ts +0 -35
  295. package/dist/engine-version.d.ts.map +0 -1
  296. package/dist/engine-version.js +0 -35
  297. package/dist/engine-version.js.map +0 -1
  298. package/dist/engine.d.ts +0 -34
  299. package/dist/engine.d.ts.map +0 -1
  300. package/dist/engine.js +0 -76
  301. package/dist/engine.js.map +0 -1
  302. package/src/engine/cache.ts +0 -135
  303. package/src/engine/download.ts +0 -143
  304. package/src/engine/platform.ts +0 -66
  305. package/src/engine/resolve.ts +0 -197
  306. package/src/engine/update-notify.ts +0 -50
  307. package/src/engine/verify.ts +0 -206
  308. package/src/engine-version.ts +0 -39
  309. package/src/engine.ts +0 -99
@@ -1,17 +1,15 @@
1
1
  import type { Command } from "commander"
2
+ import { mkdirSync, writeFileSync } from "node:fs"
2
3
  import { createInterface } from "node:readline"
4
+ import { join } from "node:path"
3
5
  import { loadConfig, loadSchemaAst } from "../config.js"
4
- import { ensureEngine, invokeEngine } from "../engine.js"
6
+ import { connectionString, schemaPathFromProject, serverBaseUrl } from "../project-config.js"
7
+ import { ensureEngine, engineRequest, type DiffResult, type Operation } from "../engine-client.js"
8
+ import { signJwt } from "../jwt.js"
9
+ import { provisionBuckets } from "../storage-provision.js"
5
10
  import { promptFirstAdminUser } from "./admin.js"
6
- interface DiffResult {
7
- operations: Operation[]
8
- }
9
11
 
10
- interface Operation {
11
- kind: string
12
- risk: "safe" | "cautious" | "destructive"
13
- description: string
14
- }
12
+ const DEV_JWT_SECRET = "super-secret-jwt-token-with-at-least-32-characters-long"
15
13
 
16
14
  export function registerPush(program: Command): void {
17
15
  program
@@ -24,72 +22,112 @@ export function registerPush(program: Command): void {
24
22
  .action(async (opts: { yes?: boolean; connection?: string }) => {
25
23
  const cwd = process.cwd()
26
24
  const config = loadConfig(cwd)
27
- const connection = opts.connection ?? config.connection
25
+ const connection = opts.connection ?? connectionString(config)
28
26
 
29
27
  await ensureEngine()
30
28
 
31
29
  console.log("Loading schema...")
32
- const ast = loadSchemaAst(config.schema, cwd)
30
+ const ast = loadSchemaAst(schemaPathFromProject(config, cwd), cwd)
33
31
 
34
- // Validate configured providers before diffing
35
32
  console.log("Diffing against database...")
36
- const diffResult = invokeEngine(
37
- ["diff", "--connection", connection, "--format", "json"],
38
- JSON.stringify(ast),
39
- )
40
- if (diffResult.exitCode !== 0) {
41
- console.error(diffResult.stderr || diffResult.stdout)
42
- process.exit(1)
43
- }
33
+ const diff = await engineRequest<DiffResult>("/diff", {
34
+ ast,
35
+ database_url: connection,
36
+ schema: "public",
37
+ })
44
38
 
45
- const diff = JSON.parse(diffResult.stdout) as DiffResult
46
39
  const ops = diff.operations ?? []
47
40
 
48
41
  if (ops.length === 0) {
49
- console.log("Schema is up to date. Nothing to push.")
50
- return
51
- }
52
-
53
- printDiff(ops)
54
-
55
- const destructive = ops.filter((o) => o.risk === "destructive")
56
- if (destructive.length > 0 && !opts.yes) {
57
- const confirmed = await confirm(
58
- `\n${destructive.length} destructive operation(s) above. Proceed? [y/N] `,
42
+ console.log(
43
+ "Schema matches the database (no DDL). Refreshing admin metadata and local Studio config...",
59
44
  )
60
- if (!confirmed) {
61
- console.log("Aborted.")
62
- return
45
+ } else {
46
+ printDiff(ops)
47
+
48
+ const destructive = ops.filter((o) => o.risk === "danger")
49
+ if (destructive.length > 0 && !opts.yes) {
50
+ const confirmed = await confirm(
51
+ `\n${destructive.length} destructive operation(s) above. Proceed? [y/N] `,
52
+ )
53
+ if (!confirmed) {
54
+ console.log("Aborted.")
55
+ return
56
+ }
63
57
  }
64
58
  }
65
59
 
66
- console.log("\nApplying migration...")
67
- const migrateResult = invokeEngine(
68
- ["migrate", "--connection", connection],
69
- JSON.stringify(ast),
70
- )
71
- if (migrateResult.exitCode !== 0) {
72
- console.error(migrateResult.stderr || migrateResult.stdout)
73
- process.exit(1)
60
+ console.log(ops.length > 0 ? "\nApplying migration..." : "\nSyncing with engine...")
61
+ const pushResult = await engineRequest<{
62
+ message?: string
63
+ status?: string
64
+ admin_refreshed?: boolean
65
+ }>("/push", {
66
+ ast,
67
+ database_url: connection,
68
+ schema: "public",
69
+ force: true,
70
+ })
71
+ if (pushResult.status === "up_to_date") {
72
+ console.log(
73
+ pushResult.admin_refreshed
74
+ ? "Admin config updated on the latest migration record (no SQL applied)."
75
+ : "Schema is up to date.",
76
+ )
77
+ } else {
78
+ console.log(pushResult.message ?? "Migration applied.")
74
79
  }
75
- console.log(migrateResult.stdout || "Migration applied.")
76
80
 
77
- // After migration, check if this is the first push and offer to create an
81
+ await writeLocalAdminConfig(ast)
82
+
83
+ // After a DDL migration, check if this is the first push and offer to create an
78
84
  // admin user if none exist (Gap Appendices task 48).
79
- await promptFirstAdminUser(connection)
85
+ if (ops.length > 0) {
86
+ await promptFirstAdminUser(connection)
87
+ }
88
+
89
+ // Provision storage buckets declared in the schema.
90
+ const baseUrl = serverBaseUrl(config)
91
+ const serviceRoleKey =
92
+ process.env["SUPATYPE_SERVICE_ROLE_KEY"] ??
93
+ (config.server.mode === "dev"
94
+ ? signJwt({ role: "service_role", iss: "supatype", iat: Math.floor(Date.now() / 1000) }, DEV_JWT_SECRET)
95
+ : undefined)
96
+
97
+ if (baseUrl && serviceRoleKey) {
98
+ const parsedAst = await engineRequest<{
99
+ storageBuckets?: Array<{
100
+ id: string
101
+ public: boolean
102
+ accessMode?: "public" | "private" | "custom"
103
+ allowedMimeTypes?: string[]
104
+ fileSizeLimit?: number
105
+ s3BucketPolicy?: string
106
+ }>
107
+ }>("/parse", { ast })
108
+ const buckets = (parsedAst.storageBuckets ?? []).map((b) => ({
109
+ id: b.id,
110
+ public: b.public,
111
+ ...(b.accessMode !== undefined && { access_mode: b.accessMode }),
112
+ ...(b.allowedMimeTypes != null && { allowed_mime_types: b.allowedMimeTypes }),
113
+ ...(b.fileSizeLimit != null && { file_size_limit: b.fileSizeLimit }),
114
+ ...(b.s3BucketPolicy != null &&
115
+ b.s3BucketPolicy !== "" && { s3_bucket_policy: b.s3BucketPolicy }),
116
+ }))
117
+ if (buckets.length > 0) {
118
+ console.log("Provisioning storage buckets...")
119
+ await provisionBuckets(`${baseUrl}/storage/v1`, serviceRoleKey, buckets)
120
+ }
121
+ }
80
122
 
81
123
  if (config.output?.types ?? config.output?.client) {
82
124
  console.log("Generating types...")
83
- const genArgs = ["generate", "--connection", connection]
84
- if (config.output?.types) genArgs.push("--types", config.output.types)
85
- if (config.output?.client) genArgs.push("--client", config.output.client)
86
-
87
- const genResult = invokeEngine(genArgs, JSON.stringify(ast))
88
- if (genResult.exitCode !== 0) {
89
- console.error(genResult.stderr || genResult.stdout)
90
- process.exit(1)
91
- }
92
- console.log(genResult.stdout || "Types generated.")
125
+ const genBody: Record<string, unknown> = { ast, lang: "typescript" }
126
+ if (config.output?.types) genBody["types_path"] = config.output.types
127
+ if (config.output?.client) genBody["client_path"] = config.output.client
128
+
129
+ const genResult = await engineRequest<{ code?: string; message?: string }>("/generate", genBody)
130
+ console.log(genResult.message ?? "Types generated.")
93
131
  }
94
132
 
95
133
  console.log("\nDone.")
@@ -97,15 +135,37 @@ export function registerPush(program: Command): void {
97
135
  }
98
136
 
99
137
  function printDiff(ops: Operation[]): void {
100
- const symbol: Record<Operation["risk"], string> = {
138
+ const symbol: Record<NonNullable<Operation["risk"]>, string> = {
101
139
  safe: "+",
102
- cautious: "~",
103
- destructive: "!",
140
+ warn: "~",
141
+ danger: "!",
104
142
  }
105
143
  console.log(`\n${ops.length} change(s) planned:\n`)
106
144
  for (const op of ops) {
107
- console.log(` [${symbol[op.risk]}] ${op.description}`)
145
+ const s = op.risk ? symbol[op.risk] : "?"
146
+ console.log(` [${s}] ${formatOperation(op)}`)
147
+ }
148
+ }
149
+
150
+ function formatOperation(op: Operation): string {
151
+ if (typeof op.description === "string" && op.description.trim().length > 0) {
152
+ return op.description
153
+ }
154
+
155
+ const kind = typeof op.kind === "string" ? op.kind : "operation"
156
+ const raw = op as unknown as Record<string, unknown>
157
+ const table = raw["table"]
158
+ const column = raw["column"]
159
+
160
+ if (typeof table === "string" && typeof column === "string") {
161
+ return `${kind} ${table}.${column}`
162
+ }
163
+ if (typeof table === "string") {
164
+ return `${kind} ${table}`
108
165
  }
166
+
167
+ // Last resort: show operation kind with compact payload.
168
+ return `${kind} ${JSON.stringify(op)}`
109
169
  }
110
170
 
111
171
  async function confirm(prompt: string): Promise<boolean> {
@@ -117,3 +177,12 @@ async function confirm(prompt: string): Promise<boolean> {
117
177
  })
118
178
  })
119
179
  }
180
+
181
+ /** Write `.supatype/admin-config.json` for local Studio (same layout as `supatype dev`). */
182
+ async function writeLocalAdminConfig(ast: unknown): Promise<void> {
183
+ const cwd = process.cwd()
184
+ const dir = join(cwd, ".supatype")
185
+ mkdirSync(dir, { recursive: true })
186
+ const admin = await engineRequest<unknown>("/admin", { ast })
187
+ writeFileSync(join(dir, "admin-config.json"), `${JSON.stringify(admin, null, 2)}\n`)
188
+ }
@@ -1,26 +1,68 @@
1
1
  import type { Command } from "commander"
2
- import { existsSync } from "node:fs"
3
- import { resolve } from "node:path"
2
+ import { existsSync, readdirSync } from "node:fs"
3
+ import { join, resolve } from "node:path"
4
+ import { isLinkedToCloudProject } from "../binary-cache.js"
5
+ import { loadConfig } from "../config.js"
6
+ import { projectRootFromConfig } from "../project-config.js"
4
7
  import { runTsFile } from "../tsx-runner.js"
5
8
 
9
+ const SEED_EXT = /\.(ts|mts|tsx)$/
10
+
11
+ /** Seed entries under `seeds/`, sorted by filename (Phase 10.6 C19). */
12
+ export function discoverSeedsDir(cwd: string, seedsDir: string): string[] {
13
+ if (!existsSync(seedsDir)) return []
14
+ const names = readdirSync(seedsDir).filter((n) => SEED_EXT.test(n))
15
+ names.sort((a, b) => a.localeCompare(b))
16
+ return names.map((n) => join(seedsDir, n))
17
+ }
18
+
6
19
  export function registerSeed(program: Command): void {
7
20
  program
8
21
  .command("seed [file]")
9
- .description("Run seed.ts (or a custom seed file) against the database")
10
- .action((file?: string) => {
22
+ .description(
23
+ "Run database seeds: optional single file; else all seeds/*.ts (alphabetical); else seed.ts",
24
+ )
25
+ .option(
26
+ "--force",
27
+ "Allow running when the project is linked to Supatype Cloud (dangerous)",
28
+ false,
29
+ )
30
+ .action(async (file: string | undefined, opts: { force: boolean }) => {
11
31
  const cwd = process.cwd()
12
- const seedFile = resolve(cwd, file ?? "seed.ts")
13
-
14
- if (!existsSync(seedFile)) {
15
- console.error(`Seed file not found: ${seedFile}`)
32
+ const config = loadConfig(cwd)
33
+ if (isLinkedToCloudProject(cwd, config) && !opts.force) {
34
+ console.error(
35
+ "[supatype] This project is linked to Supatype Cloud. Refusing to run seeds locally.\n" +
36
+ " Pass --force only if you intend to target this linked project (advanced).",
37
+ )
16
38
  process.exit(1)
17
39
  }
18
40
 
19
- console.log(`Running ${seedFile}...`)
20
- const result = runTsFile(seedFile, { cwd, stdio: "inherit" })
41
+ const root = projectRootFromConfig(config, cwd)
42
+ const seedsDir = join(root, "seeds")
43
+
44
+ let paths: string[]
45
+ if (file !== undefined && file.trim() !== "") {
46
+ paths = [resolve(cwd, file)]
47
+ } else {
48
+ paths = discoverSeedsDir(cwd, seedsDir)
49
+ if (paths.length === 0) {
50
+ paths = [resolve(root, "seed.ts")]
51
+ }
52
+ }
53
+
54
+ const missing = paths.filter((p) => !existsSync(p))
55
+ if (missing.length > 0) {
56
+ console.error(`Seed file(s) not found:\n ${missing.join("\n ")}`)
57
+ process.exit(1)
58
+ }
21
59
 
22
- if (result.exitCode !== 0) {
23
- process.exit(result.exitCode)
60
+ for (const seedFile of paths) {
61
+ console.log(`[supatype] Running ${seedFile}...`)
62
+ const result = runTsFile(seedFile, { cwd, stdio: "inherit" })
63
+ if (result.exitCode !== 0) {
64
+ process.exit(result.exitCode)
65
+ }
24
66
  }
25
67
  })
26
68
  }