okmodel 0.5.1 → 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.
- package/README.md +29 -14
- package/dist/adapters/pg/no-inflight-timeout.d.ts +17 -0
- package/dist/adapters/pg/postgres-extra.d.ts +22 -0
- package/dist/contracts/catalog/document.d.ts +19 -5
- package/dist/contracts/catalog/object.d.ts +2 -1
- package/dist/contracts/catalog/policy.d.ts +48 -0
- package/dist/contracts/catalog/types.d.ts +25 -1
- package/dist/contracts/catalog/view.d.ts +2 -0
- package/dist/contracts/internal.js +1 -1
- package/dist/contracts/location.d.ts +10 -0
- package/dist/dialects/pg/column.d.ts +13 -2
- package/dist/dialects/pg/ddl.d.ts +37 -1
- package/dist/dialects/pg/emit.d.ts +19 -1
- package/dist/dialects/pg/errors.d.ts +32 -1
- package/dist/dialects/pg/ext/citext.js +1 -1
- package/dist/dialects/pg/ext/index.js +1 -1
- package/dist/dialects/pg/ext/pg-trgm.js +1 -1
- package/dist/dialects/pg/filter-parse.d.ts +5 -4
- package/dist/dialects/pg/fn/index.js +2 -2
- package/dist/dialects/pg/index.d.ts +2 -1
- package/dist/dialects/pg/index.js +23 -17
- package/dist/dialects/pg/introspect.d.ts +7 -0
- package/dist/dialects/pg/model.d.ts +7 -2
- package/dist/dialects/pg/owner.d.ts +42 -0
- package/dist/dialects/pg/path-endpoint.d.ts +20 -0
- package/dist/dialects/pg/role/check.d.ts +3 -0
- package/dist/dialects/pg/role/index.d.ts +71 -6
- package/dist/dialects/pg/role/sql.d.ts +11 -0
- package/dist/dialects/pg/schema.d.ts +2 -0
- package/dist/dialects/pg/table.d.ts +25 -3
- package/dist/dialects/pg/tenancy.d.ts +45 -3
- package/dist/dialects/pg/view/client.d.ts +19 -1
- package/dist/dialects/pg/view/index.d.ts +4 -0
- package/dist/dialects/pg/view/index.js +21 -178
- package/dist/dialects/pg/view/refresh.d.ts +24 -0
- package/dist/runtime/batch.d.ts +1 -1
- package/dist/runtime/conflict.d.ts +2 -2
- package/dist/runtime/drift.d.ts +9 -0
- package/dist/runtime/inflight.d.ts +14 -0
- package/dist/runtime/pg/bun.js +4 -3
- package/dist/runtime/pg/pg.js +3 -3
- package/dist/runtime/pg/pglite.js +4 -3
- package/dist/runtime/pg/postgresjs.js +3 -3
- package/dist/runtime/plan.d.ts +18 -10
- package/dist/runtime/predicate.d.ts +19 -0
- package/dist/runtime/safety/index.js +1 -1
- package/dist/runtime/tenancy/composite.d.ts +26 -0
- package/dist/runtime/tenancy/context.d.ts +16 -0
- package/dist/runtime/tenancy/index.d.ts +9 -5
- package/dist/runtime/tenancy/index.js +1508 -37
- package/dist/runtime/tenancy/path.d.ts +87 -0
- package/dist/runtime/tenancy/rls.d.ts +67 -0
- package/dist/runtime/tenancy/via.d.ts +22 -0
- package/dist/runtime/traits/index.js +17 -11
- package/dist/runtime/types.d.ts +13 -1
- package/dist/runtime/validate/index.js +4 -4
- package/dist/runtime/write.d.ts +1 -1
- package/dist/shared/09p049xa.js +702 -0
- package/dist/shared/{6qd27mx0.js → 1f0xa3cb.js} +5 -5
- package/dist/shared/1nw1f3vs.js +23 -0
- package/dist/shared/{96qcj21c.js → 1z04fa85.js} +19 -9
- package/dist/shared/{qm7cdtvr.js → 2cg3wnxc.js} +296 -60
- package/dist/shared/{dyj86cmj.js → 2jd1sn0e.js} +2 -2
- package/dist/shared/{gbtcc2d7.js → 2z7wv5tj.js} +10 -35
- package/dist/shared/{k8v5v5wj.js → 32cnm7kn.js} +6 -1
- package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
- package/dist/shared/{2pqx26h8.js → 3fqwmr09.js} +31 -22
- package/dist/shared/{zqrnhwsq.js → 3qnhc7w5.js} +16 -9
- package/dist/shared/{r2sp8hrc.js → 5d8t84hg.js} +12 -3
- package/dist/shared/{87jvvhnt.js → 5j36z8dn.js} +16 -5
- package/dist/shared/{1g0drakv.js → 5yv4k6a6.js} +1 -1
- package/dist/shared/8dqhth8c.js +12 -0
- package/dist/shared/8etn7d8w.js +62 -0
- package/dist/shared/{v36c5g6p.js → 8x72s86k.js} +400 -13
- package/dist/shared/{nxdp2ze3.js → 929h19xp.js} +107 -5
- package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
- package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
- package/dist/shared/{efmy2gcg.js → ag4c7516.js} +1 -1
- package/dist/shared/b3awxn7h.js +45 -0
- package/dist/shared/b4v57v3x.js +9 -0
- package/dist/shared/bdk4sty6.js +58 -0
- package/dist/shared/{51mvgj8w.js → c58secgj.js} +100 -7
- package/dist/shared/d5azex6s.js +6 -0
- package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
- package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
- package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
- package/dist/shared/{sycnx8gt.js → f0f1n281.js} +18 -8
- package/dist/shared/{f5cw5q5r.js → g90m9b0g.js} +2 -1
- package/dist/shared/{pf0d8f77.js → gwn6v667.js} +1 -1
- package/dist/shared/{8rsy3hxz.js → h15jx9bc.js} +1 -1
- package/dist/shared/{5enne4ma.js → hazqqecq.js} +17 -93
- package/dist/shared/{jwtxdj06.js → j3rkk835.js} +32 -9
- package/dist/shared/{hf22e0wt.js → j60w0dvr.js} +19 -18
- package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
- package/dist/shared/k68eedmy.js +85 -0
- package/dist/shared/{szm0cksa.js → knmes2kh.js} +34 -6
- package/dist/shared/{0t22wwh1.js → mb2ycs1p.js} +4 -2
- package/dist/shared/{cr74e96e.js → n076ydsc.js} +1 -1
- package/dist/shared/{cctw17hj.js → nx9hh281.js} +31 -28
- package/dist/shared/{gde73es6.js → p248q79y.js} +56 -55
- package/dist/shared/{janx09m5.js → p6bjzq9q.js} +11 -7
- package/dist/shared/{6rk2gen5.js → pjr6xrm5.js} +2 -2
- package/dist/shared/{wq9n6pwr.js → pz6rj8ay.js} +82 -9
- package/dist/shared/{caw8b9d8.js → q3j1tq7a.js} +35 -22
- package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
- package/dist/shared/{tm5ab8we.js → r11n8grd.js} +2 -2
- package/dist/shared/r1fdd0f6.js +19 -0
- package/dist/shared/{8ktwd3rh.js → r3j8s5y0.js} +1 -1
- package/dist/shared/rhs3xe4k.js +7 -0
- package/dist/shared/{ntneex2a.js → rpycarcr.js} +6 -6
- package/dist/shared/{aj2qxyhj.js → sbdme3vy.js} +14 -2
- package/dist/shared/{qv2ydck9.js → t3g0k88x.js} +638 -67
- package/dist/shared/{ga3sfy93.js → ttmg09vd.js} +535 -200
- package/dist/shared/{kfjp0gck.js → venqrjna.js} +8 -4
- package/dist/shared/{fancm5pt.js → vjpnzwjz.js} +138 -15
- package/dist/shared/{32zqc1dw.js → vmfkhszw.js} +31 -7
- package/dist/shared/{krxx77g0.js → wkme6tep.js} +10 -8
- package/dist/shared/{ps7a6h14.js → wt5rzv1h.js} +12 -8
- package/dist/shared/wxr8cwns.js +6 -0
- package/dist/shared/{6mnp99hx.js → wynzeggs.js} +16 -12
- package/dist/shared/x3jc53kg.js +220 -0
- package/dist/shared/{sdc7r2ww.js → xq0mvhts.js} +8 -8
- package/dist/shared/xqve9598.js +53 -0
- package/dist/shared/{47x8x9ze.js → y2t3jktd.js} +2 -2
- package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
- package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
- package/dist/shared/{nkaxvt9q.js → ys0xzyaj.js} +1 -1
- package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
- package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
- package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
- package/dist/shared/{r8x5qhd7.js → zm0mafk4.js} +10 -4
- package/dist/shared/{y005b761.js → zy8r7qvz.js} +6 -2
- package/dist/tooling/cli.js +41 -15
- package/dist/tooling/migrate/apply.d.ts +14 -0
- package/dist/tooling/migrate/check.d.ts +3 -4
- package/dist/tooling/migrate/classify.d.ts +4 -0
- package/dist/tooling/migrate/config.d.ts +3 -2
- package/dist/tooling/migrate/files.d.ts +11 -1
- package/dist/tooling/migrate/index.js +14 -14
- package/dist/tooling/migrate/lint.d.ts +1 -1
- package/dist/tooling/migrate/lost.d.ts +28 -0
- package/dist/tooling/migrate/paths.d.ts +14 -0
- package/dist/tooling/migrate/plan.d.ts +6 -3
- package/dist/tooling/migrate/runner.d.ts +25 -0
- package/dist/tooling/migrate/sandbox.d.ts +57 -0
- package/dist/tooling/migrate/sql-lex.d.ts +20 -3
- package/dist/tooling/migrate/text.d.ts +42 -0
- package/dist/tooling/node-version.d.ts +21 -0
- package/dist/tooling/testing/facts.d.ts +33 -5
- package/dist/tooling/testing/index.d.ts +1 -1
- package/dist/tooling/testing/index.js +3 -3
- package/dist/tooling/testing/isolation.d.ts +11 -5
- package/package.json +5 -2
- package/dist/shared/7zwwyh0v.js +0 -448
- package/dist/shared/q58y17hy.js +0 -21
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
readHandle,
|
|
3
3
|
readCall,
|
|
4
4
|
attachHttp
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./j60w0dvr.js";
|
|
6
6
|
import {
|
|
7
7
|
emitWhere,
|
|
8
8
|
emitOrder,
|
|
9
|
+
refuseHidden,
|
|
9
10
|
rejectKeys,
|
|
10
11
|
readLimit,
|
|
11
12
|
projectExpr,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
list,
|
|
16
17
|
isRecord,
|
|
17
18
|
fail
|
|
18
|
-
} from "./
|
|
19
|
+
} from "./2z7wv5tj.js";
|
|
19
20
|
import {
|
|
20
21
|
OkmError2,
|
|
21
22
|
throwNamed2
|
|
@@ -68,8 +69,11 @@ function plan(session, table, options, mods, view) {
|
|
|
68
69
|
if (!isRecord(orderBy))
|
|
69
70
|
fail("OKM1120", "orderBy must be an object of fields.");
|
|
70
71
|
for (const field of Object.keys(orderBy)) {
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
const column = indexed.columns.get(field);
|
|
73
|
+
if (column !== undefined)
|
|
74
|
+
refuseHidden(column);
|
|
75
|
+
if (!spec.groups.some((group) => group.field === field)) {
|
|
76
|
+
throwNamed2("OKM1120", field, spec.groups.map((group) => group.field), `aggregate() orders by a groupBy field. Accepted names: ${list(spec.groups.map((group) => group.field))}.`);
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
}
|
|
@@ -2,28 +2,34 @@ import {
|
|
|
2
2
|
roleObject,
|
|
3
3
|
grantObject,
|
|
4
4
|
defaultPrivilegeObject
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./qq3899ht.js";
|
|
6
|
+
import {
|
|
7
|
+
columnPrivilege
|
|
8
|
+
} from "./ttmg09vd.js";
|
|
6
9
|
import {
|
|
7
10
|
quoteIdent
|
|
8
|
-
} from "./
|
|
11
|
+
} from "./9s0ypp87.js";
|
|
12
|
+
import {
|
|
13
|
+
policyObject
|
|
14
|
+
} from "./bdk4sty6.js";
|
|
9
15
|
import {
|
|
10
16
|
functionObject,
|
|
11
17
|
triggerObject
|
|
12
|
-
} from "./
|
|
18
|
+
} from "./y34a8714.js";
|
|
13
19
|
import {
|
|
14
20
|
normaliseViewQuery,
|
|
15
21
|
viewObject,
|
|
16
22
|
materializedViewObject,
|
|
17
23
|
materializedViewIndex
|
|
18
|
-
} from "./
|
|
24
|
+
} from "./zy8r7qvz.js";
|
|
19
25
|
import {
|
|
20
26
|
extensionObject
|
|
21
|
-
} from "./
|
|
27
|
+
} from "./r3j8s5y0.js";
|
|
22
28
|
import {
|
|
23
29
|
catalog,
|
|
24
30
|
enumType,
|
|
25
31
|
domainType
|
|
26
|
-
} from "./
|
|
32
|
+
} from "./ywspezzx.js";
|
|
27
33
|
import {
|
|
28
34
|
staticNamespace2,
|
|
29
35
|
identityKey2,
|
|
@@ -32,7 +38,7 @@ import {
|
|
|
32
38
|
index3,
|
|
33
39
|
constraint2,
|
|
34
40
|
sequence2
|
|
35
|
-
} from "./
|
|
41
|
+
} from "./358zsv4r.js";
|
|
36
42
|
import {
|
|
37
43
|
referentialAction
|
|
38
44
|
} from "./4e4c6vq2.js";
|
|
@@ -123,7 +129,8 @@ async function introspectSchema(runner, concrete, logical = "public", options) {
|
|
|
123
129
|
triggers,
|
|
124
130
|
functionDeps,
|
|
125
131
|
views,
|
|
126
|
-
viewDeps
|
|
132
|
+
viewDeps,
|
|
133
|
+
policies
|
|
127
134
|
] = await Promise.all([
|
|
128
135
|
runner.query(TABLES, params),
|
|
129
136
|
runner.query(COLUMNS, params),
|
|
@@ -137,7 +144,8 @@ async function introspectSchema(runner, concrete, logical = "public", options) {
|
|
|
137
144
|
runner.query(TRIGGERS, params),
|
|
138
145
|
runner.query(FUNCTION_DEPS, params),
|
|
139
146
|
runner.query(VIEWS, params),
|
|
140
|
-
runner.query(VIEW_DEPENDENCIES, params)
|
|
147
|
+
runner.query(VIEW_DEPENDENCIES, params),
|
|
148
|
+
runner.query(POLICIES, params)
|
|
141
149
|
]);
|
|
142
150
|
const objects = [];
|
|
143
151
|
const parents = new Map;
|
|
@@ -380,12 +388,38 @@ async function introspectSchema(runner, concrete, logical = "public", options) {
|
|
|
380
388
|
const columns = printedColumns(text(row, "columns"));
|
|
381
389
|
const query = normaliseViewQuery(text(row, "query"));
|
|
382
390
|
const name = text(row, "name");
|
|
391
|
+
const invoker = kind === "view" && securityInvokerOption(text(row, "options"));
|
|
383
392
|
if (kind === "materializedView") {
|
|
384
393
|
objects.push(materializedViewObject({ namespace, name, columns, query, provenance }));
|
|
385
394
|
} else {
|
|
386
|
-
objects.push(viewObject({
|
|
395
|
+
objects.push(viewObject({
|
|
396
|
+
namespace,
|
|
397
|
+
name,
|
|
398
|
+
columns,
|
|
399
|
+
query,
|
|
400
|
+
provenance,
|
|
401
|
+
...invoker ? { securityInvoker: true } : {}
|
|
402
|
+
}));
|
|
387
403
|
}
|
|
388
404
|
}
|
|
405
|
+
for (const row of policies) {
|
|
406
|
+
const parentName = text(row, "table_name");
|
|
407
|
+
const parent = parents.get(parentName);
|
|
408
|
+
if (parent === undefined)
|
|
409
|
+
continue;
|
|
410
|
+
const command = policyCommand(text(row, "command"));
|
|
411
|
+
if (command === undefined || text(row, "enabled") !== "true")
|
|
412
|
+
continue;
|
|
413
|
+
objects.push(policyObject({
|
|
414
|
+
parent,
|
|
415
|
+
name: text(row, "name"),
|
|
416
|
+
command,
|
|
417
|
+
expression: text(row, "using_expr"),
|
|
418
|
+
force: text(row, "force") === "true",
|
|
419
|
+
provenance,
|
|
420
|
+
dependencies: [{ kind: "table", namespace, name: parentName }]
|
|
421
|
+
}));
|
|
422
|
+
}
|
|
389
423
|
const viewEdges = viewDependencyEdges(viewDeps, namespace, objects);
|
|
390
424
|
for (let index = 0;index < objects.length; index += 1) {
|
|
391
425
|
const object = objects[index];
|
|
@@ -402,7 +436,8 @@ async function introspectSchema(runner, concrete, logical = "public", options) {
|
|
|
402
436
|
columns: object.definition.columns,
|
|
403
437
|
query: object.definition.query,
|
|
404
438
|
provenance,
|
|
405
|
-
dependencies
|
|
439
|
+
dependencies,
|
|
440
|
+
...object.definition.securityInvoker === true ? { securityInvoker: true } : {}
|
|
406
441
|
}) : materializedViewObject({
|
|
407
442
|
namespace,
|
|
408
443
|
name: object.identity.name,
|
|
@@ -413,7 +448,7 @@ async function introspectSchema(runner, concrete, logical = "public", options) {
|
|
|
413
448
|
});
|
|
414
449
|
}
|
|
415
450
|
if (options?.managedRoles !== undefined) {
|
|
416
|
-
objects.push(...await readPrivileges(runner, concrete, namespace, provenance, objects, options.managedRoles));
|
|
451
|
+
objects.push(...await readPrivileges(runner, concrete, logical, namespace, provenance, objects, options.managedRoles, options.reportingRole));
|
|
417
452
|
}
|
|
418
453
|
return catalog(objects);
|
|
419
454
|
}
|
|
@@ -452,6 +487,30 @@ var FUNCTION_GRANTS = `select p.proname as name,
|
|
|
452
487
|
select 1 from pg_depend d
|
|
453
488
|
where d.classid = 'pg_proc'::regclass and d.objid = p.oid and d.deptype = 'e'
|
|
454
489
|
)`;
|
|
490
|
+
var COLUMN_GRANTS = `select c.relname as name,
|
|
491
|
+
case c.relkind when 'v' then 'view' when 'm' then 'materializedView' else 'table' end as kind,
|
|
492
|
+
a.attname as column_name,
|
|
493
|
+
r.rolname as role, x.privilege_type as privilege
|
|
494
|
+
from pg_class c
|
|
495
|
+
join pg_namespace n on n.oid = c.relnamespace
|
|
496
|
+
join pg_attribute a on a.attrelid = c.oid and a.attnum > 0 and not a.attisdropped
|
|
497
|
+
cross join lateral aclexplode(a.attacl) as x
|
|
498
|
+
join pg_roles r on r.oid = x.grantee
|
|
499
|
+
where n.nspname = $1
|
|
500
|
+
and c.relkind in ('r', 'p', 'v', 'm')
|
|
501
|
+
and a.attacl is not null
|
|
502
|
+
and x.grantee <> 0
|
|
503
|
+
and x.grantee <> c.relowner`;
|
|
504
|
+
var SCHEMA_USAGE = `select 1 as ok
|
|
505
|
+
from pg_namespace n
|
|
506
|
+
cross join lateral aclexplode(n.nspacl) as a
|
|
507
|
+
where n.nspname = $1
|
|
508
|
+
and a.privilege_type = 'USAGE'
|
|
509
|
+
and (
|
|
510
|
+
a.grantee = 0
|
|
511
|
+
or a.grantee = (select oid from pg_roles where rolname = $2)
|
|
512
|
+
)
|
|
513
|
+
limit 1`;
|
|
455
514
|
var DEFAULT_PRIVILEGES = `select owner_role.rolname as for_role, grantee.rolname as grantee,
|
|
456
515
|
case d.defaclobjtype when 'S' then 'sequence' when 'f' then 'function' else 'table' end as object_kind,
|
|
457
516
|
a.privilege_type as privilege
|
|
@@ -463,13 +522,15 @@ var DEFAULT_PRIVILEGES = `select owner_role.rolname as for_role, grantee.rolname
|
|
|
463
522
|
where n.nspname = $1
|
|
464
523
|
and d.defaclobjtype in ('r', 'S', 'f')
|
|
465
524
|
and a.grantee <> 0`;
|
|
466
|
-
async function readPrivileges(runner, concrete, namespace, provenance, built, managedRoles) {
|
|
525
|
+
async function readPrivileges(runner, concrete, logical, namespace, provenance, built, managedRoles, reportingRole) {
|
|
467
526
|
const managed = new Set(managedRoles);
|
|
468
|
-
const [roles, relations, functions, defaults] = await Promise.all([
|
|
527
|
+
const [roles, relations, functions, defaults, columns, usage] = await Promise.all([
|
|
469
528
|
runner.query(ROLES, []),
|
|
470
529
|
runner.query(RELATION_GRANTS, [concrete]),
|
|
471
530
|
runner.query(FUNCTION_GRANTS, [concrete]),
|
|
472
|
-
runner.query(DEFAULT_PRIVILEGES, [concrete])
|
|
531
|
+
runner.query(DEFAULT_PRIVILEGES, [concrete]),
|
|
532
|
+
runner.query(COLUMN_GRANTS, [concrete]),
|
|
533
|
+
reportingRole === undefined ? Promise.resolve([]) : runner.query(SCHEMA_USAGE, [concrete, reportingRole])
|
|
473
534
|
]);
|
|
474
535
|
const objects = [];
|
|
475
536
|
for (const row of roles) {
|
|
@@ -530,6 +591,42 @@ async function readPrivileges(runner, concrete, namespace, provenance, built, ma
|
|
|
530
591
|
]
|
|
531
592
|
}));
|
|
532
593
|
}
|
|
594
|
+
const grouped = new Map;
|
|
595
|
+
for (const row of columns) {
|
|
596
|
+
const privilege = text(row, "privilege").toUpperCase();
|
|
597
|
+
if (privilege !== "SELECT" && privilege !== "UPDATE")
|
|
598
|
+
continue;
|
|
599
|
+
const kind = grantKind(text(row, "kind"));
|
|
600
|
+
if (kind !== "table" && kind !== "view" && kind !== "materializedView")
|
|
601
|
+
continue;
|
|
602
|
+
const name = text(row, "name");
|
|
603
|
+
const role = text(row, "role");
|
|
604
|
+
const key = `${role}\x00${kind}\x00${name}\x00${privilege}`;
|
|
605
|
+
const current = grouped.get(key) ?? { role, kind, name, privilege, columns: [] };
|
|
606
|
+
current.columns.push(text(row, "column_name"));
|
|
607
|
+
grouped.set(key, current);
|
|
608
|
+
}
|
|
609
|
+
for (const group of grouped.values()) {
|
|
610
|
+
const target = built.find((object) => privilegeTarget(object) === `${group.kind}:${group.name}`);
|
|
611
|
+
if (target === undefined)
|
|
612
|
+
continue;
|
|
613
|
+
objects.push(grantObject({
|
|
614
|
+
role: group.role,
|
|
615
|
+
object: { kind: group.kind, namespace, name: group.name },
|
|
616
|
+
privilege: columnPrivilege(group.privilege, group.columns),
|
|
617
|
+
provenance,
|
|
618
|
+
dependencies: [{ kind: "role", name: group.role }, target.identity]
|
|
619
|
+
}));
|
|
620
|
+
}
|
|
621
|
+
if (usage.length > 0 && reportingRole !== undefined) {
|
|
622
|
+
objects.push(grantObject({
|
|
623
|
+
role: reportingRole,
|
|
624
|
+
object: { kind: "namespace", namespace, name: logical },
|
|
625
|
+
privilege: "USAGE",
|
|
626
|
+
provenance,
|
|
627
|
+
dependencies: [{ kind: "role", name: reportingRole }]
|
|
628
|
+
}));
|
|
629
|
+
}
|
|
533
630
|
return objects;
|
|
534
631
|
}
|
|
535
632
|
function privilegeTarget(object) {
|
|
@@ -788,6 +885,7 @@ var TRIGGERS = `
|
|
|
788
885
|
`;
|
|
789
886
|
var VIEWS = `
|
|
790
887
|
select c.relname as name, c.relkind as kind, pg_get_viewdef(c.oid, true) as query,
|
|
888
|
+
coalesce(array_to_string(c.reloptions, ','), '') as options,
|
|
791
889
|
(
|
|
792
890
|
select coalesce(string_agg(
|
|
793
891
|
a.attname || '|' || format_type(a.atttypid, a.atttypmod),
|
|
@@ -821,6 +919,31 @@ var FUNCTION_DEPS = `
|
|
|
821
919
|
and p.prokind = 'f'
|
|
822
920
|
and p.prosrc = ''
|
|
823
921
|
`;
|
|
922
|
+
var POLICIES = `
|
|
923
|
+
select c.relname as table_name,
|
|
924
|
+
p.polname as name,
|
|
925
|
+
p.polcmd as command,
|
|
926
|
+
coalesce(pg_get_expr(p.polqual, p.polrelid), '') as using_expr,
|
|
927
|
+
c.relforcerowsecurity::text as force,
|
|
928
|
+
c.relrowsecurity::text as enabled
|
|
929
|
+
from pg_policy p
|
|
930
|
+
join pg_class c on c.oid = p.polrelid
|
|
931
|
+
join pg_namespace n on n.oid = c.relnamespace
|
|
932
|
+
where n.nspname = $1
|
|
933
|
+
and c.relkind = 'r'
|
|
934
|
+
and ${CHILD}
|
|
935
|
+
and ${member("c.oid", "pg_class")}
|
|
936
|
+
`;
|
|
937
|
+
function securityInvokerOption(options) {
|
|
938
|
+
return options.split(",").some((item) => item === "security_invoker=true" || item === "security_invoker=on");
|
|
939
|
+
}
|
|
940
|
+
function policyCommand(command) {
|
|
941
|
+
if (command === "*")
|
|
942
|
+
return "all";
|
|
943
|
+
if (command === "r")
|
|
944
|
+
return "select";
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
824
947
|
function member(oid, classid) {
|
|
825
948
|
return `not exists (
|
|
826
949
|
select 1 from pg_depend member
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isRecord,
|
|
10
10
|
registerFailFix,
|
|
11
11
|
fail
|
|
12
|
-
} from "./
|
|
12
|
+
} from "./2z7wv5tj.js";
|
|
13
13
|
import {
|
|
14
14
|
throwNamed2
|
|
15
15
|
} from "./52szzakm.js";
|
|
@@ -112,11 +112,13 @@ function samePrimary(table, columns) {
|
|
|
112
112
|
}
|
|
113
113
|
function uniqueColumns(table, on, tenantKey) {
|
|
114
114
|
const names = conflictNames(on);
|
|
115
|
+
const keys = keyList(tenantKey);
|
|
115
116
|
for (const unique of table.model.uniques) {
|
|
116
|
-
|
|
117
|
+
const fields = fieldsOf(unique, names, keys);
|
|
118
|
+
if (fields === undefined)
|
|
117
119
|
continue;
|
|
118
120
|
const columns = [];
|
|
119
|
-
for (const name of
|
|
121
|
+
for (const name of fields) {
|
|
120
122
|
const column = table.columns.get(name);
|
|
121
123
|
if (column === undefined) {
|
|
122
124
|
fail("OKM1104", `onConflict column ${name} is not on ${table.model.name}.`);
|
|
@@ -125,14 +127,14 @@ function uniqueColumns(table, on, tenantKey) {
|
|
|
125
127
|
}
|
|
126
128
|
return columns;
|
|
127
129
|
}
|
|
128
|
-
const accepted = acceptedConstraints(table.model,
|
|
129
|
-
const implicit =
|
|
130
|
+
const accepted = acceptedConstraints(table.model, keys);
|
|
131
|
+
const implicit = keys.length === 0 ? "" : ` The tenant key ${keys.join(", ")} is part of each one and is not named here.`;
|
|
130
132
|
throwNamed2("OKM1104", names.join(", "), accepted, `onConflict on ${table.model.name} names ${names.join(", ")}, which is not a unique constraint. Accepted: ${list(accepted)}.${implicit}`);
|
|
131
133
|
}
|
|
132
|
-
function acceptedConstraints(model,
|
|
134
|
+
function acceptedConstraints(model, keys) {
|
|
133
135
|
const shown = new Set;
|
|
134
136
|
for (const fields of model.uniques) {
|
|
135
|
-
const named =
|
|
137
|
+
const named = keys.length === 0 ? fields : fields.filter((field) => !keys.includes(field));
|
|
136
138
|
if (named.length === 0)
|
|
137
139
|
continue;
|
|
138
140
|
shown.add(named.length > 1 ? `(${named.join(", ")})` : named.join(""));
|
|
@@ -166,6 +168,28 @@ function conflictNames(on) {
|
|
|
166
168
|
}
|
|
167
169
|
fail("OKM1104", "onConflict on must name a unique constraint's columns.");
|
|
168
170
|
}
|
|
171
|
+
function fieldsOf(unique, names, tenantKeys) {
|
|
172
|
+
if (tenantKeys.some((key) => unique.includes(key))) {
|
|
173
|
+
const rest = [];
|
|
174
|
+
for (const field of unique) {
|
|
175
|
+
if (!tenantKeys.includes(field))
|
|
176
|
+
rest.push(field);
|
|
177
|
+
}
|
|
178
|
+
if (!same(rest, names))
|
|
179
|
+
return;
|
|
180
|
+
return unique;
|
|
181
|
+
}
|
|
182
|
+
if (!same(unique, names))
|
|
183
|
+
return;
|
|
184
|
+
return names;
|
|
185
|
+
}
|
|
186
|
+
function keyList(tenantKey) {
|
|
187
|
+
if (tenantKey === undefined)
|
|
188
|
+
return [];
|
|
189
|
+
if (typeof tenantKey === "string")
|
|
190
|
+
return [tenantKey];
|
|
191
|
+
return tenantKey;
|
|
192
|
+
}
|
|
169
193
|
function same(unique, names) {
|
|
170
194
|
if (unique.length !== names.length)
|
|
171
195
|
return false;
|
|
@@ -62,13 +62,15 @@ class PoolSockets {
|
|
|
62
62
|
}
|
|
63
63
|
wake() {
|
|
64
64
|
for (const socket of this.held)
|
|
65
|
-
socket.
|
|
65
|
+
if (socket.writable)
|
|
66
|
+
socket.ref();
|
|
66
67
|
}
|
|
67
68
|
park() {
|
|
68
69
|
if (this.busy > 0 || this.listeners > 0)
|
|
69
70
|
return;
|
|
70
71
|
for (const socket of this.held)
|
|
71
|
-
socket.
|
|
72
|
+
if (socket.writable)
|
|
73
|
+
socket.unref();
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
function driverOptions(config, state) {
|
|
@@ -117,7 +119,7 @@ function open2(config) {
|
|
|
117
119
|
},
|
|
118
120
|
async batch(statements, options) {
|
|
119
121
|
return sockets.occupy(async () => {
|
|
120
|
-
const { checkout } = await import("./
|
|
122
|
+
const { checkout } = await import("./r1fdd0f6.js");
|
|
121
123
|
const connection = await checkout(held);
|
|
122
124
|
try {
|
|
123
125
|
return await connection.batch(statements, options);
|
|
@@ -129,12 +131,12 @@ function open2(config) {
|
|
|
129
131
|
reserve() {
|
|
130
132
|
const gate = sockets.busyGate();
|
|
131
133
|
gate.enter();
|
|
132
|
-
return import("./
|
|
134
|
+
return import("./r1fdd0f6.js").then((mod) => mod.holdCheckout(gate, () => mod.checkout(held)), (error) => {
|
|
133
135
|
gate.leave();
|
|
134
136
|
throw error;
|
|
135
137
|
});
|
|
136
138
|
},
|
|
137
|
-
describe: (text, params) => sockets.occupy(() => import("./
|
|
139
|
+
describe: (text, params) => sockets.occupy(() => import("./r1fdd0f6.js").then((mod) => mod.describe(sql, text, params))),
|
|
138
140
|
stream(text, params) {
|
|
139
141
|
const gate = sockets.busyGate();
|
|
140
142
|
return async function* () {
|
|
@@ -149,7 +151,7 @@ function open2(config) {
|
|
|
149
151
|
listen(channel, onNotify) {
|
|
150
152
|
const gate = sockets.listenerGate();
|
|
151
153
|
gate.enter();
|
|
152
|
-
return import("./
|
|
154
|
+
return import("./r1fdd0f6.js").then((mod) => mod.holdListener(gate, async () => {
|
|
153
155
|
const listening = await sql.listen(channel, onNotify);
|
|
154
156
|
return async () => {
|
|
155
157
|
await listening.unlisten();
|
|
@@ -219,7 +221,7 @@ class PgSession {
|
|
|
219
221
|
onAbort();
|
|
220
222
|
else
|
|
221
223
|
watch.signal.addEventListener("abort", onAbort, { once: true });
|
|
222
|
-
return import("./
|
|
224
|
+
return import("./r1fdd0f6.js").then((mod) => mod.watchQuery(pending, watch, onAbort, {
|
|
223
225
|
start,
|
|
224
226
|
text,
|
|
225
227
|
notices: this.notices,
|
|
@@ -271,7 +273,7 @@ class PgSession {
|
|
|
271
273
|
}
|
|
272
274
|
}
|
|
273
275
|
async function* loadStream(sql, text, params) {
|
|
274
|
-
const { stream } = await import("./
|
|
276
|
+
const { stream } = await import("./r1fdd0f6.js");
|
|
275
277
|
yield* stream(sql, text, params);
|
|
276
278
|
}
|
|
277
279
|
function send(sql, text, params, named) {
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./wkme6tep.js";
|
|
4
|
+
import"./qq3899ht.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import {
|
|
7
7
|
assertRoleHealth
|
|
8
|
-
} from "./
|
|
9
|
-
import"./
|
|
8
|
+
} from "./knmes2kh.js";
|
|
9
|
+
import"./vjpnzwjz.js";
|
|
10
10
|
import {
|
|
11
11
|
errorDoc,
|
|
12
12
|
openProject
|
|
13
|
-
} from "./
|
|
13
|
+
} from "./t3g0k88x.js";
|
|
14
14
|
import {
|
|
15
15
|
omitManagedObjects,
|
|
16
|
+
sessionFailure,
|
|
17
|
+
finishQuiet,
|
|
16
18
|
assertTargetPolicy,
|
|
17
19
|
selectTarget
|
|
18
|
-
} from "./
|
|
19
|
-
import"./
|
|
20
|
+
} from "./ttmg09vd.js";
|
|
21
|
+
import"./9s0ypp87.js";
|
|
20
22
|
import {
|
|
21
23
|
OkmError2
|
|
22
24
|
} from "./52szzakm.js";
|
|
@@ -43,8 +45,10 @@ ${doc.fix}
|
|
|
43
45
|
const pool = open2({ url: target.url, max: 1 });
|
|
44
46
|
try {
|
|
45
47
|
await assertRoleHealth(pool, opened.config.roles, objects);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
throw sessionFailure(error) ?? error;
|
|
46
50
|
} finally {
|
|
47
|
-
await pool.close();
|
|
51
|
+
await finishQuiet(() => pool.close());
|
|
48
52
|
}
|
|
49
53
|
}
|
|
50
54
|
return formatTriggers(objects);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
|
-
} from "./
|
|
4
|
-
import"./
|
|
3
|
+
} from "./wkme6tep.js";
|
|
4
|
+
import"./qq3899ht.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import {
|
|
7
7
|
CURRENT,
|
|
@@ -12,26 +12,28 @@ import {
|
|
|
12
12
|
failedAt
|
|
13
13
|
} from "./9yn6a2vd.js";
|
|
14
14
|
import {
|
|
15
|
-
loadMigrations,
|
|
16
15
|
expandProvisioned,
|
|
17
16
|
provisionHistoryIsKnown
|
|
18
|
-
} from "./
|
|
19
|
-
import"./
|
|
20
|
-
import"./
|
|
17
|
+
} from "./p248q79y.js";
|
|
18
|
+
import"./knmes2kh.js";
|
|
19
|
+
import"./vjpnzwjz.js";
|
|
21
20
|
import {
|
|
21
|
+
projectPath,
|
|
22
|
+
loadMigrations,
|
|
22
23
|
loadConfig
|
|
23
|
-
} from "./
|
|
24
|
+
} from "./t3g0k88x.js";
|
|
24
25
|
import {
|
|
26
|
+
sessionFailure,
|
|
27
|
+
finishQuiet,
|
|
25
28
|
assertTargetPolicy,
|
|
26
29
|
listTargets
|
|
27
|
-
} from "./
|
|
28
|
-
import"./
|
|
30
|
+
} from "./ttmg09vd.js";
|
|
31
|
+
import"./9s0ypp87.js";
|
|
29
32
|
import {
|
|
30
33
|
OkmError2
|
|
31
34
|
} from "./52szzakm.js";
|
|
32
35
|
|
|
33
36
|
// src/tooling/migrate/status.ts
|
|
34
|
-
import { join } from "node:path";
|
|
35
37
|
function describeStatus(migrations, history, recorded) {
|
|
36
38
|
const known = new Set(migrations.map((migration) => migration.id));
|
|
37
39
|
const done = expandProvisioned(migrations, new Set(history.map((row) => `${row.migrationId}:${String(row.stepIndex)}`)), history.map((row) => row.migrationId));
|
|
@@ -99,14 +101,16 @@ async function readTargetStatus(input) {
|
|
|
99
101
|
protected: input.protected,
|
|
100
102
|
backfills: await readBackfills(pool)
|
|
101
103
|
};
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw sessionFailure(error) ?? error;
|
|
102
106
|
} finally {
|
|
103
|
-
await pool.close();
|
|
107
|
+
await finishQuiet(() => pool.close());
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
async function statusProject(cwd, flags) {
|
|
107
111
|
const config = await loadConfig(cwd);
|
|
108
112
|
const targets = chosen(listTargets(config), flags.target);
|
|
109
|
-
const migrations = loadMigrations(
|
|
113
|
+
const migrations = loadMigrations(projectPath(cwd, config.migrations ?? "migrations"));
|
|
110
114
|
const rows = [];
|
|
111
115
|
for (const target of targets) {
|
|
112
116
|
rows.push(await readTargetStatus({
|