@nodii/db-rls 0.2.2 → 0.4.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.
- package/dist/configure.d.ts +42 -8
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +87 -16
- package/dist/configure.js.map +1 -1
- package/dist/context.d.ts +36 -7
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +67 -6
- package/dist/context.js.map +1 -1
- package/dist/drizzle-client.d.ts +9 -2
- package/dist/drizzle-client.d.ts.map +1 -1
- package/dist/drizzle-client.js +28 -2
- package/dist/drizzle-client.js.map +1 -1
- package/dist/drizzle-grants.d.ts +203 -0
- package/dist/drizzle-grants.d.ts.map +1 -0
- package/dist/drizzle-grants.js +68 -0
- package/dist/drizzle-grants.js.map +1 -0
- package/dist/drizzle-policies.d.ts +90 -0
- package/dist/drizzle-policies.d.ts.map +1 -0
- package/dist/drizzle-policies.js +223 -0
- package/dist/drizzle-policies.js.map +1 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -10
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +23 -5
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +38 -4
- package/dist/init.js.map +1 -1
- package/dist/metrics.d.ts +28 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +263 -0
- package/dist/metrics.js.map +1 -0
- package/dist/migrate-guard.d.ts +14 -0
- package/dist/migrate-guard.d.ts.map +1 -0
- package/dist/migrate-guard.js +33 -0
- package/dist/migrate-guard.js.map +1 -0
- package/dist/pg-pool-adapter.d.ts.map +1 -1
- package/dist/pg-pool-adapter.js +78 -25
- package/dist/pg-pool-adapter.js.map +1 -1
- package/dist/postgres-js-client.d.ts +60 -0
- package/dist/postgres-js-client.d.ts.map +1 -0
- package/dist/postgres-js-client.js +223 -0
- package/dist/postgres-js-client.js.map +1 -0
- package/dist/types.d.ts +68 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +31 -1
- package/dist/types.js.map +1 -1
- package/package.json +24 -5
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
export type PlatformOpsScopeKind = "tenant" | "platform_global" | "all_tenants";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a Drizzle pgTable definition for the
|
|
4
|
+
* `platform_ops_grants_replica` table per D185 § 2.
|
|
5
|
+
*
|
|
6
|
+
* Schema:
|
|
7
|
+
* - id UUID PRIMARY KEY DEFAULT gen_random_uuid()
|
|
8
|
+
* - user_id UUID NOT NULL -- principal with platform-admin membership
|
|
9
|
+
* - service_id TEXT NOT NULL -- consumer service id
|
|
10
|
+
* - scope_kind TEXT NOT NULL CHECK (IN ('tenant','platform_global','all_tenants'))
|
|
11
|
+
* - scope_target UUID -- tenant_id when scope_kind='tenant'; NULL otherwise
|
|
12
|
+
* - permission TEXT NOT NULL -- catalog entry name
|
|
13
|
+
* - granted_by_user_id UUID NOT NULL -- audit trail
|
|
14
|
+
* - granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
15
|
+
* - expires_at TIMESTAMPTZ -- optional time-bound
|
|
16
|
+
* - revoked_at TIMESTAMPTZ -- soft revoke
|
|
17
|
+
*
|
|
18
|
+
* Constraints:
|
|
19
|
+
* - UNIQUE (user_id, service_id, scope_kind, scope_target, permission)
|
|
20
|
+
* - CHECK ((scope_kind = 'tenant' AND scope_target IS NOT NULL)
|
|
21
|
+
* OR (scope_kind IN ('platform_global','all_tenants') AND scope_target IS NULL))
|
|
22
|
+
*
|
|
23
|
+
* Indexes:
|
|
24
|
+
* - (user_id, service_id) WHERE revoked_at IS NULL
|
|
25
|
+
*/
|
|
26
|
+
export declare function platformOpsGrantsReplica(name?: string): import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
27
|
+
name: string;
|
|
28
|
+
schema: undefined;
|
|
29
|
+
columns: {
|
|
30
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
31
|
+
name: "id";
|
|
32
|
+
tableName: string;
|
|
33
|
+
dataType: "string";
|
|
34
|
+
columnType: "PgUUID";
|
|
35
|
+
data: string;
|
|
36
|
+
driverParam: string;
|
|
37
|
+
notNull: true;
|
|
38
|
+
hasDefault: true;
|
|
39
|
+
isPrimaryKey: true;
|
|
40
|
+
isAutoincrement: false;
|
|
41
|
+
hasRuntimeDefault: false;
|
|
42
|
+
enumValues: undefined;
|
|
43
|
+
baseColumn: never;
|
|
44
|
+
identity: undefined;
|
|
45
|
+
generated: undefined;
|
|
46
|
+
}, {}, {}>;
|
|
47
|
+
userId: import("drizzle-orm/pg-core").PgColumn<{
|
|
48
|
+
name: "user_id";
|
|
49
|
+
tableName: string;
|
|
50
|
+
dataType: "string";
|
|
51
|
+
columnType: "PgUUID";
|
|
52
|
+
data: string;
|
|
53
|
+
driverParam: string;
|
|
54
|
+
notNull: true;
|
|
55
|
+
hasDefault: false;
|
|
56
|
+
isPrimaryKey: false;
|
|
57
|
+
isAutoincrement: false;
|
|
58
|
+
hasRuntimeDefault: false;
|
|
59
|
+
enumValues: undefined;
|
|
60
|
+
baseColumn: never;
|
|
61
|
+
identity: undefined;
|
|
62
|
+
generated: undefined;
|
|
63
|
+
}, {}, {}>;
|
|
64
|
+
serviceId: import("drizzle-orm/pg-core").PgColumn<{
|
|
65
|
+
name: "service_id";
|
|
66
|
+
tableName: string;
|
|
67
|
+
dataType: "string";
|
|
68
|
+
columnType: "PgText";
|
|
69
|
+
data: string;
|
|
70
|
+
driverParam: string;
|
|
71
|
+
notNull: true;
|
|
72
|
+
hasDefault: false;
|
|
73
|
+
isPrimaryKey: false;
|
|
74
|
+
isAutoincrement: false;
|
|
75
|
+
hasRuntimeDefault: false;
|
|
76
|
+
enumValues: [string, ...string[]];
|
|
77
|
+
baseColumn: never;
|
|
78
|
+
identity: undefined;
|
|
79
|
+
generated: undefined;
|
|
80
|
+
}, {}, {}>;
|
|
81
|
+
scopeKind: import("drizzle-orm/pg-core").PgColumn<{
|
|
82
|
+
name: "scope_kind";
|
|
83
|
+
tableName: string;
|
|
84
|
+
dataType: "string";
|
|
85
|
+
columnType: "PgText";
|
|
86
|
+
data: string;
|
|
87
|
+
driverParam: string;
|
|
88
|
+
notNull: true;
|
|
89
|
+
hasDefault: false;
|
|
90
|
+
isPrimaryKey: false;
|
|
91
|
+
isAutoincrement: false;
|
|
92
|
+
hasRuntimeDefault: false;
|
|
93
|
+
enumValues: [string, ...string[]];
|
|
94
|
+
baseColumn: never;
|
|
95
|
+
identity: undefined;
|
|
96
|
+
generated: undefined;
|
|
97
|
+
}, {}, {}>;
|
|
98
|
+
scopeTarget: import("drizzle-orm/pg-core").PgColumn<{
|
|
99
|
+
name: "scope_target";
|
|
100
|
+
tableName: string;
|
|
101
|
+
dataType: "string";
|
|
102
|
+
columnType: "PgUUID";
|
|
103
|
+
data: string;
|
|
104
|
+
driverParam: string;
|
|
105
|
+
notNull: false;
|
|
106
|
+
hasDefault: false;
|
|
107
|
+
isPrimaryKey: false;
|
|
108
|
+
isAutoincrement: false;
|
|
109
|
+
hasRuntimeDefault: false;
|
|
110
|
+
enumValues: undefined;
|
|
111
|
+
baseColumn: never;
|
|
112
|
+
identity: undefined;
|
|
113
|
+
generated: undefined;
|
|
114
|
+
}, {}, {}>;
|
|
115
|
+
permission: import("drizzle-orm/pg-core").PgColumn<{
|
|
116
|
+
name: "permission";
|
|
117
|
+
tableName: string;
|
|
118
|
+
dataType: "string";
|
|
119
|
+
columnType: "PgText";
|
|
120
|
+
data: string;
|
|
121
|
+
driverParam: string;
|
|
122
|
+
notNull: true;
|
|
123
|
+
hasDefault: false;
|
|
124
|
+
isPrimaryKey: false;
|
|
125
|
+
isAutoincrement: false;
|
|
126
|
+
hasRuntimeDefault: false;
|
|
127
|
+
enumValues: [string, ...string[]];
|
|
128
|
+
baseColumn: never;
|
|
129
|
+
identity: undefined;
|
|
130
|
+
generated: undefined;
|
|
131
|
+
}, {}, {}>;
|
|
132
|
+
grantedByUserId: import("drizzle-orm/pg-core").PgColumn<{
|
|
133
|
+
name: "granted_by_user_id";
|
|
134
|
+
tableName: string;
|
|
135
|
+
dataType: "string";
|
|
136
|
+
columnType: "PgUUID";
|
|
137
|
+
data: string;
|
|
138
|
+
driverParam: string;
|
|
139
|
+
notNull: true;
|
|
140
|
+
hasDefault: false;
|
|
141
|
+
isPrimaryKey: false;
|
|
142
|
+
isAutoincrement: false;
|
|
143
|
+
hasRuntimeDefault: false;
|
|
144
|
+
enumValues: undefined;
|
|
145
|
+
baseColumn: never;
|
|
146
|
+
identity: undefined;
|
|
147
|
+
generated: undefined;
|
|
148
|
+
}, {}, {}>;
|
|
149
|
+
grantedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
150
|
+
name: "granted_at";
|
|
151
|
+
tableName: string;
|
|
152
|
+
dataType: "date";
|
|
153
|
+
columnType: "PgTimestamp";
|
|
154
|
+
data: Date;
|
|
155
|
+
driverParam: string;
|
|
156
|
+
notNull: true;
|
|
157
|
+
hasDefault: true;
|
|
158
|
+
isPrimaryKey: false;
|
|
159
|
+
isAutoincrement: false;
|
|
160
|
+
hasRuntimeDefault: false;
|
|
161
|
+
enumValues: undefined;
|
|
162
|
+
baseColumn: never;
|
|
163
|
+
identity: undefined;
|
|
164
|
+
generated: undefined;
|
|
165
|
+
}, {}, {}>;
|
|
166
|
+
expiresAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
167
|
+
name: "expires_at";
|
|
168
|
+
tableName: string;
|
|
169
|
+
dataType: "date";
|
|
170
|
+
columnType: "PgTimestamp";
|
|
171
|
+
data: Date;
|
|
172
|
+
driverParam: string;
|
|
173
|
+
notNull: false;
|
|
174
|
+
hasDefault: false;
|
|
175
|
+
isPrimaryKey: false;
|
|
176
|
+
isAutoincrement: false;
|
|
177
|
+
hasRuntimeDefault: false;
|
|
178
|
+
enumValues: undefined;
|
|
179
|
+
baseColumn: never;
|
|
180
|
+
identity: undefined;
|
|
181
|
+
generated: undefined;
|
|
182
|
+
}, {}, {}>;
|
|
183
|
+
revokedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
184
|
+
name: "revoked_at";
|
|
185
|
+
tableName: string;
|
|
186
|
+
dataType: "date";
|
|
187
|
+
columnType: "PgTimestamp";
|
|
188
|
+
data: Date;
|
|
189
|
+
driverParam: string;
|
|
190
|
+
notNull: false;
|
|
191
|
+
hasDefault: false;
|
|
192
|
+
isPrimaryKey: false;
|
|
193
|
+
isAutoincrement: false;
|
|
194
|
+
hasRuntimeDefault: false;
|
|
195
|
+
enumValues: undefined;
|
|
196
|
+
baseColumn: never;
|
|
197
|
+
identity: undefined;
|
|
198
|
+
generated: undefined;
|
|
199
|
+
}, {}, {}>;
|
|
200
|
+
};
|
|
201
|
+
dialect: "pg";
|
|
202
|
+
}>;
|
|
203
|
+
//# sourceMappingURL=drizzle-grants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-grants.d.ts","sourceRoot":"","sources":["../src/drizzle-grants.ts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,iBAAiB,GAAG,aAAa,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,SAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsC5E"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// D185 — Drizzle table builder for `platform_ops_grants_replica`.
|
|
2
|
+
//
|
|
3
|
+
// Per hub decision D185 § 2 + § 6.2. The canonical schema lives in
|
|
4
|
+
// `nodii-tenant-service` (source of truth); each consumer service that
|
|
5
|
+
// wires a 4-pool db-rls replicates the table locally via the
|
|
6
|
+
// `@nodii/replica-consumer` outbox-consumer pattern (`09-replication
|
|
7
|
+
// § 6.2`). This helper emits the Drizzle schema for the replica so
|
|
8
|
+
// consumer services don't drift on column shape.
|
|
9
|
+
//
|
|
10
|
+
// Subpath export: `@nodii/db-rls/drizzle/platform-ops-grants`.
|
|
11
|
+
//
|
|
12
|
+
// Usage:
|
|
13
|
+
//
|
|
14
|
+
// import { platformOpsGrantsReplica } from "@nodii/db-rls/drizzle/platform-ops-grants";
|
|
15
|
+
//
|
|
16
|
+
// export const grantsReplica = platformOpsGrantsReplica();
|
|
17
|
+
// // OR with custom name:
|
|
18
|
+
// export const grantsReplica = platformOpsGrantsReplica("tenant_platform_ops_grants_replica");
|
|
19
|
+
import { sql } from "drizzle-orm";
|
|
20
|
+
import { check, index, pgTable, text, timestamp, unique, uuid, } from "drizzle-orm/pg-core";
|
|
21
|
+
/**
|
|
22
|
+
* Returns a Drizzle pgTable definition for the
|
|
23
|
+
* `platform_ops_grants_replica` table per D185 § 2.
|
|
24
|
+
*
|
|
25
|
+
* Schema:
|
|
26
|
+
* - id UUID PRIMARY KEY DEFAULT gen_random_uuid()
|
|
27
|
+
* - user_id UUID NOT NULL -- principal with platform-admin membership
|
|
28
|
+
* - service_id TEXT NOT NULL -- consumer service id
|
|
29
|
+
* - scope_kind TEXT NOT NULL CHECK (IN ('tenant','platform_global','all_tenants'))
|
|
30
|
+
* - scope_target UUID -- tenant_id when scope_kind='tenant'; NULL otherwise
|
|
31
|
+
* - permission TEXT NOT NULL -- catalog entry name
|
|
32
|
+
* - granted_by_user_id UUID NOT NULL -- audit trail
|
|
33
|
+
* - granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
34
|
+
* - expires_at TIMESTAMPTZ -- optional time-bound
|
|
35
|
+
* - revoked_at TIMESTAMPTZ -- soft revoke
|
|
36
|
+
*
|
|
37
|
+
* Constraints:
|
|
38
|
+
* - UNIQUE (user_id, service_id, scope_kind, scope_target, permission)
|
|
39
|
+
* - CHECK ((scope_kind = 'tenant' AND scope_target IS NOT NULL)
|
|
40
|
+
* OR (scope_kind IN ('platform_global','all_tenants') AND scope_target IS NULL))
|
|
41
|
+
*
|
|
42
|
+
* Indexes:
|
|
43
|
+
* - (user_id, service_id) WHERE revoked_at IS NULL
|
|
44
|
+
*/
|
|
45
|
+
export function platformOpsGrantsReplica(name = "platform_ops_grants_replica") {
|
|
46
|
+
return pgTable(name, {
|
|
47
|
+
id: uuid("id").primaryKey().default(sql `gen_random_uuid()`),
|
|
48
|
+
userId: uuid("user_id").notNull(),
|
|
49
|
+
serviceId: text("service_id").notNull(),
|
|
50
|
+
scopeKind: text("scope_kind").notNull(),
|
|
51
|
+
scopeTarget: uuid("scope_target"),
|
|
52
|
+
permission: text("permission").notNull(),
|
|
53
|
+
grantedByUserId: uuid("granted_by_user_id").notNull(),
|
|
54
|
+
grantedAt: timestamp("granted_at", { withTimezone: true })
|
|
55
|
+
.notNull()
|
|
56
|
+
.default(sql `NOW()`),
|
|
57
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
58
|
+
revokedAt: timestamp("revoked_at", { withTimezone: true }),
|
|
59
|
+
}, (t) => [
|
|
60
|
+
unique(`${name}_grant_uniq`).on(t.userId, t.serviceId, t.scopeKind, t.scopeTarget, t.permission),
|
|
61
|
+
check(`${name}_scope_target_shape`, sql `(${t.scopeKind} = 'tenant' AND ${t.scopeTarget} IS NOT NULL) OR (${t.scopeKind} IN ('platform_global','all_tenants') AND ${t.scopeTarget} IS NULL)`),
|
|
62
|
+
check(`${name}_scope_kind_enum`, sql `${t.scopeKind} IN ('tenant','platform_global','all_tenants')`),
|
|
63
|
+
index(`${name}_user_service_active`)
|
|
64
|
+
.on(t.userId, t.serviceId)
|
|
65
|
+
.where(sql `${t.revokedAt} IS NULL`),
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=drizzle-grants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-grants.js","sourceRoot":"","sources":["../src/drizzle-grants.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,mEAAmE;AACnE,uEAAuE;AACvE,6DAA6D;AAC7D,qEAAqE;AACrE,mEAAmE;AACnE,iDAAiD;AACjD,EAAE;AACF,+DAA+D;AAC/D,EAAE;AACF,SAAS;AACT,EAAE;AACF,0FAA0F;AAC1F,EAAE;AACF,6DAA6D;AAC7D,4BAA4B;AAC5B,iGAAiG;AAEjG,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,MAAM,EACN,IAAI,GACL,MAAM,qBAAqB,CAAC;AAI7B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAI,GAAG,6BAA6B;IAC3E,OAAO,OAAO,CACZ,IAAI,EACJ;QACE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,GAAG,CAAA,mBAAmB,CAAC;QAC3D,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;QACjC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;QACvC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;QACvC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC;QACjC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;QACxC,eAAe,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC,OAAO,EAAE;QACrD,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;aACvD,OAAO,EAAE;aACT,OAAO,CAAC,GAAG,CAAA,OAAO,CAAC;QACtB,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAC1D,SAAS,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;KAC3D,EACD,CAAC,CAAC,EAAE,EAAE,CAAC;QACL,MAAM,CAAC,GAAG,IAAI,aAAa,CAAC,CAAC,EAAE,CAC7B,CAAC,CAAC,MAAM,EACR,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,SAAS,EACX,CAAC,CAAC,WAAW,EACb,CAAC,CAAC,UAAU,CACb;QACD,KAAK,CACH,GAAG,IAAI,qBAAqB,EAC5B,GAAG,CAAA,IAAI,CAAC,CAAC,SAAS,mBAAmB,CAAC,CAAC,WAAW,qBAAqB,CAAC,CAAC,SAAS,6CAA6C,CAAC,CAAC,WAAW,WAAW,CACxJ;QACD,KAAK,CACH,GAAG,IAAI,kBAAkB,EACzB,GAAG,CAAA,GAAG,CAAC,CAAC,SAAS,gDAAgD,CAClE;QACD,KAAK,CAAC,GAAG,IAAI,sBAAsB,CAAC;aACjC,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC;aACzB,KAAK,CAAC,GAAG,CAAA,GAAG,CAAC,CAAC,SAAS,UAAU,CAAC;KACtC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { PgColumn, PgPolicy } from "drizzle-orm/pg-core";
|
|
2
|
+
import type { WithRlsOpts } from "./rls-policy-gen";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the canonical 5-policy Drizzle constructs (per doctrine § 4)
|
|
5
|
+
* for a tenant-scoped table.
|
|
6
|
+
*
|
|
7
|
+
* Default (`allow=["SELECT","INSERT"]`) emits:
|
|
8
|
+
*
|
|
9
|
+
* 1. `<table>_owner` FOR ALL TO nodii_owner USING (true) WITH CHECK (true)
|
|
10
|
+
* 2. `<table>_auth_select` FOR SELECT TO authenticated USING (<col> IN (SELECT auth.user_tenant_ids(auth.get_user_id())))
|
|
11
|
+
* 3. `<table>_auth_insert` FOR INSERT TO authenticated WITH CHECK (...)
|
|
12
|
+
* 4. `<table>_svc_select` FOR SELECT TO nodii_services USING (<col> = auth.get_tenant_id())
|
|
13
|
+
* 5. `<table>_svc_insert` FOR INSERT TO nodii_services WITH CHECK (...)
|
|
14
|
+
*
|
|
15
|
+
* Extending `allow` to include `"UPDATE"` / `"DELETE"` adds the
|
|
16
|
+
* corresponding verb policies for both auth + svc.
|
|
17
|
+
*
|
|
18
|
+
* `t.tenantId` must be a Drizzle column reference (used to thread the
|
|
19
|
+
* column name + table binding into the policy `link(table)` step that
|
|
20
|
+
* drizzle-kit performs).
|
|
21
|
+
*/
|
|
22
|
+
export declare function withRls(tenantCol: PgColumn, opts?: WithRlsOpts): PgPolicy[];
|
|
23
|
+
/** Per-verb permission name binding for the platform-ops policies. Each
|
|
24
|
+
* string is a catalog entry name (e.g. `"modules.write"`) — when a
|
|
25
|
+
* request runs with `app.platform_ops_permission` matching this name,
|
|
26
|
+
* the corresponding policy applies. A missing entry means there's no
|
|
27
|
+
* policy emitted for that verb (deny-by-default RLS behavior). */
|
|
28
|
+
export interface PlatformOpsPerVerbPermissions {
|
|
29
|
+
read?: string;
|
|
30
|
+
insert?: string;
|
|
31
|
+
update?: string;
|
|
32
|
+
delete?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface WithPlatformOpsOpts {
|
|
35
|
+
/** Override the default `platform_ops_grants_replica` table name.
|
|
36
|
+
* Use when the consuming service replicates the grants table under
|
|
37
|
+
* a different name (e.g. prefixed with the service slug). */
|
|
38
|
+
grantsTable?: string;
|
|
39
|
+
/** Override the tenant column name in the generated predicate. Falls
|
|
40
|
+
* back to the Drizzle column's name. */
|
|
41
|
+
tenantColumn?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
45
|
+
* **tenant-scoped** table exposed via a platform-ops cross-tenant
|
|
46
|
+
* surface. Emits one policy per verb in `perms`:
|
|
47
|
+
*
|
|
48
|
+
* - `<table>_platform_ops_read` FOR SELECT TO nodii_platform_ops USING (<grants-predicate with perms.read>)
|
|
49
|
+
* - `<table>_platform_ops_insert` FOR INSERT TO nodii_platform_ops WITH CHECK (<grants-predicate with perms.insert>)
|
|
50
|
+
* - `<table>_platform_ops_update` FOR UPDATE TO nodii_platform_ops USING + WITH CHECK (<grants-predicate with perms.update>)
|
|
51
|
+
* - `<table>_platform_ops_delete` FOR DELETE TO nodii_platform_ops USING (<grants-predicate with perms.delete>)
|
|
52
|
+
*
|
|
53
|
+
* Predicate shape (per D185 § 3):
|
|
54
|
+
*
|
|
55
|
+
* EXISTS (
|
|
56
|
+
* SELECT 1 FROM platform_ops_grants_replica g
|
|
57
|
+
* WHERE g.user_id = current_setting('app.user_id')::uuid
|
|
58
|
+
* AND g.service_id = current_setting('app.platform_ops_service_id')
|
|
59
|
+
* AND g.permission = <permission name literal>
|
|
60
|
+
* AND g.revoked_at IS NULL
|
|
61
|
+
* AND (g.expires_at IS NULL OR g.expires_at > NOW())
|
|
62
|
+
* AND (
|
|
63
|
+
* g.scope_kind = 'all_tenants'
|
|
64
|
+
* OR (g.scope_kind = 'tenant' AND g.scope_target = <tenantCol>)
|
|
65
|
+
* )
|
|
66
|
+
* )
|
|
67
|
+
*
|
|
68
|
+
* Note: the permission literal is embedded in the policy body at
|
|
69
|
+
* migration-emit time (not read from `app.platform_ops_permission` at
|
|
70
|
+
* runtime). This means each verb can be bound to a distinct catalog
|
|
71
|
+
* entry — `app.platform_ops_permission` GUC is set by `withPlatformOps`
|
|
72
|
+
* to enable auditing/forensics but is NOT what the policy checks.
|
|
73
|
+
*
|
|
74
|
+
* Compose alongside `withRls(t.tenantId)` on the same table when both
|
|
75
|
+
* platform-ops AND in-tenant surfaces are exposed.
|
|
76
|
+
*/
|
|
77
|
+
export declare function withPlatformOpsTenant(tenantCol: PgColumn, perms: PlatformOpsPerVerbPermissions, opts?: WithPlatformOpsOpts): PgPolicy[];
|
|
78
|
+
/**
|
|
79
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
80
|
+
* **platform-global** table that has no tenant_id column (modules,
|
|
81
|
+
* role catalogs, etc.). Emits one policy per verb in `perms` using the
|
|
82
|
+
* `scope_kind='platform_global'` predicate variant.
|
|
83
|
+
*/
|
|
84
|
+
export declare function withPlatformOpsGlobal(table: {
|
|
85
|
+
_: {
|
|
86
|
+
name: string;
|
|
87
|
+
};
|
|
88
|
+
[key: string]: unknown;
|
|
89
|
+
}, perms: PlatformOpsPerVerbPermissions, opts?: WithPlatformOpsOpts): PgPolicy[];
|
|
90
|
+
//# sourceMappingURL=drizzle-policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-policies.d.ts","sourceRoot":"","sources":["../src/drizzle-policies.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,QAAQ,EACnB,IAAI,GAAE,WAAgB,GACrB,QAAQ,EAAE,CAsCZ;AA6ED;;;;mEAImE;AACnE,MAAM,WAAW,6BAA6B;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,MAAM,WAAW,mBAAmB;IAClC;;kEAE8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6CACyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,QAAQ,EACnB,KAAK,EAAE,6BAA6B,EACpC,IAAI,GAAE,mBAAwB,GAC7B,QAAQ,EAAE,CA0BZ;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE;IAAE,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EACtD,KAAK,EAAE,6BAA6B,EACpC,IAAI,GAAE,mBAAwB,GAC7B,QAAQ,EAAE,CA0BZ"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// Drizzle table-builder helper — `withRls(t.tenantId)` per doctrine § 4.2.
|
|
2
|
+
//
|
|
3
|
+
// Exposed via subpath `@nodii/db-rls/drizzle`. Returns an array of
|
|
4
|
+
// `PgPolicy` constructs that consumers spread into Drizzle's third-arg
|
|
5
|
+
// extras callback:
|
|
6
|
+
//
|
|
7
|
+
// import { withRls } from "@nodii/db-rls/drizzle";
|
|
8
|
+
//
|
|
9
|
+
// export const billingInvoices = pgTable("billing_invoices", {
|
|
10
|
+
// id: uuid("id").primaryKey().defaultRandom(),
|
|
11
|
+
// tenantId: uuid("tenant_id").notNull(),
|
|
12
|
+
// amount: integer("amount").notNull(),
|
|
13
|
+
// }, (t) => [
|
|
14
|
+
// ...withRls(t.tenantId), // default 5 policies
|
|
15
|
+
// // OR with extra verbs:
|
|
16
|
+
// // ...withRls(t.tenantId, { allow: ["SELECT","INSERT","UPDATE","DELETE"] }),
|
|
17
|
+
// ]);
|
|
18
|
+
//
|
|
19
|
+
// Drizzle-kit reads these PgPolicy constructs and emits the canonical
|
|
20
|
+
// 5-policy DDL (§ 4) into the generated migration SQL. Naming follows
|
|
21
|
+
// doctrine § 4 exactly: `<table>_owner`, `<table>_auth_select`,
|
|
22
|
+
// `<table>_auth_insert`, `<table>_svc_select`, `<table>_svc_insert`
|
|
23
|
+
// (no `_policy` suffix).
|
|
24
|
+
//
|
|
25
|
+
// The legacy string-DDL `withRls(table: string)` helper exported from
|
|
26
|
+
// `@nodii/db-rls` (main barrel) keeps its `*_policy` suffix for backwards
|
|
27
|
+
// parity with v0.1.x consumers — both surfaces ship.
|
|
28
|
+
import { getTableName, sql } from "drizzle-orm";
|
|
29
|
+
import { pgPolicy } from "drizzle-orm/pg-core";
|
|
30
|
+
const DEFAULT_ALLOW = ["SELECT", "INSERT"];
|
|
31
|
+
/**
|
|
32
|
+
* Returns the canonical 5-policy Drizzle constructs (per doctrine § 4)
|
|
33
|
+
* for a tenant-scoped table.
|
|
34
|
+
*
|
|
35
|
+
* Default (`allow=["SELECT","INSERT"]`) emits:
|
|
36
|
+
*
|
|
37
|
+
* 1. `<table>_owner` FOR ALL TO nodii_owner USING (true) WITH CHECK (true)
|
|
38
|
+
* 2. `<table>_auth_select` FOR SELECT TO authenticated USING (<col> IN (SELECT auth.user_tenant_ids(auth.get_user_id())))
|
|
39
|
+
* 3. `<table>_auth_insert` FOR INSERT TO authenticated WITH CHECK (...)
|
|
40
|
+
* 4. `<table>_svc_select` FOR SELECT TO nodii_services USING (<col> = auth.get_tenant_id())
|
|
41
|
+
* 5. `<table>_svc_insert` FOR INSERT TO nodii_services WITH CHECK (...)
|
|
42
|
+
*
|
|
43
|
+
* Extending `allow` to include `"UPDATE"` / `"DELETE"` adds the
|
|
44
|
+
* corresponding verb policies for both auth + svc.
|
|
45
|
+
*
|
|
46
|
+
* `t.tenantId` must be a Drizzle column reference (used to thread the
|
|
47
|
+
* column name + table binding into the policy `link(table)` step that
|
|
48
|
+
* drizzle-kit performs).
|
|
49
|
+
*/
|
|
50
|
+
export function withRls(tenantCol, opts = {}) {
|
|
51
|
+
const verbs = opts.allow && opts.allow.length > 0 ? opts.allow : DEFAULT_ALLOW;
|
|
52
|
+
const tableName = getTableName(tenantCol.table);
|
|
53
|
+
const policyBase = unqualifiedName(tableName);
|
|
54
|
+
const tenantColumn = opts.tenantColumn ?? tenantCol.name;
|
|
55
|
+
// Authenticated predicate: tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id()))
|
|
56
|
+
const authPredicate = sql.raw(`${tenantColumn} IN (SELECT auth.user_tenant_ids(auth.get_user_id()))`);
|
|
57
|
+
// Services predicate: tenant_id = auth.get_tenant_id()
|
|
58
|
+
const svcPredicate = sql.raw(`${tenantColumn} = auth.get_tenant_id()`);
|
|
59
|
+
const policies = [];
|
|
60
|
+
// 1. Owner FOR ALL.
|
|
61
|
+
policies.push(pgPolicy(`${policyBase}_owner`, {
|
|
62
|
+
as: "permissive",
|
|
63
|
+
for: "all",
|
|
64
|
+
to: "nodii_owner",
|
|
65
|
+
using: sql `true`,
|
|
66
|
+
withCheck: sql `true`,
|
|
67
|
+
}));
|
|
68
|
+
// 2. authenticated per verb.
|
|
69
|
+
for (const verb of verbs) {
|
|
70
|
+
policies.push(authPolicyFor(policyBase, verb, authPredicate));
|
|
71
|
+
}
|
|
72
|
+
// 3. nodii_services per verb.
|
|
73
|
+
for (const verb of verbs) {
|
|
74
|
+
policies.push(svcPolicyFor(policyBase, verb, svcPredicate));
|
|
75
|
+
}
|
|
76
|
+
return policies;
|
|
77
|
+
}
|
|
78
|
+
function authPolicyFor(policyBase, verb, predicate) {
|
|
79
|
+
const name = `${policyBase}_auth_${verb.toLowerCase()}`;
|
|
80
|
+
return pgPolicy(name, {
|
|
81
|
+
as: "permissive",
|
|
82
|
+
for: drizzleFor(verb),
|
|
83
|
+
to: "authenticated",
|
|
84
|
+
...predicates(verb, predicate),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
function svcPolicyFor(policyBase, verb, predicate) {
|
|
88
|
+
const name = `${policyBase}_svc_${verb.toLowerCase()}`;
|
|
89
|
+
return pgPolicy(name, {
|
|
90
|
+
as: "permissive",
|
|
91
|
+
for: drizzleFor(verb),
|
|
92
|
+
to: "nodii_services",
|
|
93
|
+
...predicates(verb, predicate),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function drizzleFor(verb) {
|
|
97
|
+
return verb.toLowerCase();
|
|
98
|
+
}
|
|
99
|
+
function predicates(verb, predicate) {
|
|
100
|
+
switch (verb) {
|
|
101
|
+
case "INSERT":
|
|
102
|
+
return { withCheck: predicate };
|
|
103
|
+
case "UPDATE":
|
|
104
|
+
return { using: predicate, withCheck: predicate };
|
|
105
|
+
default:
|
|
106
|
+
// SELECT, DELETE
|
|
107
|
+
return { using: predicate };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function unqualifiedName(table) {
|
|
111
|
+
const tail = table.includes(".") ? (table.split(".").pop() ?? table) : table;
|
|
112
|
+
return tail.replace(/^"|"$/g, "");
|
|
113
|
+
}
|
|
114
|
+
const PLATFORM_OPS_GRANTS_REPLICA_DEFAULT = "platform_ops_grants_replica";
|
|
115
|
+
/**
|
|
116
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
117
|
+
* **tenant-scoped** table exposed via a platform-ops cross-tenant
|
|
118
|
+
* surface. Emits one policy per verb in `perms`:
|
|
119
|
+
*
|
|
120
|
+
* - `<table>_platform_ops_read` FOR SELECT TO nodii_platform_ops USING (<grants-predicate with perms.read>)
|
|
121
|
+
* - `<table>_platform_ops_insert` FOR INSERT TO nodii_platform_ops WITH CHECK (<grants-predicate with perms.insert>)
|
|
122
|
+
* - `<table>_platform_ops_update` FOR UPDATE TO nodii_platform_ops USING + WITH CHECK (<grants-predicate with perms.update>)
|
|
123
|
+
* - `<table>_platform_ops_delete` FOR DELETE TO nodii_platform_ops USING (<grants-predicate with perms.delete>)
|
|
124
|
+
*
|
|
125
|
+
* Predicate shape (per D185 § 3):
|
|
126
|
+
*
|
|
127
|
+
* EXISTS (
|
|
128
|
+
* SELECT 1 FROM platform_ops_grants_replica g
|
|
129
|
+
* WHERE g.user_id = current_setting('app.user_id')::uuid
|
|
130
|
+
* AND g.service_id = current_setting('app.platform_ops_service_id')
|
|
131
|
+
* AND g.permission = <permission name literal>
|
|
132
|
+
* AND g.revoked_at IS NULL
|
|
133
|
+
* AND (g.expires_at IS NULL OR g.expires_at > NOW())
|
|
134
|
+
* AND (
|
|
135
|
+
* g.scope_kind = 'all_tenants'
|
|
136
|
+
* OR (g.scope_kind = 'tenant' AND g.scope_target = <tenantCol>)
|
|
137
|
+
* )
|
|
138
|
+
* )
|
|
139
|
+
*
|
|
140
|
+
* Note: the permission literal is embedded in the policy body at
|
|
141
|
+
* migration-emit time (not read from `app.platform_ops_permission` at
|
|
142
|
+
* runtime). This means each verb can be bound to a distinct catalog
|
|
143
|
+
* entry — `app.platform_ops_permission` GUC is set by `withPlatformOps`
|
|
144
|
+
* to enable auditing/forensics but is NOT what the policy checks.
|
|
145
|
+
*
|
|
146
|
+
* Compose alongside `withRls(t.tenantId)` on the same table when both
|
|
147
|
+
* platform-ops AND in-tenant surfaces are exposed.
|
|
148
|
+
*/
|
|
149
|
+
export function withPlatformOpsTenant(tenantCol, perms, opts = {}) {
|
|
150
|
+
const tableName = getTableName(tenantCol.table);
|
|
151
|
+
const policyBase = unqualifiedName(tableName);
|
|
152
|
+
const tenantColumn = opts.tenantColumn ?? tenantCol.name;
|
|
153
|
+
const grantsTable = opts.grantsTable ?? PLATFORM_OPS_GRANTS_REPLICA_DEFAULT;
|
|
154
|
+
const policies = [];
|
|
155
|
+
for (const verb of ["read", "insert", "update", "delete"]) {
|
|
156
|
+
const permission = perms[verb];
|
|
157
|
+
if (!permission)
|
|
158
|
+
continue;
|
|
159
|
+
const predicate = platformOpsTenantPredicate(grantsTable, tenantColumn, permission);
|
|
160
|
+
policies.push(pgPolicy(`${policyBase}_platform_ops_${verb}`, {
|
|
161
|
+
as: "permissive",
|
|
162
|
+
for: drizzleForPlatformOps(verb),
|
|
163
|
+
to: "nodii_platform_ops",
|
|
164
|
+
...platformOpsPredicates(verb, predicate),
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
167
|
+
return policies;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Returns the platform-ops policy bundle (per D185 § 3) for a
|
|
171
|
+
* **platform-global** table that has no tenant_id column (modules,
|
|
172
|
+
* role catalogs, etc.). Emits one policy per verb in `perms` using the
|
|
173
|
+
* `scope_kind='platform_global'` predicate variant.
|
|
174
|
+
*/
|
|
175
|
+
export function withPlatformOpsGlobal(table, perms, opts = {}) {
|
|
176
|
+
// For platform-global tables, callers pass the Drizzle pgTable itself
|
|
177
|
+
// (no tenant column to thread). We derive the policy name from the
|
|
178
|
+
// table's symbol identifier via getTableName(table).
|
|
179
|
+
const tableName = getTableName(table);
|
|
180
|
+
const policyBase = unqualifiedName(tableName);
|
|
181
|
+
const grantsTable = opts.grantsTable ?? PLATFORM_OPS_GRANTS_REPLICA_DEFAULT;
|
|
182
|
+
const policies = [];
|
|
183
|
+
for (const verb of ["read", "insert", "update", "delete"]) {
|
|
184
|
+
const permission = perms[verb];
|
|
185
|
+
if (!permission)
|
|
186
|
+
continue;
|
|
187
|
+
const predicate = platformOpsGlobalPredicate(grantsTable, permission);
|
|
188
|
+
policies.push(pgPolicy(`${policyBase}_platform_ops_${verb}`, {
|
|
189
|
+
as: "permissive",
|
|
190
|
+
for: drizzleForPlatformOps(verb),
|
|
191
|
+
to: "nodii_platform_ops",
|
|
192
|
+
...platformOpsPredicates(verb, predicate),
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
return policies;
|
|
196
|
+
}
|
|
197
|
+
function platformOpsTenantPredicate(grantsTable, tenantColumn, permission) {
|
|
198
|
+
const lit = sqlLiteral(permission);
|
|
199
|
+
return sql.raw(`EXISTS (SELECT 1 FROM ${grantsTable} g WHERE g.user_id = current_setting('app.user_id')::uuid AND g.service_id = current_setting('app.platform_ops_service_id') AND g.permission = ${lit} AND g.revoked_at IS NULL AND (g.expires_at IS NULL OR g.expires_at > NOW()) AND (g.scope_kind = 'all_tenants' OR (g.scope_kind = 'tenant' AND g.scope_target = ${tenantColumn})))`);
|
|
200
|
+
}
|
|
201
|
+
function platformOpsGlobalPredicate(grantsTable, permission) {
|
|
202
|
+
const lit = sqlLiteral(permission);
|
|
203
|
+
return sql.raw(`EXISTS (SELECT 1 FROM ${grantsTable} g WHERE g.user_id = current_setting('app.user_id')::uuid AND g.service_id = current_setting('app.platform_ops_service_id') AND g.scope_kind = 'platform_global' AND g.permission = ${lit} AND g.revoked_at IS NULL AND (g.expires_at IS NULL OR g.expires_at > NOW()))`);
|
|
204
|
+
}
|
|
205
|
+
function drizzleForPlatformOps(verb) {
|
|
206
|
+
return verb === "read" ? "select" : verb;
|
|
207
|
+
}
|
|
208
|
+
function platformOpsPredicates(verb, predicate) {
|
|
209
|
+
switch (verb) {
|
|
210
|
+
case "insert":
|
|
211
|
+
return { withCheck: predicate };
|
|
212
|
+
case "update":
|
|
213
|
+
return { using: predicate, withCheck: predicate };
|
|
214
|
+
default:
|
|
215
|
+
return { using: predicate };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/** SQL literal escape — doubles single quotes, wraps in quotes. */
|
|
219
|
+
function sqlLiteral(s) {
|
|
220
|
+
const escaped = s.replace(/'/g, "''");
|
|
221
|
+
return `'${escaped}'`;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=drizzle-policies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle-policies.js","sourceRoot":"","sources":["../src/drizzle-policies.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
export declare const LIB_NAME = "db-rls";
|
|
2
|
-
export declare const VERSION = "0.
|
|
2
|
+
export declare const VERSION = "0.4.0";
|
|
3
3
|
export { initDbRls, requireDbRls, getDbRlsOrNull, requirePool, _resetForTests, } from "./init";
|
|
4
4
|
export type { InitDbRlsConfig, ResolvedDbRls } from "./init";
|
|
5
|
-
export { configureDbRls, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure";
|
|
6
|
-
export type { ConfigureDbRlsOpts } from "./configure";
|
|
5
|
+
export { configureDbRls, configureDbRls2Pool, configureDbRls4Pool, PoolCredentialMismatch, _resetConfigureForTests, } from "./configure";
|
|
6
|
+
export type { ConfigureDbRlsOpts, ConfigureDbRlsPools, } from "./configure";
|
|
7
7
|
export { PgClientPool } from "./pg-pool-adapter";
|
|
8
8
|
export type { PgPoolAdapterOpts } from "./pg-pool-adapter";
|
|
9
|
-
export { withUserContext, withSystemContext, withOwnerContext, autoDispatch, } from "./context";
|
|
9
|
+
export { withUserContext, withSystemContext, withOwnerContext, withPlatformOps, autoDispatch, } from "./context";
|
|
10
10
|
export { withUserContextDb, withSystemContextDb, withOwnerContextDb, } from "./drizzle-client";
|
|
11
11
|
export type { DrizzleClient, NodePgDatabase } from "./drizzle-client";
|
|
12
|
+
export type { OwnerContextOpts } from "./migrate-guard";
|
|
13
|
+
export { assertMigrateAllowed } from "./migrate-guard";
|
|
12
14
|
export { AUTH_SCHEMA_SQL, AUTH_SCHEMA_GRANTS_SQL, applyAuthSchemaMigrations, authSchemaFullSql, } from "./auth-schema";
|
|
13
15
|
export type { SqlExecutor } from "./auth-schema";
|
|
14
16
|
export { withRls, generateTableGrants } from "./rls-policy-gen";
|
|
@@ -18,6 +20,7 @@ export type { MigrateGenInput, MigrateGenResult } from "./migrate-gen";
|
|
|
18
20
|
export { generateRlsPolicy, authSchemaHelpers } from "./rls-policy";
|
|
19
21
|
export { InMemoryPgPool } from "./in-memory-pool";
|
|
20
22
|
export type { TranscriptEntry } from "./in-memory-pool";
|
|
21
|
-
export {
|
|
22
|
-
export
|
|
23
|
+
export { DB_RLS_METRIC_VOCABULARY, _resetMetricsWarnLedgerForTests, } from "./metrics";
|
|
24
|
+
export { DbRlsConfigError, DbRlsError, DbRlsNotInitialized, MissingTenantContext, OwnerContextOutsideMigrate, PoolUnavailable, TransactionRolledBack, } from "./types";
|
|
25
|
+
export type { AuthContext, AutoDispatchOpts, DbRlsMode, GenerateRlsPolicyOpts, PgPool, PgTx, PlatformOpsContextOpts, PoolKind, SystemContextOpts, UserContextOpts, } from "./types";
|
|
23
26
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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,eAAe,EACf,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,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIvE,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"}
|