@nodii/db-rls 0.5.2 → 0.6.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.
@@ -1,12 +1,29 @@
1
1
  #!/usr/bin/env node
2
- // CLI shim for `npx @nodii/db-rls migrate-gen <serviceName>`.
2
+ // CLI shim for `npx @nodii/db-rls <subcommand>`.
3
3
  //
4
- // The real logic lives in src/migrate-gen.ts; this shim just unwraps
5
- // argv and calls runMigrateGenCli + translates the return value to
6
- // process.exit.
4
+ // The real logic lives in src/*.ts; this shim unwraps argv, dispatches by
5
+ // subcommand, and translates the return value to process.exit.
6
+ //
7
+ // Subcommands:
8
+ // migrate-gen <serviceName> [--out <dir>] [--stub]
9
+ // verify-rls --tables <a,b,c> [--ref <x,y>] [--schema <name>] [--db <url>]
10
+ //
11
+ // (Filename kept as migrate-gen.mjs for the package.json `bin` mapping;
12
+ // it is the single `nodii-db-rls` entrypoint, not migrate-gen only.)
7
13
 
8
14
  import { runMigrateGenCli } from "../dist/migrate-gen.js";
15
+ import { runVerifyRlsCli } from "../dist/verify-rls-cli.js";
16
+
17
+ const argv = process.argv.slice(2);
18
+ const sub = argv[0];
9
19
 
10
- const args = process.argv.slice(2);
11
- const code = runMigrateGenCli(args);
12
- process.exit(code);
20
+ if (sub === "verify-rls") {
21
+ const { code, message } = await runVerifyRlsCli(argv.slice(1));
22
+ // Coverage failures (1) + usage (2) go to stderr; success (0) to stdout.
23
+ (code === 0 ? console.log : console.error)(message);
24
+ process.exit(code);
25
+ } else {
26
+ // migrate-gen (default + back-compat: runMigrateGenCli accepts the
27
+ // leading "migrate-gen" token and prints usage on a missing serviceName).
28
+ process.exit(runMigrateGenCli(argv));
29
+ }
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export { withUserContextDb, withSystemContextDb, withOwnerContextDb, } from "./d
11
11
  export type { DrizzleClient, NodePgDatabase } from "./drizzle-client";
12
12
  export type { OwnerContextOpts } from "./migrate-guard";
13
13
  export { assertMigrateAllowed } from "./migrate-guard";
14
+ export { RlsCoverageError, verifyRls } from "./verify-rls";
15
+ export type { ReferenceTablePredicate, RlsCoverageOffender, RlsQuerier, VerifyRlsOpts, } from "./verify-rls";
14
16
  export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, } from "./auth-schema";
15
17
  export type { SqlExecutor } from "./auth-schema";
16
18
  export { withRls, generateTableGrants, withPlatformOpsTenantSql, withPlatformOpsGlobalSql, platformOpsTenantPredicateSql, platformOpsGlobalPredicateSql, platformOpsVerbClauseSql, sqlLiteral, PLATFORM_OPS_GRANTS_REPLICA_DEFAULT, referenceTableGrantsSql, findTenantColumn, ReferenceTableTenantColumnError, REFERENCE_TABLE_SKIP_RLS_MARKER, } from "./rls-policy-gen";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EAItB,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,wBAAwB,EACxB,UAAU,EACV,mCAAmC,EAEnC,uBAAuB,EACvB,gBAAgB,EAChB,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,OAAO,EACP,WAAW,EACX,eAAe,EACf,6BAA6B,EAC7B,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,sBAAsB,EACtB,QAAQ,EACR,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,eAAO,MAAM,QAAQ,WAAW,CAAC;AACjC,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EAItB,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAMvD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,YAAY,EACV,uBAAuB,EACvB,mBAAmB,EACnB,UAAU,EACV,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,wBAAwB,EACxB,UAAU,EACV,mCAAmC,EAEnC,uBAAuB,EACvB,gBAAgB,EAChB,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,OAAO,EACP,WAAW,EACX,eAAe,EACf,6BAA6B,EAC7B,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,sBAAsB,EACtB,QAAQ,EACR,iBAAiB,EACjB,eAAe,GAChB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -42,6 +42,11 @@ export { withUserContext, withSystemContext, withOwnerContext, withPlatformOpsCo
42
42
  withPlatformOps, _resetWithPlatformOpsDeprecationWarnedForTests, autoDispatch, } from "./context";
43
43
  export { withUserContextDb, withSystemContextDb, withOwnerContextDb, } from "./drizzle-client";
44
44
  export { assertMigrateAllowed } from "./migrate-guard";
45
+ // 08-rls § A1 + § 7.6 — RLS-coverage preflight guard. Service db:setup
46
+ // gates call verifyRls() after migrations to catch the drizzle-snapshot
47
+ // RLS hazard (a tenant table created without ENABLE ROW LEVEL SECURITY),
48
+ // exempting § 7.6 reference tables (GRANT-controlled, NO RLS by design).
49
+ export { RlsCoverageError, verifyRls } from "./verify-rls";
45
50
  export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, } from "./auth-schema";
46
51
  export { withRls, generateTableGrants, withPlatformOpsTenantSql, withPlatformOpsGlobalSql, platformOpsTenantPredicateSql, platformOpsGlobalPredicateSql, platformOpsVerbClauseSql, sqlLiteral, PLATFORM_OPS_GRANTS_REPLICA_DEFAULT,
47
52
  // 08-rls § 7.6 — pure platform-global reference tables (GRANT-controlled).
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,wDAAwD;AACxD,6CAA6C;AAC7C,EAAE;AACF,yCAAyC;AACzC,sEAAsE;AACtE,wCAAwC;AACxC,sDAAsD;AACtD,+DAA+D;AAC/D,4EAA4E;AAC5E,gDAAgD;AAChD,mEAAmE;AACnE,mDAAmD;AACnD,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,6EAA6E;AAC7E,sCAAsC;AACtC,uEAAuE;AACvE,0EAA0E;AAC1E,8EAA8E;AAC9E,kFAAkF;AAClF,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,qCAAqC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB;AACtB,uEAAuE;AACvE,wEAAwE;AACxE,sCAAsC;AACtC,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,wBAAwB,EACxB,UAAU,EACV,mCAAmC;AACnC,2EAA2E;AAC3E,uBAAuB,EACvB,gBAAgB,EAChB,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAQvB,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,wDAAwD;AACxD,6CAA6C;AAC7C,EAAE;AACF,yCAAyC;AACzC,sEAAsE;AACtE,wCAAwC;AACxC,sDAAsD;AACtD,+DAA+D;AAC/D,4EAA4E;AAC5E,gDAAgD;AAChD,mEAAmE;AACnE,mDAAmD;AACnD,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,wEAAwE;AACxE,sEAAsE;AACtE,6EAA6E;AAC7E,6EAA6E;AAC7E,sCAAsC;AACtC,uEAAuE;AACvE,0EAA0E;AAC1E,8EAA8E;AAC9E,kFAAkF;AAClF,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,qCAAqC;AAErC,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AACjC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB;AACtB,uEAAuE;AACvE,wEAAwE;AACxE,sCAAsC;AACtC,eAAe,EACf,8CAA8C,EAC9C,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,uEAAuE;AACvE,wEAAwE;AACxE,yEAAyE;AACzE,yEAAyE;AACzE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQ3D,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,OAAO,EACP,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,wBAAwB,EACxB,UAAU,EACV,mCAAmC;AACnC,2EAA2E;AAC3E,uBAAuB,EACvB,gBAAgB,EAChB,+BAA+B,EAC/B,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAW1B,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAQvB,qEAAqE;AACrE,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,eAAe,EACf,qBAAqB,GACtB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface RunVerifyRlsCliResult {
2
+ /** Process exit code: 0 = all covered, 1 = coverage failure, 2 = usage. */
3
+ code: number;
4
+ /** Human-readable line for stdout/stderr (caller prints). */
5
+ message: string;
6
+ }
7
+ /**
8
+ * Parses argv (without the leading `verify-rls` token) and runs the
9
+ * coverage check. Returns an exit code + message rather than calling
10
+ * `process.exit`, so it is unit-testable. The bin shim translates.
11
+ *
12
+ * Flags:
13
+ * --tables a,b,c (required) RLS-required tables (comma-separated)
14
+ * --ref c,d reference tables to exempt (§ 7.6)
15
+ * --schema public default schema for bare names (default: public)
16
+ * --db <url> connection string (else DATABASE_URL / DB_RLS_PG_URL)
17
+ * --help / -h
18
+ */
19
+ export declare function runVerifyRlsCli(args: readonly string[]): Promise<RunVerifyRlsCliResult>;
20
+ //# sourceMappingURL=verify-rls-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-rls-cli.d.ts","sourceRoot":"","sources":["../src/verify-rls-cli.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IACpC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAqDhC"}
@@ -0,0 +1,99 @@
1
+ // verify-rls CLI — `nodii-db-rls verify-rls --tables a,b [--ref c] [--schema public]`.
2
+ //
3
+ // Thin CLI around `verifyRls` so a service can wire a `db:verify-rls`
4
+ // script (or a CI step) without writing its own pg-connect boilerplate.
5
+ // The importable `verifyRls` function (src/verify-rls.ts) remains the core
6
+ // deliverable — this is the optional bin mirror of migrate-gen's CLI.
7
+ //
8
+ // Connection string comes from `--db <url>` or the `DATABASE_URL` /
9
+ // `DB_RLS_PG_URL` env var (in that order). `pg` is an optional peer dep;
10
+ // the CLI imports it lazily so importing the library does not require it.
11
+ import { RlsCoverageError, verifyRls } from "./verify-rls";
12
+ function splitList(value) {
13
+ if (!value)
14
+ return [];
15
+ return value
16
+ .split(",")
17
+ .map((s) => s.trim())
18
+ .filter((s) => s.length > 0);
19
+ }
20
+ /**
21
+ * Parses argv (without the leading `verify-rls` token) and runs the
22
+ * coverage check. Returns an exit code + message rather than calling
23
+ * `process.exit`, so it is unit-testable. The bin shim translates.
24
+ *
25
+ * Flags:
26
+ * --tables a,b,c (required) RLS-required tables (comma-separated)
27
+ * --ref c,d reference tables to exempt (§ 7.6)
28
+ * --schema public default schema for bare names (default: public)
29
+ * --db <url> connection string (else DATABASE_URL / DB_RLS_PG_URL)
30
+ * --help / -h
31
+ */
32
+ export async function runVerifyRlsCli(args) {
33
+ let tables;
34
+ let refs;
35
+ let schema;
36
+ let dbUrl;
37
+ for (let i = 0; i < args.length; i++) {
38
+ const a = args[i];
39
+ if (a === "--tables" && i + 1 < args.length)
40
+ tables = args[++i];
41
+ else if (a === "--ref" && i + 1 < args.length)
42
+ refs = args[++i];
43
+ else if (a === "--schema" && i + 1 < args.length)
44
+ schema = args[++i];
45
+ else if (a === "--db" && i + 1 < args.length)
46
+ dbUrl = args[++i];
47
+ else if (a === "--help" || a === "-h") {
48
+ return { code: 0, message: usage() };
49
+ }
50
+ }
51
+ const requiredTables = splitList(tables);
52
+ if (requiredTables.length === 0) {
53
+ return { code: 2, message: usage() };
54
+ }
55
+ const connectionString = dbUrl ?? process.env.DATABASE_URL ?? process.env.DB_RLS_PG_URL;
56
+ if (!connectionString) {
57
+ return {
58
+ code: 2,
59
+ message: "verify-rls: no connection string — pass --db <url> or set DATABASE_URL / DB_RLS_PG_URL.",
60
+ };
61
+ }
62
+ // Lazy-import pg (optional peer dep). Keeps the library importable
63
+ // without pg installed; only the CLI path requires it.
64
+ const { Pool } = await import("pg");
65
+ const pool = new Pool({ connectionString, max: 1 });
66
+ try {
67
+ await verifyRls(pool, {
68
+ requiredTables,
69
+ schema,
70
+ referenceTables: splitList(refs),
71
+ });
72
+ return {
73
+ code: 0,
74
+ message: `verify-rls: OK — ${requiredTables.length} RLS-required table(s) covered.`,
75
+ };
76
+ }
77
+ catch (err) {
78
+ if (err instanceof RlsCoverageError) {
79
+ return { code: 1, message: err.message };
80
+ }
81
+ throw err;
82
+ }
83
+ finally {
84
+ await pool.end().catch(() => { });
85
+ }
86
+ }
87
+ function usage() {
88
+ return `usage: verify-rls --tables <a,b,c> [--ref <x,y>] [--schema <name>] [--db <url>]
89
+
90
+ Verifies every --tables relation has ROW LEVEL SECURITY enabled
91
+ (pg_class.relrowsecurity = true), exempting any --ref reference table
92
+ (08-rls § 7.6 — GRANT-controlled, NO RLS by design). Exits 1 (loud) if
93
+ any RLS-required table is missing RLS.
94
+
95
+ Connection string: --db <url>, else DATABASE_URL, else DB_RLS_PG_URL.
96
+
97
+ Spec: @nodii/db-rls 08-rls § A1 (RLS on every tenant-scoped table).`;
98
+ }
99
+ //# sourceMappingURL=verify-rls-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-rls-cli.js","sourceRoot":"","sources":["../src/verify-rls-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { DbRlsError } from "./types";
2
+ /** Minimal query surface for the preflight catalog read. `pg.Pool` and
3
+ * `pg.PoolClient` both satisfy this; `PgClientPool` exposes `.rawPool`.
4
+ * We deliberately do NOT reuse the tx-bound `PgPool` — the preflight is a
5
+ * single read, not a GUC-scoped transaction. */
6
+ export interface RlsQuerier {
7
+ query<R = unknown>(sql: string, params?: readonly unknown[]): Promise<{
8
+ rows: R[];
9
+ }>;
10
+ }
11
+ /** A predicate that returns `true` when `table` is a reference table
12
+ * (GRANT-controlled, NO RLS by design — § 7.6) and must therefore be
13
+ * EXEMPT from the RLS-coverage check. `table` is the table name exactly
14
+ * as it appears in `requiredTables` (may be schema-qualified). */
15
+ export type ReferenceTablePredicate = (table: string) => boolean;
16
+ export interface VerifyRlsOpts {
17
+ /** Tables that REQUIRE RLS (the canonical 5-policy posture, § A1). Each
18
+ * may be bare (`orders`) or schema-qualified (`billing.orders`); a bare
19
+ * name resolves against `schema`. */
20
+ requiredTables: readonly string[];
21
+ /** Schema for bare (unqualified) table names. Defaults to `"public"`. */
22
+ schema?: string;
23
+ /** Reference tables to EXEMPT (§ 7.6 — GRANT-controlled, NO RLS by
24
+ * design). Supply EITHER this list OR `isReferenceTable`. Entries are
25
+ * matched against `requiredTables` after both are normalized to
26
+ * `schema.table`, so `["billing.country_codes"]` and a bare
27
+ * `["country_codes"]` (with `schema:"billing"`) both match. */
28
+ referenceTables?: readonly string[];
29
+ /** Alternative to `referenceTables` — a predicate receiving the table
30
+ * name as it appears in `requiredTables`. Use when the exempt set is
31
+ * computed (e.g. read from a registry). If both are supplied a table is
32
+ * exempt when EITHER matches. */
33
+ isReferenceTable?: ReferenceTablePredicate;
34
+ /** Back-compat alias kept intentionally undocumented in callers: when
35
+ * `false`, reference-table exemption is disabled and a reference table
36
+ * missing RLS WOULD be flagged. Defaults to `true` (exemptions on). */
37
+ allowReferenceTables?: boolean;
38
+ }
39
+ /** One RLS-required table whose coverage is missing or whose catalog row
40
+ * could not be found. */
41
+ export interface RlsCoverageOffender {
42
+ /** Table name as supplied in `requiredTables`. */
43
+ table: string;
44
+ /** Resolved schema used for the catalog lookup. */
45
+ schema: string;
46
+ /** Resolved (unqualified) relation name used for the catalog lookup. */
47
+ relname: string;
48
+ /** Why this table is an offender:
49
+ * - `"rls_disabled"` — the table exists but `relrowsecurity = false`.
50
+ * - `"not_found"` — no `pg_class` row matched (table absent / wrong
51
+ * schema). Also a failure: a required table that doesn't exist can't
52
+ * be protected. */
53
+ reason: "rls_disabled" | "not_found";
54
+ }
55
+ /**
56
+ * Thrown by `verifyRls` when one or more RLS-required tables are missing
57
+ * row-level security (or are absent). Carries the structured offender list
58
+ * so a `db:setup` gate can render a precise failure. Reference tables
59
+ * (§ 7.6) are NEVER offenders — they are exempt before this is thrown.
60
+ */
61
+ export declare class RlsCoverageError extends DbRlsError {
62
+ readonly offenders: readonly RlsCoverageOffender[];
63
+ constructor(offenders: readonly RlsCoverageOffender[]);
64
+ }
65
+ /**
66
+ * Verifies that every table in `requiredTables` has row-level security
67
+ * enabled (`pg_class.relrowsecurity = true`), exempting any § 7.6
68
+ * reference table. Resolves OK (returns `void`) when all required tables
69
+ * are covered; throws `RlsCoverageError` listing the offenders otherwise.
70
+ *
71
+ * The query is a single read against `pg_class` joined to `pg_namespace`
72
+ * — read-only, no GUCs, no writes. Run it from a migration / `db:setup`
73
+ * gate against any pool (typically the owner/admin pool).
74
+ */
75
+ export declare function verifyRls(pool: RlsQuerier, opts: VerifyRlsOpts): Promise<void>;
76
+ //# sourceMappingURL=verify-rls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-rls.d.ts","sourceRoot":"","sources":["../src/verify-rls.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;iDAGiD;AACjD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,CAAC,GAAG,OAAO,EACf,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAC1B,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,EAAE,CAAA;KAAE,CAAC,CAAC;CAC3B;AAED;;;mEAGmE;AACnE,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAEjE,MAAM,WAAW,aAAa;IAC5B;;0CAEsC;IACtC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;oEAIgE;IAChE,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;sCAGkC;IAClC,gBAAgB,CAAC,EAAE,uBAAuB,CAAC;IAC3C;;4EAEwE;IACxE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;0BAC0B;AAC1B,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB;;;;2BAIuB;IACvB,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,UAAU;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;gBACvC,SAAS,EAAE,SAAS,mBAAmB,EAAE;CAKtD;AA2CD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Ef"}
@@ -0,0 +1,145 @@
1
+ // verify-rls — a preflight RLS-coverage guard (08-rls § A1 + § 7.6).
2
+ //
3
+ // A service's `scripts/db/verify-rls.ts` (and any `db:setup` gate) calls
4
+ // `verifyRls(pool, { requiredTables })` after migrations apply. It queries
5
+ // `pg_class.relrowsecurity` (joined with `pg_namespace` for the schema)
6
+ // for each table that REQUIRES RLS and FAILS LOUD — throwing
7
+ // `RlsCoverageError` listing the offenders — if any RLS-required table
8
+ // reports `relrowsecurity = false`.
9
+ //
10
+ // This catches the "drizzle snapshot RLS hazard": a migration that creates
11
+ // a tenant-scoped table but never `ALTER TABLE ... ENABLE ROW LEVEL
12
+ // SECURITY`. Without RLS the table leaks every tenant's rows to the
13
+ // services / authenticated pools — a silent tenant-isolation breach that
14
+ // the 5-policy DDL exists to prevent.
15
+ //
16
+ // Composition with 08-rls § 7.6 (db-rls 0.5.1) — a pure platform-global
17
+ // reference table is GRANT-controlled with NO RLS *by design*
18
+ // (`relrowsecurity = false` is the correct state, see `referenceTableGrantsSql`).
19
+ // Such tables MUST NOT be flagged. `verifyRls` therefore takes the set of
20
+ // reference tables (or a predicate) to EXEMPT: an RLS-required table missing
21
+ // RLS is an error; a reference table missing RLS is expected.
22
+ //
23
+ // The verify path is a single read-only catalog query — it does NOT need
24
+ // the GUC/tx-bound `PgPool` surface. It accepts any object exposing a
25
+ // `query(sql, params)` returning `{ rows }`, which `pg.Pool` /
26
+ // `PgClientPool.rawPool` satisfy directly. Byte-consistent error semantics
27
+ // across TS / Python / Go ports.
28
+ import { DbRlsError } from "./types";
29
+ /**
30
+ * Thrown by `verifyRls` when one or more RLS-required tables are missing
31
+ * row-level security (or are absent). Carries the structured offender list
32
+ * so a `db:setup` gate can render a precise failure. Reference tables
33
+ * (§ 7.6) are NEVER offenders — they are exempt before this is thrown.
34
+ */
35
+ export class RlsCoverageError extends DbRlsError {
36
+ offenders;
37
+ constructor(offenders) {
38
+ super(formatMessage(offenders));
39
+ this.name = "RlsCoverageError";
40
+ this.offenders = offenders;
41
+ }
42
+ }
43
+ function formatMessage(offenders) {
44
+ const lines = offenders.map((o) => {
45
+ const qualified = `${o.schema}.${o.relname}`;
46
+ return o.reason === "not_found"
47
+ ? ` - ${qualified} (NOT FOUND — required RLS table is absent from the catalog)`
48
+ : ` - ${qualified} (relrowsecurity = false — RLS not enabled)`;
49
+ });
50
+ return `rls_coverage: ${offenders.length} RLS-required table(s) missing row-level security (08-rls § A1). A migration created the table but never \`ALTER TABLE ... ENABLE ROW LEVEL SECURITY\` — these tables leak every tenant's rows to the services/authenticated pools. Offenders:\n${lines.join("\n")}\nFix: add the canonical 5-policy DDL (withRls) for each, or register it as a § 7.6 reference table if it is genuinely platform-global GRANT-controlled data.`;
51
+ }
52
+ /** Strip optional surrounding double-quotes from one identifier part. */
53
+ function unquote(part) {
54
+ return part.replace(/^"|"$/g, "");
55
+ }
56
+ /** Resolve a (possibly schema-qualified, possibly quoted) table name to
57
+ * `{ schema, relname }`. Bare names resolve against `defaultSchema`. */
58
+ function resolveTable(table, defaultSchema) {
59
+ if (table.includes(".")) {
60
+ const idx = table.indexOf(".");
61
+ const schema = unquote(table.slice(0, idx));
62
+ const relname = unquote(table.slice(idx + 1));
63
+ return { original: table, schema, relname };
64
+ }
65
+ return { original: table, schema: defaultSchema, relname: unquote(table) };
66
+ }
67
+ /** Normalized `schema.relname` key for exemption matching. */
68
+ function key(r) {
69
+ return `${r.schema}.${r.relname}`;
70
+ }
71
+ /**
72
+ * Verifies that every table in `requiredTables` has row-level security
73
+ * enabled (`pg_class.relrowsecurity = true`), exempting any § 7.6
74
+ * reference table. Resolves OK (returns `void`) when all required tables
75
+ * are covered; throws `RlsCoverageError` listing the offenders otherwise.
76
+ *
77
+ * The query is a single read against `pg_class` joined to `pg_namespace`
78
+ * — read-only, no GUCs, no writes. Run it from a migration / `db:setup`
79
+ * gate against any pool (typically the owner/admin pool).
80
+ */
81
+ export async function verifyRls(pool, opts) {
82
+ const defaultSchema = opts.schema ?? "public";
83
+ const exemptionsEnabled = opts.allowReferenceTables ?? true;
84
+ // Build the exempt set (normalized schema.relname keys) + predicate.
85
+ const exemptKeys = new Set();
86
+ if (exemptionsEnabled && opts.referenceTables) {
87
+ for (const t of opts.referenceTables) {
88
+ exemptKeys.add(key(resolveTable(t, defaultSchema)));
89
+ }
90
+ }
91
+ const predicate = exemptionsEnabled && opts.isReferenceTable
92
+ ? opts.isReferenceTable
93
+ : undefined;
94
+ // Resolve + filter out exempt reference tables BEFORE querying.
95
+ const toCheck = [];
96
+ for (const original of opts.requiredTables) {
97
+ const resolved = resolveTable(original, defaultSchema);
98
+ const isExempt = exemptKeys.has(key(resolved)) ||
99
+ (predicate ? predicate(original) : false);
100
+ if (!isExempt)
101
+ toCheck.push(resolved);
102
+ }
103
+ if (toCheck.length === 0)
104
+ return;
105
+ // One catalog query covering all to-check tables. We pass parallel
106
+ // schema[] + relname[] arrays and join in SQL so a single round-trip
107
+ // resolves every table; missing rows are detected by set difference.
108
+ const schemas = toCheck.map((t) => t.schema);
109
+ const relnames = toCheck.map((t) => t.relname);
110
+ const res = await pool.query(`SELECT n.nspname, c.relname, c.relrowsecurity
111
+ FROM unnest($1::text[], $2::text[]) AS req(schemaname, tablename)
112
+ JOIN pg_namespace n ON n.nspname = req.schemaname
113
+ JOIN pg_class c ON c.relnamespace = n.oid
114
+ AND c.relname = req.tablename
115
+ AND c.relkind IN ('r', 'p')`, [schemas, relnames]);
116
+ // Index the catalog rows by schema.relname.
117
+ const found = new Map();
118
+ for (const row of res.rows) {
119
+ found.set(`${row.nspname}.${row.relname}`, row.relrowsecurity);
120
+ }
121
+ const offenders = [];
122
+ for (const t of toCheck) {
123
+ const k = key(t);
124
+ if (!found.has(k)) {
125
+ offenders.push({
126
+ table: t.original,
127
+ schema: t.schema,
128
+ relname: t.relname,
129
+ reason: "not_found",
130
+ });
131
+ }
132
+ else if (found.get(k) === false) {
133
+ offenders.push({
134
+ table: t.original,
135
+ schema: t.schema,
136
+ relname: t.relname,
137
+ reason: "rls_disabled",
138
+ });
139
+ }
140
+ }
141
+ if (offenders.length > 0) {
142
+ throw new RlsCoverageError(offenders);
143
+ }
144
+ }
145
+ //# sourceMappingURL=verify-rls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-rls.js","sourceRoot":"","sources":["../src/verify-rls.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,wEAAwE;AACxE,6DAA6D;AAC7D,uEAAuE;AACvE,oCAAoC;AACpC,EAAE;AACF,2EAA2E;AAC3E,oEAAoE;AACpE,oEAAoE;AACpE,yEAAyE;AACzE,sCAAsC;AACtC,EAAE;AACF,wEAAwE;AACxE,8DAA8D;AAC9D,kFAAkF;AAClF,0EAA0E;AAC1E,6EAA6E;AAC7E,8DAA8D;AAC9D,EAAE;AACF,yEAAyE;AACzE,sEAAsE;AACtE,+DAA+D;AAC/D,2EAA2E;AAC3E,iCAAiC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA4DrC;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IACrC,SAAS,CAAiC;IACnD,YAAY,SAAyC;QACnD,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,SAAS,aAAa,CAAC,SAAyC;IAC9D,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAChC,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QAC7C,OAAO,CAAC,CAAC,MAAM,KAAK,WAAW;YAC7B,CAAC,CAAC,OAAO,SAAS,8DAA8D;YAChF,CAAC,CAAC,OAAO,SAAS,6CAA6C,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,OAAO,iBAAiB,SAAS,CAAC,MAAM,mPAAmP,KAAK,CAAC,IAAI,CACnS,IAAI,CACL,+JAA+J,CAAC;AACnK,CAAC;AASD,yEAAyE;AACzE,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;yEACyE;AACzE,SAAS,YAAY,CAAC,KAAa,EAAE,aAAqB;IACxD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,8DAA8D;AAC9D,SAAS,GAAG,CAAC,CAAsC;IACjD,OAAO,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAgB,EAChB,IAAmB;IAEnB,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC;IAC9C,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC;IAE5D,qEAAqE;IACrE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,IAAI,iBAAiB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACrC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GACb,iBAAiB,IAAI,IAAI,CAAC,gBAAgB;QACxC,CAAC,CAAC,IAAI,CAAC,gBAAgB;QACvB,CAAC,CAAC,SAAS,CAAC;IAEhB,gEAAgE;IAChE,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACvD,MAAM,QAAQ,GACZ,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEjC,mEAAmE;IACnE,qEAAqE;IACrE,qEAAqE;IACrE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAK1B;;;;;oCAKgC,EAChC,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAC;IAEF,4CAA4C;IAC5C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,SAAS,GAA0B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,SAAS,CAAC,IAAI,CAAC;gBACb,KAAK,EAAE,CAAC,CAAC,QAAQ;gBACjB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;YAClC,SAAS,CAAC,IAAI,CAAC;gBACb,KAAK,EAAE,CAAC,CAAC,QAAQ;gBACjB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodii/db-rls",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "Three-pool RLS dispatch + GUC-set + entry-point helpers + RLS policy DDL generator for the Nodii microservice stack. Polyglot per D159 (TS + Python + Go). Spec: planning hub docKey=db-rls.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -43,7 +43,8 @@
43
43
  "peerDependencies": {
44
44
  "drizzle-orm": ">=0.36 <0.50",
45
45
  "pg": "^8.13.0",
46
- "postgres": "^3.4.0"
46
+ "postgres": "^3.4.0",
47
+ "@nodii/telemetry": ">=0.5.2 <1.0.0"
47
48
  },
48
49
  "peerDependenciesMeta": {
49
50
  "drizzle-orm": {
@@ -69,8 +70,5 @@
69
70
  "type": "git",
70
71
  "url": "git+https://github.com/cognion-nucleus/nodii-libs.git",
71
72
  "directory": "ts/db-rls"
72
- },
73
- "dependencies": {
74
- "@nodii/telemetry": "0.5.2"
75
73
  }
76
74
  }