okmodel 0.4.0 → 0.5.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 +86 -6
- package/dist/contracts/catalog/document.d.ts +20 -0
- package/dist/contracts/driver.d.ts +7 -0
- package/dist/dialects/pg/introspect.d.ts +6 -0
- package/dist/dialects/pg/role/sql.d.ts +10 -0
- package/dist/dialects/pg/schema.d.ts +15 -6
- package/dist/dialects/pg/view/index.d.ts +20 -6
- package/dist/dialects/pg/view/scratch.d.ts +2 -2
- package/dist/runtime/pg/bun.d.ts +12 -7
- package/dist/runtime/pg/bun.js +4 -1
- package/dist/runtime/pg/pg.d.ts +12 -6
- package/dist/runtime/pg/pg.js +4 -1
- package/dist/runtime/pg/pglite.d.ts +11 -3
- package/dist/runtime/pg/pglite.js +4 -1
- package/dist/runtime/pg/postgresjs.d.ts +12 -6
- package/dist/runtime/pg/postgresjs.js +4 -1
- package/dist/runtime/plan.d.ts +3 -1
- package/dist/runtime/tenancy/index.js +1 -1
- package/dist/runtime/topology.d.ts +191 -0
- package/dist/runtime/traits/index.js +6 -6
- package/dist/runtime/types.d.ts +57 -2
- package/dist/runtime/validate/index.js +1 -1
- package/dist/shared/{nxb42q7h.js → 47xzb9fc.js} +2 -2
- package/dist/shared/{6693j9rs.js → 5fqx9yh4.js} +6 -2
- package/dist/shared/{8jb4ymh2.js → 8bwbwy8h.js} +12 -1
- package/dist/shared/{41kv2xdm.js → 8xsbagad.js} +1 -1
- package/dist/shared/{sr5ms7b3.js → 922qbgnw.js} +3 -3
- package/dist/shared/{tny2t3sm.js → 990a291j.js} +4 -4
- package/dist/shared/{jns2wx4t.js → 9tgmr1gh.js} +1 -1
- package/dist/shared/{n5y9zyj1.js → ayz64vzj.js} +13 -12
- package/dist/shared/{kkzwp3d2.js → bt9sfq0z.js} +16 -14
- package/dist/shared/{c5g81ngb.js → bzsjtd7c.js} +7 -5
- package/dist/shared/{radd3z4g.js → ckjbyrt9.js} +1 -1
- package/dist/shared/{zg24x0hm.js → dxjp14rk.js} +10 -2
- package/dist/shared/{xghkt7a9.js → fancm5pt.js} +6 -233
- package/dist/shared/{yjw02enp.js → fyqkk1m0.js} +4 -4
- package/dist/shared/{ygem90rn.js → g516zdsb.js} +8 -3
- package/dist/shared/{v7tpnhnz.js → h4nqvjkp.js} +5 -3
- package/dist/shared/{edwqqryd.js → h8ne16fq.js} +1 -1
- package/dist/shared/{ady1ms74.js → jdgqqx31.js} +5 -5
- package/dist/shared/{kafaa5zv.js → k7cc9nzk.js} +24 -7
- package/dist/shared/{7nk68fj8.js → kdkxh3kb.js} +17 -10
- package/dist/shared/nkc9sfqb.js +1161 -0
- package/dist/shared/{awrsqrn7.js → p7pfx624.js} +2 -2
- package/dist/shared/{xrfnq5k8.js → qgvt8nx1.js} +11 -2
- package/dist/shared/{84ptn35q.js → qy9rdq0g.js} +6 -5
- package/dist/shared/{qn0srwwq.js → r6pj4fq2.js} +5 -3
- package/dist/shared/{2321avmn.js → r73pt594.js} +21 -13
- package/dist/shared/{kj680nxv.js → rasvvzgz.js} +8 -6
- package/dist/shared/{hcmdtwgh.js → szm0cksa.js} +4 -1
- package/dist/shared/{axhk06q1.js → tq9afp8d.js} +1 -1
- package/dist/shared/wxn4b7pp.js +252 -0
- package/dist/shared/{q6zsyh31.js → xdpj5kkm.js} +19 -8
- package/dist/shared/{s4mb6a4b.js → xhh1srw3.js} +54 -10
- package/dist/shared/{jgxzjzcz.js → xsq7v6wp.js} +2 -2
- package/dist/shared/{hqjsxnz7.js → ykv7wh5b.js} +5 -4
- package/dist/shared/{q795afwa.js → z2rnngj4.js} +3 -3
- package/dist/tooling/cli.js +12 -12
- package/dist/tooling/migrate/apply.d.ts +2 -0
- package/dist/tooling/migrate/files.d.ts +7 -0
- package/dist/tooling/migrate/index.js +8 -6
- package/dist/tooling/testing/facts.d.ts +3 -0
- package/dist/tooling/testing/index.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Primary and replica endpoints (spec §15.1).
|
|
3
|
+
*
|
|
4
|
+
* Loaded only when `connect` is given a topology object. The string and pool
|
|
5
|
+
* paths do not import this module. An automatic read chooses among eligible
|
|
6
|
+
* replicas. One watermark on this handle covers the root, `for()`, `unscoped()`,
|
|
7
|
+
* `using()`, and `reserve()`.
|
|
8
|
+
*/
|
|
9
|
+
import type { DriverPool, DriverTimeouts } from "../contracts/driver.js";
|
|
10
|
+
import type { QuerySchema } from "../dialects/pg/model.js";
|
|
11
|
+
import type { ConnectOptions, Connected } from "./types.js";
|
|
12
|
+
/** `"primary"` or `"replica"`. `using` and `route` accept only these. */
|
|
13
|
+
export type RouteName = "primary" | "replica";
|
|
14
|
+
/**
|
|
15
|
+
* One routing choice.
|
|
16
|
+
*
|
|
17
|
+
* `onRoute` receives this. `inspect()` does not, until the dev inspector (M2).
|
|
18
|
+
*/
|
|
19
|
+
export type RouteEvent = {
|
|
20
|
+
/** What the statement was classified as. */
|
|
21
|
+
readonly op: "read" | "write" | "tx" | "lock";
|
|
22
|
+
/** Endpoint name. The primary is `"primary"`. */
|
|
23
|
+
readonly endpoint: string;
|
|
24
|
+
/**
|
|
25
|
+
* `primary-required`, `constraint:primary`, `constraint:replica`,
|
|
26
|
+
* `auto:<name>`, or `fallback:<no-replicas | unhealthy | position-unknown | saturated | behind>`.
|
|
27
|
+
*/
|
|
28
|
+
readonly reason: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* One replica passed to a custom `routing.select`.
|
|
32
|
+
*
|
|
33
|
+
* `lag` is the replica's byte lag, or `null` when the primary insert position
|
|
34
|
+
* or the replica replay position has not been seen. `latencyMs` stays `null`
|
|
35
|
+
* until a probe or a successful read has been timed.
|
|
36
|
+
*/
|
|
37
|
+
export type ReplicaCandidate = {
|
|
38
|
+
/** Endpoint name. */
|
|
39
|
+
readonly name: string;
|
|
40
|
+
/** Configured weight. Zero and below are OKM1120 at connect. */
|
|
41
|
+
readonly weight: number;
|
|
42
|
+
/** In-flight statements this router is running on the replica. */
|
|
43
|
+
readonly inflight: number;
|
|
44
|
+
/** EWMA of observed round-trip time, in milliseconds, or `null`. */
|
|
45
|
+
readonly latencyMs: number | null;
|
|
46
|
+
/** Byte lag behind the primary, or `null` when either position is unknown. */
|
|
47
|
+
readonly lag: number | null;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* A topology client.
|
|
51
|
+
*
|
|
52
|
+
* `using` returns a client that forces one route. That client has no `close`
|
|
53
|
+
* and no `using`. Only the root closes the pools.
|
|
54
|
+
*/
|
|
55
|
+
export type RoutedClient<S extends QuerySchema> = Connected<S> & {
|
|
56
|
+
/**
|
|
57
|
+
* Forces later operations onto the primary or a replica.
|
|
58
|
+
*
|
|
59
|
+
* @param route - `"primary"` or `"replica"`
|
|
60
|
+
* @returns A client with no `close` and no `using`
|
|
61
|
+
*/
|
|
62
|
+
using(route: RouteName): Omit<Connected<S>, "close">;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Replay position for one replica.
|
|
66
|
+
*
|
|
67
|
+
* Tests supply this over independent databases. The probe still runs `SELECT 1`
|
|
68
|
+
* on the replica's pool. The position does not come from a mocked driver.
|
|
69
|
+
*/
|
|
70
|
+
export type ReplicaState = {
|
|
71
|
+
/**
|
|
72
|
+
* @param endpoint - The replica being probed
|
|
73
|
+
* @returns The replay LSN, or `null` when the replica has not replayed
|
|
74
|
+
*/
|
|
75
|
+
replayLsn(endpoint: {
|
|
76
|
+
readonly name: string;
|
|
77
|
+
}): string | null | Promise<string | null>;
|
|
78
|
+
/**
|
|
79
|
+
* Replay timestamp for a time `maxLag`.
|
|
80
|
+
*
|
|
81
|
+
* Omitted, and with no seam, the probe reads `pg_last_xact_replay_timestamp()`
|
|
82
|
+
* only when `maxLag` is a duration.
|
|
83
|
+
*
|
|
84
|
+
* @param endpoint - The replica being probed
|
|
85
|
+
* @returns A timestamp, or `null` when the replica has not replayed a transaction
|
|
86
|
+
*/
|
|
87
|
+
replayTime?(endpoint: {
|
|
88
|
+
readonly name: string;
|
|
89
|
+
}): Date | string | null | Promise<Date | string | null>;
|
|
90
|
+
};
|
|
91
|
+
/** One replica in `{ primary, replicas }`. A string is a URL with weight 1. */
|
|
92
|
+
export type ReplicaInput = {
|
|
93
|
+
readonly url: string;
|
|
94
|
+
readonly weight?: number;
|
|
95
|
+
readonly name?: string;
|
|
96
|
+
readonly pool?: {
|
|
97
|
+
readonly max?: number;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
/** The first argument of `connect` when it is a topology. */
|
|
101
|
+
export type TopologyInput = {
|
|
102
|
+
readonly primary: string;
|
|
103
|
+
readonly replicas?: readonly (string | ReplicaInput)[];
|
|
104
|
+
};
|
|
105
|
+
/** Options only the topology module reads. */
|
|
106
|
+
export type TopologyOptions = {
|
|
107
|
+
/**
|
|
108
|
+
* Background probe interval. `"1s"` when omitted.
|
|
109
|
+
*
|
|
110
|
+
* `select` chooses among eligible replicas. The default is `"weighted"`.
|
|
111
|
+
* `consistency` is `"session"` (the default) or `"eventual"`. `maxLag` is a
|
|
112
|
+
* duration (`"5s"`, `"500ms"`, `"2m"`) or a size (`"16MB"`, `"512KB"`,
|
|
113
|
+
* `"1GB"`, `"4096B"`). `fallback` is `"primary"` (the default) or `"error"`.
|
|
114
|
+
*/
|
|
115
|
+
readonly routing?: {
|
|
116
|
+
readonly probe?: string | number;
|
|
117
|
+
readonly select?: "weighted" | "roundRobin" | "leastConnections" | "latencyAware" | ((candidates: readonly ReplicaCandidate[], ctx: {
|
|
118
|
+
readonly op: "read";
|
|
119
|
+
}) => ReplicaCandidate | string);
|
|
120
|
+
readonly consistency?: "session" | "eventual";
|
|
121
|
+
readonly fallback?: "primary" | "error";
|
|
122
|
+
readonly maxLag?: string;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Called after an endpoint is chosen.
|
|
126
|
+
*
|
|
127
|
+
* A throw is swallowed. The operation still runs.
|
|
128
|
+
*/
|
|
129
|
+
readonly onRoute?: (event: RouteEvent) => void;
|
|
130
|
+
/** Test seam for replay positions. Omitted, the probe reads `pg_last_wal_replay_lsn()`. */
|
|
131
|
+
readonly replicaState?: ReplicaState;
|
|
132
|
+
};
|
|
133
|
+
/** One endpoint after connect. Tests read this. It is not the query path. */
|
|
134
|
+
export type EndpointView = {
|
|
135
|
+
readonly name: string;
|
|
136
|
+
readonly role: "primary" | "replica";
|
|
137
|
+
readonly weight: number;
|
|
138
|
+
/** `max` passed to the driver. Absent when connect did not set one. */
|
|
139
|
+
readonly max: number | undefined;
|
|
140
|
+
/** Whether `replication.position` was detected on this endpoint. */
|
|
141
|
+
readonly position: boolean;
|
|
142
|
+
readonly circuit: "closed" | "open";
|
|
143
|
+
readonly failures: number;
|
|
144
|
+
readonly replayLsn: string | null;
|
|
145
|
+
/** Delay until the next probe. The primary is 0. */
|
|
146
|
+
readonly nextDelayMs: number;
|
|
147
|
+
};
|
|
148
|
+
/** The topology a client was built with. */
|
|
149
|
+
export type TopologyView = {
|
|
150
|
+
readonly endpoints: readonly EndpointView[];
|
|
151
|
+
};
|
|
152
|
+
/** Fields each driver's `open` may read. Extra keys are ignored by that driver. */
|
|
153
|
+
type EndpointConfig = {
|
|
154
|
+
readonly url: string;
|
|
155
|
+
readonly dataDir: string;
|
|
156
|
+
readonly max?: number;
|
|
157
|
+
readonly timeouts?: DriverTimeouts;
|
|
158
|
+
readonly prepared?: "named" | "unnamed";
|
|
159
|
+
readonly searchPath?: string;
|
|
160
|
+
readonly ssl?: unknown;
|
|
161
|
+
};
|
|
162
|
+
/** Opens one endpoint. postgres.js reads `url`. PGlite reads `dataDir`. */
|
|
163
|
+
export type EndpointOpen = (config: EndpointConfig) => DriverPool | Promise<DriverPool>;
|
|
164
|
+
/**
|
|
165
|
+
* Opens one pool per endpoint, detects `replication.position`, and starts replica probes.
|
|
166
|
+
*
|
|
167
|
+
* An automatic read runs the selection pipeline and `routing.select`.
|
|
168
|
+
* `close()` stops the probes and closes every pool this call opened,
|
|
169
|
+
* including clients from `using`.
|
|
170
|
+
*
|
|
171
|
+
* @param target - `{ primary, replicas }`
|
|
172
|
+
* @param options - Schema, pool default, probe interval, and the optional seam
|
|
173
|
+
* @param open - The driver's `open`
|
|
174
|
+
* @returns The client
|
|
175
|
+
*/
|
|
176
|
+
export declare function connectTopology<S extends QuerySchema>(target: object, options: ConnectOptions<S> & TopologyOptions & {
|
|
177
|
+
readonly max?: number;
|
|
178
|
+
readonly prepared?: "named" | "unnamed";
|
|
179
|
+
readonly searchPath?: string;
|
|
180
|
+
readonly ssl?: unknown;
|
|
181
|
+
}, open: EndpointOpen): Promise<RoutedClient<S>>;
|
|
182
|
+
/**
|
|
183
|
+
* Reads the endpoints recorded for a client this module built.
|
|
184
|
+
*
|
|
185
|
+
* A string `connect` has no record. Routing does not call this.
|
|
186
|
+
*
|
|
187
|
+
* @param client - The value `connect` returned
|
|
188
|
+
* @returns The endpoints, or `undefined` when `client` is not a topology client
|
|
189
|
+
*/
|
|
190
|
+
export declare function readTopology(client: object): TopologyView | undefined;
|
|
191
|
+
export default connectTopology;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"../../shared/
|
|
1
|
+
import"../../shared/8bwbwy8h.js";
|
|
2
2
|
import {
|
|
3
3
|
checkPresetNames,
|
|
4
4
|
duplicatePreset
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from "../../shared/n0dgs0pb.js";
|
|
9
9
|
import {
|
|
10
10
|
quoteIdent
|
|
11
|
-
} from "../../shared/
|
|
11
|
+
} from "../../shared/8xsbagad.js";
|
|
12
12
|
import {
|
|
13
13
|
functionObject,
|
|
14
14
|
triggerObject
|
|
@@ -38,10 +38,10 @@ import {
|
|
|
38
38
|
queryHandle,
|
|
39
39
|
attachHttp,
|
|
40
40
|
settleCall
|
|
41
|
-
} from "../../shared/
|
|
41
|
+
} from "../../shared/bt9sfq0z.js";
|
|
42
42
|
import {
|
|
43
43
|
installArchiveInspect
|
|
44
|
-
} from "../../shared/
|
|
44
|
+
} from "../../shared/qgvt8nx1.js";
|
|
45
45
|
import {
|
|
46
46
|
fitIdentifier2
|
|
47
47
|
} from "../../shared/nfzc5z0w.js";
|
|
@@ -58,7 +58,7 @@ function rewriteArchivable(self, tables, casing, schemaTraits, cascade) {
|
|
|
58
58
|
const edges = foreignKeys(tables, casing, byName);
|
|
59
59
|
const archiveSql = casing === "snake" ? "archived_at" : "archivedAt";
|
|
60
60
|
const idSql = casing === "snake" ? "archive_id" : "archiveId";
|
|
61
|
-
const predicate =
|
|
61
|
+
const predicate = casing === "snake" ? "(archived_at IS NULL)" : '("archivedAt" IS NULL)';
|
|
62
62
|
return tables.map((item) => {
|
|
63
63
|
if (!applies(self, item, schemaTraits))
|
|
64
64
|
return item;
|
|
@@ -459,7 +459,7 @@ function refuse(host, table) {
|
|
|
459
459
|
}
|
|
460
460
|
var archiveMod;
|
|
461
461
|
function loadArchive() {
|
|
462
|
-
archiveMod ??= import("../../shared/
|
|
462
|
+
archiveMod ??= import("../../shared/ckjbyrt9.js");
|
|
463
463
|
return archiveMod;
|
|
464
464
|
}
|
|
465
465
|
async function settle(host, table, mods) {
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -99,6 +99,12 @@ export type CallOptions = {
|
|
|
99
99
|
readonly signal?: AbortSignal;
|
|
100
100
|
/** Milliseconds. The call fails as `timeout` when it runs longer. */
|
|
101
101
|
readonly timeout?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Forces this read onto the primary or a replica.
|
|
104
|
+
*
|
|
105
|
+
* Absent, a topology client chooses. A single endpoint serves either value.
|
|
106
|
+
*/
|
|
107
|
+
readonly route?: "primary" | "replica";
|
|
102
108
|
};
|
|
103
109
|
/** Options shared by reads. */
|
|
104
110
|
export type ReadOptions<S extends QuerySchema, K extends keyof S["~byName"]> = CallOptions & {
|
|
@@ -602,6 +608,55 @@ export type TxClient<S extends QuerySchema, Root extends boolean = false> = {
|
|
|
602
608
|
*/
|
|
603
609
|
advisoryLock(key: string | number | bigint, options?: CallOptions): Promise<void>;
|
|
604
610
|
} & TxApi<S, Root>;
|
|
611
|
+
/** A view field: its column name in camel case, as the client publishes it. */
|
|
612
|
+
type CamelName<N extends string> = N extends `_${infer Rest}` ? CamelName<Rest> : N extends `${infer Head}_${infer Tail}` ? `${Head}${Capitalize<CamelName<Tail>>}` : N;
|
|
613
|
+
/** One view row. Every column is decoded as text, so each field is a string or null. */
|
|
614
|
+
type ViewRow<D> = D extends {
|
|
615
|
+
readonly "~columns"?: infer C extends readonly {
|
|
616
|
+
readonly name: string;
|
|
617
|
+
}[];
|
|
618
|
+
} ? {
|
|
619
|
+
readonly [Col in C[number] as CamelName<Col["name"]>]: string | null;
|
|
620
|
+
} : never;
|
|
621
|
+
/** Options `find` and `one` take on a view. */
|
|
622
|
+
type ViewReadOptions<Row> = CallOptions & {
|
|
623
|
+
readonly where?: FieldWhere<Row>;
|
|
624
|
+
readonly select?: readonly (keyof Row & string)[];
|
|
625
|
+
readonly orderBy?: OrderBy<Row>;
|
|
626
|
+
readonly limit?: number;
|
|
627
|
+
};
|
|
628
|
+
/** The read-only handle `db.views` holds for one view. */
|
|
629
|
+
type ViewApi<Row> = {
|
|
630
|
+
find<const O extends ViewReadOptions<Row> & {
|
|
631
|
+
readonly limit: number;
|
|
632
|
+
}>(options: O): Read<readonly Show<Selected<Row, O extends {
|
|
633
|
+
readonly select: infer Sel;
|
|
634
|
+
} ? Sel : undefined>>[]>;
|
|
635
|
+
find<const O extends ViewReadOptions<Row>>(options: O): {
|
|
636
|
+
all(reason: string): Read<readonly Show<Selected<Row, O extends {
|
|
637
|
+
readonly select: infer Sel;
|
|
638
|
+
} ? Sel : undefined>>[]>;
|
|
639
|
+
};
|
|
640
|
+
one<const O extends ViewReadOptions<Row>>(options?: O): Read<Show<Selected<Row, O extends {
|
|
641
|
+
readonly select: infer Sel;
|
|
642
|
+
} ? Sel : undefined>> | null>;
|
|
643
|
+
count(options?: CallOptions & {
|
|
644
|
+
readonly where?: FieldWhere<Row>;
|
|
645
|
+
}): Read<number>;
|
|
646
|
+
exists(options?: CallOptions & {
|
|
647
|
+
readonly where?: FieldWhere<Row>;
|
|
648
|
+
}): Read<boolean>;
|
|
649
|
+
};
|
|
650
|
+
/** `db.views`, typed from `schema({ views })`. Absent when the schema declares none. */
|
|
651
|
+
type ViewsClient<S> = S extends {
|
|
652
|
+
readonly "~views": infer V extends readonly unknown[];
|
|
653
|
+
} ? {
|
|
654
|
+
readonly views: {
|
|
655
|
+
readonly [D in V[number] as D extends {
|
|
656
|
+
readonly name: infer N extends string;
|
|
657
|
+
} ? CamelName<N> : never]: ViewApi<Show<ViewRow<D>>>;
|
|
658
|
+
};
|
|
659
|
+
} : unknown;
|
|
605
660
|
/** A client whose tables are already inside one tenant or an unscoped reason. */
|
|
606
661
|
type ScopedClient<S extends QuerySchema> = {
|
|
607
662
|
readonly [K in keyof S["~byName"] & string]: TableApi<S, K>;
|
|
@@ -612,7 +667,7 @@ type ScopedClient<S extends QuerySchema> = {
|
|
|
612
667
|
close(): Promise<void>;
|
|
613
668
|
/** Resolves when the dialect and `requires` checks have finished. */
|
|
614
669
|
readonly connected: Promise<void>;
|
|
615
|
-
} & TxApi<S, false> & IfAsyncDisposable<typeof Symbol>;
|
|
670
|
+
} & TxApi<S, false> & ViewsClient<S> & IfAsyncDisposable<typeof Symbol>;
|
|
616
671
|
/** `for` and `unscoped` on a schema that set tenancy. */
|
|
617
672
|
type ScopeMethods<S extends QuerySchema> = TenantKeyOf<S> extends never ? object : {
|
|
618
673
|
/**
|
|
@@ -650,7 +705,7 @@ export type Connected<S extends QuerySchema> = {
|
|
|
650
705
|
close(): Promise<void>;
|
|
651
706
|
/** Resolves when the dialect and `requires` checks have finished. */
|
|
652
707
|
readonly connected: Promise<void>;
|
|
653
|
-
} & TxApi<S, true> & ScopeMethods<S> & IfAsyncDisposable<typeof Symbol>;
|
|
708
|
+
} & TxApi<S, true> & ScopeMethods<S> & ViewsClient<S> & IfAsyncDisposable<typeof Symbol>;
|
|
654
709
|
/**
|
|
655
710
|
* A catalog `okm build` wrote.
|
|
656
711
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
withHttp,
|
|
3
3
|
attachHttp
|
|
4
|
-
} from "./
|
|
4
|
+
} from "./bt9sfq0z.js";
|
|
5
5
|
import {
|
|
6
6
|
OkmError2
|
|
7
7
|
} from "./52szzakm.js";
|
|
@@ -31,7 +31,7 @@ async function acceptServer(pool, schema, rows, http, requireMeta, options, sour
|
|
|
31
31
|
}));
|
|
32
32
|
}
|
|
33
33
|
} else {
|
|
34
|
-
const { assertCompatible } = await import("./
|
|
34
|
+
const { assertCompatible } = await import("./z2rnngj4.js");
|
|
35
35
|
try {
|
|
36
36
|
await assertCompatible(pool, schema, recorded, source, options);
|
|
37
37
|
} catch (error) {
|
|
@@ -4,9 +4,11 @@ import {
|
|
|
4
4
|
renameTable2,
|
|
5
5
|
serializeCatalog2,
|
|
6
6
|
catalogHash2,
|
|
7
|
+
startupCatalog2,
|
|
8
|
+
startupHash2,
|
|
7
9
|
loadTrustedCatalog2,
|
|
8
10
|
parseCatalog2
|
|
9
|
-
} from "./
|
|
11
|
+
} from "./8bwbwy8h.js";
|
|
10
12
|
export {
|
|
11
13
|
catalogHash2 as catalogHash,
|
|
12
14
|
creationOrder2 as creationOrder,
|
|
@@ -14,5 +16,7 @@ export {
|
|
|
14
16
|
parseCatalog2 as parseCatalog,
|
|
15
17
|
renameColumn2 as renameColumn,
|
|
16
18
|
renameTable2 as renameTable,
|
|
17
|
-
serializeCatalog2 as serializeCatalog
|
|
19
|
+
serializeCatalog2 as serializeCatalog,
|
|
20
|
+
startupCatalog2 as startupCatalog,
|
|
21
|
+
startupHash2 as startupHash
|
|
18
22
|
};
|
|
@@ -229,6 +229,17 @@ function catalogHash2(source) {
|
|
|
229
229
|
serializedHash.set(source, hash);
|
|
230
230
|
return hash;
|
|
231
231
|
}
|
|
232
|
+
function startupCatalog2(source) {
|
|
233
|
+
if (!source.objects.some(isPrivilege))
|
|
234
|
+
return source;
|
|
235
|
+
return { version: source.version, objects: source.objects.filter((item) => !isPrivilege(item)) };
|
|
236
|
+
}
|
|
237
|
+
function startupHash2(source) {
|
|
238
|
+
return catalogHash2(startupCatalog2(source));
|
|
239
|
+
}
|
|
240
|
+
function isPrivilege(object) {
|
|
241
|
+
return object.kind === "role" || object.kind === "grant" || object.kind === "defaultPrivilege";
|
|
242
|
+
}
|
|
232
243
|
function loadTrustedCatalog2(text, hash) {
|
|
233
244
|
if (sha2562(text) !== hash) {
|
|
234
245
|
catalogError2("OKM1027", "Catalog hash does not match the build artifact.");
|
|
@@ -1444,4 +1455,4 @@ function assertNeverKind(value) {
|
|
|
1444
1455
|
return catalogError2("OKM1020", `Unexpected kind ${JSON.stringify(value)}.`);
|
|
1445
1456
|
}
|
|
1446
1457
|
|
|
1447
|
-
export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, loadTrustedCatalog2, parseCatalog2 };
|
|
1458
|
+
export { roleObject, grantObject, defaultPrivilegeObject, creationOrder2, renameColumn2, renameTable2, serializeCatalog2, catalogHash2, startupCatalog2, startupHash2, loadTrustedCatalog2, parseCatalog2 };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
withHttp
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./bt9sfq0z.js";
|
|
4
4
|
import {
|
|
5
5
|
decodeResult
|
|
6
|
-
} from "./
|
|
6
|
+
} from "./qgvt8nx1.js";
|
|
7
7
|
import {
|
|
8
8
|
OkmError2
|
|
9
9
|
} from "./52szzakm.js";
|
|
@@ -17,7 +17,7 @@ async function* streamRows(session, call, prepare, log) {
|
|
|
17
17
|
})));
|
|
18
18
|
}
|
|
19
19
|
const { plan, params } = await prepare();
|
|
20
|
-
const decode = plan.outputs.includes.length === 0 ? decodeResult : (await import("./
|
|
20
|
+
const decode = plan.outputs.includes.length === 0 ? decodeResult : (await import("./h8ne16fq.js")).decodeIncluded;
|
|
21
21
|
for await (const chunk of session.pool.stream(plan.text, params)) {
|
|
22
22
|
const decoded = decode(plan, chunk, call.table);
|
|
23
23
|
if (!Array.isArray(decoded))
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
open2
|
|
3
3
|
} from "./wqem4jed.js";
|
|
4
|
-
import"./
|
|
4
|
+
import"./8bwbwy8h.js";
|
|
5
5
|
import"./n442h54c.js";
|
|
6
6
|
import {
|
|
7
7
|
assertTargetPolicy,
|
|
8
8
|
selectTarget,
|
|
9
9
|
openProject
|
|
10
|
-
} from "./
|
|
11
|
-
import"./
|
|
12
|
-
import"./
|
|
10
|
+
} from "./xdpj5kkm.js";
|
|
11
|
+
import"./ayz64vzj.js";
|
|
12
|
+
import"./8xsbagad.js";
|
|
13
13
|
import {
|
|
14
14
|
isExactVersion,
|
|
15
15
|
compareExtensionVersions
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
creationOrder2,
|
|
3
3
|
renameColumn2,
|
|
4
4
|
renameTable2
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./8bwbwy8h.js";
|
|
6
6
|
import {
|
|
7
7
|
quoteIdent,
|
|
8
8
|
ownedByView,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
identitySequence,
|
|
16
16
|
createTableSql,
|
|
17
17
|
qualify
|
|
18
|
-
} from "./
|
|
18
|
+
} from "./8xsbagad.js";
|
|
19
19
|
import {
|
|
20
20
|
isExactVersion,
|
|
21
21
|
compareExtensionVersions,
|
|
@@ -122,7 +122,7 @@ function privilegeSql(before, after, schema, recreated = new Set) {
|
|
|
122
122
|
revoke.push({ sql: grantStatement(object, schema, true), kind: "revoke" });
|
|
123
123
|
}
|
|
124
124
|
if (object.kind === "defaultPrivilege") {
|
|
125
|
-
revoke.push({ sql: defaultStatement(object, true), kind: "revoke-default" });
|
|
125
|
+
revoke.push({ sql: defaultStatement(object, schema, true), kind: "revoke-default" });
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
for (const [key, object] of afterBy) {
|
|
@@ -151,7 +151,7 @@ function privilegeSql(before, after, schema, recreated = new Set) {
|
|
|
151
151
|
if (previous !== undefined)
|
|
152
152
|
continue;
|
|
153
153
|
if (object.kind === "defaultPrivilege") {
|
|
154
|
-
defaults.push({ sql: defaultStatement(object, false), kind: "grant-default" });
|
|
154
|
+
defaults.push({ sql: defaultStatement(object, schema, false), kind: "grant-default" });
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
return { revoke, prepare: [...roles, ...defaults], grant };
|
|
@@ -163,6 +163,9 @@ function createdRoleName(sql) {
|
|
|
163
163
|
return quoted.replaceAll('""', '"');
|
|
164
164
|
return match?.[2];
|
|
165
165
|
}
|
|
166
|
+
function createRoleOnce(sql) {
|
|
167
|
+
return `do $okm$ begin ${sql}; exception when duplicate_object or unique_violation then null; end $okm$`;
|
|
168
|
+
}
|
|
166
169
|
function changesRole(sql) {
|
|
167
170
|
return /^\s*(create|alter)\s+role\b/i.test(sql);
|
|
168
171
|
}
|
|
@@ -195,13 +198,12 @@ function grantStatement(object, schema, revoke) {
|
|
|
195
198
|
const direction = revoke ? "from" : "to";
|
|
196
199
|
return `${verb} ${privilege} on ${grantTarget(object.identity.object, schema)} ${direction} ${quoteIdent(object.identity.role)}`;
|
|
197
200
|
}
|
|
198
|
-
function defaultStatement(object, revoke) {
|
|
201
|
+
function defaultStatement(object, schema, revoke) {
|
|
199
202
|
const privilege = object.identity.privilege.toLowerCase();
|
|
200
203
|
assertPrivilege(privilege);
|
|
201
204
|
const verb = revoke ? "revoke" : "grant";
|
|
202
205
|
const direction = revoke ? "from" : "to";
|
|
203
|
-
|
|
204
|
-
return `alter default privileges for role ${quoteIdent(object.identity.forRole)} in schema ${quoteIdent(namespace)} ${verb} ${privilege} on ${objectKindSql(object.identity.objectKind)} ${direction} ${quoteIdent(object.identity.grantee)}`;
|
|
206
|
+
return `alter default privileges for role ${quoteIdent(object.identity.forRole)} in schema ${quoteIdent(schema)} ${verb} ${privilege} on ${objectKindSql(object.identity.objectKind)} ${direction} ${quoteIdent(object.identity.grantee)}`;
|
|
205
207
|
}
|
|
206
208
|
function grantTargetKey(object) {
|
|
207
209
|
if (object.kind === "table" || object.kind === "view" || object.kind === "materializedView" || object.kind === "sequence") {
|
|
@@ -222,14 +224,13 @@ function grantTargetKey(object) {
|
|
|
222
224
|
});
|
|
223
225
|
}
|
|
224
226
|
function grantTarget(object, schema) {
|
|
225
|
-
const name = object.namespace.form === "static" ? object.namespace.name : schema;
|
|
226
227
|
if (object.kind === "sequence")
|
|
227
|
-
return `sequence ${qualify(
|
|
228
|
+
return `sequence ${qualify(schema, object.name)}`;
|
|
228
229
|
if (object.kind === "function")
|
|
229
|
-
return functionTarget(object.name,
|
|
230
|
+
return functionTarget(object.name, schema);
|
|
230
231
|
if (object.kind === "namespace")
|
|
231
232
|
return `schema ${quoteIdent(object.name)}`;
|
|
232
|
-
return `table ${qualify(
|
|
233
|
+
return `table ${qualify(schema, object.name)}`;
|
|
233
234
|
}
|
|
234
235
|
function functionTarget(name, schema) {
|
|
235
236
|
const open = name.lastIndexOf("(");
|
|
@@ -2428,4 +2429,4 @@ function order(value) {
|
|
|
2428
2429
|
return value;
|
|
2429
2430
|
}
|
|
2430
2431
|
|
|
2431
|
-
export { canonicalTypeName, createdRoleName, changesRole, DEFAULT_BACKFILL_PAUSE_MS, DEFAULT_BACKFILL_STATEMENT_TIMEOUT_MS, batchSizeField, aboutBatchCount, boundaryQuery, checkedCast, classOf, strictestClass, assertExtensionsAvailable, omitManagedObjects, parseReplace, planMigration, formatPlan, parsePlan, staleRenames };
|
|
2432
|
+
export { canonicalTypeName, createdRoleName, createRoleOnce, changesRole, DEFAULT_BACKFILL_PAUSE_MS, DEFAULT_BACKFILL_STATEMENT_TIMEOUT_MS, batchSizeField, aboutBatchCount, boundaryQuery, checkedCast, classOf, strictestClass, assertExtensionsAvailable, omitManagedObjects, parseReplace, planMigration, formatPlan, parsePlan, staleRenames };
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
decodeResult,
|
|
8
8
|
logicalIntent,
|
|
9
9
|
appliedRules
|
|
10
|
-
} from "./
|
|
10
|
+
} from "./qgvt8nx1.js";
|
|
11
11
|
import {
|
|
12
12
|
OkmError2,
|
|
13
13
|
safe2,
|
|
@@ -72,7 +72,7 @@ function openClient(session) {
|
|
|
72
72
|
},
|
|
73
73
|
close,
|
|
74
74
|
connected: session.connected,
|
|
75
|
-
tx: (...args) => import("./
|
|
75
|
+
tx: (...args) => import("./k7cc9nzk.js").then((mod) => mod.tx(session, args)),
|
|
76
76
|
batch: (ops, options) => batchHandle(session, ops, options),
|
|
77
77
|
...session.tx?.extras
|
|
78
78
|
};
|
|
@@ -107,7 +107,7 @@ function tableApi(session, table, view, uses) {
|
|
|
107
107
|
const api = {
|
|
108
108
|
find(options = {}) {
|
|
109
109
|
if ("lock" in options) {
|
|
110
|
-
return lazyRead(session, () => import("./
|
|
110
|
+
return lazyRead(session, () => import("./dxjp14rk.js"), table, options, base, view);
|
|
111
111
|
}
|
|
112
112
|
return start(session, "find", table, options, base, view);
|
|
113
113
|
},
|
|
@@ -121,10 +121,10 @@ function tableApi(session, table, view, uses) {
|
|
|
121
121
|
return start(session, "exists", table, options, base, view);
|
|
122
122
|
},
|
|
123
123
|
page(options) {
|
|
124
|
-
return lazyRead(session, () => import("./
|
|
124
|
+
return lazyRead(session, () => import("./h4nqvjkp.js"), table, options, base, view);
|
|
125
125
|
},
|
|
126
126
|
aggregate(options = {}) {
|
|
127
|
-
return lazyRead(session, () => import("./
|
|
127
|
+
return lazyRead(session, () => import("./r6pj4fq2.js"), table, options, base, view);
|
|
128
128
|
},
|
|
129
129
|
insert(data, options = {}) {
|
|
130
130
|
return writeHandle(session, "insert", table, data, options, mods);
|
|
@@ -154,13 +154,13 @@ function tableApi(session, table, view, uses) {
|
|
|
154
154
|
return api;
|
|
155
155
|
}
|
|
156
156
|
function batchHandle(session, ops, options, replica) {
|
|
157
|
-
return queryHandle(() => import("./
|
|
157
|
+
return queryHandle(() => import("./xsq7v6wp.js").then((mod) => mod.batch(session, ops, options, replica)), {
|
|
158
158
|
replica: () => batchHandle(session, ops, options, true)
|
|
159
159
|
});
|
|
160
160
|
}
|
|
161
161
|
var writers;
|
|
162
162
|
function loadWrite() {
|
|
163
|
-
writers ??= import("./
|
|
163
|
+
writers ??= import("./p7pfx624.js");
|
|
164
164
|
return writers;
|
|
165
165
|
}
|
|
166
166
|
function queryHandle(run, extra) {
|
|
@@ -245,7 +245,7 @@ function lazyRead(session, load, table, options, mods, view) {
|
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
247
|
async function decodeRows(plan, rows, table) {
|
|
248
|
-
return plan.outputs.includes.length === 0 ? decodeResult(plan, rows, table) : (await import("./
|
|
248
|
+
return plan.outputs.includes.length === 0 ? decodeResult(plan, rows, table) : (await import("./h8ne16fq.js")).decodeIncluded(plan, rows, table);
|
|
249
249
|
}
|
|
250
250
|
function readHandle(session, table, call, mods, decode, extra) {
|
|
251
251
|
let prepared;
|
|
@@ -320,7 +320,7 @@ function readHandle(session, table, call, mods, decode, extra) {
|
|
|
320
320
|
}
|
|
321
321
|
function streamLazy(session, call, prepare) {
|
|
322
322
|
return async function* () {
|
|
323
|
-
const { streamRows } = await import("./
|
|
323
|
+
const { streamRows } = await import("./922qbgnw.js");
|
|
324
324
|
yield* streamRows(session, call, prepare, (error) => logged(session, error));
|
|
325
325
|
}();
|
|
326
326
|
}
|
|
@@ -357,7 +357,7 @@ function readCall(op, table, options, all, scope, model, schema, view) {
|
|
|
357
357
|
};
|
|
358
358
|
}
|
|
359
359
|
async function checkServer(pool, schema, http, requireMeta, options, source) {
|
|
360
|
-
const server = await import("./
|
|
360
|
+
const server = await import("./47xzb9fc.js");
|
|
361
361
|
let rows;
|
|
362
362
|
try {
|
|
363
363
|
const result = await pool.execute(server.versionQuery, undefined, options);
|
|
@@ -386,7 +386,7 @@ function errorFields(error) {
|
|
|
386
386
|
var includeHooks;
|
|
387
387
|
var operatorSql;
|
|
388
388
|
function loadOperatorSql() {
|
|
389
|
-
operatorSql ??= import("./
|
|
389
|
+
operatorSql ??= import("./tq9afp8d.js").then(() => {
|
|
390
390
|
return;
|
|
391
391
|
});
|
|
392
392
|
return operatorSql;
|
|
@@ -394,7 +394,7 @@ function loadOperatorSql() {
|
|
|
394
394
|
function hooksFor(call) {
|
|
395
395
|
if (call.include === undefined)
|
|
396
396
|
return Promise.resolve(undefined);
|
|
397
|
-
includeHooks ??= import("./
|
|
397
|
+
includeHooks ??= import("./h8ne16fq.js").then((mod) => mod.includeHooks);
|
|
398
398
|
return includeHooks;
|
|
399
399
|
}
|
|
400
400
|
function bindNow(schema, call) {
|
|
@@ -426,11 +426,13 @@ function attachHttp(http, error) {
|
|
|
426
426
|
}
|
|
427
427
|
function callOptions(input, statement) {
|
|
428
428
|
const timeout = input.timeout ?? statement;
|
|
429
|
-
|
|
429
|
+
const route = input.route;
|
|
430
|
+
if (input.signal === undefined && timeout === undefined && route === undefined)
|
|
430
431
|
return;
|
|
431
432
|
return {
|
|
432
433
|
...input.signal !== undefined ? { signal: input.signal } : {},
|
|
433
|
-
...timeout !== undefined ? { timeout } : {}
|
|
434
|
+
...timeout !== undefined ? { timeout } : {},
|
|
435
|
+
...route !== undefined ? { route } : {}
|
|
434
436
|
};
|
|
435
437
|
}
|
|
436
438
|
function mapOptions(http, includeValues) {
|