pipework 0.8.19 → 0.9.0

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 (54) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/auth/tenant/index.d.ts +1 -1
  3. package/dist/auth/tenant/index.d.ts.map +1 -1
  4. package/dist/auth/tenant/index.js +1 -1
  5. package/dist/auth/tenant/index.js.map +1 -1
  6. package/dist/auth/tenant/namespace.d.ts +3 -3
  7. package/dist/auth/tenant/namespace.d.ts.map +1 -1
  8. package/dist/auth/tenant/namespace.js +3 -3
  9. package/dist/auth/tenant/namespace.js.map +1 -1
  10. package/dist/auth/tenant/rls.d.ts +24 -3
  11. package/dist/auth/tenant/rls.d.ts.map +1 -1
  12. package/dist/auth/tenant/rls.js +59 -19
  13. package/dist/auth/tenant/rls.js.map +1 -1
  14. package/dist/cli/commands/db.d.ts +8 -0
  15. package/dist/cli/commands/db.d.ts.map +1 -1
  16. package/dist/cli/commands/db.js +129 -72
  17. package/dist/cli/commands/db.js.map +1 -1
  18. package/dist/core/config/load.d.ts +2 -0
  19. package/dist/core/config/load.d.ts.map +1 -1
  20. package/dist/core/config/load.js +7 -3
  21. package/dist/core/config/load.js.map +1 -1
  22. package/dist/core/config/namespace.d.ts +3 -0
  23. package/dist/core/config/namespace.d.ts.map +1 -1
  24. package/dist/core/config/schema.d.ts +6 -0
  25. package/dist/core/config/schema.d.ts.map +1 -1
  26. package/dist/core/config/schema.js +3 -0
  27. package/dist/core/config/schema.js.map +1 -1
  28. package/dist/core/pipework.d.ts +3 -3
  29. package/dist/core/pipework.d.ts.map +1 -1
  30. package/dist/core/pipework.js +13 -5
  31. package/dist/core/pipework.js.map +1 -1
  32. package/dist/data/db/pool.d.ts +2 -0
  33. package/dist/data/db/pool.d.ts.map +1 -1
  34. package/dist/data/db/pool.js.map +1 -1
  35. package/dist/data/migrate/generate.js +1 -1
  36. package/dist/data/migrate/generate.js.map +1 -1
  37. package/dist/data/migrate/rls-generate.d.ts +1 -1
  38. package/dist/data/migrate/rls-generate.d.ts.map +1 -1
  39. package/dist/data/migrate/rls-generate.js +20 -4
  40. package/dist/data/migrate/rls-generate.js.map +1 -1
  41. package/dist/request/context/create.d.ts +6 -0
  42. package/dist/request/context/create.d.ts.map +1 -1
  43. package/dist/request/context/create.js +6 -0
  44. package/dist/request/context/create.js.map +1 -1
  45. package/dist/request/context/run-in-transaction.d.ts.map +1 -1
  46. package/dist/request/context/run-in-transaction.js +8 -2
  47. package/dist/request/context/run-in-transaction.js.map +1 -1
  48. package/dist/request/context/types.d.ts +4 -0
  49. package/dist/request/context/types.d.ts.map +1 -1
  50. package/dist/test/setup.d.ts +6 -0
  51. package/dist/test/setup.d.ts.map +1 -1
  52. package/dist/test/setup.js +53 -3
  53. package/dist/test/setup.js.map +1 -1
  54. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.0
4
+
5
+ - **New: runtime role separation — RLS is now actually enforced.** Until now the app connected to Postgres as the database owner, and an owner is `BYPASSRLS` — so every generated RLS policy was inert in production: the 144 policies isolated nothing. This release splits the single per-database role into two. `db setup` now provisions an **owner** role (`<name>_owner`, `BYPASSRLS`) that owns the database, runs migrations, and bootstraps; and a non-owner **runtime** role (`<name>_app`, `NOBYPASSRLS`) that runtime request/job transactions authenticate as and that RLS policies enforce against. Isolation now comes from Postgres itself on a role that cannot bypass it, not from app-side filtering alone. The runtime DML grants (`SELECT, INSERT, UPDATE, DELETE` on tables, `USAGE, SELECT` on sequences) are applied at provision time on an owner-authenticated connection, plus `ALTER DEFAULT PRIVILEGES FOR ROLE <owner>` so every future migration-created table is auto-granted to the runtime role — an RLS-enabled table can never be left ungranted (which would blank rows the app is entitled to). New `buildRuntimeGrants` helper.
6
+ - **Breaking: `db setup` role naming and new config fields.** The single per-database role is gone; `db setup` now creates `<name>_owner` and `<name>_app`. Two new optional `database` config fields name the env vars for the runtime connection URL: `appUrl` (and `appTestUrl` for the test database). When `appUrl` is unset the runtime falls back to the owner `url` and `db setup` warns — RLS is then inert, preserving the old single-role behavior, but role separation is off. To get enforcement, set `appUrl`/`appTestUrl` and re-run `db setup`. Any deployment that hard-coded the old role name must update to `<name>_owner`.
7
+ - **New: principal context (user + as-of) propagation for user-level and temporal RLS.** `Flow` now carries `user` (the acting principal's id) and `asOf` (the instant access is evaluated against; null = current), threaded through `createRequestContext` / `createJobContext` / `createTestContext`. The runtime chokepoint propagates them to the connection as the `pipework.user_id` and `pipework.asof` GUCs alongside `pipework.tenant_id`, so RLS policies can enforce per-user and temporal (as-of) visibility, not just tenant. `verifyPrincipalContext` cross-checks the GUCs against the active Flow, fail-closed.
8
+
9
+ ## 0.8.20
10
+
11
+ - **Fix: test-database cloning aborted when it couldn't terminate an autovacuum backend** — `cloneTestDatabase` ran `pg_terminate_backend` over *every* session attached to the per-process template before `CREATE DATABASE ... WITH TEMPLATE`. On a shared cluster an autovacuum worker attaches to every database and runs as superuser, so a non-superuser test role (`*_test`) hit `permission denied to terminate process` (42501) and the whole clone — and the test file — failed intermittently. The terminate is now scoped to `backend_type = 'client backend'` (never a background worker) and is best-effort, and the `CREATE DATABASE` retries on SQLSTATE 55006 (`object_in_use`) with capped backoff, waiting out any session it couldn't close rather than depending on superuser termination rights. New `withTemplateRetry` helper, unit-tested.
12
+
3
13
  ## 0.8.19
4
14
 
5
15
  - **Fix: the flow-cardinality check false-failed under a scoped run** — `pipework check --staged` (and any diff-scoped run) hands the cardinality analyzer only the affected modules, and dropping modules can only shorten the longest `step`-edge chain, so the derived `trace.structuralMax` is a *lower bound* on the true global max. The config-vs-derived comparison used exact equality, so a staged change to a module shallower than the global cap hard-failed the pre-commit hook with `trace.structuralMax is stale — config has 4, analyzer derived 3` and told the user to lower the cap — which would then break the full-scope check (it correctly derives 4) and truncate legitimate depth-4 traces at runtime. The comparison is now scope-aware: `derived > configured` is a hard error under any scope (a subset that exceeds the cap proves the whole graph does), while `derived < configured` is only flagged as staleness when the analyzer saw every module (`fullScope`); a scoped run defers that verdict to the full-scope pre-push check. `resolveModulePaths` now returns whether the scope covered all modules (#328).
@@ -2,7 +2,7 @@ export type { TenantConfig, TenantContext } from './types.js';
2
2
  export { validateTenantId, validateSessionVarName, validateSessionVarValue } from './validate.js';
3
3
  export { propagateTenantLocals } from './propagate.js';
4
4
  export { extractTenant, type TenantExtractionResult } from './extract.js';
5
- export { tenantIsolationPolicy, enableTenantRls, verifyTenantContext } from './rls.js';
5
+ export { tenantIsolationPolicy, enableTenantRls, verifyPrincipalContext } from './rls.js';
6
6
  export { scopeTable, getScopeConfig, isTenantScoped, type ScopeConfig } from './scope.js';
7
7
  export { createScopedDb, createTenantGuardDb } from './scoped-db.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACtF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AACzF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -1,7 +1,7 @@
1
1
  export { validateTenantId, validateSessionVarName, validateSessionVarValue } from './validate.js';
2
2
  export { propagateTenantLocals } from './propagate.js';
3
3
  export { extractTenant } from './extract.js';
4
- export { tenantIsolationPolicy, enableTenantRls, verifyTenantContext } from './rls.js';
4
+ export { tenantIsolationPolicy, enableTenantRls, verifyPrincipalContext } from './rls.js';
5
5
  export { scopeTable, getScopeConfig, isTenantScoped } from './scope.js';
6
6
  export { createScopedDb, createTenantGuardDb } from './scoped-db.js';
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/tenant/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAA+B,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACtF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/tenant/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAA;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAA+B,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AACzF,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAA;AACzF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { validateTenantId } from './validate.js';
2
- import { enableTenantRls, tenantIsolationPolicy, verifyTenantContext } from './rls.js';
2
+ import { enableTenantRls, tenantIsolationPolicy, verifyPrincipalContext } from './rls.js';
3
3
  import { propagateTenantLocals } from './propagate.js';
4
4
  import { extractTenant } from './extract.js';
5
5
  import { isTenantScoped } from './scope.js';
@@ -11,8 +11,8 @@ export declare const tenant: {
11
11
  rls: typeof enableTenantRls;
12
12
  /** Returns the SQL string for a tenant isolation RLS policy — use in migrations. */
13
13
  policy: typeof tenantIsolationPolicy;
14
- /** Cross-checks ALS tenant against Postgres set_config('pipework.tenant_id') — defense-in-depth. */
15
- verify: typeof verifyTenantContext;
14
+ /** Cross-checks the ALS principal (tenant, user, asOf) against the Postgres session GUCs — defense-in-depth. */
15
+ verify: typeof verifyPrincipalContext;
16
16
  /** Sets pipework.tenant_id on the Postgres connection via set_config(). */
17
17
  propagate: typeof propagateTenantLocals;
18
18
  /** Extracts tenant ID from auth context using the configured extraction strategy. */
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,sGAAsG;AACtG,eAAO,MAAM,MAAM;IACjB,wEAAwE;;IAExE,kFAAkF;;IAElF,oFAAoF;;IAEpF,oGAAoG;;IAEpG,2EAA2E;;IAE3E,qFAAqF;;IAErF,+FAA+F;;CAEhG,CAAA"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,sGAAsG;AACtG,eAAO,MAAM,MAAM;IACjB,wEAAwE;;IAExE,kFAAkF;;IAElF,oFAAoF;;IAEpF,gHAAgH;;IAEhH,2EAA2E;;IAE3E,qFAAqF;;IAErF,+FAA+F;;CAEhG,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { validateTenantId } from './validate.js';
2
- import { enableTenantRls, tenantIsolationPolicy, verifyTenantContext } from './rls.js';
2
+ import { enableTenantRls, tenantIsolationPolicy, verifyPrincipalContext } from './rls.js';
3
3
  import { propagateTenantLocals } from './propagate.js';
4
4
  import { extractTenant } from './extract.js';
5
5
  import { isTenantScoped } from './scope.js';
@@ -11,8 +11,8 @@ export const tenant = {
11
11
  rls: enableTenantRls,
12
12
  /** Returns the SQL string for a tenant isolation RLS policy — use in migrations. */
13
13
  policy: tenantIsolationPolicy,
14
- /** Cross-checks ALS tenant against Postgres set_config('pipework.tenant_id') — defense-in-depth. */
15
- verify: verifyTenantContext,
14
+ /** Cross-checks the ALS principal (tenant, user, asOf) against the Postgres session GUCs — defense-in-depth. */
15
+ verify: verifyPrincipalContext,
16
16
  /** Sets pipework.tenant_id on the Postgres connection via set_config(). */
17
17
  propagate: propagateTenantLocals,
18
18
  /** Extracts tenant ID from auth context using the configured extraction strategy. */
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/auth/tenant/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,sGAAsG;AACtG,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,wEAAwE;IACxE,QAAQ,EAAE,gBAAgB;IAC1B,kFAAkF;IAClF,GAAG,EAAE,eAAe;IACpB,oFAAoF;IACpF,MAAM,EAAE,qBAAqB;IAC7B,oGAAoG;IACpG,MAAM,EAAE,mBAAmB;IAC3B,2EAA2E;IAC3E,SAAS,EAAE,qBAAqB;IAChC,qFAAqF;IACrF,OAAO,EAAE,aAAa;IACtB,+FAA+F;IAC/F,cAAc;CACf,CAAA"}
1
+ {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/auth/tenant/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,sGAAsG;AACtG,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,wEAAwE;IACxE,QAAQ,EAAE,gBAAgB;IAC1B,kFAAkF;IAClF,GAAG,EAAE,eAAe;IACpB,oFAAoF;IACpF,MAAM,EAAE,qBAAqB;IAC7B,gHAAgH;IAChH,MAAM,EAAE,sBAAsB;IAC9B,2EAA2E;IAC3E,SAAS,EAAE,qBAAqB;IAChC,qFAAqF;IACrF,OAAO,EAAE,aAAa;IACtB,+FAA+F;IAC/F,cAAc;CACf,CAAA"}
@@ -1,5 +1,26 @@
1
1
  import type { DB } from '../../data/db/index.js';
2
- export declare function tenantIsolationPolicy(table: string, column?: string, sessionVar?: string): string;
3
- export declare function enableTenantRls(db: DB, table: string, column?: string): Promise<void>;
4
- export declare function verifyTenantContext(db: DB, expectedTenant: string | null): Promise<void>;
2
+ /**
3
+ * SQL types a tenant discriminator column may be. The union members are
4
+ * literal Postgres type names, so they double as the cast target — a tenant
5
+ * policy compares the column against the session GUC cast to this type. A
6
+ * field whose kind is not one of these cannot be a tenant key; the generate
7
+ * layer rejects it before reaching here (see rls-generate.ts).
8
+ */
9
+ export type TenantKeyType = 'uuid' | 'text' | 'integer' | 'bigint';
10
+ export declare function tenantIsolationPolicy(table: string, column?: string, keyType?: TenantKeyType, sessionVar?: string, force?: boolean): string;
11
+ export declare function enableTenantRls(db: DB, table: string, column?: string, keyType?: TenantKeyType, force?: boolean): Promise<void>;
12
+ /** The principal axes carried on the request/job context and propagated as GUCs. */
13
+ export interface ExpectedPrincipal {
14
+ readonly tenant: string | null;
15
+ readonly user: string | null;
16
+ readonly asOf: string | null;
17
+ }
18
+ /**
19
+ * Cross-checks the application's principal (tenant, user, asOf) against the GUCs
20
+ * actually set on the Postgres session — defense-in-depth against an
21
+ * AsyncLocalStorage context swap propagating one principal's identity onto
22
+ * another's transaction. All three axes are checked together so a mismatch on
23
+ * any one aborts before a query can read the wrong rows.
24
+ */
25
+ export declare function verifyPrincipalContext(db: DB, expected: ExpectedPrincipal): Promise<void>;
5
26
  //# sourceMappingURL=rls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rls.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/rls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAIhD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAoB,EAAE,UAAU,GAAE,MAA6B,GAAG,MAAM,CAYpI;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,EAAE,EACN,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,EAAE,EACN,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,OAAO,CAAC,IAAI,CAAC,CAcf"}
1
+ {"version":3,"file":"rls.d.ts","sourceRoot":"","sources":["../../../src/auth/tenant/rls.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAIhD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAA;AAqBlE,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAoB,EAC5B,OAAO,GAAE,aAAsB,EAC/B,UAAU,GAAE,MAA6B,EACzC,KAAK,GAAE,OAAc,GACpB,MAAM,CAUR;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,EAAE,EACN,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAoB,EAC5B,OAAO,GAAE,aAAsB,EAC/B,KAAK,GAAE,OAAc,GACpB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,oFAAoF;AACpF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBf"}
@@ -1,35 +1,75 @@
1
1
  import { sql } from '../../data/db/sql.js';
2
2
  import { quoteIdentifier } from '../../data/db/identifiers.js';
3
3
  import { validateSessionVarName } from './validate.js';
4
- export function tenantIsolationPolicy(table, column = 'tenant_id', sessionVar = 'pipework.tenant_id') {
4
+ function tenantPolicyName(table) {
5
+ return `pipework_tenant_isolation_${table.replace(/[^a-zA-Z0-9_]/g, '_')}`;
6
+ }
7
+ /**
8
+ * The USING predicate of a tenant isolation policy.
9
+ *
10
+ * The cast (`::uuid` etc.) is required: current_setting returns text, and
11
+ * Postgres will not implicitly compare `uuid = text`. NULLIF(...,'') means an
12
+ * unset or explicitly-empty session GUC yields NULL — a deny-by-default match —
13
+ * instead of throwing on `''::uuid`. (current_setting(var, true) is itself NULL
14
+ * when the GUC was never set; the NULLIF only guards the empty-string case that
15
+ * set_config can produce.)
16
+ */
17
+ function tenantUsingClause(column, keyType, sessionVar) {
18
+ const c = quoteIdentifier(column, 'column');
19
+ return `${c} = NULLIF(current_setting('${sessionVar}', true), '')::${keyType}`;
20
+ }
21
+ export function tenantIsolationPolicy(table, column = 'tenant_id', keyType = 'uuid', sessionVar = 'pipework.tenant_id', force = true) {
5
22
  validateSessionVarName(sessionVar);
6
23
  const t = quoteIdentifier(table, 'table');
7
- const c = quoteIdentifier(column, 'column');
8
- const policyName = `pipework_tenant_isolation_${table.replace(/[^a-zA-Z0-9_]/g, '_')}`;
9
24
  return [
10
25
  `ALTER TABLE ${t} ENABLE ROW LEVEL SECURITY`,
11
- `ALTER TABLE ${t} FORCE ROW LEVEL SECURITY`,
12
- `CREATE POLICY ${quoteIdentifier(policyName, 'policy')} ON ${t} USING (${c} = current_setting('${sessionVar}', true))`,
26
+ ...(force ? [`ALTER TABLE ${t} FORCE ROW LEVEL SECURITY`] : []),
27
+ `CREATE POLICY ${quoteIdentifier(tenantPolicyName(table), 'policy')} ON ${t} USING (${tenantUsingClause(column, keyType, sessionVar)})`,
13
28
  ].join(';\n');
14
29
  }
15
- export async function enableTenantRls(db, table, column = 'tenant_id') {
30
+ export async function enableTenantRls(db, table, column = 'tenant_id', keyType = 'uuid', force = true) {
16
31
  const t = quoteIdentifier(table, 'table');
17
- const c = quoteIdentifier(column, 'column');
18
- const policyName = quoteIdentifier(`pipework_tenant_isolation_${table.replace(/[^a-zA-Z0-9_]/g, '_')}`, 'policy');
32
+ const policyName = quoteIdentifier(tenantPolicyName(table), 'policy');
19
33
  await db.execute(sql.raw(`ALTER TABLE ${t} ENABLE ROW LEVEL SECURITY`));
20
- await db.execute(sql.raw(`ALTER TABLE ${t} FORCE ROW LEVEL SECURITY`));
21
- await db.execute(sql.raw(`CREATE POLICY ${policyName} ON ${t} USING (${c} = current_setting('pipework.tenant_id', true))`));
34
+ if (force)
35
+ await db.execute(sql.raw(`ALTER TABLE ${t} FORCE ROW LEVEL SECURITY`));
36
+ await db.execute(sql.raw(`CREATE POLICY ${policyName} ON ${t} USING (${tenantUsingClause(column, keyType, 'pipework.tenant_id')})`));
22
37
  }
23
- export async function verifyTenantContext(db, expectedTenant) {
24
- const result = await db.execute(sql `SELECT current_setting('pipework.tenant_id', true) AS tenant_id`);
25
- const raw = result[0]?.tenant_id ?? null;
26
- const pgTenant = raw === '' ? null : raw;
27
- if (pgTenant !== expectedTenant) {
28
- throw new Error(`[pipework] Tenant context mismatch between application and database.\n\n` +
29
- ` Application context tenant: ${expectedTenant ?? '(null)'}\n` +
30
- ` PostgreSQL session tenant: ${pgTenant ?? '(null)'}\n\n` +
38
+ /**
39
+ * Cross-checks the application's principal (tenant, user, asOf) against the GUCs
40
+ * actually set on the Postgres session — defense-in-depth against an
41
+ * AsyncLocalStorage context swap propagating one principal's identity onto
42
+ * another's transaction. All three axes are checked together so a mismatch on
43
+ * any one aborts before a query can read the wrong rows.
44
+ */
45
+ export async function verifyPrincipalContext(db, expected) {
46
+ const result = await db.execute(sql `SELECT
47
+ current_setting('pipework.tenant_id', true) AS tenant_id,
48
+ current_setting('pipework.user_id', true) AS user_id,
49
+ current_setting('pipework.asof', true) AS asof`);
50
+ const row = result[0];
51
+ const mismatches = [];
52
+ if (normalizeGuc(row?.tenant_id) !== expected.tenant)
53
+ mismatches.push(formatAxis('tenant', expected.tenant, normalizeGuc(row?.tenant_id)));
54
+ if (normalizeGuc(row?.user_id) !== expected.user)
55
+ mismatches.push(formatAxis('user', expected.user, normalizeGuc(row?.user_id)));
56
+ if (normalizeGuc(row?.asof) !== expected.asOf)
57
+ mismatches.push(formatAxis('asOf', expected.asOf, normalizeGuc(row?.asof)));
58
+ if (mismatches.length > 0) {
59
+ throw new Error(`[pipework] Principal context mismatch between application and database.\n\n` +
60
+ mismatches.join('\n') + `\n\n` +
31
61
  ` This indicates an AsyncLocalStorage context integrity failure.\n` +
32
- ` The request has been aborted to prevent cross-tenant data access.\n`);
62
+ ` The request has been aborted to prevent cross-tenant or cross-user data access.\n`);
33
63
  }
34
64
  }
65
+ // current_setting(var, true) is NULL when the GUC was never set; set_config can
66
+ // also leave an empty string. Both collapse to null so they compare equal to an
67
+ // absent application-side axis.
68
+ function normalizeGuc(raw) {
69
+ const v = raw ?? null;
70
+ return v === '' ? null : v;
71
+ }
72
+ function formatAxis(axis, app, pg) {
73
+ return ` ${axis}: application context = ${app ?? '(null)'}, PostgreSQL session = ${pg ?? '(null)'}`;
74
+ }
35
75
  //# sourceMappingURL=rls.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rls.js","sourceRoot":"","sources":["../../../src/auth/tenant/rls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAEtD,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,SAAiB,WAAW,EAAE,aAAqB,oBAAoB;IAC1H,sBAAsB,CAAC,UAAU,CAAC,CAAA;IAElC,MAAM,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IACzC,MAAM,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,6BAA6B,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAA;IAEtF,OAAO;QACL,eAAe,CAAC,4BAA4B;QAC5C,eAAe,CAAC,2BAA2B;QAC3C,iBAAiB,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,uBAAuB,UAAU,WAAW;KACvH,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAM,EACN,KAAa,EACb,SAAiB,WAAW;IAE5B,MAAM,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IACzC,MAAM,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,eAAe,CAChC,6BAA6B,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,EACnE,QAAQ,CACT,CAAA;IAED,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,4BAA4B,CAAC,CAAC,CAAA;IACvE,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,2BAA2B,CAAC,CAAC,CAAA;IACtE,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CACtB,iBAAiB,UAAU,OAAO,CAAC,WAAW,CAAC,iDAAiD,CACjG,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAM,EACN,cAA6B;IAE7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAA,iEAAiE,CAAC,CAAA;IACrG,MAAM,GAAG,GAAI,MAAyD,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,IAAI,CAAA;IAC5F,MAAM,QAAQ,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAA;IAExC,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,0EAA0E;YAC1E,iCAAiC,cAAc,IAAI,QAAQ,IAAI;YAC/D,iCAAiC,QAAQ,IAAI,QAAQ,MAAM;YAC3D,oEAAoE;YACpE,uEAAuE,CACxE,CAAA;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"rls.js","sourceRoot":"","sources":["../../../src/auth/tenant/rls.ts"],"names":[],"mappings":"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"}
@@ -7,4 +7,12 @@ export interface DbOptions {
7
7
  readonly adminUrl?: string | undefined;
8
8
  }
9
9
  export declare function db(opts: DbOptions): Promise<void>;
10
+ /**
11
+ * The DML grants for the non-owner runtime role, applied at provision time on a
12
+ * connection authenticated as the owner. The two ALTER DEFAULT PRIVILEGES lines
13
+ * are the drift guard: every future table the owner creates via migrations is
14
+ * granted to the runtime role automatically, so an RLS-enabled table can never
15
+ * be left ungranted — which would blank the rows the app is entitled to.
16
+ */
17
+ export declare function buildRuntimeGrants(schema: string, ownerRole: string, runtimeRole: string): string[];
10
18
  //# sourceMappingURL=db.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/db.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,wBAAsB,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBvD"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/db.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,wBAAsB,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBvD;AAyND;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAWnG"}
@@ -28,90 +28,117 @@ export async function db(opts) {
28
28
  }
29
29
  }
30
30
  async function setup(opts) {
31
- const { config } = await loadConfig(resolve(opts.cwd));
32
- const databases = filterDatabases(config, opts.db);
33
- for (const [name, dbConfig] of databases) {
34
- info('Setting up database: ' + name);
35
- const adminUrl = resolveAdminUrl(opts, dbConfig);
36
- if (adminUrl === null) {
37
- const envName = dbConfig.adminUrl ?? 'ADMIN_DATABASE_URL';
38
- logError('No admin URL for database "' + name + '". Set ' + envName + ' or pass --admin-url.');
39
- process.exit(1);
40
- }
41
- const isTest = opts.test === true;
42
- const dbName = isTest ? name + '_test' : name;
43
- const roleName = name + '_app';
44
- const password = randomBytes(16).toString('hex');
45
- const envVarName = isTest ? dbConfig.testUrl : dbConfig.url;
46
- const connectionUrl = buildConnectionUrl(adminUrl, dbName, roleName, password);
47
- let adminClient = null;
48
- try {
49
- adminClient = await connectAdmin(adminUrl);
50
- await ensureRole(adminClient, roleName, password);
51
- await ensureDatabase(adminClient, dbName, roleName);
52
- if (dbConfig.extensions !== undefined && dbConfig.extensions.length > 0) {
53
- const extClient = await connectAdmin(connectionUrl);
31
+ {
32
+ const { config } = await loadConfig(resolve(opts.cwd));
33
+ const databases = filterDatabases(config, opts.db);
34
+ for (const [name, dbConfig] of databases) {
35
+ info('Setting up database: ' + name);
36
+ const adminUrl = resolveAdminUrl(opts, dbConfig);
37
+ if (adminUrl === null) {
38
+ const envName = dbConfig.adminUrl ?? 'ADMIN_DATABASE_URL';
39
+ logError('No admin URL for database "' + name + '". Set ' + envName + ' or pass --admin-url.');
40
+ process.exit(1);
41
+ }
42
+ const isTest = opts.test === true;
43
+ const dbName = isTest ? name + '_test' : name;
44
+ const ownerRole = name + '_owner';
45
+ const runtimeRole = name + '_app';
46
+ const ownerPassword = randomBytes(16).toString('hex');
47
+ const runtimePassword = randomBytes(16).toString('hex');
48
+ const ownerUrl = buildConnectionUrl(adminUrl, dbName, ownerRole, ownerPassword);
49
+ const runtimeUrl = buildConnectionUrl(adminUrl, dbName, runtimeRole, runtimePassword);
50
+ const ownerEnvVar = isTest ? dbConfig.testUrl : dbConfig.url;
51
+ const runtimeEnvVar = isTest ? dbConfig.appTestUrl : dbConfig.appUrl;
52
+ let adminClient = null;
53
+ try {
54
+ adminClient = await connectAdmin(adminUrl);
55
+ await ensureRole(adminClient, ownerRole, ownerPassword, { bypassRls: true });
56
+ await ensureRole(adminClient, runtimeRole, runtimePassword, { bypassRls: false });
57
+ await ensureDatabase(adminClient, dbName, ownerRole);
58
+ await grantConnect(adminClient, dbName, runtimeRole);
59
+ // Extensions and the runtime grants run as the owner so the database
60
+ // objects (and the owner-scoped default privileges) belong to the owner.
61
+ const ownerClient = await connectAdmin(ownerUrl);
54
62
  try {
55
- for (const ext of dbConfig.extensions) {
56
- await ensureExtension(extClient, ext);
63
+ if (dbConfig.extensions !== undefined) {
64
+ for (const ext of dbConfig.extensions) {
65
+ await ensureExtension(ownerClient, ext);
66
+ }
67
+ }
68
+ for (const stmt of buildRuntimeGrants('public', ownerRole, runtimeRole)) {
69
+ await ownerClient.query(stmt);
57
70
  }
58
71
  }
59
72
  finally {
60
- await extClient.close();
73
+ await ownerClient.close();
74
+ }
75
+ info('Granted runtime DML to role: ' + runtimeRole);
76
+ success('Database "' + dbName + '" ready (owner: ' + ownerRole + ', runtime: ' + runtimeRole + ')');
77
+ if (ownerEnvVar !== undefined) {
78
+ writeEnvVar(opts.cwd, ownerEnvVar, ownerUrl);
79
+ success('Wrote ' + ownerEnvVar + ' to .env');
80
+ }
81
+ if (runtimeEnvVar !== undefined) {
82
+ writeEnvVar(opts.cwd, runtimeEnvVar, runtimeUrl);
83
+ success('Wrote ' + runtimeEnvVar + ' to .env');
84
+ }
85
+ else {
86
+ warn('No appUrl configured for "' + name + '" — runtime would fall back to the owner connection and RLS would be inert. Set appUrl/appTestUrl in the database config to enable role separation.');
61
87
  }
62
88
  }
63
- success('Database "' + dbName + '" ready (role: ' + roleName + ')');
64
- if (envVarName !== undefined) {
65
- writeEnvVar(opts.cwd, envVarName, connectionUrl);
66
- success('Wrote ' + envVarName + ' to .env');
89
+ catch (err) {
90
+ logError('Failed to setup "' + name + '": ' + (err instanceof Error ? err.message : String(err)));
91
+ process.exit(1);
67
92
  }
68
- }
69
- catch (err) {
70
- logError('Failed to setup "' + name + '": ' + (err instanceof Error ? err.message : String(err)));
71
- process.exit(1);
72
- }
73
- finally {
74
- if (adminClient !== null) {
75
- await adminClient.close();
93
+ finally {
94
+ if (adminClient !== null) {
95
+ await adminClient.close();
96
+ }
76
97
  }
77
98
  }
99
+ success('Database setup complete');
78
100
  }
79
- success('Database setup complete');
80
101
  }
81
102
  async function teardown(opts) {
82
- const { config } = await loadConfig(resolve(opts.cwd));
83
- const databases = filterDatabases(config, opts.db);
84
- if (config.environment === 'production' && opts.confirm !== true) {
85
- logError('Teardown in production requires --confirm flag.');
86
- process.exit(1);
87
- }
88
- for (const [name, dbConfig] of databases) {
89
- const adminUrl = resolveAdminUrl(opts, dbConfig);
90
- if (adminUrl === null) {
91
- warn('No admin URL for database "' + name + '" — skipping teardown');
92
- continue;
93
- }
94
- let adminClient = null;
95
- try {
96
- adminClient = await connectAdmin(adminUrl);
97
- const dbName = name;
98
- const testDbName = name + '_test';
99
- const roleName = name + '_app';
100
- await dropDatabaseIfExists(adminClient, testDbName);
101
- await dropDatabaseIfExists(adminClient, dbName);
102
- await dropRoleIfExists(adminClient, roleName);
103
- success('Torn down: ' + name);
104
- }
105
- catch (err) {
106
- logError('Failed to teardown "' + name + '": ' + (err instanceof Error ? err.message : String(err)));
103
+ {
104
+ const { config } = await loadConfig(resolve(opts.cwd));
105
+ const databases = filterDatabases(config, opts.db);
106
+ if (config.environment === 'production' && opts.confirm !== true) {
107
+ logError('Teardown in production requires --confirm flag.');
108
+ process.exit(1);
107
109
  }
108
- finally {
109
- if (adminClient !== null) {
110
- await adminClient.close();
110
+ for (const [name, dbConfig] of databases) {
111
+ const adminUrl = resolveAdminUrl(opts, dbConfig);
112
+ if (adminUrl === null) {
113
+ warn('No admin URL for database "' + name + '" — skipping teardown');
114
+ continue;
115
+ }
116
+ let adminClient = null;
117
+ try {
118
+ adminClient = await connectAdmin(adminUrl);
119
+ const dbName = name;
120
+ const testDbName = name + '_test';
121
+ const ownerRole = name + '_owner';
122
+ const runtimeRole = name + '_app';
123
+ // Databases first: dropping them removes the in-database grants and
124
+ // owner-scoped default privileges, so the roles drop cleanly afterwards.
125
+ await dropDatabaseIfExists(adminClient, testDbName);
126
+ await dropDatabaseIfExists(adminClient, dbName);
127
+ await dropRoleIfExists(adminClient, runtimeRole);
128
+ await dropRoleIfExists(adminClient, ownerRole);
129
+ success('Torn down: ' + name);
130
+ }
131
+ catch (err) {
132
+ logError('Failed to teardown "' + name + '": ' + (err instanceof Error ? err.message : String(err)));
133
+ }
134
+ finally {
135
+ if (adminClient !== null) {
136
+ await adminClient.close();
137
+ }
111
138
  }
112
139
  }
140
+ success('Database teardown complete');
113
141
  }
114
- success('Database teardown complete');
115
142
  }
116
143
  function filterDatabases(config, dbFilter) {
117
144
  const entries = Object.entries(config.databases);
@@ -169,17 +196,47 @@ async function connectAdmin(url) {
169
196
  },
170
197
  };
171
198
  }
172
- async function ensureRole(client, name, password) {
199
+ // Both roles are LOGIN, non-superuser, and cannot create databases or roles.
200
+ // The single discriminator is BYPASSRLS: the owner has it (DDL/bootstrap reads
201
+ // and writes across every tenant), the non-owner runtime role explicitly does
202
+ // not, so generated RLS policies actually bind to it.
203
+ function roleAttributeClause(attrs) {
204
+ return 'NOSUPERUSER NOCREATEDB NOCREATEROLE ' + (attrs.bypassRls ? 'BYPASSRLS' : 'NOBYPASSRLS');
205
+ }
206
+ async function ensureRole(client, name, password, attrs) {
207
+ const clause = roleAttributeClause(attrs);
173
208
  const rows = await client.query('SELECT 1 FROM pg_roles WHERE rolname = $1', [name]);
174
209
  if (rows.length === 0) {
175
- await client.query('CREATE ROLE ' + quoteIdent(name) + ' WITH LOGIN PASSWORD \'' + escapePassword(password) + '\'');
210
+ await client.query('CREATE ROLE ' + quoteIdent(name) + ' WITH LOGIN PASSWORD \'' + escapePassword(password) + '\' ' + clause);
176
211
  info('Created role: ' + name);
177
212
  }
178
213
  else {
179
- await client.query('ALTER ROLE ' + quoteIdent(name) + ' WITH PASSWORD \'' + escapePassword(password) + '\'');
180
- info('Updated password for role: ' + name);
214
+ await client.query('ALTER ROLE ' + quoteIdent(name) + ' WITH LOGIN PASSWORD \'' + escapePassword(password) + '\' ' + clause);
215
+ info('Updated role: ' + name);
181
216
  }
182
217
  }
218
+ async function grantConnect(client, dbName, role) {
219
+ await client.query('GRANT CONNECT ON DATABASE ' + quoteIdent(dbName) + ' TO ' + quoteIdent(role));
220
+ }
221
+ /**
222
+ * The DML grants for the non-owner runtime role, applied at provision time on a
223
+ * connection authenticated as the owner. The two ALTER DEFAULT PRIVILEGES lines
224
+ * are the drift guard: every future table the owner creates via migrations is
225
+ * granted to the runtime role automatically, so an RLS-enabled table can never
226
+ * be left ungranted — which would blank the rows the app is entitled to.
227
+ */
228
+ export function buildRuntimeGrants(schema, ownerRole, runtimeRole) {
229
+ const s = quoteIdent(schema);
230
+ const owner = quoteIdent(ownerRole);
231
+ const runtime = quoteIdent(runtimeRole);
232
+ return [
233
+ 'GRANT USAGE ON SCHEMA ' + s + ' TO ' + runtime,
234
+ 'GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA ' + s + ' TO ' + runtime,
235
+ 'GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA ' + s + ' TO ' + runtime,
236
+ 'ALTER DEFAULT PRIVILEGES FOR ROLE ' + owner + ' IN SCHEMA ' + s + ' GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ' + runtime,
237
+ 'ALTER DEFAULT PRIVILEGES FOR ROLE ' + owner + ' IN SCHEMA ' + s + ' GRANT USAGE, SELECT ON SEQUENCES TO ' + runtime,
238
+ ];
239
+ }
183
240
  async function ensureDatabase(client, dbName, owner) {
184
241
  const rows = await client.query('SELECT 1 FROM pg_database WHERE datname = $1', [dbName]);
185
242
  if (rows.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/cli/commands/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/cli/commands/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAYpD,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,IAAe;IACtC,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,KAAK,OAAO;YACV,MAAM,KAAK,CAAC,IAAI,CAAC,CAAA;YACjB,MAAK;QACP,KAAK,UAAU;YACb,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;YACpB,MAAK;QACP,KAAK,OAAO;YACV,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAA;YACpB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAA;YACjB,MAAK;QACP,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAA;YACvC,QAAQ,CAAC,yBAAyB,GAAG,GAAG,CAAC,CAAA;YACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,oCAAoC,CAAC,GAAG,MAAM,CAAC,CAAA;YACzF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAA;YAClG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAA;YAC7F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAA;YACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,IAAe;IAClC,CAAC;QACC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACtD,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;QAElD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAA;YAEpC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YAChD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,IAAI,oBAAoB,CAAA;gBACzD,QAAQ,CAAC,6BAA6B,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,uBAAuB,CAAC,CAAA;gBAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAA;YACjC,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;YAC7C,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,CAAA;YACjC,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,CAAA;YACjC,MAAM,aAAa,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACrD,MAAM,eAAe,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACvD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAA;YAC/E,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,CAAC,CAAA;YACrF,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAA;YAC5D,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAA;YAEpE,IAAI,WAAW,GAAuB,IAAI,CAAA;YAC1C,IAAI,CAAC;gBACH,WAAW,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAE1C,MAAM,UAAU,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;gBAC5E,MAAM,UAAU,CAAC,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;gBACjF,MAAM,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA;gBACpD,MAAM,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;gBAEpD,qEAAqE;gBACrE,yEAAyE;gBACzE,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAChD,IAAI,CAAC;oBACH,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;wBACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;4BACtC,MAAM,eAAe,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;wBACzC,CAAC;oBACH,CAAC;oBACD,KAAK,MAAM,IAAI,IAAI,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;wBACxE,MAAM,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAC/B,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACT,MAAM,WAAW,CAAC,KAAK,EAAE,CAAA;gBAC3B,CAAC;gBACD,IAAI,CAAC,+BAA+B,GAAG,WAAW,CAAC,CAAA;gBAEnD,OAAO,CAAC,YAAY,GAAG,MAAM,GAAG,kBAAkB,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,GAAG,CAAC,CAAA;gBAEnG,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;oBAC5C,OAAO,CAAC,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC,CAAA;gBAC9C,CAAC;gBACD,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;oBAChC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,UAAU,CAAC,CAAA;oBAChD,OAAO,CAAC,QAAQ,GAAG,aAAa,GAAG,UAAU,CAAC,CAAA;gBAChD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,4BAA4B,GAAG,IAAI,GAAG,qJAAqJ,CAAC,CAAA;gBACnM,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,mBAAmB,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;gBACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;oBAAS,CAAC;gBACT,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACzB,MAAM,WAAW,CAAC,KAAK,EAAE,CAAA;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,yBAAyB,CAAC,CAAA;IACpC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAe;IACrC,CAAC;QACC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACtD,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAA;QAElD,IAAI,MAAM,CAAC,WAAW,KAAK,YAAY,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACjE,QAAQ,CAAC,iDAAiD,CAAC,CAAA;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YAChD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,IAAI,CAAC,6BAA6B,GAAG,IAAI,GAAG,uBAAuB,CAAC,CAAA;gBACpE,SAAQ;YACV,CAAC;YAED,IAAI,WAAW,GAAuB,IAAI,CAAA;YAC1C,IAAI,CAAC;gBACH,WAAW,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAA;gBAE1C,MAAM,MAAM,GAAG,IAAI,CAAA;gBACnB,MAAM,UAAU,GAAG,IAAI,GAAG,OAAO,CAAA;gBACjC,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,CAAA;gBACjC,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,CAAA;gBAEjC,oEAAoE;gBACpE,yEAAyE;gBACzE,MAAM,oBAAoB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;gBACnD,MAAM,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;gBAC/C,MAAM,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;gBAChD,MAAM,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;gBAE9C,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAA;YAC/B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,QAAQ,CAAC,sBAAsB,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YACtG,CAAC;oBAAS,CAAC;gBACT,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACzB,MAAM,WAAW,CAAC,KAAK,EAAE,CAAA;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,4BAA4B,CAAC,CAAA;IACvC,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,MAAiB,EAAE,QAAiB;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAChD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAA;QAC9D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,YAAY,GAAG,QAAQ,GAAG,oCAAoC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAC7G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,IAAe,EAAE,QAAwB;IAChE,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAA;IACrD,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAC9C,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE;YAAE,OAAO,OAAO,CAAA;IAC7D,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;IAClD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAA;IAC9D,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB,EAAE,MAAc,EAAE,IAAY,EAAE,QAAgB;IAC1F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7B,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAA;QACnB,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACvB,GAAG,CAAC,QAAQ,GAAG,GAAG,GAAG,MAAM,CAAA;QAC3B,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAA;QAChE,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,eAAe,GAAG,IAAI,GAAG,GAAG,GAAG,QAAQ,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,MAAM,CAAA;QACxF,CAAC;QACD,OAAO,eAAe,GAAG,IAAI,GAAG,GAAG,GAAG,QAAQ,GAAG,kBAAkB,GAAG,MAAM,CAAA;IAC9E,CAAC;AACH,CAAC;AAOD,KAAK,UAAU,YAAY,CAAC,GAAW;IACrC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC,CAAA;IAC5D,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,MAAc,EAAE,MAAkB;YAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAiB,CAAC,CAAA;YACjD,CAAC;YACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC9B,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAA;QACpB,CAAC;KACF,CAAA;AACH,CAAC;AAOD,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,sDAAsD;AACtD,SAAS,mBAAmB,CAAC,KAAqB;IAChD,OAAO,sCAAsC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;AACjG,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,MAAmB,EAAE,IAAY,EAAE,QAAgB,EAAE,KAAqB;IAClG,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;IACzC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,CAAC,IAAI,CAAC,CAAc,CAAA;IACjG,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,yBAAyB,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC,CAAA;QAC7H,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAC/B,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,yBAAyB,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC,CAAA;QAC5H,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,MAAmB,EAAE,MAAc,EAAE,IAAY;IAC3E,MAAM,MAAM,CAAC,KAAK,CAAC,4BAA4B,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;AACnG,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,SAAiB,EAAE,WAAmB;IACvF,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;IAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IACnC,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACvC,OAAO;QACL,wBAAwB,GAAG,CAAC,GAAG,MAAM,GAAG,OAAO;QAC/C,+DAA+D,GAAG,CAAC,GAAG,MAAM,GAAG,OAAO;QACtF,iDAAiD,GAAG,CAAC,GAAG,MAAM,GAAG,OAAO;QACxE,oCAAoC,GAAG,KAAK,GAAG,aAAa,GAAG,CAAC,GAAG,qDAAqD,GAAG,OAAO;QAClI,oCAAoC,GAAG,KAAK,GAAG,aAAa,GAAG,CAAC,GAAG,uCAAuC,GAAG,OAAO;KACrH,CAAA;AACH,CAAC;AAGD,KAAK,UAAU,cAAc,CAAC,MAAmB,EAAE,MAAc,EAAE,KAAa;IAC9E,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,CAAC,MAAM,CAAC,CAAc,CAAA;IACtG,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,CAAC,KAAK,CAAC,kBAAkB,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;QAC3F,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,CAAA;IACrC,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,YAAY,GAAG,MAAM,GAAG,kBAAkB,CAAC,CAAA;IAClD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,MAAmB,EAAE,GAAW;IAC7D,MAAM,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IACvE,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,CAAA;AAC3B,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,MAAmB,EAAE,MAAc;IACrE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,CAAC,MAAM,CAAC,CAAc,CAAA;IACtG,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAA;QACzD,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,CAAA;IACrC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,MAAmB,EAAE,IAAY;IAC/D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,CAAC,IAAI,CAAC,CAAc,CAAA;IACjG,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAA;QACnD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,IAAI,GAAG,GAAG,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,GAAG,GAAG,IAAI,GAAG,GAAG,CAAA;AACzB,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB;IACtC,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,GAAW,EAAE,KAAa;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IACjC,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACxC,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,CAAA;QACnD,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,CAAA;YACrD,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;YACxC,OAAM;QACR,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;IACzE,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;AAC/E,CAAC"}
@@ -47,6 +47,7 @@ export interface ResolvedConfig {
47
47
  export interface ResolvedDatabase {
48
48
  readonly name: string;
49
49
  readonly url: string;
50
+ readonly appUrl?: string;
50
51
  readonly schema: string | string[] | undefined;
51
52
  readonly migrations: string | undefined;
52
53
  readonly extensions: readonly string[];
@@ -57,6 +58,7 @@ export interface ResolvedDatabase {
57
58
  };
58
59
  readonly rls?: {
59
60
  readonly sessionVar: string;
61
+ readonly force: boolean;
60
62
  };
61
63
  }
62
64
  export declare function loadConfig(raw: unknown): ResolvedConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/core/config/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,KAAK,WAAW,EAAuB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAK9H,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,kHAAkH;IAClH,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAA;IACvD;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAA;IAC7C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAA;IACzC,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAClD,aAAa,IAAI,SAAS,MAAM,EAAE,CAAA;IAClC,mBAAmB,IAAI,MAAM,CAAA;IAC7B,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAA;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAA;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IACnD,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAA;CAC/C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAavD"}
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/core/config/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,KAAK,WAAW,EAAuB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAK9H,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,kHAAkH;IAClH,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAA;IACvD;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAA;IACvB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,qBAAqB,CAAA;IAC7C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAA;IACzC,SAAS,IAAI,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAClD,aAAa,IAAI,SAAS,MAAM,EAAE,CAAA;IAClC,mBAAmB,IAAI,MAAM,CAAA;IAC7B,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAAA;CACrD;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAA;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;IACnD,QAAQ,CAAC,GAAG,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;CACxE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAavD"}