okmodel 0.1.0 → 0.2.1
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 +237 -19
- package/dist/adapters/capabilities.d.ts +34 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +17 -0
- package/dist/adapters/pg/bunsql.d.ts +60 -0
- package/dist/adapters/pg/call.d.ts +2 -12
- package/dist/adapters/pg/nodepostgres-extra.d.ts +18 -0
- package/dist/adapters/pg/nodepostgres.d.ts +57 -0
- package/dist/adapters/pg/postgres-extra.d.ts +50 -1
- package/dist/adapters/pg/postgresjs.d.ts +0 -4
- package/dist/adapters/pg/session.d.ts +94 -0
- package/dist/adapters/pg/watch.d.ts +18 -0
- package/dist/contracts/catalog/object.d.ts +1 -0
- package/dist/contracts/catalog/types.d.ts +15 -8
- package/dist/contracts/connection.d.ts +13 -0
- package/dist/contracts/driver.d.ts +18 -5
- package/dist/contracts/error.d.ts +17 -1
- package/dist/contracts/generator.d.ts +63 -0
- package/dist/contracts/index.d.ts +2 -2
- package/dist/contracts/index.js +1 -1
- package/dist/contracts/internal.js +11 -9
- package/dist/contracts/location.d.ts +24 -0
- package/dist/contracts/rows.d.ts +15 -0
- package/dist/dialects/pg/archive-bind.d.ts +22 -0
- package/dist/dialects/pg/column.d.ts +126 -9
- package/dist/dialects/pg/compile.d.ts +1 -0
- package/dist/dialects/pg/custom.d.ts +6 -0
- package/dist/dialects/pg/filter-parse.d.ts +19 -0
- package/dist/dialects/pg/filters.d.ts +19 -0
- package/dist/dialects/pg/index.d.ts +11 -2
- package/dist/dialects/pg/index.js +159 -1063
- package/dist/dialects/pg/keys.d.ts +19 -3
- package/dist/dialects/pg/model.d.ts +223 -2
- package/dist/dialects/pg/operator-fit.d.ts +86 -0
- package/dist/dialects/pg/operators.d.ts +39 -1
- package/dist/dialects/pg/ops/arr-append.d.ts +9 -0
- package/dist/dialects/pg/ops/arr-ns.d.ts +7 -0
- package/dist/dialects/pg/ops/arr-remove.d.ts +9 -0
- package/dist/dialects/pg/ops/containedBy.d.ts +9 -0
- package/dist/dialects/pg/ops/contains.d.ts +8 -4
- package/dist/dialects/pg/ops/hasAnyKey.d.ts +8 -0
- package/dist/dialects/pg/ops/hasKey.d.ts +8 -0
- package/dist/dialects/pg/ops/json-ns.d.ts +6 -0
- package/dist/dialects/pg/ops/json-set.d.ts +12 -0
- package/dist/dialects/pg/ops/matches.d.ts +16 -0
- package/dist/dialects/pg/ops/overlaps.d.ts +9 -0
- package/dist/dialects/pg/ops/path.d.ts +13 -0
- package/dist/dialects/pg/preset.d.ts +76 -0
- package/dist/dialects/pg/relations.d.ts +59 -2
- package/dist/dialects/pg/schema.d.ts +109 -5
- package/dist/dialects/pg/table.d.ts +130 -11
- package/dist/dialects/pg/temporal.d.ts +9 -7
- package/dist/dialects/pg/tenancy.d.ts +94 -0
- package/dist/dialects/pg/through.d.ts +21 -0
- package/dist/dialects/pg/trait.d.ts +141 -0
- package/dist/dialects/pg/where.d.ts +37 -0
- package/dist/runtime/aggregate.d.ts +25 -0
- package/dist/runtime/archive-handle.d.ts +18 -0
- package/dist/runtime/archive-rules.d.ts +12 -0
- package/dist/runtime/archive.d.ts +73 -0
- package/dist/runtime/batch.d.ts +20 -0
- package/dist/runtime/client.d.ts +114 -5
- package/dist/runtime/conflict.d.ts +2 -1
- package/dist/runtime/exposure.d.ts +27 -0
- package/dist/runtime/hookm.d.ts +39 -0
- package/dist/runtime/ids/index.d.ts +11 -0
- package/dist/runtime/ids/index.js +193 -0
- package/dist/runtime/ids/okid-extended.d.ts +19 -0
- package/dist/runtime/ids/okid-generator.d.ts +21 -0
- package/dist/runtime/ids/okid-shared.d.ts +89 -0
- package/dist/runtime/ids/okid.d.ts +24 -0
- package/dist/runtime/ids/uuid.d.ts +21 -0
- package/dist/runtime/lock.d.ts +22 -0
- package/dist/runtime/operator-sql.d.ts +8 -0
- package/dist/runtime/page.d.ts +25 -0
- package/dist/runtime/pg/bun.d.ts +30 -0
- package/dist/runtime/pg/bun.js +52 -0
- package/dist/runtime/pg/pg.d.ts +29 -0
- package/dist/runtime/pg/pg.js +52 -0
- package/dist/runtime/pg/pglite.js +16 -17
- package/dist/runtime/pg/postgresjs.js +14 -24
- package/dist/runtime/plan.d.ts +146 -7
- package/dist/runtime/preset-stack.d.ts +17 -0
- package/dist/runtime/presets.d.ts +48 -0
- package/dist/runtime/read-stream.d.ts +26 -0
- package/dist/runtime/safety/index.d.ts +159 -0
- package/dist/runtime/safety/index.js +294 -0
- package/dist/runtime/safety-hook.d.ts +42 -0
- package/dist/runtime/server-check.d.ts +34 -0
- package/dist/runtime/tenancy/index.d.ts +37 -0
- package/dist/runtime/tenancy/index.js +365 -0
- package/dist/runtime/trait-read.d.ts +30 -0
- package/dist/runtime/traits/index.d.ts +128 -0
- package/dist/runtime/traits/index.js +509 -0
- package/dist/runtime/transaction.d.ts +19 -0
- package/dist/runtime/tx.d.ts +22 -7
- package/dist/runtime/types.d.ts +390 -25
- package/dist/runtime/validate/bind.d.ts +11 -0
- package/dist/runtime/validate/closed.d.ts +16 -0
- package/dist/runtime/validate/engine.d.ts +41 -0
- package/dist/runtime/validate/hook.d.ts +17 -0
- package/dist/runtime/validate/index.d.ts +21 -0
- package/dist/runtime/validate/index.js +175 -0
- package/dist/runtime/validate/load.d.ts +13 -0
- package/dist/runtime/validate/places.d.ts +41 -0
- package/dist/runtime/validate/rules.d.ts +108 -0
- package/dist/runtime/validate/surface.d.ts +102 -0
- package/dist/runtime/write.d.ts +30 -5
- package/dist/shared/{fgqgsb5z.js → 0qkxbm1f.js} +2 -2
- package/dist/shared/0v1g424p.js +26 -0
- package/dist/shared/10tjenmd.js +210 -0
- package/dist/shared/{tb4ze1tr.js → 1dp5knt7.js} +95 -10
- package/dist/shared/38crxbgn.js +229 -0
- package/dist/shared/3a5ne750.js +158 -0
- package/dist/shared/4b9da9d7.js +138 -0
- package/dist/shared/4e4c6vq2.js +62 -0
- package/dist/shared/{ckb1p0a4.js → 4jzzghr6.js} +416 -83
- package/dist/shared/{ycwz42az.js → 52szzakm.js} +6 -26
- package/dist/shared/{kynx7vbm.js → 5z4q2zda.js} +604 -21
- package/dist/shared/672t5vym.js +12 -0
- package/dist/shared/7m88x3e9.js +45 -0
- package/dist/shared/7mht49yd.js +1091 -0
- package/dist/shared/{mtkwv8wx.js → 7p2wbz7f.js} +1 -1
- package/dist/shared/83eaefwr.js +10 -0
- package/dist/shared/96ps4g1z.js +32 -0
- package/dist/shared/97g2jnrw.js +76 -0
- package/dist/shared/{xy79j5hq.js → 9k6vetvf.js} +25 -36
- package/dist/shared/{w8samvk1.js → a1gdp7j9.js} +1 -1
- package/dist/shared/a5sxz52y.js +13 -0
- package/dist/shared/{dynq16vb.js → b066g80h.js} +8 -6
- package/dist/shared/cstgkzdx.js +154 -0
- package/dist/shared/{ax16zpvm.js → d04j53v8.js} +6 -5
- package/dist/shared/{y9m15dfv.js → d2whjz4k.js} +15 -9
- package/dist/shared/dd4f8mnx.js +307 -0
- package/dist/shared/e6wg00wd.js +164 -0
- package/dist/shared/e7a268fy.js +195 -0
- package/dist/shared/{vkm3q4x1.js → eaxwrgby.js} +4 -3
- package/dist/shared/{7ck0dtry.js → ecdzej21.js} +160 -81
- package/dist/shared/{px90pf9p.js → edwqqryd.js} +21 -16
- package/dist/shared/{g2v6gnc8.js → eqmtn1bj.js} +57 -5
- package/dist/shared/g1b5zzj9.js +75 -0
- package/dist/shared/g9f0zqce.js +376 -0
- package/dist/shared/ge03bfca.js +64 -0
- package/dist/shared/{79ggp945.js → jns2wx4t.js} +55 -12
- package/dist/shared/k3ted12y.js +33 -0
- package/dist/shared/k7dwkhvq.js +31 -0
- package/dist/shared/{hd293j9g.js → kyxb62mc.js} +14 -2
- package/dist/shared/m9tv7xn7.js +404 -0
- package/dist/shared/mrq77sgw.js +55 -0
- package/dist/shared/mxmcdsh5.js +450 -0
- package/dist/shared/n442h54c.js +14 -0
- package/dist/shared/n47rd821.js +442 -0
- package/dist/shared/n4jqhpqz.js +27 -0
- package/dist/shared/{mkjmqjv4.js → nfzc5z0w.js} +2 -104
- package/dist/shared/nsva2a6b.js +42 -0
- package/dist/shared/ps43134h.js +69 -0
- package/dist/shared/{8b04d28c.js → py3nh7jy.js} +2 -2
- package/dist/shared/qa5dsc7z.js +86 -0
- package/dist/shared/{g5fhqmwe.js → qxa0yb9j.js} +6 -4
- package/dist/shared/r6nwkxnt.js +86 -0
- package/dist/shared/{4j72449d.js → rtnaqre0.js} +3 -3
- package/dist/shared/rwmrejjz.js +26 -0
- package/dist/shared/{zhc5vmgf.js → s6gqfn5j.js} +2 -2
- package/dist/shared/sacqha1y.js +70 -0
- package/dist/shared/{qk3hxfja.js → sfh4pk75.js} +5 -5
- package/dist/shared/{j5cn2963.js → t4tbsy9h.js} +13 -64
- package/dist/shared/{ngk8gj61.js → tbszx8mz.js} +15 -1
- package/dist/shared/v18jva5b.js +90 -0
- package/dist/shared/x9v1qgeb.js +201 -0
- package/dist/shared/xatfg0gn.js +193 -0
- package/dist/shared/xkz8g6by.js +225 -0
- package/dist/shared/{f5thc1s0.js → xrfnq5k8.js} +237 -418
- package/dist/shared/ytg3xf9p.js +149 -0
- package/dist/shared/yw5c610b.js +48 -0
- package/dist/shared/zd93g3rq.js +31 -0
- package/dist/shared/zt8y0wzb.js +132 -0
- package/dist/shared/{p0cbr3g2.js → zwmqxb0g.js} +1 -1
- package/dist/tooling/cli.js +14 -10
- package/dist/tooling/migrate/commands.d.ts +10 -0
- package/dist/tooling/migrate/engine.d.ts +36 -0
- package/package.json +56 -4
- package/dist/shared/gk7cs7sp.js +0 -566
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trait values `schema()` applies.
|
|
3
|
+
*
|
|
4
|
+
* The timestamp columns and their clock live in `okmodel/traits`. This module
|
|
5
|
+
* only reads the object a schema passes in, so an application that never
|
|
6
|
+
* imports a trait does not load that code.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Columns an archivable trait asks `schema()` to keep.
|
|
10
|
+
*
|
|
11
|
+
* `at` and `id` are field names. `cascade` names child tables archived and
|
|
12
|
+
* restored with the row. The trait's rewrite makes uniques partial and checks
|
|
13
|
+
* the cascade. Absent means the table is not archivable.
|
|
14
|
+
*/
|
|
15
|
+
export type ArchiveRequest = {
|
|
16
|
+
readonly at: string;
|
|
17
|
+
readonly id: string;
|
|
18
|
+
readonly cascade: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Columns `schema()` passes to {@link Trait.apply}.
|
|
22
|
+
*
|
|
23
|
+
* `columns` starts as the table's own fields. `apply` adds the trait's fields
|
|
24
|
+
* or throws OKM1012 when a name is already there. `archive` is set by
|
|
25
|
+
* `archivable()` and read once, after every trait has applied.
|
|
26
|
+
*/
|
|
27
|
+
export type TraitModel = {
|
|
28
|
+
columns: Record<string, object>;
|
|
29
|
+
archive?: ArchiveRequest;
|
|
30
|
+
/**
|
|
31
|
+
* Presets collected so far: the table's own first, then each trait's.
|
|
32
|
+
*
|
|
33
|
+
* Starts as the table's own object. A trait copies it before adding, so the
|
|
34
|
+
* author's object is never changed.
|
|
35
|
+
*/
|
|
36
|
+
presets?: Readonly<Record<string, unknown>> | undefined;
|
|
37
|
+
/** Trait that added each preset. A name missing here is the table's own. */
|
|
38
|
+
presetFrom?: Record<string, string>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The table `apply` is adding columns to.
|
|
42
|
+
*/
|
|
43
|
+
export type TraitContext = {
|
|
44
|
+
readonly table: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Columns and write rules a trait contributes.
|
|
48
|
+
*
|
|
49
|
+
* `fields` are real columns. `touch` columns are set to `now()` on update.
|
|
50
|
+
* `sealed` columns cannot be set from input, including `{ allow }`.
|
|
51
|
+
* A touched column is sealed. `apply` is the trait's own merge. `schema()`
|
|
52
|
+
* only calls it.
|
|
53
|
+
*/
|
|
54
|
+
export type Trait = {
|
|
55
|
+
readonly name: string;
|
|
56
|
+
readonly fields: Readonly<Record<string, object>>;
|
|
57
|
+
readonly touch?: readonly string[];
|
|
58
|
+
readonly sealed?: readonly string[];
|
|
59
|
+
/** Presets the trait adds to every table it applies to. */
|
|
60
|
+
readonly presets?: Readonly<Record<string, unknown>>;
|
|
61
|
+
/**
|
|
62
|
+
* Adds this trait's columns to one table.
|
|
63
|
+
*
|
|
64
|
+
* @param model - Columns collected so far
|
|
65
|
+
* @param ctx - Table name, for OKM1012
|
|
66
|
+
*/
|
|
67
|
+
apply(model: TraitModel, ctx: TraitContext): void;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Field maps of every trait in a list, as one object.
|
|
71
|
+
*
|
|
72
|
+
* An empty list contributes no fields. The field types stay on the value
|
|
73
|
+
* `trait()` returned; this reads them back.
|
|
74
|
+
*
|
|
75
|
+
* @typeParam TTraits - Trait list
|
|
76
|
+
*/
|
|
77
|
+
export type FieldsOfList<TTraits> = TTraits extends readonly [] ? Record<never, never> : TTraits extends readonly (infer TItem)[] ? UnionToIntersection<TItem extends {
|
|
78
|
+
readonly fields: infer TFields;
|
|
79
|
+
} ? TFields : Record<never, never>> : Record<never, never>;
|
|
80
|
+
/**
|
|
81
|
+
* `{ "~archive": true }` when a trait list includes `archivable()`.
|
|
82
|
+
*
|
|
83
|
+
* An empty match contributes `unknown`, so a table without the trait does
|
|
84
|
+
* not gain the key.
|
|
85
|
+
*
|
|
86
|
+
* @typeParam TTraits - Trait list, or a single trait object
|
|
87
|
+
*/
|
|
88
|
+
export type HasArchive<TTraits> = [
|
|
89
|
+
Extract<TTraits extends readonly (infer TItem)[] ? TItem : TTraits, {
|
|
90
|
+
readonly "~archive": true;
|
|
91
|
+
}>
|
|
92
|
+
] extends [never] ? unknown : {
|
|
93
|
+
readonly "~archive": true;
|
|
94
|
+
};
|
|
95
|
+
/** The `presets` maps of a trait list, as a union. Empty when no trait has any. */
|
|
96
|
+
type TraitPresetUnion<TTraits> = TTraits extends readonly (infer TItem)[] ? TItem extends {
|
|
97
|
+
readonly presets: infer TPresets;
|
|
98
|
+
} ? TPresets : never : never;
|
|
99
|
+
/**
|
|
100
|
+
* `{ "~presets": ... }` when a trait list adds presets, joined into one map.
|
|
101
|
+
*
|
|
102
|
+
* Nothing is added otherwise, so a table without trait presets keeps its type.
|
|
103
|
+
*
|
|
104
|
+
* @typeParam TTraits - Trait list
|
|
105
|
+
*/
|
|
106
|
+
export type PresetsOfList<TTraits> = [TraitPresetUnion<TTraits>] extends [never] ? unknown : {
|
|
107
|
+
readonly "~presets": UnionToIntersection<TraitPresetUnion<TTraits>>;
|
|
108
|
+
};
|
|
109
|
+
type UnionToIntersection<TUnion> = (TUnion extends unknown ? (argument: TUnion) => void : never) extends (argument: infer TIntersection) => void ? TIntersection : never;
|
|
110
|
+
/** A trait object before `trait()` attaches `apply`. */
|
|
111
|
+
type CheckedTrait = {
|
|
112
|
+
readonly name: string;
|
|
113
|
+
readonly fields: Readonly<Record<string, object>>;
|
|
114
|
+
readonly touch?: readonly string[];
|
|
115
|
+
readonly sealed?: readonly string[];
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Checks one trait object.
|
|
119
|
+
*
|
|
120
|
+
* `methods` and `requires` are part of the type and rejected until the
|
|
121
|
+
* prompt that implements them.
|
|
122
|
+
*
|
|
123
|
+
* @param value - One entry of a traits list
|
|
124
|
+
* @param where - `schema()` or the table name, for the error
|
|
125
|
+
* @returns The same object when it is a trait
|
|
126
|
+
*/
|
|
127
|
+
export declare function checkTrait(value: unknown, where: string): CheckedTrait;
|
|
128
|
+
/**
|
|
129
|
+
* Trait field builders that apply to one table, in catalog order.
|
|
130
|
+
*
|
|
131
|
+
* `emitRowTypes` uses this. `schema()` has already rejected a conflict.
|
|
132
|
+
*
|
|
133
|
+
* @param schemaTraits - Traits stored on the built schema
|
|
134
|
+
* @param options - This table's `traits` and `omitDefaults`
|
|
135
|
+
* @returns Field name and builder pairs. Empty when the table has no traits
|
|
136
|
+
*/
|
|
137
|
+
export declare function contributedFields(schemaTraits: readonly Trait[] | undefined, options: {
|
|
138
|
+
readonly traits?: readonly Trait[];
|
|
139
|
+
readonly omitDefaults?: string;
|
|
140
|
+
} | undefined): readonly (readonly [string, object])[];
|
|
141
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where-value types shared by the client and by presets.
|
|
3
|
+
*
|
|
4
|
+
* They sit in the dialect layer so `table({ presets })` can type a preset's
|
|
5
|
+
* `where` without importing the client types. `runtime/types.ts` re-exports
|
|
6
|
+
* the two names callers use.
|
|
7
|
+
*/
|
|
8
|
+
import type { Between, Compare, Containment, Eq, HasAnyKey, HasKey, InList, Matches, Not, NotIn, Overlaps, Path, Pattern, RawPattern } from "./operators.js";
|
|
9
|
+
import type { Range } from "./range.js";
|
|
10
|
+
export type IsObject<V> = V extends object ? V extends readonly unknown[] ? false : null extends V ? false : true : false;
|
|
11
|
+
/** Text patterns, including substring `contains`. `matches` is for tsvector, which is also `string`. */
|
|
12
|
+
type TextOps = Pattern<"startsWith"> | Pattern<"contains"> | Pattern<"endsWith"> | RawPattern<"like"> | RawPattern<"ilike"> | Matches;
|
|
13
|
+
/** Array, jsonb, or range containment, plus overlap where that operator fits. */
|
|
14
|
+
type StructuredOps<V> = Containment<"contains" | "containedBy", V> | Overlaps<V>;
|
|
15
|
+
/** A JSON fragment. Containment matches part of a document, not the whole column type. */
|
|
16
|
+
type JsonFragment = string | number | boolean | null | readonly JsonFragment[] | {
|
|
17
|
+
readonly [key: string]: JsonFragment;
|
|
18
|
+
};
|
|
19
|
+
/** jsonb and json filters. `hasKey` is rejected at runtime on json. */
|
|
20
|
+
type JsonOps = Containment<"contains" | "containedBy", JsonFragment> | HasKey | HasAnyKey | Path<string> | Path<number> | Path<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* A plain object that can be json or jsonb.
|
|
23
|
+
*
|
|
24
|
+
* Arrays, ranges, and bytea are not json. Timestamp values are objects too, and
|
|
25
|
+
* the Temporal declarations are structural, so a timestamp column is rejected
|
|
26
|
+
* at runtime (OKM1124) rather than here.
|
|
27
|
+
*/
|
|
28
|
+
export type IsJsonObject<V> = V extends readonly unknown[] ? false : V extends Range<unknown> ? false : V extends Uint8Array ? false : IsObject<V>;
|
|
29
|
+
/** Operators the column value type can accept. `unknown` keeps every family and the runtime decides. */
|
|
30
|
+
type TypedOps<V> = [unknown] extends [V] ? TextOps | StructuredOps<V> | JsonOps : (V extends string ? TextOps : never) | (V extends readonly unknown[] ? StructuredOps<V> : never) | (V extends Range<unknown> ? StructuredOps<V> : never) | (IsJsonObject<V> extends true ? JsonOps : never);
|
|
31
|
+
/** A where operand. Object columns take `eq`, not a bare object. */
|
|
32
|
+
export type WhereValue<V> = V extends unknown ? (IsObject<V> extends true ? never : V) | null | Eq<V> | Compare<"lt", V> | Compare<"lte", V> | Compare<"gt", V> | Compare<"gte", V> | Between<V> | InList<V> | NotIn<V> | Not<V | null | TextOps | InList<V>> | TypedOps<V> : never;
|
|
33
|
+
/** Field filters. Relation filters are one level, so the type does not cycle. */
|
|
34
|
+
export type FieldWhere<Row> = {
|
|
35
|
+
readonly [K in keyof Row]?: WhereValue<Row[K]> | undefined;
|
|
36
|
+
};
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouped aggregates (spec section 10).
|
|
3
|
+
*
|
|
4
|
+
* `count`, `sum`, `avg`, `min`, and `max` over the rows a `where` selects, per
|
|
5
|
+
* `groupBy` group. The statement is written here and the `where` is written by
|
|
6
|
+
* the planner's `emitWhere`, so the tenant and active-set predicates apply to
|
|
7
|
+
* every aggregate exactly as they apply to a `find`. This module loads on the
|
|
8
|
+
* first `aggregate()`.
|
|
9
|
+
*
|
|
10
|
+
* Not here: `having`, `bucket`, and ordering by an aggregate. A hidden column
|
|
11
|
+
* cannot be grouped or aggregated, so an aggregate never shows what a read hides.
|
|
12
|
+
*/
|
|
13
|
+
import { type Mods, type Session } from "./client.js";
|
|
14
|
+
import { type ArchiveView } from "./plan.js";
|
|
15
|
+
/**
|
|
16
|
+
* Builds the handle for one `aggregate()` call.
|
|
17
|
+
*
|
|
18
|
+
* @param session - Client session
|
|
19
|
+
* @param table - Table name
|
|
20
|
+
* @param options - `where`, `groupBy`, the aggregates, `orderBy`, and `limit`
|
|
21
|
+
* @param mods - `.all` reason, signal, and timeout
|
|
22
|
+
* @param view - Archive visibility
|
|
23
|
+
* @returns A handle that resolves to the grouped rows
|
|
24
|
+
*/
|
|
25
|
+
export declare function build(session: Session, table: string, options: object, mods: Mods, view: ArchiveView | undefined): Promise<unknown> & Record<string, unknown>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table methods `archivable()` adds through the shared client hook.
|
|
3
|
+
*
|
|
4
|
+
* Core does not name `archive` or `restore`. A failed import of the statement
|
|
5
|
+
* chunk rejects the call. The active-set predicate stays in the planner.
|
|
6
|
+
*/
|
|
7
|
+
import type { SchemaHookCtx } from "../dialects/pg/model.js";
|
|
8
|
+
/**
|
|
9
|
+
* Adds `archive`, `restore`, `withArchived`, and `onlyArchived` to one table.
|
|
10
|
+
*
|
|
11
|
+
* A table that is not archivable still receives the methods when the schema
|
|
12
|
+
* imported the trait, and a call throws OKM1052. The throw for a missing model
|
|
13
|
+
* is repeated by the statement chunk if execution reaches it.
|
|
14
|
+
*
|
|
15
|
+
* @param target - The table handle being built
|
|
16
|
+
* @param ctx - Table name, visibility, and the session
|
|
17
|
+
*/
|
|
18
|
+
export declare function attachArchive(target: Record<string, unknown>, ctx: SchemaHookCtx): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phrases the archive safety rule reads.
|
|
3
|
+
*
|
|
4
|
+
* Installed by `archivable()`. A schema that does not use the trait does not
|
|
5
|
+
* load this file, and reads record nothing.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Installs the phrase recorder on the planner.
|
|
9
|
+
*
|
|
10
|
+
* Safe to call more than once. The recorder replaces the previous one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function installArchiveContributions(): void;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `archive` and `restore`.
|
|
3
|
+
*
|
|
4
|
+
* Loaded on the first call. A failed import fails that call. The active-set
|
|
5
|
+
* predicate stays in the planner, so a failed import does not show archived rows.
|
|
6
|
+
*/
|
|
7
|
+
import type { QuerySchema } from "../dialects/pg/model.js";
|
|
8
|
+
import { type CallScope } from "./plan.js";
|
|
9
|
+
import { type RunHost } from "./tx.js";
|
|
10
|
+
import type { PreparedWrite } from "./write.js";
|
|
11
|
+
type LifecycleOp = "archive" | "restore";
|
|
12
|
+
type Mods = {
|
|
13
|
+
readonly all?: string;
|
|
14
|
+
readonly expect?: number;
|
|
15
|
+
/** Filters the chained presets added. The archive handle resolves them. */
|
|
16
|
+
readonly presets?: readonly unknown[];
|
|
17
|
+
};
|
|
18
|
+
type Host = RunHost & {
|
|
19
|
+
readonly schema: QuerySchema;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Archives or restores matching rows.
|
|
23
|
+
*
|
|
24
|
+
* One statement. Cascaded children share the `archiveId`. A restore whose
|
|
25
|
+
* parent is still archived changes nothing and fails.
|
|
26
|
+
*
|
|
27
|
+
* @param host - Schema and pool
|
|
28
|
+
* @param op - `archive` or `restore`
|
|
29
|
+
* @param table - Table name
|
|
30
|
+
* @param input - `{ where }` or, for restore, `{ archiveId }`
|
|
31
|
+
* @param options - `expect`, signal, and timeout
|
|
32
|
+
* @param mods - `.all` and `.expect`
|
|
33
|
+
* @param scope - Tenant value, when the schema has tenancy
|
|
34
|
+
* @returns `{ count, archiveId }` or `{ count }`
|
|
35
|
+
*/
|
|
36
|
+
export declare function executeArchive(host: Host, op: LifecycleOp, table: string, input: unknown, options: object, mods: Mods, scope: CallScope | undefined): Promise<{
|
|
37
|
+
readonly count: number;
|
|
38
|
+
readonly archiveId?: string;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Plans archive or restore and returns its statement and the function that decodes the result.
|
|
42
|
+
*
|
|
43
|
+
* `batch` runs the statement with those of other operations.
|
|
44
|
+
*
|
|
45
|
+
* @param schema - Connected schema
|
|
46
|
+
* @param op - `archive` or `restore`
|
|
47
|
+
* @param table - Table name
|
|
48
|
+
* @param input - `{ where }` or `{ archiveId }`
|
|
49
|
+
* @param options - `expect`, signal, and timeout
|
|
50
|
+
* @param mods - `.all` and `.expect`
|
|
51
|
+
* @param scope - Tenant value, when the schema has tenancy
|
|
52
|
+
* @returns The statement, the call options, and `finish`
|
|
53
|
+
*/
|
|
54
|
+
export declare function prepareArchive(schema: QuerySchema, op: LifecycleOp, table: string, input: unknown, options: object, mods: Mods, scope: CallScope | undefined): PreparedWrite;
|
|
55
|
+
/**
|
|
56
|
+
* Plans archive or restore and does not run it.
|
|
57
|
+
*
|
|
58
|
+
* @param schema - Connected schema
|
|
59
|
+
* @param op - `archive` or `restore`
|
|
60
|
+
* @param table - Table name
|
|
61
|
+
* @param input - `{ where }` or `{ archiveId }`
|
|
62
|
+
* @param options - `expect`, signal, and timeout
|
|
63
|
+
* @param mods - `.all` and `.expect`
|
|
64
|
+
* @param scope - Tenant value, when the schema has tenancy
|
|
65
|
+
* @returns The statement
|
|
66
|
+
*/
|
|
67
|
+
export declare function explainArchive(schema: QuerySchema, op: LifecycleOp, table: string, input: unknown, options: object, mods: Mods, scope: CallScope | undefined): {
|
|
68
|
+
readonly statements: readonly {
|
|
69
|
+
readonly text: string;
|
|
70
|
+
readonly params: readonly (string | null)[];
|
|
71
|
+
}[];
|
|
72
|
+
};
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public `batch` (spec §15, batch contract).
|
|
3
|
+
*
|
|
4
|
+
* Plans each operation, joins their statements, and runs them as one atomic
|
|
5
|
+
* unit on the primary. Results come back in the order given. A failure rolls
|
|
6
|
+
* everything back and the error carries `batchIndex`, the failing operation,
|
|
7
|
+
* or `null` when the commit failed. Inside `tx()` the unit is a savepoint, so
|
|
8
|
+
* the transaction survives. Loaded the first time a batch is awaited.
|
|
9
|
+
*/
|
|
10
|
+
import { type Session } from "./client.js";
|
|
11
|
+
/**
|
|
12
|
+
* Runs write handles as one atomic unit.
|
|
13
|
+
*
|
|
14
|
+
* @param session - Client session
|
|
15
|
+
* @param ops - Write handles: `insert`, `update`, `delete`, `archive`. A `restore`, or a write with `expect`, is OKM1121 (D183)
|
|
16
|
+
* @param options - `signal` and `timeout` for the whole batch
|
|
17
|
+
* @param replica - Set by `.replica()`. A batch needs the primary (OKM1840)
|
|
18
|
+
* @returns One result per operation, in order
|
|
19
|
+
*/
|
|
20
|
+
export declare function batch(session: Session, ops: unknown, options: object | undefined, replica: true | undefined): Promise<readonly unknown[]>;
|
package/dist/runtime/client.d.ts
CHANGED
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
* The plan cache is per client and bounded.
|
|
6
6
|
*/
|
|
7
7
|
import type { DriverPool } from "../contracts/driver.js";
|
|
8
|
-
import {
|
|
9
|
-
import type
|
|
10
|
-
import {
|
|
11
|
-
import type
|
|
12
|
-
type
|
|
8
|
+
import type { IdGenerators } from "../contracts/generator.js";
|
|
9
|
+
import { OkmError, type ErrorStatuses, type OkmErrorOptions } from "../contracts/error.js";
|
|
10
|
+
import type { PresetUse, QuerySchema } from "../dialects/pg/model.js";
|
|
11
|
+
import { type ArchiveView, type Plan, type ReadCall, type CallScope, type ReadOp } from "./plan.js";
|
|
12
|
+
import type { CatalogArtifact, Connected, Hookm, Timeouts } from "./types.js";
|
|
13
|
+
/** A client's connection state. The lazy read modules take it. */
|
|
14
|
+
export type Session = {
|
|
13
15
|
readonly schema: QuerySchema;
|
|
14
16
|
readonly pool: DriverPool;
|
|
15
17
|
readonly ownsPool: boolean;
|
|
@@ -23,6 +25,29 @@ type Session = {
|
|
|
23
25
|
} | undefined;
|
|
24
26
|
readonly connected: Promise<void>;
|
|
25
27
|
readonly cache: Map<string, Plan>;
|
|
28
|
+
readonly generators: IdGenerators | undefined;
|
|
29
|
+
/** Ceilings from `connect({ timeouts })`. */
|
|
30
|
+
readonly timeouts: Timeouts | undefined;
|
|
31
|
+
/** Observers from `connect({ hookm })`. */
|
|
32
|
+
readonly hookm: readonly Hookm[] | undefined;
|
|
33
|
+
/** Set on the client a transaction hands out. `extras` are the methods only that client has. */
|
|
34
|
+
readonly tx?: {
|
|
35
|
+
readonly extras: object;
|
|
36
|
+
readonly depth: number;
|
|
37
|
+
};
|
|
38
|
+
/** Tenant value or an unscoped reason. Absent on the root client. */
|
|
39
|
+
readonly scope?: CallScope;
|
|
40
|
+
/** Shared close. `for()` and `unscoped()` reuse the same promise. */
|
|
41
|
+
readonly closing: {
|
|
42
|
+
current: Promise<void> | undefined;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/** Per-call modifiers of a read. */
|
|
46
|
+
export type Mods = {
|
|
47
|
+
readonly all?: string;
|
|
48
|
+
readonly required?: boolean;
|
|
49
|
+
/** Presets chained on the handle. The presets module resolves them on first use. */
|
|
50
|
+
readonly uses?: PresetUse | undefined;
|
|
26
51
|
};
|
|
27
52
|
/**
|
|
28
53
|
* Builds a client for one pool.
|
|
@@ -40,8 +65,92 @@ export declare function createClient<S extends QuerySchema>(schema: S, pool: Dri
|
|
|
40
65
|
readonly logger?: Session["logger"] | undefined;
|
|
41
66
|
readonly signal?: AbortSignal | undefined;
|
|
42
67
|
readonly timeout?: number | undefined;
|
|
68
|
+
readonly timeouts?: Timeouts | undefined;
|
|
69
|
+
readonly hookm?: readonly Hookm[] | undefined;
|
|
43
70
|
readonly catalog?: CatalogArtifact | undefined;
|
|
44
71
|
readonly catalogDir?: string | undefined;
|
|
45
72
|
readonly requireMeta?: boolean | undefined;
|
|
73
|
+
readonly generators?: IdGenerators | undefined;
|
|
46
74
|
}): Connected<S>;
|
|
75
|
+
export declare function openClient<S extends QuerySchema>(session: Session): Connected<S>;
|
|
76
|
+
/**
|
|
77
|
+
* A query handle that starts its work once, the first time it is awaited.
|
|
78
|
+
*
|
|
79
|
+
* @param run - The work. Called at most once
|
|
80
|
+
* @param extra - Methods that stay on the handle beside `then`
|
|
81
|
+
* @returns The handle
|
|
82
|
+
*/
|
|
83
|
+
export declare function queryHandle<T extends object>(run: () => Promise<unknown>, extra: T): Promise<unknown> & T;
|
|
84
|
+
/** A bound plan and its wire parameters. */
|
|
85
|
+
type Prepared = {
|
|
86
|
+
readonly plan: Plan;
|
|
87
|
+
readonly params: readonly (string | null)[];
|
|
88
|
+
};
|
|
89
|
+
/** Rows as the driver returns them. */
|
|
90
|
+
type Rows = readonly (readonly (string | null)[])[];
|
|
91
|
+
/**
|
|
92
|
+
* Decodes the rows of a prepared read, with includes when the plan has them.
|
|
93
|
+
*
|
|
94
|
+
* @param plan - Compiled plan
|
|
95
|
+
* @param rows - Wire rows
|
|
96
|
+
* @param table - Table name, for `not_unique`
|
|
97
|
+
* @returns Rows, one row or null, a count, or a boolean
|
|
98
|
+
*/
|
|
99
|
+
export declare function decodeRows(plan: Plan, rows: Rows, table: string): Promise<unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* A lazy read handle for one planned call.
|
|
102
|
+
*
|
|
103
|
+
* `find`, `one`, `count`, and `exists` use it, and so do the lazy `page` and
|
|
104
|
+
* `aggregate` modules. It plans once, caches the plan per client, maps the
|
|
105
|
+
* error, and offers `inspect` and `sql`.
|
|
106
|
+
*
|
|
107
|
+
* @param session - Client session
|
|
108
|
+
* @param table - Table name
|
|
109
|
+
* @param call - The read
|
|
110
|
+
* @param mods - Signal and timeout
|
|
111
|
+
* @param decode - Turns the wire rows into the result
|
|
112
|
+
* @param extra - Methods that belong to this read, given the memoised prepare
|
|
113
|
+
* @returns The handle
|
|
114
|
+
*/
|
|
115
|
+
export declare function readHandle(session: Session, table: string, call: ReadCall, mods: Mods, decode: (plan: Plan, rows: Rows) => unknown, extra?: (prepare: () => Promise<Prepared>) => Record<string, unknown>): Promise<unknown> & Record<string, unknown>;
|
|
116
|
+
/**
|
|
117
|
+
* Builds the logical read from caller options.
|
|
118
|
+
*
|
|
119
|
+
* @param op - Read kind
|
|
120
|
+
* @param table - Table name
|
|
121
|
+
* @param options - `where`, `select`, `orderBy`, `limit`, `include`
|
|
122
|
+
* @param all - Reason given to `.all`
|
|
123
|
+
* @param scope - Tenant scope, when the client has one
|
|
124
|
+
* @param model - Table model
|
|
125
|
+
* @param schema - Connected schema
|
|
126
|
+
* @param view - Archive visibility
|
|
127
|
+
* @returns The call the planner binds
|
|
128
|
+
*/
|
|
129
|
+
export declare function readCall(op: ReadOp, table: string, options: object, all: string | undefined, scope: CallScope | undefined, model: QuerySchema["model"][string] | undefined, schema: QuerySchema, view?: ArchiveView): ReadCall;
|
|
130
|
+
/**
|
|
131
|
+
* Attaches connect's HTTP statuses to options for one {@link OkmError}.
|
|
132
|
+
*
|
|
133
|
+
* @param http - Statuses from `connect({ errors })`
|
|
134
|
+
* @param options - Error options that do not yet name a status map
|
|
135
|
+
* @returns Options `toHttp()` can read
|
|
136
|
+
*/
|
|
137
|
+
export declare function withHttp(http: ErrorStatuses | undefined, options: OkmErrorOptions): OkmErrorOptions;
|
|
138
|
+
/**
|
|
139
|
+
* Copies `error` so {@link OkmError.toHttp} uses the statuses from `connect`.
|
|
140
|
+
*
|
|
141
|
+
* @param http - Statuses from `connect({ errors })`. Omitted, `error` is returned
|
|
142
|
+
* @param error - Failure that did not carry those statuses
|
|
143
|
+
* @returns The error `toHttp()` reads
|
|
144
|
+
*/
|
|
145
|
+
export declare function attachHttp(http: ErrorStatuses | undefined, error: OkmError): OkmError;
|
|
146
|
+
/**
|
|
147
|
+
* Maps a driver or query error and records it on the session logger.
|
|
148
|
+
*
|
|
149
|
+
* The archive hook uses this so a failed statement stays an `OkmError`.
|
|
150
|
+
*
|
|
151
|
+
* @param session - Pool, statuses, and logger
|
|
152
|
+
* @param error - Rejection from the driver or the statement chunk
|
|
153
|
+
* @returns Never. The mapped error is thrown
|
|
154
|
+
*/
|
|
155
|
+
export declare function settleCall(session: Session, error: unknown): Promise<never>;
|
|
47
156
|
export {};
|
|
@@ -17,9 +17,10 @@ export type ConflictPlan = {
|
|
|
17
17
|
*
|
|
18
18
|
* @param table - Target table
|
|
19
19
|
* @param value - The option the caller passed
|
|
20
|
+
* @param allow - Guarded fields this write may set
|
|
20
21
|
* @returns The plan, or `undefined` for the default `"error"`
|
|
21
22
|
*/
|
|
22
|
-
export declare function readConflict(table: Indexed, value: unknown): ConflictPlan | undefined;
|
|
23
|
+
export declare function readConflict(table: Indexed, value: unknown, allow?: ReadonlySet<string>): ConflictPlan | undefined;
|
|
23
24
|
/**
|
|
24
25
|
* Appends the conflict clause, or wraps a first-or-create insert.
|
|
25
26
|
*
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redaction for hidden and sensitive fields.
|
|
3
|
+
*
|
|
4
|
+
* Loaded the first time a concealed table is inspected or a read of one fails.
|
|
5
|
+
*/
|
|
6
|
+
import { OkmError } from "../contracts/error.js";
|
|
7
|
+
import type { QuerySchema } from "../dialects/pg/model.js";
|
|
8
|
+
import type { ReadCall } from "./plan.js";
|
|
9
|
+
import type { Inspection } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Replaces concealed values in an inspection and records the exposure rules.
|
|
12
|
+
*
|
|
13
|
+
* @param schema - Connected schema
|
|
14
|
+
* @param view - Inspection that still holds the real values
|
|
15
|
+
* @param call - The read, used to encode parameter values and to see `select`
|
|
16
|
+
* @returns The inspection a caller can print
|
|
17
|
+
*/
|
|
18
|
+
export declare function redactView(schema: QuerySchema, view: Inspection, call: ReadCall): Inspection;
|
|
19
|
+
/**
|
|
20
|
+
* Removes concealed values from a read error.
|
|
21
|
+
*
|
|
22
|
+
* @param error - Failure from the driver or the planner
|
|
23
|
+
* @param schema - Connected schema
|
|
24
|
+
* @param call - The read whose hidden or sensitive values may have been echoed
|
|
25
|
+
* @returns The error, with those values replaced
|
|
26
|
+
*/
|
|
27
|
+
export declare function scrubCall(error: OkmError, schema: QuerySchema, call: ReadCall): OkmError;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calls the observers of `connect({ hookm })`.
|
|
3
|
+
*
|
|
4
|
+
* Hookm are events only (spec §18). An error a hook throws is dropped, so an
|
|
5
|
+
* observer never changes a query, a commit, or a rollback. Loaded when a hook
|
|
6
|
+
* is set and an event happens.
|
|
7
|
+
*/
|
|
8
|
+
import type { Notice } from "../contracts/driver.js";
|
|
9
|
+
import type { Hookm, TransactionEvent } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Tells every `onNotice` about server notices, in order.
|
|
12
|
+
*
|
|
13
|
+
* @param hookm - Observers from `connect`
|
|
14
|
+
* @param notices - Notices a statement returned
|
|
15
|
+
*/
|
|
16
|
+
export declare function notices(hookm: readonly Hookm[] | undefined, notices: readonly Notice[]): void;
|
|
17
|
+
/**
|
|
18
|
+
* Tells every `onTransaction` that a transaction or savepoint changed phase.
|
|
19
|
+
*
|
|
20
|
+
* @param hookm - Observers from `connect`
|
|
21
|
+
* @param phase - `start`, `commit`, or `rollback`
|
|
22
|
+
* @param depth - 0 for the transaction, 1 and up for savepoints
|
|
23
|
+
*/
|
|
24
|
+
export declare function phase(hookm: readonly Hookm[] | undefined, phase: TransactionEvent["phase"], depth: number): void;
|
|
25
|
+
/**
|
|
26
|
+
* Gives an error no caller can receive to every `onError` and to the logger.
|
|
27
|
+
*
|
|
28
|
+
* @param session - Observers and the logger from `connect`
|
|
29
|
+
* @param error - What failed, for example an `afterCommit` callback
|
|
30
|
+
*/
|
|
31
|
+
export declare function report(session: {
|
|
32
|
+
readonly hookm: readonly Hookm[] | undefined;
|
|
33
|
+
readonly logger: {
|
|
34
|
+
error?(entry: {
|
|
35
|
+
readonly code: string;
|
|
36
|
+
readonly summary: string;
|
|
37
|
+
}): void;
|
|
38
|
+
} | undefined;
|
|
39
|
+
}, error: unknown): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client id generators (`okmodel/ids`).
|
|
3
|
+
*
|
|
4
|
+
* Pass these to `.default()` or `schema({ defaults: { id } })`. A literal
|
|
5
|
+
* passed to `.default()` stays a database default. These functions are not
|
|
6
|
+
* part of the runtime entry, so an application that does not import them
|
|
7
|
+
* does not ship them.
|
|
8
|
+
*/
|
|
9
|
+
export { uuidv4, uuidv7 } from "./uuid.js";
|
|
10
|
+
export { okid, type OkidOptions } from "./okid-generator.js";
|
|
11
|
+
export type { ClientGenerator, IdGenerators } from "../../contracts/generator.js";
|