@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.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +208 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/dist/app/proxy-dev-app.d.ts +13 -0
- package/dist/app/proxy-dev-app.d.ts.map +1 -0
- package/dist/app/proxy-dev-app.js +53 -0
- package/dist/app/proxy-dev-app.js.map +1 -0
- package/dist/app-config.d.ts +7 -0
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js +113 -0
- package/dist/app-config.js.map +1 -0
- package/dist/augmentation-generator.d.ts +2 -0
- package/dist/augmentation-generator.d.ts.map +1 -0
- package/dist/augmentation-generator.js +111 -0
- package/dist/augmentation-generator.js.map +1 -0
- package/dist/binary-cache.d.ts +94 -0
- package/dist/binary-cache.d.ts.map +1 -0
- package/dist/binary-cache.js +669 -0
- package/dist/binary-cache.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +4 -3
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +56 -209
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/cache.d.ts +6 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +105 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/cloud.d.ts +20 -0
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +50 -52
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +47 -54
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/deploy.d.ts +2 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +79 -52
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +11 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +759 -385
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +30 -15
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/engine.d.ts +1 -3
- package/dist/commands/engine.d.ts.map +1 -1
- package/dist/commands/engine.js +13 -85
- package/dist/commands/engine.js.map +1 -1
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +92 -105
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +22 -12
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +137 -410
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate-from-v1.d.ts +5 -0
- package/dist/commands/migrate-from-v1.d.ts.map +1 -0
- package/dist/commands/migrate-from-v1.js +125 -0
- package/dist/commands/migrate-from-v1.js.map +1 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +27 -23
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/pg.d.ts +8 -0
- package/dist/commands/pg.d.ts.map +1 -0
- package/dist/commands/pg.js +102 -0
- package/dist/commands/pg.js.map +1 -0
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +5 -66
- package/dist/commands/pull.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +128 -38
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/seed.d.ts +2 -0
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +44 -11
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/self-host.d.ts +7 -1
- package/dist/commands/self-host.d.ts.map +1 -1
- package/dist/commands/self-host.js +272 -758
- package/dist/commands/self-host.js.map +1 -1
- package/dist/commands/self-update.d.ts +9 -0
- package/dist/commands/self-update.d.ts.map +1 -0
- package/dist/commands/self-update.js +33 -0
- package/dist/commands/self-update.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +4 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/types.d.ts +3 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +62 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +93 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/components.d.ts +5 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +3 -0
- package/dist/components.js.map +1 -0
- package/dist/config.d.ts +10 -51
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +101 -33
- package/dist/config.js.map +1 -1
- package/dist/dev-compose.d.ts +17 -0
- package/dist/dev-compose.d.ts.map +1 -0
- package/dist/dev-compose.js +374 -0
- package/dist/dev-compose.js.map +1 -0
- package/dist/diff-output.d.ts +4 -0
- package/dist/diff-output.d.ts.map +1 -0
- package/dist/diff-output.js +12 -0
- package/dist/diff-output.js.map +1 -0
- package/dist/docker-postgres.d.ts +57 -0
- package/dist/docker-postgres.d.ts.map +1 -0
- package/dist/docker-postgres.js +208 -0
- package/dist/docker-postgres.js.map +1 -0
- package/dist/engine-client.d.ts +69 -0
- package/dist/engine-client.d.ts.map +1 -0
- package/dist/engine-client.js +157 -0
- package/dist/engine-client.js.map +1 -0
- package/dist/ensure-binary.d.ts +7 -0
- package/dist/ensure-binary.d.ts.map +1 -0
- package/dist/ensure-binary.js +17 -0
- package/dist/ensure-binary.js.map +1 -0
- package/dist/functions-router-gen.d.ts +14 -0
- package/dist/functions-router-gen.d.ts.map +1 -0
- package/dist/functions-router-gen.js +199 -0
- package/dist/functions-router-gen.js.map +1 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/kong-config.d.ts +25 -0
- package/dist/kong-config.d.ts.map +1 -0
- package/dist/kong-config.js +71 -0
- package/dist/kong-config.js.map +1 -0
- package/dist/local-gateway.d.ts +7 -0
- package/dist/local-gateway.d.ts.map +1 -0
- package/dist/local-gateway.js +9 -0
- package/dist/local-gateway.js.map +1 -0
- package/dist/local-storage.d.ts +8 -0
- package/dist/local-storage.d.ts.map +1 -0
- package/dist/local-storage.js +14 -0
- package/dist/local-storage.js.map +1 -0
- package/dist/pgbouncer-userlist.d.ts +5 -0
- package/dist/pgbouncer-userlist.d.ts.map +1 -0
- package/dist/pgbouncer-userlist.js +14 -0
- package/dist/pgbouncer-userlist.js.map +1 -0
- package/dist/postgres-ctl.d.ts +44 -0
- package/dist/postgres-ctl.d.ts.map +1 -0
- package/dist/postgres-ctl.js +137 -0
- package/dist/postgres-ctl.js.map +1 -0
- package/dist/process-manager.d.ts +43 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +135 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/project-config.d.ts +235 -0
- package/dist/project-config.d.ts.map +1 -0
- package/dist/project-config.js +160 -0
- package/dist/project-config.js.map +1 -0
- package/dist/pull-utils.d.ts +15 -0
- package/dist/pull-utils.d.ts.map +1 -1
- package/dist/pull-utils.js +12 -0
- package/dist/pull-utils.js.map +1 -1
- package/dist/release-pins.d.ts +7 -0
- package/dist/release-pins.d.ts.map +1 -0
- package/dist/release-pins.js +27 -0
- package/dist/release-pins.js.map +1 -0
- package/dist/release-public-key.d.ts +8 -0
- package/dist/release-public-key.d.ts.map +1 -0
- package/dist/release-public-key.js +13 -0
- package/dist/release-public-key.js.map +1 -0
- package/dist/runtime-routes.d.ts +34 -0
- package/dist/runtime-routes.d.ts.map +1 -0
- package/dist/runtime-routes.js +252 -0
- package/dist/runtime-routes.js.map +1 -0
- package/dist/schema-ast-v2.d.ts +127 -0
- package/dist/schema-ast-v2.d.ts.map +1 -0
- package/dist/schema-ast-v2.js +226 -0
- package/dist/schema-ast-v2.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +5 -6
- package/dist/scripts/postinstall.d.ts.map +1 -1
- package/dist/scripts/postinstall.js +36 -20
- package/dist/scripts/postinstall.js.map +1 -1
- package/dist/self-host-compose.d.ts +22 -0
- package/dist/self-host-compose.d.ts.map +1 -0
- package/dist/self-host-compose.js +347 -0
- package/dist/self-host-compose.js.map +1 -0
- package/dist/storage-provision.d.ts +24 -0
- package/dist/storage-provision.d.ts.map +1 -0
- package/dist/storage-provision.js +44 -0
- package/dist/storage-provision.js.map +1 -0
- package/dist/studio-admin-roles.d.ts +7 -0
- package/dist/studio-admin-roles.d.ts.map +1 -0
- package/dist/studio-admin-roles.js +14 -0
- package/dist/studio-admin-roles.js.map +1 -0
- package/dist/studio-dev-server.d.ts +22 -0
- package/dist/studio-dev-server.d.ts.map +1 -0
- package/dist/studio-dev-server.js +28 -0
- package/dist/studio-dev-server.js.map +1 -0
- package/dist/systemd.d.ts +26 -0
- package/dist/systemd.d.ts.map +1 -0
- package/dist/systemd.js +102 -0
- package/dist/systemd.js.map +1 -0
- package/dist/tsx-runner.d.ts.map +1 -1
- package/dist/tsx-runner.js +9 -2
- package/dist/tsx-runner.js.map +1 -1
- package/dist/type-extractor.d.ts +4 -0
- package/dist/type-extractor.d.ts.map +1 -0
- package/dist/type-extractor.js +1213 -0
- package/dist/type-extractor.js.map +1 -0
- package/dist/type-resolver.d.ts +33 -0
- package/dist/type-resolver.d.ts.map +1 -0
- package/dist/type-resolver.js +338 -0
- package/dist/type-resolver.js.map +1 -0
- package/package.json +4 -3
- package/releases/deno/VERSION +1 -0
- package/scripts/mirror-deno-release.sh +76 -0
- package/src/TYPE-RESOLUTION.md +294 -0
- package/src/app/proxy-dev-app.ts +67 -0
- package/src/app-config.ts +128 -0
- package/src/augmentation-generator.ts +126 -0
- package/src/binary-cache.ts +822 -0
- package/src/cli.ts +13 -8
- package/src/commands/admin.ts +4 -3
- package/src/commands/app.ts +67 -231
- package/src/commands/cache.ts +117 -0
- package/src/commands/cloud.ts +63 -64
- package/src/commands/db.ts +54 -63
- package/src/commands/deploy.ts +96 -62
- package/src/commands/dev.ts +933 -405
- package/src/commands/diff.ts +31 -29
- package/src/commands/engine.ts +13 -116
- package/src/commands/functions.ts +97 -115
- package/src/commands/generate.ts +23 -10
- package/src/commands/init.ts +149 -414
- package/src/commands/migrate-from-v1.ts +131 -0
- package/src/commands/migrate.ts +27 -23
- package/src/commands/pg.ts +133 -0
- package/src/commands/pull.ts +6 -85
- package/src/commands/push.ts +161 -56
- package/src/commands/seed.ts +54 -12
- package/src/commands/self-host.ts +312 -880
- package/src/commands/self-update.ts +45 -0
- package/src/commands/status.ts +4 -3
- package/src/commands/types.ts +76 -0
- package/src/commands/update.ts +109 -0
- package/src/components.ts +6 -0
- package/src/config.ts +127 -94
- package/src/dev-compose.ts +455 -0
- package/src/diff-output.ts +12 -0
- package/src/docker-postgres.ts +295 -0
- package/src/engine-client.ts +236 -0
- package/src/ensure-binary.ts +28 -0
- package/src/functions-router-gen.ts +224 -0
- package/src/index.ts +4 -12
- package/src/kong-config.ts +93 -0
- package/src/local-gateway.ts +9 -0
- package/src/local-storage.ts +14 -0
- package/src/pgbouncer-userlist.ts +15 -0
- package/src/postgres-ctl.ts +171 -0
- package/src/process-manager.ts +168 -0
- package/src/project-config.ts +386 -0
- package/src/pull-utils.ts +24 -0
- package/src/release-pins.ts +31 -0
- package/src/release-public-key.ts +12 -0
- package/src/runtime-routes.ts +291 -0
- package/src/schema-ast-v2.ts +324 -0
- package/src/scripts/postinstall.ts +36 -25
- package/src/self-host-compose.ts +389 -0
- package/src/storage-provision.ts +58 -0
- package/src/studio-admin-roles.ts +16 -0
- package/src/studio-dev-server.ts +53 -0
- package/src/systemd.ts +137 -0
- package/src/tsx-runner.ts +11 -1
- package/src/type-extractor.ts +1479 -0
- package/src/type-resolver.ts +457 -0
- package/tests/app-command.test.ts +54 -0
- package/tests/augmentation-generator.test.ts +59 -0
- package/tests/binary-cache-cloud-overrides.test.ts +123 -0
- package/tests/cached-artifact-format.test.ts +84 -0
- package/tests/cli-help.test.ts +40 -14
- package/tests/config.test.ts +171 -37
- package/tests/docker-postgres.test.ts +39 -0
- package/tests/engine-distribution.test.ts +3 -3
- package/tests/ensure-binary.test.ts +59 -0
- package/tests/init.test.ts +28 -86
- package/tests/migrate-from-v1.test.ts +29 -0
- package/tests/normalize-admin-config.test.ts +48 -0
- package/tests/pg-spawn-env.test.ts +18 -0
- package/tests/postgres-archive-tag.test.ts +9 -0
- package/tests/proxy-dev-app.test.ts +33 -0
- package/tests/pull-utils.test.ts +36 -1
- package/tests/release-pins.test.ts +28 -0
- package/tests/runtime-contract.test.ts +351 -0
- package/tests/seed-discover.test.ts +31 -0
- package/tests/studio-admin-roles.test.ts +27 -0
- package/tests/tsconfig.json +9 -0
- package/tests/type-extractor.test.ts +985 -0
- package/tests/type-resolver.test.ts +59 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +12 -0
- package/dist/engine/cache.d.ts +0 -37
- package/dist/engine/cache.d.ts.map +0 -1
- package/dist/engine/cache.js +0 -121
- package/dist/engine/cache.js.map +0 -1
- package/dist/engine/download.d.ts +0 -19
- package/dist/engine/download.d.ts.map +0 -1
- package/dist/engine/download.js +0 -108
- package/dist/engine/download.js.map +0 -1
- package/dist/engine/platform.d.ts +0 -24
- package/dist/engine/platform.d.ts.map +0 -1
- package/dist/engine/platform.js +0 -50
- package/dist/engine/platform.js.map +0 -1
- package/dist/engine/resolve.d.ts +0 -37
- package/dist/engine/resolve.d.ts.map +0 -1
- package/dist/engine/resolve.js +0 -133
- package/dist/engine/resolve.js.map +0 -1
- package/dist/engine/update-notify.d.ts +0 -11
- package/dist/engine/update-notify.d.ts.map +0 -1
- package/dist/engine/update-notify.js +0 -43
- package/dist/engine/update-notify.js.map +0 -1
- package/dist/engine/verify.d.ts +0 -50
- package/dist/engine/verify.d.ts.map +0 -1
- package/dist/engine/verify.js +0 -161
- package/dist/engine/verify.js.map +0 -1
- package/dist/engine-version.d.ts +0 -35
- package/dist/engine-version.d.ts.map +0 -1
- package/dist/engine-version.js +0 -35
- package/dist/engine-version.js.map +0 -1
- package/dist/engine.d.ts +0 -34
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js +0 -76
- package/dist/engine.js.map +0 -1
- package/src/engine/cache.ts +0 -135
- package/src/engine/download.ts +0 -143
- package/src/engine/platform.ts +0 -66
- package/src/engine/resolve.ts +0 -197
- package/src/engine/update-notify.ts +0 -50
- package/src/engine/verify.ts +0 -206
- package/src/engine-version.ts +0 -39
- package/src/engine.ts +0 -99
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Command } from "commander"
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs"
|
|
3
|
+
import { basename, dirname, extname, join, resolve } from "node:path"
|
|
4
|
+
import ts from "typescript"
|
|
5
|
+
import { loadConfig } from "../config.js"
|
|
6
|
+
import { schemaPathFromProject } from "../project-config.js"
|
|
7
|
+
|
|
8
|
+
export function registerMigrateFromV1(program: Command): void {
|
|
9
|
+
program
|
|
10
|
+
.command("migrate-from-v1")
|
|
11
|
+
.description("Codemod runtime model() schema DSL into RFC v2 Model<> type aliases")
|
|
12
|
+
.option("--schema <path>", "Path to v1 schema file (defaults to supatype.config.ts schema)")
|
|
13
|
+
.option("--write", "Overwrite source file instead of creating .v2.ts sibling")
|
|
14
|
+
.action((opts: { schema?: string; write?: boolean }) => {
|
|
15
|
+
const cwd = process.cwd()
|
|
16
|
+
const cfg = loadConfig(cwd)
|
|
17
|
+
const schemaPath = opts.schema !== undefined
|
|
18
|
+
? resolve(cwd, opts.schema)
|
|
19
|
+
: schemaPathFromProject(cfg, cwd)
|
|
20
|
+
if (!existsSync(schemaPath)) {
|
|
21
|
+
throw new Error(`Schema file not found: ${schemaPath}`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const src = readFileSync(schemaPath, "utf8")
|
|
25
|
+
const sf = ts.createSourceFile(schemaPath, src, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS)
|
|
26
|
+
const output = codemodSource(sf)
|
|
27
|
+
const outPath = opts.write
|
|
28
|
+
? schemaPath
|
|
29
|
+
: join(dirname(schemaPath), basename(schemaPath).replace(extname(schemaPath), ".v2.ts"))
|
|
30
|
+
|
|
31
|
+
writeFileSync(outPath, output, "utf8")
|
|
32
|
+
console.log(`v2 schema written to ${outPath}`)
|
|
33
|
+
if (!opts.write) {
|
|
34
|
+
console.log("Review TODO comments and replace unknown mappings before using this file in production.")
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function codemodSource(sf: ts.SourceFile): string {
|
|
40
|
+
const lines: string[] = []
|
|
41
|
+
lines.push('import type { Model, UUID, Optional } from "@supatype/types"')
|
|
42
|
+
lines.push("")
|
|
43
|
+
lines.push("// TODO(v2-migration): verify each mapped type and access rule below.")
|
|
44
|
+
lines.push("")
|
|
45
|
+
|
|
46
|
+
for (const stmt of sf.statements) {
|
|
47
|
+
if (!ts.isVariableStatement(stmt)) continue
|
|
48
|
+
if (!(ts.getModifiers(stmt)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false)) continue
|
|
49
|
+
|
|
50
|
+
for (const decl of stmt.declarationList.declarations) {
|
|
51
|
+
if (!ts.isIdentifier(decl.name) || !decl.initializer) continue
|
|
52
|
+
const modelCall = extractModelCall(decl.initializer)
|
|
53
|
+
if (!modelCall) continue
|
|
54
|
+
const fields = extractFields(modelCall.config)
|
|
55
|
+
const modelType = renderModelType(decl.name.text, fields)
|
|
56
|
+
lines.push(modelType)
|
|
57
|
+
lines.push("")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (lines.length <= 4) {
|
|
62
|
+
lines.push("// TODO(v2-migration): no model() declarations were detected in this file.")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return lines.join("\n")
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function extractModelCall(node: ts.Expression): { config: ts.ObjectLiteralExpression } | null {
|
|
69
|
+
if (!ts.isCallExpression(node)) return null
|
|
70
|
+
if (!ts.isIdentifier(node.expression) || node.expression.text !== "model") return null
|
|
71
|
+
const config = node.arguments[1]
|
|
72
|
+
if (!config || !ts.isObjectLiteralExpression(config)) return null
|
|
73
|
+
return { config }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function extractFields(config: ts.ObjectLiteralExpression): Array<{ name: string; type: string }> {
|
|
77
|
+
const fieldsProp = config.properties.find(
|
|
78
|
+
(p) => ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === "fields",
|
|
79
|
+
)
|
|
80
|
+
if (!fieldsProp || !ts.isPropertyAssignment(fieldsProp) || !ts.isObjectLiteralExpression(fieldsProp.initializer)) {
|
|
81
|
+
return []
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const result: Array<{ name: string; type: string }> = []
|
|
85
|
+
for (const prop of fieldsProp.initializer.properties) {
|
|
86
|
+
if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue
|
|
87
|
+
result.push({
|
|
88
|
+
name: prop.name.text,
|
|
89
|
+
type: mapFieldInitializerToType(prop.initializer),
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
return result
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function mapFieldInitializerToType(node: ts.Expression): string {
|
|
96
|
+
if (!ts.isCallExpression(node)) return "unknown // TODO(v2-migration): unsupported field expression"
|
|
97
|
+
if (!ts.isPropertyAccessExpression(node.expression)) return "unknown // TODO(v2-migration): unsupported field expression"
|
|
98
|
+
if (!ts.isIdentifier(node.expression.expression) || node.expression.expression.text !== "field") {
|
|
99
|
+
return "unknown // TODO(v2-migration): unsupported field expression"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const kind = node.expression.name.text
|
|
103
|
+
switch (kind) {
|
|
104
|
+
case "uuid":
|
|
105
|
+
return "UUID"
|
|
106
|
+
case "text":
|
|
107
|
+
case "slug":
|
|
108
|
+
case "email":
|
|
109
|
+
case "url":
|
|
110
|
+
return "string"
|
|
111
|
+
case "integer":
|
|
112
|
+
case "smallInt":
|
|
113
|
+
case "float":
|
|
114
|
+
case "decimal":
|
|
115
|
+
return "number"
|
|
116
|
+
case "boolean":
|
|
117
|
+
return "boolean"
|
|
118
|
+
case "richText":
|
|
119
|
+
case "json":
|
|
120
|
+
return "Record<string, unknown>"
|
|
121
|
+
default:
|
|
122
|
+
return "unknown // TODO(v2-migration): map field." + kind
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function renderModelType(name: string, fields: Array<{ name: string; type: string }>): string {
|
|
127
|
+
const fieldsBlock = fields
|
|
128
|
+
.map((field) => ` ${field.name}: ${field.type}`)
|
|
129
|
+
.join("\n")
|
|
130
|
+
return `export type ${name} = Model<{\n${fieldsBlock}\n}>`
|
|
131
|
+
}
|
package/src/commands/migrate.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Command } from "commander"
|
|
2
2
|
import { createInterface } from "node:readline"
|
|
3
|
-
import { loadConfig } from "../config.js"
|
|
4
|
-
import {
|
|
3
|
+
import { loadConfig, loadSchemaAst } from "../config.js"
|
|
4
|
+
import { connectionString, schemaPathFromProject } from "../project-config.js"
|
|
5
|
+
import { ensureEngine, engineRequest } from "../engine-client.js"
|
|
5
6
|
|
|
6
7
|
export function registerMigrate(program: Command): void {
|
|
7
8
|
// migrate — apply all pending migrations
|
|
@@ -11,15 +12,15 @@ export function registerMigrate(program: Command): void {
|
|
|
11
12
|
.option("--connection <url>", "Database connection URL (overrides config)")
|
|
12
13
|
.action(async (opts: { connection?: string }) => {
|
|
13
14
|
const config = loadConfig()
|
|
14
|
-
const connection = opts.connection ?? config
|
|
15
|
+
const connection = opts.connection ?? connectionString(config)
|
|
15
16
|
|
|
16
17
|
await ensureEngine()
|
|
17
|
-
const result =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
console.log(result.
|
|
18
|
+
const result = await engineRequest<{ message?: string }>("/migrations", {
|
|
19
|
+
database_url: connection,
|
|
20
|
+
schema: "public",
|
|
21
|
+
action: "pending",
|
|
22
|
+
})
|
|
23
|
+
console.log(result.message ?? "Migrations applied.")
|
|
23
24
|
})
|
|
24
25
|
|
|
25
26
|
// rollback — undo the last applied migration
|
|
@@ -29,15 +30,15 @@ export function registerMigrate(program: Command): void {
|
|
|
29
30
|
.option("--connection <url>", "Database connection URL (overrides config)")
|
|
30
31
|
.action(async (opts: { connection?: string }) => {
|
|
31
32
|
const config = loadConfig()
|
|
32
|
-
const connection = opts.connection ?? config
|
|
33
|
+
const connection = opts.connection ?? connectionString(config)
|
|
33
34
|
|
|
34
35
|
await ensureEngine()
|
|
35
|
-
const result =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
console.log(result.
|
|
36
|
+
const result = await engineRequest<{ message?: string }>("/migrations", {
|
|
37
|
+
database_url: connection,
|
|
38
|
+
schema: "public",
|
|
39
|
+
action: "rollback",
|
|
40
|
+
})
|
|
41
|
+
console.log(result.message ?? "Rolled back.")
|
|
41
42
|
})
|
|
42
43
|
|
|
43
44
|
// reset — drop all tables and re-apply from scratch
|
|
@@ -60,15 +61,18 @@ export function registerMigrate(program: Command): void {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
const config = loadConfig()
|
|
63
|
-
const connection = opts.connection ?? config
|
|
64
|
+
const connection = opts.connection ?? connectionString(config)
|
|
65
|
+
const cwd = process.cwd()
|
|
64
66
|
|
|
65
67
|
await ensureEngine()
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
const ast = loadSchemaAst(schemaPathFromProject(config, cwd), cwd)
|
|
69
|
+
const result = await engineRequest<{ message?: string }>("/push", {
|
|
70
|
+
ast,
|
|
71
|
+
database_url: connection,
|
|
72
|
+
schema: "public",
|
|
73
|
+
force: true,
|
|
74
|
+
})
|
|
75
|
+
console.log(result.message ?? "Reset complete.")
|
|
72
76
|
})
|
|
73
77
|
}
|
|
74
78
|
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* supatype pg — manage the native Postgres instance for a project.
|
|
3
|
+
*
|
|
4
|
+
* Commands: start, stop, reset, psql
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Command } from "commander"
|
|
8
|
+
import { spawnSync } from "node:child_process"
|
|
9
|
+
import { existsSync, mkdirSync, rmSync } from "node:fs"
|
|
10
|
+
import { homedir } from "node:os"
|
|
11
|
+
import { join } from "node:path"
|
|
12
|
+
import { loadConfig } from "../config.js"
|
|
13
|
+
import { resolveBinary } from "../binary-cache.js"
|
|
14
|
+
import {
|
|
15
|
+
initdb,
|
|
16
|
+
start as pgStart,
|
|
17
|
+
stop as pgStop,
|
|
18
|
+
waitReady,
|
|
19
|
+
} from "../postgres-ctl.js"
|
|
20
|
+
|
|
21
|
+
export function registerPg(program: Command): void {
|
|
22
|
+
const pg = program
|
|
23
|
+
.command("pg")
|
|
24
|
+
.description("Manage the native Postgres instance for the current project")
|
|
25
|
+
|
|
26
|
+
// ── start ────────────────────────────────────────────────────────────────
|
|
27
|
+
pg.command("start")
|
|
28
|
+
.description("Start Postgres for the current project")
|
|
29
|
+
.action(async () => {
|
|
30
|
+
const config = loadConfig()
|
|
31
|
+
const opts = await pgOpts(config)
|
|
32
|
+
initdb(opts)
|
|
33
|
+
pgStart(opts)
|
|
34
|
+
await waitReady(opts, 10_000)
|
|
35
|
+
console.log(
|
|
36
|
+
`[supatype] Postgres started on port ${opts.port} (data: ${opts.dataDir})`,
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// ── stop ─────────────────────────────────────────────────────────────────
|
|
41
|
+
pg.command("stop")
|
|
42
|
+
.description("Stop Postgres for the current project")
|
|
43
|
+
.action(async () => {
|
|
44
|
+
const config = loadConfig()
|
|
45
|
+
const opts = await pgOpts(config)
|
|
46
|
+
pgStop(opts)
|
|
47
|
+
console.log("[supatype] Postgres stopped.")
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// ── reset ─────────────────────────────────────────────────────────────────
|
|
51
|
+
pg.command("reset")
|
|
52
|
+
.description("Stop Postgres, wipe the data directory, and re-initialise")
|
|
53
|
+
.option("--force", "Skip confirmation prompt")
|
|
54
|
+
.action(async (opts: { force: boolean }) => {
|
|
55
|
+
const config = loadConfig()
|
|
56
|
+
const pgOpts_ = await pgOpts(config)
|
|
57
|
+
|
|
58
|
+
if (!opts.force) {
|
|
59
|
+
const readline = await import("node:readline")
|
|
60
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
|
|
61
|
+
const answer = await new Promise<string>((resolve) =>
|
|
62
|
+
rl.question(
|
|
63
|
+
`This will DELETE all data in ${pgOpts_.dataDir}. Continue? [y/N] `,
|
|
64
|
+
resolve,
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
rl.close()
|
|
68
|
+
if (answer.toLowerCase() !== "y") {
|
|
69
|
+
console.log("Aborted.")
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
pgStop(pgOpts_)
|
|
75
|
+
if (existsSync(pgOpts_.dataDir)) {
|
|
76
|
+
rmSync(pgOpts_.dataDir, { recursive: true, force: true })
|
|
77
|
+
console.log(`[supatype] Data directory removed: ${pgOpts_.dataDir}`)
|
|
78
|
+
}
|
|
79
|
+
mkdirSync(pgOpts_.dataDir, { recursive: true })
|
|
80
|
+
initdb(pgOpts_)
|
|
81
|
+
pgStart(pgOpts_)
|
|
82
|
+
await waitReady(pgOpts_, 10_000)
|
|
83
|
+
console.log("[supatype] Postgres reset and started.")
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// ── psql ─────────────────────────────────────────────────────────────────
|
|
87
|
+
pg.command("psql [dbname]")
|
|
88
|
+
.description("Open a psql shell connected to the project database")
|
|
89
|
+
.action(async (dbname?: string) => {
|
|
90
|
+
const config = loadConfig()
|
|
91
|
+
const opts = await pgOpts(config)
|
|
92
|
+
const db = dbname ?? config.project.name
|
|
93
|
+
const psql = join(opts.pgBinDir, "psql")
|
|
94
|
+
|
|
95
|
+
const result = spawnSync(
|
|
96
|
+
psql,
|
|
97
|
+
["-h", "127.0.0.1", "-p", String(opts.port), "-U", "postgres", db],
|
|
98
|
+
{ stdio: "inherit" },
|
|
99
|
+
)
|
|
100
|
+
process.exit(result.status ?? 0)
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// Helper: build PgOptions from config
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
async function pgOpts(
|
|
109
|
+
config: ReturnType<typeof loadConfig>,
|
|
110
|
+
): Promise<import("../postgres-ctl.js").PgOptions> {
|
|
111
|
+
const projectName = config.project.name
|
|
112
|
+
const stateRoot = join(homedir(), ".supatype", "projects", projectName)
|
|
113
|
+
const dataDir = config.database.data_dir ?? join(stateRoot, "data")
|
|
114
|
+
const logsDir = join(stateRoot, "logs")
|
|
115
|
+
mkdirSync(logsDir, { recursive: true })
|
|
116
|
+
|
|
117
|
+
// Resolve pg binary dir.
|
|
118
|
+
const pgCacheDir = await (async () => {
|
|
119
|
+
const override = config.overrides?.postgres_dir
|
|
120
|
+
if (override) return join(override, "bin")
|
|
121
|
+
const { cachePath, currentPlatform } = await import("../binary-cache.js")
|
|
122
|
+
const platform = currentPlatform()
|
|
123
|
+
const version = config.versions.postgres
|
|
124
|
+
return join(cachePath("postgres", version), `pg-${version}`, "bin")
|
|
125
|
+
})()
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
pgBinDir: pgCacheDir,
|
|
129
|
+
dataDir,
|
|
130
|
+
port: 5432,
|
|
131
|
+
logPath: join(logsDir, "postgres.log"),
|
|
132
|
+
}
|
|
133
|
+
}
|
package/src/commands/pull.ts
CHANGED
|
@@ -1,96 +1,17 @@
|
|
|
1
1
|
import type { Command } from "commander"
|
|
2
|
-
import {
|
|
3
|
-
import { resolve } from "node:path"
|
|
4
|
-
import { loadConfig } from "../config.js"
|
|
5
|
-
import { ensureEngine, invokeEngine } from "../engine.js"
|
|
6
|
-
import { pgTypeToField, toCamelCase, type ColumnInfo } from "../pull-utils.js"
|
|
7
|
-
|
|
8
|
-
interface IntrospectResult {
|
|
9
|
-
models: Array<{
|
|
10
|
-
name: string
|
|
11
|
-
tableName: string
|
|
12
|
-
columns: ColumnInfo[]
|
|
13
|
-
}>
|
|
14
|
-
}
|
|
2
|
+
import { ensureEngine } from "../engine-client.js"
|
|
15
3
|
|
|
16
4
|
export function registerPull(program: Command): void {
|
|
17
5
|
program
|
|
18
6
|
.command("pull")
|
|
19
7
|
.description(
|
|
20
|
-
"Introspect an existing Postgres database
|
|
8
|
+
"Introspect an existing Postgres database (deprecated in type-first mode)",
|
|
21
9
|
)
|
|
22
|
-
.
|
|
23
|
-
.option("--output <path>", "Output directory for schema files", "./schema")
|
|
24
|
-
.action(async (opts: { connection?: string; output: string }) => {
|
|
25
|
-
const cwd = process.cwd()
|
|
26
|
-
const connection = opts.connection ?? loadConfig(cwd).connection
|
|
27
|
-
|
|
10
|
+
.action(async () => {
|
|
28
11
|
await ensureEngine()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"--connection",
|
|
33
|
-
connection,
|
|
34
|
-
"--format",
|
|
35
|
-
"json",
|
|
36
|
-
])
|
|
37
|
-
if (result.exitCode !== 0) {
|
|
38
|
-
console.error(result.stderr || result.stdout)
|
|
39
|
-
process.exit(1)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const introspected = JSON.parse(result.stdout) as IntrospectResult
|
|
43
|
-
const models = introspected.models ?? []
|
|
44
|
-
|
|
45
|
-
if (models.length === 0) {
|
|
46
|
-
console.log("No tables found in the database.")
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const outputDir = resolve(cwd, opts.output)
|
|
51
|
-
mkdirSync(outputDir, { recursive: true })
|
|
52
|
-
|
|
53
|
-
for (const model of models) {
|
|
54
|
-
const content = generateModelFile(model)
|
|
55
|
-
writeFileSync(resolve(outputDir, `${model.name}.ts`), content, "utf8")
|
|
56
|
-
console.log(` wrote ${opts.output}/${model.name}.ts`)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const indexContent = generateIndexFile(models.map((m) => m.name))
|
|
60
|
-
writeFileSync(resolve(outputDir, "index.ts"), indexContent, "utf8")
|
|
61
|
-
console.log(` wrote ${opts.output}/index.ts`)
|
|
62
|
-
|
|
63
|
-
console.log(
|
|
64
|
-
`\nPulled ${models.length} model(s). Review TODO comments before running supatype push.\n`,
|
|
12
|
+
throw new Error(
|
|
13
|
+
"The legacy `supatype pull` schema generator has been removed.\n" +
|
|
14
|
+
"Use type-based models with @supatype/types and run `supatype generate`.",
|
|
65
15
|
)
|
|
66
16
|
})
|
|
67
17
|
}
|
|
68
|
-
|
|
69
|
-
function generateModelFile(model: IntrospectResult["models"][number]): string {
|
|
70
|
-
const fieldLines = model.columns
|
|
71
|
-
.map((col) => ` ${col.name}: ${pgTypeToField(col)},`)
|
|
72
|
-
.join("\n")
|
|
73
|
-
|
|
74
|
-
return `import { model, field, access } from "@supatype/schema"
|
|
75
|
-
|
|
76
|
-
// TODO: review access rules — all operations default to authenticated
|
|
77
|
-
export const ${toCamelCase(model.name)} = model(${JSON.stringify(model.name)}, {
|
|
78
|
-
tableName: ${JSON.stringify(model.tableName)},
|
|
79
|
-
fields: {
|
|
80
|
-
${fieldLines}
|
|
81
|
-
},
|
|
82
|
-
access: {
|
|
83
|
-
read: access.role("authenticated"),
|
|
84
|
-
create: access.role("authenticated"),
|
|
85
|
-
update: access.role("authenticated"),
|
|
86
|
-
delete: access.role("authenticated"),
|
|
87
|
-
},
|
|
88
|
-
})
|
|
89
|
-
`
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function generateIndexFile(names: string[]): string {
|
|
93
|
-
return names
|
|
94
|
-
.map((n) => `export { ${toCamelCase(n)} } from "./${n}.js"`)
|
|
95
|
-
.join("\n") + "\n"
|
|
96
|
-
}
|