@supatype/cli 0.1.5 → 0.1.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.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +143 -93
- package/.turbo/turbo-typecheck.log +1 -1
- package/deno.d.ts +52 -0
- package/dist/augmentation-generator.d.ts +22 -0
- package/dist/augmentation-generator.d.ts.map +1 -1
- package/dist/augmentation-generator.js +43 -7
- package/dist/augmentation-generator.js.map +1 -1
- package/dist/binary-cache.d.ts +14 -0
- package/dist/binary-cache.d.ts.map +1 -1
- package/dist/binary-cache.js +33 -13
- package/dist/binary-cache.js.map +1 -1
- package/dist/cache-clean.d.ts +15 -0
- package/dist/cache-clean.d.ts.map +1 -0
- package/dist/cache-clean.js +76 -0
- package/dist/cache-clean.js.map +1 -0
- package/dist/cache-pins.d.ts +51 -0
- package/dist/cache-pins.d.ts.map +1 -0
- package/dist/cache-pins.js +184 -0
- package/dist/cache-pins.js.map +1 -0
- package/dist/cli-install-method.d.ts +19 -0
- package/dist/cli-install-method.d.ts.map +1 -0
- package/dist/cli-install-method.js +60 -0
- package/dist/cli-install-method.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/cloud-credentials.d.ts +34 -0
- package/dist/cloud-credentials.d.ts.map +1 -0
- package/dist/cloud-credentials.js +139 -0
- package/dist/cloud-credentials.js.map +1 -0
- package/dist/commands/admin.d.ts +11 -0
- package/dist/commands/admin.d.ts.map +1 -1
- package/dist/commands/admin.js +131 -22
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/cache.d.ts.map +1 -1
- package/dist/commands/cache.js +67 -71
- package/dist/commands/cache.js.map +1 -1
- package/dist/commands/cloud.d.ts.map +1 -1
- package/dist/commands/cloud.js +32 -8
- package/dist/commands/cloud.js.map +1 -1
- package/dist/commands/db.d.ts +1 -0
- package/dist/commands/db.d.ts.map +1 -1
- package/dist/commands/db.js +147 -1
- package/dist/commands/db.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +50 -10
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +28 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +60 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/functions.d.ts +7 -0
- package/dist/commands/functions.d.ts.map +1 -1
- package/dist/commands/functions.js +40 -6
- package/dist/commands/functions.js.map +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +5 -1
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/hooks.d.ts +12 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +118 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +41 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/internal.d.ts +6 -0
- package/dist/commands/internal.d.ts.map +1 -0
- package/dist/commands/internal.js +22 -0
- package/dist/commands/internal.js.map +1 -0
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +2 -0
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/link-helpers.d.ts.map +1 -1
- package/dist/commands/link-helpers.js +8 -2
- package/dist/commands/link-helpers.js.map +1 -1
- package/dist/commands/login.d.ts +7 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +110 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +110 -7
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/self-update.d.ts +7 -0
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +18 -11
- package/dist/commands/self-update.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -3
- package/dist/config.js.map +1 -1
- package/dist/db-preflight.d.ts +78 -0
- package/dist/db-preflight.d.ts.map +1 -0
- package/dist/db-preflight.js +452 -0
- package/dist/db-preflight.js.map +1 -0
- package/dist/dev-compose.d.ts +1 -1
- package/dist/dev-compose.d.ts.map +1 -1
- package/dist/dev-compose.js +129 -72
- package/dist/dev-compose.js.map +1 -1
- package/dist/env-file.d.ts +40 -2
- package/dist/env-file.d.ts.map +1 -1
- package/dist/env-file.js +132 -11
- package/dist/env-file.js.map +1 -1
- package/dist/field-masking-tier.d.ts +50 -0
- package/dist/field-masking-tier.d.ts.map +1 -0
- package/dist/field-masking-tier.js +91 -0
- package/dist/field-masking-tier.js.map +1 -0
- package/dist/functions-deno-types.d.ts +24 -0
- package/dist/functions-deno-types.d.ts.map +1 -0
- package/dist/functions-deno-types.js +155 -0
- package/dist/functions-deno-types.js.map +1 -0
- package/dist/hook-upload.d.ts +30 -0
- package/dist/hook-upload.d.ts.map +1 -0
- package/dist/hook-upload.js +86 -0
- package/dist/hook-upload.js.map +1 -0
- package/dist/hooks-generator.d.ts +8 -0
- package/dist/hooks-generator.d.ts.map +1 -0
- package/dist/hooks-generator.js +332 -0
- package/dist/hooks-generator.js.map +1 -0
- package/dist/link.d.ts +4 -0
- package/dist/link.d.ts.map +1 -1
- package/dist/link.js +2 -0
- package/dist/link.js.map +1 -1
- package/dist/local-secrets.d.ts +71 -0
- package/dist/local-secrets.d.ts.map +1 -0
- package/dist/local-secrets.js +100 -0
- package/dist/local-secrets.js.map +1 -0
- package/dist/model-hooks.d.ts +73 -0
- package/dist/model-hooks.d.ts.map +1 -0
- package/dist/model-hooks.js +211 -0
- package/dist/model-hooks.js.map +1 -0
- package/dist/postgres-ctl.d.ts +11 -0
- package/dist/postgres-ctl.d.ts.map +1 -1
- package/dist/postgres-ctl.js +25 -2
- package/dist/postgres-ctl.js.map +1 -1
- package/dist/project-config.d.ts +121 -1
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +150 -1
- package/dist/project-config.js.map +1 -1
- package/dist/resolve-target.d.ts +4 -0
- package/dist/resolve-target.d.ts.map +1 -1
- package/dist/resolve-target.js +69 -73
- package/dist/resolve-target.js.map +1 -1
- package/dist/schema-ast-v2.d.ts +2 -1
- package/dist/schema-ast-v2.d.ts.map +1 -1
- package/dist/schema-ast-v2.js +4 -2
- package/dist/schema-ast-v2.js.map +1 -1
- package/dist/schema-push-lock.d.ts.map +1 -1
- package/dist/schema-push-lock.js +43 -16
- package/dist/schema-push-lock.js.map +1 -1
- package/dist/self-host-compose.d.ts +24 -0
- package/dist/self-host-compose.d.ts.map +1 -1
- package/dist/self-host-compose.js +301 -69
- package/dist/self-host-compose.js.map +1 -1
- package/dist/service-role-check.d.ts +21 -0
- package/dist/service-role-check.d.ts.map +1 -0
- package/dist/service-role-check.js +85 -0
- package/dist/service-role-check.js.map +1 -0
- package/dist/target-client.d.ts +17 -0
- package/dist/target-client.d.ts.map +1 -1
- package/dist/target-client.js +69 -17
- package/dist/target-client.js.map +1 -1
- package/dist/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor.js +736 -32
- package/dist/type-extractor.js.map +1 -1
- package/dist/ui/runtime/command-chrome.js +1 -1
- package/dist/ui/runtime/command-chrome.js.map +1 -1
- package/dist/ui/runtime/stdin-after-ink.d.ts.map +1 -1
- package/dist/ui/runtime/stdin-after-ink.js +3 -1
- package/dist/ui/runtime/stdin-after-ink.js.map +1 -1
- package/package.json +4 -1
- package/scripts/generate-homebrew-formula.mjs +121 -0
- package/src/augmentation-generator.ts +46 -9
- package/src/binary-cache.ts +47 -15
- package/src/cache-clean.ts +81 -0
- package/src/cache-pins.ts +243 -0
- package/src/cli-install-method.ts +67 -0
- package/src/cli.ts +6 -0
- package/src/cloud-credentials.ts +183 -0
- package/src/commands/admin.ts +153 -28
- package/src/commands/cache.ts +90 -75
- package/src/commands/cloud.ts +32 -8
- package/src/commands/db.ts +162 -1
- package/src/commands/dev.ts +57 -8
- package/src/commands/doctor.ts +69 -3
- package/src/commands/functions.ts +42 -5
- package/src/commands/generate.ts +5 -1
- package/src/commands/hooks.ts +138 -0
- package/src/commands/init.ts +42 -8
- package/src/commands/internal.ts +23 -0
- package/src/commands/keys.ts +2 -0
- package/src/commands/link-helpers.ts +9 -2
- package/src/commands/login.ts +127 -0
- package/src/commands/push.ts +124 -7
- package/src/commands/self-update.ts +85 -13
- package/src/config.ts +22 -3
- package/src/db-preflight.ts +575 -0
- package/src/dev-compose.ts +144 -73
- package/src/env-file.ts +157 -11
- package/src/field-masking-tier.ts +107 -0
- package/src/functions-deno-types.ts +188 -0
- package/src/hook-upload.ts +107 -0
- package/src/hooks-generator.ts +352 -0
- package/src/link.ts +7 -0
- package/src/local-secrets.ts +104 -0
- package/src/model-hooks.ts +260 -0
- package/src/postgres-ctl.ts +29 -2
- package/src/project-config.ts +236 -2
- package/src/resolve-target.ts +113 -68
- package/src/schema-ast-v2.ts +5 -2
- package/src/schema-push-lock.ts +56 -17
- package/src/self-host-compose.ts +344 -68
- package/src/service-role-check.ts +111 -0
- package/src/target-client.ts +105 -18
- package/src/type-extractor.ts +883 -28
- package/src/ui/runtime/command-chrome.ts +1 -1
- package/src/ui/runtime/stdin-after-ink.ts +3 -1
- package/tests/access-composition.test.ts +667 -0
- package/tests/admin-studio-membership.test.ts +121 -0
- package/tests/api-schemas.test.ts +83 -0
- package/tests/archive-name-alias.test.ts +42 -0
- package/tests/augmentation-generator.test.ts +72 -4
- package/tests/cache-clean.test.ts +206 -0
- package/tests/cli-help.test.ts +3 -0
- package/tests/cli-install-method.test.ts +66 -0
- package/tests/command-chrome-coverage.test.ts +31 -26
- package/tests/command-chrome-wrap.test.ts +1 -0
- package/tests/db-preflight.test.ts +72 -0
- package/tests/doctor-render.test.ts +62 -0
- package/tests/doctor-service-role.test.ts +55 -0
- package/tests/env-file.test.ts +121 -0
- package/tests/external-database-compose.test.ts +184 -0
- package/tests/external-database-config.test.ts +154 -0
- package/tests/field-masking-tier.test.ts +184 -0
- package/tests/functions-deno-types.test.ts +197 -0
- package/tests/homebrew-formula.test.ts +58 -0
- package/tests/hook-upload.test.ts +125 -0
- package/tests/hooks-generator.test.ts +212 -0
- package/tests/init.test.ts +3 -0
- package/tests/local-secrets.test.ts +92 -0
- package/tests/model-hooks.test.ts +322 -0
- package/tests/runtime-contract.test.ts +113 -1
- package/tests/service-role-check.test.ts +109 -0
- package/tests/service-role-routes.test.ts +51 -0
- package/tests/target-client-refresh.test.ts +94 -0
- package/tests/type-extractor.test.ts +187 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/tests/engine-distribution.test.ts +0 -418
package/dist/config.js
CHANGED
|
@@ -3,6 +3,7 @@ import { resolve } from "node:path";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { evalTsSnippet } from "./tsx-runner.js";
|
|
6
|
+
import { readEnvFile } from "./env-file.js";
|
|
6
7
|
import { mergeProjectConfig, validateProjectConfig, } from "./project-config.js";
|
|
7
8
|
import { extractSchemaAstFromTypes } from "./type-extractor.js";
|
|
8
9
|
/** Identity helper — provides type inference for config files. */
|
|
@@ -58,7 +59,21 @@ export function loadConfig(cwd = process.cwd()) {
|
|
|
58
59
|
if (localRaw === null)
|
|
59
60
|
return base;
|
|
60
61
|
const localNorm = normalizeProjectJson(localRaw);
|
|
61
|
-
|
|
62
|
+
// Re-validated after merging: the local override can reintroduce a combination the base file was
|
|
63
|
+
// rejected for — `database.provider` beside an inherited `database.external`, say — and merging
|
|
64
|
+
// has no opinion about that.
|
|
65
|
+
return validateProjectConfig(mergeProjectConfig(base, localNorm), "supatype.local.config.ts (merged with supatype.config.ts)");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Environment for the child process that imports the config module.
|
|
69
|
+
*
|
|
70
|
+
* `supatype.config.ts` is TypeScript, so the natural way to keep a database password out of version
|
|
71
|
+
* control is `process.env.DATABASE_URL` — which only works if the project's `.env` is visible to the
|
|
72
|
+
* process doing the import. A real environment variable still wins over the file, matching how every
|
|
73
|
+
* other dotenv reader behaves and how Compose itself resolves the same names.
|
|
74
|
+
*/
|
|
75
|
+
function configLoadEnv(cwd) {
|
|
76
|
+
return { ...readEnvFile(cwd), ...process.env };
|
|
62
77
|
}
|
|
63
78
|
function loadFirstTsConfig(cwd, candidates) {
|
|
64
79
|
for (const candidate of candidates) {
|
|
@@ -71,7 +86,7 @@ const mod = await import(${JSON.stringify(urlPath)})
|
|
|
71
86
|
const config = mod.default ?? mod
|
|
72
87
|
process.stdout.write(JSON.stringify(config))
|
|
73
88
|
`;
|
|
74
|
-
const result = evalTsSnippet(snippet, { cwd });
|
|
89
|
+
const result = evalTsSnippet(snippet, { cwd, env: configLoadEnv(cwd) });
|
|
75
90
|
if (result.exitCode === 0) {
|
|
76
91
|
return JSON.parse(result.stdout);
|
|
77
92
|
}
|
|
@@ -115,7 +130,7 @@ const mod = await import(${JSON.stringify(urlPath)})
|
|
|
115
130
|
const config = mod.default ?? mod
|
|
116
131
|
process.stdout.write(JSON.stringify(config))
|
|
117
132
|
`;
|
|
118
|
-
const result = evalTsSnippet(snippet, { cwd });
|
|
133
|
+
const result = evalTsSnippet(snippet, { cwd, env: configLoadEnv(cwd) });
|
|
119
134
|
if (result.exitCode !== 0)
|
|
120
135
|
return null;
|
|
121
136
|
return JSON.parse(result.stdout);
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,EACL,kBAAkB,EAClB,qBAAqB,GAEtB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AA+D/D,kEAAkE;AAClE,MAAM,UAAU,YAAY,CAAC,MAA6B;IACxD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,WAAW,GAAG,sBAAsB,CAAA;AAE1C,MAAM,sBAAsB,GAAG;IAC7B,oBAAoB;IACpB,oBAAoB;IACpB,qBAAqB;CACtB,CAAA;AAED,MAAM,uBAAuB,GAAG;IAC9B,0BAA0B;IAC1B,0BAA0B;IAC1B,2BAA2B;CAC5B,CAAA;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,GAAY;IACxC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,GAAG,CAAA;IACvD,MAAM,CAAC,GAAG,EAAE,GAAI,GAA+B,EAAE,CAAA;IACjD,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IACvB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,QAAQ,CAAC,GAAG;YACZ,IAAI,EAAE,GAAG;YACT,SAAS,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ;SAC1E,CAAA;QACD,OAAO,CAAC,CAAC,WAAW,CAAC,CAAA;IACvB,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACpD,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,SAAS,WAAW,mCAAmC;YACrD,2GAA2G;YAC3G,2DAA2D,CAC9D,CAAA;IACH,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAA;IAC9D,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,uEAAuE;YACrE,oBAAoB,CACvB,CAAA;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,qBAAqB,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAA;IAElE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAA;IAChE,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAElC,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAmC,CAAA;IAClF,OAAO,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does this database meet what Supatype needs of it?
|
|
3
|
+
*
|
|
4
|
+
* Written for the bring-your-own-Postgres case: an external database will not look like
|
|
5
|
+
* `supatype/postgres`, and the failures it produces are mostly indirect. The four API roles are
|
|
6
|
+
* the sharpest example — every `GRANT` the engine emits is guarded with
|
|
7
|
+
* `IF EXISTS (SELECT 1 FROM pg_roles …)`, so a missing role is skipped in silence and the symptom
|
|
8
|
+
* is an API that cannot switch roles at all, days later.
|
|
9
|
+
*
|
|
10
|
+
* So each check states the requirement, what depends on it, and the SQL that fixes it. One module
|
|
11
|
+
* holds both the probe and the remedy on purpose: `--emit` and `--fix` cannot then disagree with
|
|
12
|
+
* what `check` reported.
|
|
13
|
+
*
|
|
14
|
+
* **Severity is about consequence, not tidiness.** `Fail` means the stack will not work. `Degrade`
|
|
15
|
+
* means a named feature is unavailable and everything else is fine. `Warn` means the operator
|
|
16
|
+
* should know something, and nothing is wrong.
|
|
17
|
+
*/
|
|
18
|
+
import pg from "pg";
|
|
19
|
+
export type Severity = "pass" | "warn" | "degrade" | "fail";
|
|
20
|
+
export interface CheckResult {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
severity: Severity;
|
|
24
|
+
/** What was found, in the operator's terms. */
|
|
25
|
+
detail: string;
|
|
26
|
+
/** What stops working, named. Omitted when nothing does. */
|
|
27
|
+
impact?: string;
|
|
28
|
+
/** SQL that resolves it, if SQL can. */
|
|
29
|
+
remedy?: string;
|
|
30
|
+
/**
|
|
31
|
+
* True when the remedy cannot run inside a transaction — server settings, chiefly. `--fix`
|
|
32
|
+
* refuses these and reports them rather than half-applying.
|
|
33
|
+
*/
|
|
34
|
+
remedyNeedsOperator?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface PreflightReport {
|
|
37
|
+
results: CheckResult[];
|
|
38
|
+
/** Highest severity seen, so a caller can pick an exit code without re-deriving it. */
|
|
39
|
+
worst: Severity;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Stands in for the `authenticator` password when the operator has not supplied one.
|
|
43
|
+
*
|
|
44
|
+
* Fine to print for a human to replace; never acceptable to execute. `--fix` refuses when a remedy
|
|
45
|
+
* still contains it, because the decision was that this credential belongs to the operator —
|
|
46
|
+
* Supatype does not invent one for a database it does not own, and creating a role with a
|
|
47
|
+
* placeholder password would be worse than refusing.
|
|
48
|
+
*/
|
|
49
|
+
export declare const PASSWORD_PLACEHOLDER = "<choose-a-password>";
|
|
50
|
+
/** True when this remedy would execute the placeholder rather than a real credential. */
|
|
51
|
+
export declare function needsOperatorPassword(remedies: readonly CheckResult[]): boolean;
|
|
52
|
+
export interface PreflightOptions {
|
|
53
|
+
/** Schema Supatype will manage. Matches `schema.pg_schema`. */
|
|
54
|
+
schema: string;
|
|
55
|
+
/** Password to give `authenticator` in the remedy, when it has to be created. */
|
|
56
|
+
authenticatorPassword?: string;
|
|
57
|
+
}
|
|
58
|
+
export declare function runPreflight(client: pg.ClientBase, opts: PreflightOptions): Promise<PreflightReport>;
|
|
59
|
+
/**
|
|
60
|
+
* Everything `--fix` can apply, as one script.
|
|
61
|
+
*
|
|
62
|
+
* Excludes anything needing the operator (server settings), because those cannot be transactional
|
|
63
|
+
* and mostly cannot be done in SQL on managed Postgres at all.
|
|
64
|
+
*/
|
|
65
|
+
export declare function transactionalRemedies(report: PreflightReport): CheckResult[];
|
|
66
|
+
export declare function operatorRemedies(report: PreflightReport): CheckResult[];
|
|
67
|
+
/**
|
|
68
|
+
* Apply the transactional remedies in a **single transaction**.
|
|
69
|
+
*
|
|
70
|
+
* `CREATE ROLE`, `GRANT`, `CREATE SCHEMA` and `CREATE EXTENSION` are all transactional in
|
|
71
|
+
* Postgres, so any failure rolls the whole thing back and the database is exactly as it was. That
|
|
72
|
+
* is the guarantee worth having when the database belongs to someone else.
|
|
73
|
+
*
|
|
74
|
+
* Server settings are the exception and are never included — `ALTER SYSTEM` cannot run in a
|
|
75
|
+
* transaction, and needs a restart besides. Those are reported for the operator to do.
|
|
76
|
+
*/
|
|
77
|
+
export declare function applyRemedies(client: pg.ClientBase, remedies: readonly CheckResult[]): Promise<void>;
|
|
78
|
+
//# sourceMappingURL=db-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-preflight.d.ts","sourceRoot":"","sources":["../src/db-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAA;AAE3D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,QAAQ,CAAA;IAClB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,uFAAuF;IACvF,KAAK,EAAE,QAAQ,CAAA;CAChB;AAwED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,wBAAwB,CAAA;AAEzD,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,GAAG,OAAO,CAE/E;AAcD,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAA;IACd,iFAAiF;IACjF,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,EAAE,CAAC,UAAU,EACrB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,eAAe,CAAC,CAgT1B;AA4ED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,EAAE,CAE5E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,WAAW,EAAE,CAEvE;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,EAAE,CAAC,UAAU,EACrB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC/B,OAAO,CAAC,IAAI,CAAC,CAef"}
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Does this database meet what Supatype needs of it?
|
|
3
|
+
*
|
|
4
|
+
* Written for the bring-your-own-Postgres case: an external database will not look like
|
|
5
|
+
* `supatype/postgres`, and the failures it produces are mostly indirect. The four API roles are
|
|
6
|
+
* the sharpest example — every `GRANT` the engine emits is guarded with
|
|
7
|
+
* `IF EXISTS (SELECT 1 FROM pg_roles …)`, so a missing role is skipped in silence and the symptom
|
|
8
|
+
* is an API that cannot switch roles at all, days later.
|
|
9
|
+
*
|
|
10
|
+
* So each check states the requirement, what depends on it, and the SQL that fixes it. One module
|
|
11
|
+
* holds both the probe and the remedy on purpose: `--emit` and `--fix` cannot then disagree with
|
|
12
|
+
* what `check` reported.
|
|
13
|
+
*
|
|
14
|
+
* **Severity is about consequence, not tidiness.** `Fail` means the stack will not work. `Degrade`
|
|
15
|
+
* means a named feature is unavailable and everything else is fine. `Warn` means the operator
|
|
16
|
+
* should know something, and nothing is wrong.
|
|
17
|
+
*/
|
|
18
|
+
/** Slot name for the decoding probe. Dropped immediately; never left behind. */
|
|
19
|
+
const PROBE_SLOT = "supatype_preflight_probe";
|
|
20
|
+
/**
|
|
21
|
+
* Ask the database to do the one thing realtime needs, then undo it.
|
|
22
|
+
*
|
|
23
|
+
* SQLSTATEs measured against `supatype/postgres` rather than recalled:
|
|
24
|
+
* `55000` wal_level too low, `58P01` the plugin's library is absent, `42501` the role may not use
|
|
25
|
+
* replication slots.
|
|
26
|
+
*/
|
|
27
|
+
async function probeLogicalDecoding(q) {
|
|
28
|
+
const base = { id: "logical-decoding", title: "wal2json logical decoding (realtime)" };
|
|
29
|
+
try {
|
|
30
|
+
await q(`SELECT pg_create_logical_replication_slot($1, 'wal2json')`, [PROBE_SLOT]);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
const code = error.code;
|
|
34
|
+
const detail = code === "58P01"
|
|
35
|
+
? "the wal2json output plugin is not installed on this server"
|
|
36
|
+
: code === "42501"
|
|
37
|
+
? "this role may not use replication slots (no REPLICATION attribute)"
|
|
38
|
+
: error instanceof Error
|
|
39
|
+
? error.message
|
|
40
|
+
: String(error);
|
|
41
|
+
return {
|
|
42
|
+
...base,
|
|
43
|
+
severity: "degrade",
|
|
44
|
+
detail,
|
|
45
|
+
impact: "Realtime subscriptions are unavailable; everything else is unaffected. The service still " +
|
|
46
|
+
"starts, reports this reason on /health/ready, and serves nothing else differently.",
|
|
47
|
+
...(code === "42501"
|
|
48
|
+
? { remedy: `ALTER ROLE CURRENT_USER WITH REPLICATION;`, remedyNeedsOperator: true }
|
|
49
|
+
: {
|
|
50
|
+
remedy: [
|
|
51
|
+
"-- wal2json is a server library, not an extension: it must be installed on the host",
|
|
52
|
+
"-- (or offered by your provider) and cannot be added over SQL. Supatype's own image",
|
|
53
|
+
"-- ships it. Set database.external.realtime: false to stop starting the service.",
|
|
54
|
+
].join("\n"),
|
|
55
|
+
remedyNeedsOperator: true,
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// Leave nothing behind. A slot that is never read holds WAL forever, which on a database Supatype
|
|
60
|
+
// does not own is the rudest possible failure: the disk fills and nothing says why.
|
|
61
|
+
try {
|
|
62
|
+
await q(`SELECT pg_drop_replication_slot($1)`, [PROBE_SLOT]);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
...base,
|
|
67
|
+
severity: "warn",
|
|
68
|
+
detail: "the probe slot was created but could not be dropped",
|
|
69
|
+
impact: `An unread replication slot named "${PROBE_SLOT}" retains WAL indefinitely and will ` +
|
|
70
|
+
"eventually fill the disk.",
|
|
71
|
+
remedy: `SELECT pg_drop_replication_slot('${PROBE_SLOT}');`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { ...base, severity: "pass", detail: "a wal2json slot can be created and dropped" };
|
|
75
|
+
}
|
|
76
|
+
const REQUIRED_ROLES = ["anon", "authenticated", "service_role", "authenticator"];
|
|
77
|
+
/**
|
|
78
|
+
* Stands in for the `authenticator` password when the operator has not supplied one.
|
|
79
|
+
*
|
|
80
|
+
* Fine to print for a human to replace; never acceptable to execute. `--fix` refuses when a remedy
|
|
81
|
+
* still contains it, because the decision was that this credential belongs to the operator —
|
|
82
|
+
* Supatype does not invent one for a database it does not own, and creating a role with a
|
|
83
|
+
* placeholder password would be worse than refusing.
|
|
84
|
+
*/
|
|
85
|
+
export const PASSWORD_PLACEHOLDER = "<choose-a-password>";
|
|
86
|
+
/** True when this remedy would execute the placeholder rather than a real credential. */
|
|
87
|
+
export function needsOperatorPassword(remedies) {
|
|
88
|
+
return remedies.some((r) => r.remedy?.includes(PASSWORD_PLACEHOLDER) === true);
|
|
89
|
+
}
|
|
90
|
+
const SEVERITY_ORDER = { pass: 0, warn: 1, degrade: 2, fail: 3 };
|
|
91
|
+
function worstOf(results) {
|
|
92
|
+
return results.reduce((acc, r) => (SEVERITY_ORDER[r.severity] > SEVERITY_ORDER[acc] ? r.severity : acc), "pass");
|
|
93
|
+
}
|
|
94
|
+
/** Minimum server version. Settled by the owner; the masking rewrite touches planner internals. */
|
|
95
|
+
const MIN_MAJOR = 17;
|
|
96
|
+
export async function runPreflight(client, opts) {
|
|
97
|
+
const results = [];
|
|
98
|
+
const q = async (sql, params = []) => (await client.query(sql, params)).rows;
|
|
99
|
+
/** For probes that always return exactly one row. */
|
|
100
|
+
const one = async (sql, params = []) => {
|
|
101
|
+
const rows = await q(sql, params);
|
|
102
|
+
const row = rows[0];
|
|
103
|
+
if (!row)
|
|
104
|
+
throw new Error(`Preflight probe returned no rows: ${sql}`);
|
|
105
|
+
return row;
|
|
106
|
+
};
|
|
107
|
+
// ── Server version ─────────────────────────────────────────────────────────
|
|
108
|
+
const { server_version_num } = await one("SHOW server_version_num");
|
|
109
|
+
const major = Math.floor(Number(server_version_num) / 10000);
|
|
110
|
+
results.push({
|
|
111
|
+
id: "server-version",
|
|
112
|
+
title: `Postgres ${MIN_MAJOR} or later`,
|
|
113
|
+
severity: major >= MIN_MAJOR ? "pass" : "fail",
|
|
114
|
+
detail: `server reports major version ${major}`,
|
|
115
|
+
...(major < MIN_MAJOR && {
|
|
116
|
+
impact: "Supatype's baseline is PG17; the masking rewrite depends on planner internals that are not stable across majors.",
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
// ── Who are we, and what can we do ─────────────────────────────────────────
|
|
120
|
+
const privs = await one(`SELECT current_user,
|
|
121
|
+
rolsuper AS is_super,
|
|
122
|
+
rolcreaterole AS can_create_role
|
|
123
|
+
FROM pg_roles WHERE rolname = current_user`);
|
|
124
|
+
results.push({
|
|
125
|
+
id: "connection-identity",
|
|
126
|
+
title: "Connected identity",
|
|
127
|
+
severity: "pass",
|
|
128
|
+
detail: `connected as "${privs.current_user}"` +
|
|
129
|
+
(privs.is_super ? " (superuser)" : privs.can_create_role ? " (can create roles)" : " (cannot create roles)"),
|
|
130
|
+
});
|
|
131
|
+
// ── Target schema ──────────────────────────────────────────────────────────
|
|
132
|
+
const schemaRows = await q("SELECT nspname FROM pg_namespace WHERE nspname = $1", [opts.schema]);
|
|
133
|
+
const schemaExists = schemaRows.length > 0;
|
|
134
|
+
const { can_create, database } = await one(`SELECT has_database_privilege(current_database(), 'CREATE') AS can_create,
|
|
135
|
+
current_database() AS database`);
|
|
136
|
+
results.push({
|
|
137
|
+
id: "target-schema",
|
|
138
|
+
title: `Schema "${opts.schema}"`,
|
|
139
|
+
severity: schemaExists || can_create ? "pass" : "fail",
|
|
140
|
+
detail: schemaExists
|
|
141
|
+
? `exists`
|
|
142
|
+
: can_create
|
|
143
|
+
? "does not exist, and can be created"
|
|
144
|
+
: "does not exist, and this role cannot create it",
|
|
145
|
+
...(!schemaExists && can_create && { remedy: `CREATE SCHEMA IF NOT EXISTS ${ident(opts.schema)};` }),
|
|
146
|
+
...(!schemaExists && !can_create && {
|
|
147
|
+
impact: "The engine needs its own schema for migration history and schema state.",
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
// `CREATE` on the database, which the check above only asked about when the target schema was
|
|
151
|
+
// missing — and `public` always exists, so on a database where the role cannot create schemas that
|
|
152
|
+
// check passed while the stack could not start.
|
|
153
|
+
//
|
|
154
|
+
// Measured on a role with `CONNECT` and `USAGE ON SCHEMA public` but no `CREATE`: storage's
|
|
155
|
+
// bootstrap fails `42501 permission denied for database`, and so does every one of the engine's own
|
|
156
|
+
// schemas. Storage was the least examined service in this plan and this is the whole of what it
|
|
157
|
+
// needs — no extensions, no superuser, no replication, just somewhere to put `storage.buckets` and
|
|
158
|
+
// `storage.objects`.
|
|
159
|
+
results.push({
|
|
160
|
+
id: "create-schemas",
|
|
161
|
+
title: "CREATE on the database",
|
|
162
|
+
severity: can_create ? "pass" : "fail",
|
|
163
|
+
detail: can_create ? "granted" : "not granted to this role",
|
|
164
|
+
...(!can_create && {
|
|
165
|
+
impact: "Four schemas cannot be created: `storage` (buckets and objects), `_platform` (trigger " +
|
|
166
|
+
"functions), `supatype` (Studio's views) and `_supatype` (migration history). Storage exits " +
|
|
167
|
+
"at boot and the engine cannot record a migration.",
|
|
168
|
+
remedy: `GRANT CREATE ON DATABASE ${ident(database)} TO ${ident(privs.current_user)};`,
|
|
169
|
+
}),
|
|
170
|
+
});
|
|
171
|
+
// ── The four API roles ─────────────────────────────────────────────────────
|
|
172
|
+
const roleRows = await q(`SELECT rolname, rolinherit, rolcanlogin FROM pg_roles WHERE rolname = ANY($1)`, [REQUIRED_ROLES]);
|
|
173
|
+
const present = new Map(roleRows.map((r) => [r.rolname, r]));
|
|
174
|
+
const missing = REQUIRED_ROLES.filter((r) => !present.has(r));
|
|
175
|
+
results.push({
|
|
176
|
+
id: "api-roles",
|
|
177
|
+
title: "API roles (anon, authenticated, service_role, authenticator)",
|
|
178
|
+
severity: missing.length === 0 ? "pass" : "fail",
|
|
179
|
+
detail: missing.length === 0
|
|
180
|
+
? "all four present"
|
|
181
|
+
: `missing: ${missing.join(", ")}`,
|
|
182
|
+
...(missing.length > 0 && {
|
|
183
|
+
// The silence is the point: without these, nothing errors, the API just cannot switch roles.
|
|
184
|
+
impact: "PostgREST switches to these roles per request. Every GRANT the engine emits is guarded " +
|
|
185
|
+
"with IF EXISTS on the role, so absent roles are skipped silently and the failure surfaces " +
|
|
186
|
+
"later as an API that cannot authenticate." +
|
|
187
|
+
// Found by running --fix as a CREATEROLE-but-not-superuser operator, which is what a
|
|
188
|
+
// managed provider typically gives you: it failed with a bare "permission denied to
|
|
189
|
+
// create role" because BYPASSRLS is superuser-only. Better to say so up front.
|
|
190
|
+
(needsSuperuserForRoles(missing, privs.is_super)
|
|
191
|
+
? "\n Note: service_role needs BYPASSRLS, which only a superuser can grant. " +
|
|
192
|
+
`This connection is not a superuser, so --fix cannot create it — have someone with ` +
|
|
193
|
+
`superuser apply the emitted SQL, or create service_role first.`
|
|
194
|
+
: ""),
|
|
195
|
+
remedy: roleRemedy(missing, opts.authenticatorPassword),
|
|
196
|
+
// A remedy that cannot succeed at this privilege level should not be attempted in a
|
|
197
|
+
// transaction that will only roll back.
|
|
198
|
+
...(needsSuperuserForRoles(missing, privs.is_super) && { remedyNeedsOperator: true }),
|
|
199
|
+
}),
|
|
200
|
+
});
|
|
201
|
+
// `authenticator` must not inherit: it is the containment boundary that stops a JWT naming a
|
|
202
|
+
// privileged role from getting it.
|
|
203
|
+
const authenticator = present.get("authenticator");
|
|
204
|
+
if (authenticator) {
|
|
205
|
+
const ok = !authenticator.rolinherit && authenticator.rolcanlogin;
|
|
206
|
+
results.push({
|
|
207
|
+
id: "authenticator-shape",
|
|
208
|
+
title: "authenticator is NOINHERIT and can log in",
|
|
209
|
+
severity: ok ? "pass" : "fail",
|
|
210
|
+
detail: `rolinherit=${authenticator.rolinherit}, rolcanlogin=${authenticator.rolcanlogin}`,
|
|
211
|
+
...(!ok && {
|
|
212
|
+
impact: "NOINHERIT is what confines PostgREST to anon/authenticated/service_role. An INHERIT " +
|
|
213
|
+
"authenticator carries the privileges of every role granted to it.",
|
|
214
|
+
remedy: `ALTER ROLE authenticator NOINHERIT LOGIN;`,
|
|
215
|
+
}),
|
|
216
|
+
});
|
|
217
|
+
const memberships = await q(`SELECT r.rolname FROM pg_auth_members m
|
|
218
|
+
JOIN pg_roles r ON r.oid = m.roleid
|
|
219
|
+
JOIN pg_roles g ON g.oid = m.member
|
|
220
|
+
WHERE g.rolname = 'authenticator'`);
|
|
221
|
+
const held = new Set(memberships.map((m) => m.rolname));
|
|
222
|
+
const needed = ["anon", "authenticated", "service_role"].filter((r) => !held.has(r));
|
|
223
|
+
results.push({
|
|
224
|
+
id: "authenticator-memberships",
|
|
225
|
+
title: "authenticator can reach the three API roles",
|
|
226
|
+
severity: needed.length === 0 ? "pass" : "fail",
|
|
227
|
+
detail: needed.length === 0 ? "all three granted" : `not granted: ${needed.join(", ")}`,
|
|
228
|
+
...(needed.length > 0 && {
|
|
229
|
+
impact: "PostgREST cannot SET ROLE to a role it is not a member of; those requests fail.",
|
|
230
|
+
remedy: needed.map((r) => `GRANT ${r} TO authenticator;`).join("\n"),
|
|
231
|
+
}),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
// ── Extensions ─────────────────────────────────────────────────────────────
|
|
235
|
+
const installed = new Set((await q("SELECT extname FROM pg_extension")).map((r) => r.extname));
|
|
236
|
+
const available = new Set((await q("SELECT name FROM pg_available_extensions")).map((r) => r.name));
|
|
237
|
+
results.push(extensionCheck("pgcrypto", installed, available, {
|
|
238
|
+
title: "pgcrypto",
|
|
239
|
+
needs: "UUID primary keys — the engine emits gen_random_uuid() defaults.",
|
|
240
|
+
whenMissing: "fail",
|
|
241
|
+
}));
|
|
242
|
+
for (const name of ["vector", "postgis"]) {
|
|
243
|
+
results.push(extensionCheck(name, installed, available, {
|
|
244
|
+
title: name,
|
|
245
|
+
needs: `only schemas using ${name === "vector" ? "Vector<> fields" : "Geo/GeoPoint fields"}.`,
|
|
246
|
+
whenMissing: "warn",
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
// Field rules are enforced either way now, so this is no longer a degrade.
|
|
250
|
+
//
|
|
251
|
+
// It reported "per-column rules cannot be enforced" and "a push carrying them refuses", both of
|
|
252
|
+
// which stopped being true when the view tier landed. What the operator needs to know is *which*
|
|
253
|
+
// mechanism they will get and the one way the two differ.
|
|
254
|
+
results.push({
|
|
255
|
+
id: "ext-supatype_mask",
|
|
256
|
+
title: "Field-level access rules (access.fields)",
|
|
257
|
+
severity: installed.has("supatype_mask") ? "pass" : "warn",
|
|
258
|
+
detail: installed.has("supatype_mask")
|
|
259
|
+
? "enforced by supatype_mask, the planner rewrite (tier 1)"
|
|
260
|
+
: available.has("supatype_mask")
|
|
261
|
+
? "supatype_mask is available but not installed — rules will be enforced by generated api views (tier 2)"
|
|
262
|
+
: "enforced by generated api views (tier 2); supatype_mask is not available on this server",
|
|
263
|
+
...(!installed.has("supatype_mask") && {
|
|
264
|
+
impact: "Tier 2 puts the masking expression in a view instead of the query planner. It is the same " +
|
|
265
|
+
"behaviour with one exception: an aggregate over a masked column returns the sum of what the " +
|
|
266
|
+
"caller may read, where tier 1 raises. Unreachable through the API — PostgREST ships with " +
|
|
267
|
+
"aggregates disabled and Supatype never enables them — so this matters only for direct SQL " +
|
|
268
|
+
"against the api views. PostgREST is pointed at `api` instead of your managed schema, and the " +
|
|
269
|
+
"API roles hold their privileges on the views rather than the tables.",
|
|
270
|
+
...(available.has("supatype_mask") && {
|
|
271
|
+
remedy: "CREATE EXTENSION IF NOT EXISTS supatype_mask;",
|
|
272
|
+
}),
|
|
273
|
+
}),
|
|
274
|
+
});
|
|
275
|
+
// ── Realtime ───────────────────────────────────────────────────────────────
|
|
276
|
+
const { wal_level } = await one("SHOW wal_level");
|
|
277
|
+
const walLogical = wal_level === "logical";
|
|
278
|
+
results.push({
|
|
279
|
+
id: "wal-level",
|
|
280
|
+
title: "wal_level = logical (realtime)",
|
|
281
|
+
severity: walLogical ? "pass" : "degrade",
|
|
282
|
+
detail: `wal_level is "${wal_level}"`,
|
|
283
|
+
...(!walLogical && {
|
|
284
|
+
impact: "Realtime subscriptions are unavailable; everything else is unaffected.",
|
|
285
|
+
remedy: "-- Requires a server restart, and on managed Postgres a parameter-group change\n" +
|
|
286
|
+
"-- rather than SQL. Shown for a self-managed server:\n" +
|
|
287
|
+
"ALTER SYSTEM SET wal_level = 'logical';",
|
|
288
|
+
remedyNeedsOperator: true,
|
|
289
|
+
}),
|
|
290
|
+
});
|
|
291
|
+
const slots = await one(`SELECT (SELECT count(*) FROM pg_replication_slots)::text AS used,
|
|
292
|
+
current_setting('max_replication_slots') AS max`);
|
|
293
|
+
const slotsFree = Number(slots.max) - Number(slots.used);
|
|
294
|
+
results.push({
|
|
295
|
+
id: "replication-slots",
|
|
296
|
+
title: "A spare replication slot (realtime)",
|
|
297
|
+
severity: slotsFree > 0 ? "pass" : "degrade",
|
|
298
|
+
detail: `${slots.used} of ${slots.max} in use`,
|
|
299
|
+
...(slotsFree <= 0 && {
|
|
300
|
+
impact: "Realtime cannot create its slot.",
|
|
301
|
+
remedy: "ALTER SYSTEM SET max_replication_slots = 10;",
|
|
302
|
+
remedyNeedsOperator: true,
|
|
303
|
+
}),
|
|
304
|
+
});
|
|
305
|
+
// The definitive realtime check: create the slot realtime would create, then drop it.
|
|
306
|
+
//
|
|
307
|
+
// There is no catalog to consult. `wal2json` is a shared library, not an extension, so it never
|
|
308
|
+
// appears in `pg_available_extensions` — the only way to know whether this database can decode is
|
|
309
|
+
// to ask it to. Cloud SQL does not ship the plugin at all; plenty of managed Postgres will not
|
|
310
|
+
// grant `REPLICATION`. Both produce a stack that looks healthy until the first subscription.
|
|
311
|
+
//
|
|
312
|
+
// Skipped when `wal_level` or the slot budget already rules it out, since the probe would fail for
|
|
313
|
+
// that reason and report it a second time under a less specific heading.
|
|
314
|
+
if (walLogical && slotsFree > 0) {
|
|
315
|
+
results.push(await probeLogicalDecoding(q));
|
|
316
|
+
}
|
|
317
|
+
// ── Existing tables in the target schema ───────────────────────────────────
|
|
318
|
+
if (schemaExists) {
|
|
319
|
+
const tables = await q(
|
|
320
|
+
// Anything not carrying Supatype's ownership marker. Today that is every table, since
|
|
321
|
+
// tables are not stamped yet (E4); once they are, this narrows to genuinely foreign ones
|
|
322
|
+
// without needing to change.
|
|
323
|
+
`SELECT c.relname FROM pg_class c
|
|
324
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
325
|
+
WHERE n.nspname = $1 AND c.relkind = 'r'
|
|
326
|
+
AND coalesce(obj_description(c.oid, 'pg_class'), '') NOT LIKE 'supatype:managed%'
|
|
327
|
+
ORDER BY c.relname`, [opts.schema]);
|
|
328
|
+
if (tables.length > 0) {
|
|
329
|
+
const names = tables.map((t) => t.relname);
|
|
330
|
+
results.push({
|
|
331
|
+
id: "existing-tables",
|
|
332
|
+
title: `Existing tables in "${opts.schema}"`,
|
|
333
|
+
severity: "warn",
|
|
334
|
+
detail: `${names.length} table(s) Supatype did not create: ` +
|
|
335
|
+
names.slice(0, 8).join(", ") +
|
|
336
|
+
(names.length > 8 ? `, … and ${names.length - 8} more` : ""),
|
|
337
|
+
impact: "These are not described by your schema. Model them, or keep them out of the managed " +
|
|
338
|
+
"schema — a push only manages what it created.",
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return { results, worst: worstOf(results) };
|
|
343
|
+
}
|
|
344
|
+
function extensionCheck(name, installed, available, meta) {
|
|
345
|
+
if (installed.has(name)) {
|
|
346
|
+
return { id: `ext-${name}`, title: meta.title, severity: "pass", detail: "installed" };
|
|
347
|
+
}
|
|
348
|
+
if (available.has(name)) {
|
|
349
|
+
return {
|
|
350
|
+
id: `ext-${name}`,
|
|
351
|
+
title: meta.title,
|
|
352
|
+
severity: "warn",
|
|
353
|
+
detail: "available but not installed",
|
|
354
|
+
impact: `Needed for ${meta.needs}`,
|
|
355
|
+
remedy: `CREATE EXTENSION IF NOT EXISTS ${ident(name)};`,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
id: `ext-${name}`,
|
|
360
|
+
title: meta.title,
|
|
361
|
+
severity: meta.whenMissing,
|
|
362
|
+
detail: "not available on this server",
|
|
363
|
+
impact: `Needed for ${meta.needs}`,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* SQL to create the missing API roles.
|
|
368
|
+
*
|
|
369
|
+
* `authenticator` needs a password because PostgREST logs in as it; the others never do. The
|
|
370
|
+
* password is the operator's to supply — Supatype does not invent a credential for a database it
|
|
371
|
+
* does not own.
|
|
372
|
+
*/
|
|
373
|
+
function roleRemedy(missing, authenticatorPassword) {
|
|
374
|
+
const lines = [];
|
|
375
|
+
for (const role of missing) {
|
|
376
|
+
if (role === "authenticator") {
|
|
377
|
+
const pw = authenticatorPassword
|
|
378
|
+
? `'${authenticatorPassword.replace(/'/g, "''")}'`
|
|
379
|
+
: `'${PASSWORD_PLACEHOLDER}'`;
|
|
380
|
+
lines.push(`CREATE ROLE authenticator LOGIN NOINHERIT PASSWORD ${pw};`);
|
|
381
|
+
}
|
|
382
|
+
else if (role === "service_role") {
|
|
383
|
+
// BYPASSRLS is what makes seeds, migrations and server-side code work.
|
|
384
|
+
lines.push(`CREATE ROLE service_role NOLOGIN NOINHERIT BYPASSRLS;`);
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
lines.push(`CREATE ROLE ${ident(role)} NOLOGIN NOINHERIT;`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (missing.includes("authenticator") || missing.length > 0) {
|
|
391
|
+
for (const role of ["anon", "authenticated", "service_role"]) {
|
|
392
|
+
lines.push(`GRANT ${role} TO authenticator;`);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return lines.join("\n");
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Whether creating the missing roles needs superuser rather than merely CREATEROLE.
|
|
399
|
+
*
|
|
400
|
+
* `service_role` carries `BYPASSRLS`, and only a superuser may set that attribute. A CREATEROLE
|
|
401
|
+
* operator — which is what managed Postgres typically gives you — gets "permission denied to
|
|
402
|
+
* create role" with no indication that the attribute is the reason.
|
|
403
|
+
*/
|
|
404
|
+
function needsSuperuserForRoles(missing, isSuperuser) {
|
|
405
|
+
return missing.includes("service_role") && !isSuperuser;
|
|
406
|
+
}
|
|
407
|
+
/** Quote an identifier for inclusion in emitted SQL. */
|
|
408
|
+
function ident(name) {
|
|
409
|
+
return `"${name.replace(/"/g, '""')}"`;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Everything `--fix` can apply, as one script.
|
|
413
|
+
*
|
|
414
|
+
* Excludes anything needing the operator (server settings), because those cannot be transactional
|
|
415
|
+
* and mostly cannot be done in SQL on managed Postgres at all.
|
|
416
|
+
*/
|
|
417
|
+
export function transactionalRemedies(report) {
|
|
418
|
+
return report.results.filter((r) => r.remedy !== undefined && r.remedyNeedsOperator !== true);
|
|
419
|
+
}
|
|
420
|
+
export function operatorRemedies(report) {
|
|
421
|
+
return report.results.filter((r) => r.remedyNeedsOperator === true);
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Apply the transactional remedies in a **single transaction**.
|
|
425
|
+
*
|
|
426
|
+
* `CREATE ROLE`, `GRANT`, `CREATE SCHEMA` and `CREATE EXTENSION` are all transactional in
|
|
427
|
+
* Postgres, so any failure rolls the whole thing back and the database is exactly as it was. That
|
|
428
|
+
* is the guarantee worth having when the database belongs to someone else.
|
|
429
|
+
*
|
|
430
|
+
* Server settings are the exception and are never included — `ALTER SYSTEM` cannot run in a
|
|
431
|
+
* transaction, and needs a restart besides. Those are reported for the operator to do.
|
|
432
|
+
*/
|
|
433
|
+
export async function applyRemedies(client, remedies) {
|
|
434
|
+
if (remedies.length === 0)
|
|
435
|
+
return;
|
|
436
|
+
await client.query("BEGIN");
|
|
437
|
+
try {
|
|
438
|
+
for (const r of remedies) {
|
|
439
|
+
// Comment lines are guidance, not SQL.
|
|
440
|
+
const sql = r.remedy.split("\n").filter((l) => !l.trimStart().startsWith("--")).join("\n");
|
|
441
|
+
if (sql.trim() === "")
|
|
442
|
+
continue;
|
|
443
|
+
await client.query(sql);
|
|
444
|
+
}
|
|
445
|
+
await client.query("COMMIT");
|
|
446
|
+
}
|
|
447
|
+
catch (err) {
|
|
448
|
+
await client.query("ROLLBACK").catch(() => undefined);
|
|
449
|
+
throw err;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
//# sourceMappingURL=db-preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-preflight.js","sourceRoot":"","sources":["../src/db-preflight.ts"],"names":[],"mappings":"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"}
|
package/dist/dev-compose.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface DevComposeOptions {
|
|
|
10
10
|
watch: boolean;
|
|
11
11
|
}
|
|
12
12
|
/** In-compose Postgres URL (SCRAM; not published to the host). */
|
|
13
|
-
export declare function composeDbUrl(): string;
|
|
13
|
+
export declare function composeDbUrl(cwd: string): string;
|
|
14
14
|
/**
|
|
15
15
|
* When `provider: docker` and `overrides.engine` is set, ensure Postgres is published
|
|
16
16
|
* on the host (SUPATYPE_DEV_DB_PORT) so the local engine binary can connect.
|