okmodel 0.5.1 → 0.7.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 +100 -1116
- package/dist/adapters/capabilities.d.ts +3 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +14 -1
- package/dist/adapters/pg/cursor.d.ts +17 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +20 -0
- package/dist/adapters/pg/nodepostgres-extra.d.ts +22 -1
- package/dist/adapters/pg/nodepostgres.d.ts +12 -0
- package/dist/adapters/pg/pglite-wire.d.ts +24 -0
- package/dist/adapters/pg/pglite.d.ts +10 -0
- package/dist/adapters/pg/postgres-extra.d.ts +41 -3
- package/dist/adapters/pg/reserved.d.ts +42 -0
- package/dist/adapters/pg/session.d.ts +0 -18
- 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/connection.d.ts +7 -6
- 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/floor.d.ts +68 -0
- package/dist/dialects/pg/fn/index.js +2 -2
- package/dist/dialects/pg/index.d.ts +8 -2
- package/dist/dialects/pg/index.js +67 -171
- package/dist/dialects/pg/introspect.d.ts +7 -0
- package/dist/dialects/pg/keys.d.ts +11 -8
- package/dist/dialects/pg/model.d.ts +47 -2
- package/dist/dialects/pg/morph.d.ts +43 -0
- package/dist/dialects/pg/operator-fit.d.ts +2 -2
- package/dist/dialects/pg/operators.d.ts +14 -7
- package/dist/dialects/pg/ops/bucket.d.ts +65 -0
- package/dist/dialects/pg/ops/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/matches.d.ts +9 -12
- package/dist/dialects/pg/ops/relevance.d.ts +13 -0
- package/dist/dialects/pg/ops/search-query.d.ts +22 -0
- package/dist/dialects/pg/ops/window.d.ts +103 -0
- package/dist/dialects/pg/owner.d.ts +42 -0
- package/dist/dialects/pg/path-endpoint.d.ts +20 -0
- package/dist/dialects/pg/preset.d.ts +1 -1
- package/dist/dialects/pg/relations.d.ts +100 -3
- 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 +33 -3
- 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/aggregate.d.ts +8 -2
- package/dist/runtime/batch.d.ts +1 -1
- package/dist/runtime/bucket-group.d.ts +70 -0
- package/dist/runtime/conflict.d.ts +24 -6
- package/dist/runtime/drift.d.ts +9 -0
- package/dist/runtime/include.d.ts +0 -8
- package/dist/runtime/inflight.d.ts +14 -0
- package/dist/runtime/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -5
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.d.ts +1 -0
- package/dist/runtime/pg/pglite.js +9 -8
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +113 -15
- package/dist/runtime/predicate.d.ts +19 -0
- package/dist/runtime/read-stream.d.ts +13 -16
- package/dist/runtime/result-name.d.ts +17 -0
- package/dist/runtime/safety/index.js +1 -1
- package/dist/runtime/server-check.d.ts +3 -3
- package/dist/runtime/sort-bind.d.ts +21 -0
- package/dist/runtime/sort.d.ts +56 -0
- package/dist/runtime/sync.d.ts +70 -0
- 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 +1511 -38
- 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/text-search.d.ts +20 -0
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +187 -17
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +231 -23
- package/dist/runtime/validate/index.js +4 -4
- package/dist/runtime/version.d.ts +39 -0
- package/dist/runtime/window.d.ts +21 -0
- package/dist/runtime/write.d.ts +55 -3
- package/dist/shared/{krxx77g0.js → 14vx95q4.js} +12 -18
- package/dist/shared/1est4ezg.js +313 -0
- package/dist/shared/{4az561fn.js → 1qa0qajz.js} +8 -23
- package/dist/shared/1w508jbr.js +1611 -0
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/2d3xq4ps.js +9 -0
- package/dist/shared/2shdbn8q.js +23 -0
- package/dist/shared/{t4tbsy9h.js → 358zsv4r.js} +1 -1
- package/dist/shared/3v7t1yrv.js +208 -0
- package/dist/shared/5e3tf63j.js +220 -0
- package/dist/shared/5fe3kbsh.js +10 -0
- package/dist/shared/5v3xf80k.js +37 -0
- package/dist/shared/{51mvgj8w.js → 63qtkrca.js} +130 -3
- package/dist/shared/{gbtcc2d7.js → 67txcrcw.js} +62 -66
- package/dist/shared/79dt02vc.js +12 -0
- package/dist/shared/{v36c5g6p.js → 7k9grvf6.js} +407 -14
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7mnme5tn.js +8 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/{87jvvhnt.js → 81ebdx9p.js} +48 -68
- package/dist/shared/{szm0cksa.js → 8skf0cam.js} +34 -6
- package/dist/shared/{gjthds9j.js → 9628a9xt.js} +1 -1
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/{8xsbagad.js → 9s0ypp87.js} +88 -7
- package/dist/shared/9y3mmmh1.js +436 -0
- package/dist/shared/ab9gmbwy.js +213 -0
- package/dist/shared/{sycnx8gt.js → ax7qv55k.js} +18 -8
- package/dist/shared/{f5cw5q5r.js → aytqh5y2.js} +6 -4
- package/dist/shared/{fancm5pt.js → b5pftnn2.js} +138 -15
- package/dist/shared/{efmy2gcg.js → b76b8d95.js} +2 -2
- package/dist/shared/bdk4sty6.js +58 -0
- package/dist/shared/{32zqc1dw.js → bg3rym3g.js} +63 -32
- package/dist/shared/{0t22wwh1.js → bm22fvzr.js} +16 -14
- package/dist/shared/bz84tkzm.js +342 -0
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/cn957f8d.js +179 -0
- package/dist/shared/{pf0d8f77.js → cnkky55j.js} +25 -14
- package/dist/shared/{5fqx9yh4.js → dk8v79p3.js} +3 -1
- package/dist/shared/{nkaxvt9q.js → dkxgzaqd.js} +224 -19
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/{4m9fn52z.js → ed0b8k4s.js} +1 -1
- package/dist/shared/{z2rnngj4.js → ek2wt2dz.js} +8 -5
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/g6evj1j3.js +66 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{qv2ydck9.js → gs74dbj5.js} +651 -76
- package/dist/shared/gzaveazc.js +285 -0
- package/dist/shared/{8rsy3hxz.js → h15jx9bc.js} +1 -1
- package/dist/shared/{dyj86cmj.js → hyh73qk6.js} +3 -3
- package/dist/shared/je4axnm8.js +22 -0
- package/dist/shared/{ycatkxmq.js → jgqj11w4.js} +1 -1
- package/dist/shared/{6qd27mx0.js → jvd0mqag.js} +5 -5
- package/dist/shared/jznfax0y.js +155 -0
- package/dist/shared/{cgbamx3e.js → kb2sdhfb.js} +7 -4
- package/dist/shared/{ps7a6h14.js → kr0jzbw2.js} +12 -8
- package/dist/shared/{janx09m5.js → ktz42yez.js} +20 -8
- package/dist/shared/{gde73es6.js → m6p12kbr.js} +56 -55
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{nxdp2ze3.js → mtaszv5a.js} +144 -12
- package/dist/shared/n816peh1.js +45 -0
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/{cctw17hj.js → p6qc5gcp.js} +38 -34
- package/dist/shared/{6rk2gen5.js → pbp1ss85.js} +20 -17
- package/dist/shared/pt94kz7f.js +6 -0
- package/dist/shared/{wq9n6pwr.js → pz6rj8ay.js} +82 -9
- package/dist/shared/q5c6ngn3.js +13 -0
- package/dist/shared/{8bwbwy8h.js → qq3899ht.js} +128 -18
- 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/{sdc7r2ww.js → rs73fca9.js} +8 -8
- package/dist/shared/{tm5ab8we.js → sfz1ksn6.js} +7 -4
- package/dist/shared/{6mnp99hx.js → svncdeh5.js} +16 -12
- package/dist/shared/{hf22e0wt.js → tbrvgw6z.js} +62 -42
- package/dist/shared/te5as7z7.js +622 -0
- package/dist/shared/{ga3sfy93.js → tsvww22q.js} +535 -200
- package/dist/shared/{47x8x9ze.js → ttsqgp4p.js} +20 -13
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/vb6qfyve.js +152 -0
- package/dist/shared/{r2sp8hrc.js → vczs8gd4.js} +22 -13
- package/dist/shared/{1g0drakv.js → vqrjpcqn.js} +145 -3
- package/dist/shared/{2pqx26h8.js → w72kgg4q.js} +31 -22
- package/dist/shared/{96qcj21c.js → w79hsckn.js} +16 -51
- package/dist/shared/wa07eas9.js +730 -0
- package/dist/shared/{k8v5v5wj.js → x933k9a3.js} +75 -34
- package/dist/shared/{cr74e96e.js → xhfsfkgk.js} +62 -28
- package/dist/shared/xjk7hnn5.js +272 -0
- package/dist/shared/{5enne4ma.js → xnxsed62.js} +66 -113
- package/dist/shared/xqve9598.js +53 -0
- package/dist/shared/{9x25fxhc.js → y34a8714.js} +1 -1
- package/dist/shared/{k7dwkhvq.js → y6jdds7g.js} +4 -1
- package/dist/shared/y6njgyda.js +249 -0
- package/dist/shared/{c9z5g0fm.js → ywr8hmey.js} +5 -2
- package/dist/shared/{g7ez901n.js → ywspezzx.js} +1 -1
- package/dist/shared/z7s6fpxv.js +62 -0
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/{9m80mkac.js → ze4hxsmy.js} +1 -1
- package/dist/shared/zm0ptry0.js +40 -0
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zp9fmend.js +145 -0
- 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/engine.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 +8 -3
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/7zwwyh0v.js +0 -448
- package/dist/shared/aj2qxyhj.js +0 -90
- package/dist/shared/caw8b9d8.js +0 -204
- package/dist/shared/jwtxdj06.js +0 -76
- package/dist/shared/kfjp0gck.js +0 -212
- package/dist/shared/q58y17hy.js +0 -21
- package/dist/shared/qm7cdtvr.js +0 -912
- package/dist/shared/r8x5qhd7.js +0 -86
- package/dist/shared/zqrnhwsq.js +0 -31
|
@@ -15,6 +15,13 @@ export type IntrospectOptions = {
|
|
|
15
15
|
* When omitted, roles, grants, and default privileges are not read.
|
|
16
16
|
*/
|
|
17
17
|
readonly managedRoles?: readonly string[];
|
|
18
|
+
/**
|
|
19
|
+
* Read-only role.
|
|
20
|
+
*
|
|
21
|
+
* Schema `USAGE` is read for this role only. Other roles keep the schema
|
|
22
|
+
* privileges they already have.
|
|
23
|
+
*/
|
|
24
|
+
readonly reportingRole?: string;
|
|
18
25
|
};
|
|
19
26
|
/** A connection that can run one query. Parameters are `$1`, `$2`, … */
|
|
20
27
|
export type CatalogQuery = {
|
|
@@ -8,15 +8,18 @@ export type IdDefault = "uuidv7" | "uuidv4" | "none";
|
|
|
8
8
|
/**
|
|
9
9
|
* Primary key.
|
|
10
10
|
*
|
|
11
|
-
* With no options, the database default is `
|
|
12
|
-
* `schema({ defaults: { id } })` says otherwise.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* With no options, the database default is `gen_random_uuid()` unless
|
|
12
|
+
* `schema({ defaults: { id } })` says otherwise. That function is built in
|
|
13
|
+
* from Postgres 13, so a bare call works on every supported major. `uuidv7`
|
|
14
|
+
* stores `uuidv7()` and needs Postgres 18 (`minPostgres: 18`). Pick it for a large write-heavy
|
|
15
|
+
* table: the ids are time-ordered and the index stays local. Random ids are
|
|
16
|
+
* fine elsewhere. `none` takes the id on insert. A client generator
|
|
17
|
+
* (`uuidv4`, `uuidv7`, or `okid(...)` from `okmodel/ids`) is filled on insert
|
|
18
|
+
* and stored with no database default. OKID is `text` with collation `C`. A
|
|
19
|
+
* database default is omitted from insert and update. `none` is required on
|
|
20
|
+
* insert and omitted from update.
|
|
18
21
|
*
|
|
19
|
-
* @param options - Which default to store. Omitted means the schema default, or `
|
|
22
|
+
* @param options - Which default to store. Omitted means the schema default, or `gen_random_uuid()`
|
|
20
23
|
* @returns An id column
|
|
21
24
|
*/
|
|
22
25
|
export declare function id(): ColumnBuilder<string, IdFlags>;
|
|
@@ -21,8 +21,13 @@ export type ColumnModel = {
|
|
|
21
21
|
* call a codec it does not need.
|
|
22
22
|
*/
|
|
23
23
|
readonly decode: ((wire: string) => unknown) | undefined;
|
|
24
|
-
/**
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Excluded from a default select. Named selects still return it. Includes never return it.
|
|
26
|
+
*
|
|
27
|
+
* `"filter"` is still excluded, and `where` and `orderBy` may name it.
|
|
28
|
+
* `true` is excluded and refused there (OKM1120).
|
|
29
|
+
*/
|
|
30
|
+
readonly hidden: boolean | "filter";
|
|
26
31
|
/**
|
|
27
32
|
* Redacted in logs, errors, and `inspect()`.
|
|
28
33
|
*
|
|
@@ -58,6 +63,39 @@ export type ColumnModel = {
|
|
|
58
63
|
*/
|
|
59
64
|
readonly accepts?: readonly string[] | undefined;
|
|
60
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* One table a morph include can return.
|
|
68
|
+
*
|
|
69
|
+
* `type` is the table's TypeScript name, which is what the type column stores.
|
|
70
|
+
*/
|
|
71
|
+
export type MorphTarget = {
|
|
72
|
+
readonly type: string;
|
|
73
|
+
readonly table: string;
|
|
74
|
+
/** SQL name of the target table. */
|
|
75
|
+
readonly sql: string;
|
|
76
|
+
/** SQL name of the target's single primary-key column. */
|
|
77
|
+
readonly keySql: string;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* A polymorphic pair: a type column and an id column.
|
|
81
|
+
*
|
|
82
|
+
* `to` is the owner side (one of several tables). `many` is the reverse on a target.
|
|
83
|
+
* Absent on every other relation, so a normal relation does not carry it.
|
|
84
|
+
*/
|
|
85
|
+
export type MorphModel = {
|
|
86
|
+
readonly direction: "to" | "many";
|
|
87
|
+
/** Column stem. The fields are `${name}Type` and `${name}Id`. */
|
|
88
|
+
readonly name: string;
|
|
89
|
+
readonly typeField: string;
|
|
90
|
+
readonly idField: string;
|
|
91
|
+
/** SQL name of the type column. */
|
|
92
|
+
readonly typeSql: string;
|
|
93
|
+
/** SQL name of the id column. */
|
|
94
|
+
readonly idSql: string;
|
|
95
|
+
/** On a reverse many, the table name stored in the type column. */
|
|
96
|
+
readonly typeValue?: string;
|
|
97
|
+
readonly targets: readonly MorphTarget[];
|
|
98
|
+
};
|
|
61
99
|
/**
|
|
62
100
|
* A resolved relation.
|
|
63
101
|
*
|
|
@@ -72,6 +110,13 @@ export type RelationModel = {
|
|
|
72
110
|
readonly local: readonly string[];
|
|
73
111
|
/** SQL names on the related table. */
|
|
74
112
|
readonly remote: readonly string[];
|
|
113
|
+
/**
|
|
114
|
+
* Set on a morph relation.
|
|
115
|
+
*
|
|
116
|
+
* The include planner reads `to`. A reverse many reads `many` and emits
|
|
117
|
+
* through {@link RelationModel.through}.
|
|
118
|
+
*/
|
|
119
|
+
readonly morph?: MorphModel;
|
|
75
120
|
/**
|
|
76
121
|
* Set on a `manyThrough` relation.
|
|
77
122
|
*
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolver and emitters of a `morph` relation.
|
|
3
|
+
*
|
|
4
|
+
* The relation object carries both. `schema()` calls the resolver, and the
|
|
5
|
+
* planner calls the emitter with its own helpers, so a schema that never
|
|
6
|
+
* calls `morph` or `morphMany` does not ship this module. A target in another
|
|
7
|
+
* tenant or archived never shows: the include planner applies those predicates
|
|
8
|
+
* to each target, the same way it does for any relation.
|
|
9
|
+
*/
|
|
10
|
+
import type { RelationModel } from "./model.js";
|
|
11
|
+
import type { RelationScope } from "./relations.js";
|
|
12
|
+
/**
|
|
13
|
+
* Resolves `morph(name, targets)` on the table that holds the type and id columns.
|
|
14
|
+
*
|
|
15
|
+
* @param scope - What `schema()` knows
|
|
16
|
+
* @param name - Column stem: `${name}Type` and `${name}Id`
|
|
17
|
+
* @param targets - Closed list of target table names
|
|
18
|
+
* @returns The resolved to-one relation
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveMorph(scope: RelationScope, name: string, targets: readonly string[]): RelationModel;
|
|
21
|
+
/**
|
|
22
|
+
* Resolves `morphMany(table, name)` on a target table.
|
|
23
|
+
*
|
|
24
|
+
* The many reads the owner table's type and id columns. The owner must declare
|
|
25
|
+
* `morph(name, targets)` and list this table.
|
|
26
|
+
*
|
|
27
|
+
* @param scope - What `schema()` knows. `owner` is the target table
|
|
28
|
+
* @param table - Table that holds the type and id columns
|
|
29
|
+
* @param name - Column stem declared on that table
|
|
30
|
+
* @returns The resolved to-many relation
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveMorphMany(scope: RelationScope, table: string, name: string): RelationModel;
|
|
33
|
+
/**
|
|
34
|
+
* Refuses `morphTo` when the name, type, or id is missing.
|
|
35
|
+
*
|
|
36
|
+
* `null` used to throw a TypeError on `.length`. An empty name or type stays
|
|
37
|
+
* OKM1020. A null or non-string id, or a null type, is OKM1120.
|
|
38
|
+
*
|
|
39
|
+
* @param name - Column stem
|
|
40
|
+
* @param type - Target table name
|
|
41
|
+
* @param id - That table's primary key
|
|
42
|
+
*/
|
|
43
|
+
export declare function assertMorphTo(name: unknown, type: unknown, id: unknown): void;
|
|
@@ -58,9 +58,9 @@ export declare function assertNoControl(value: string, role: string): void;
|
|
|
58
58
|
*/
|
|
59
59
|
export declare function assertBoundText(value: string, role: string): void;
|
|
60
60
|
/**
|
|
61
|
-
* Rejects a
|
|
61
|
+
* Rejects a text search language that is not an identifier.
|
|
62
62
|
*
|
|
63
|
-
* @param config -
|
|
63
|
+
* @param config - Language name, such as `english`
|
|
64
64
|
*/
|
|
65
65
|
export declare function assertRegconfig(config: string): void;
|
|
66
66
|
/**
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
declare const brand: unique symbol;
|
|
8
8
|
declare const RUNTIME: unique symbol;
|
|
9
9
|
/** Operator names the read path compiles. */
|
|
10
|
-
export type OperatorName = "eq" | "lt" | "lte" | "gt" | "gte" | "between" | "startsWith" | "contains" | "endsWith" | "like" | "ilike" | "inList" | "notIn" | "not" | "or" | "and" | "has" | "none" | "every" | "inc" | "containedBy" | "overlaps" | "hasKey" | "hasAnyKey" | "path" | "matches" | "similar" | "wordSimilar" | "json.set" | "arr.append" | "arr.remove";
|
|
10
|
+
export type OperatorName = "eq" | "lt" | "lte" | "gt" | "gte" | "between" | "startsWith" | "contains" | "endsWith" | "like" | "ilike" | "inList" | "notIn" | "not" | "or" | "and" | "has" | "none" | "every" | "inc" | "containedBy" | "overlaps" | "hasKey" | "hasAnyKey" | "path" | "matches" | "relevance" | "similar" | "wordSimilar" | "json.set" | "arr.append" | "arr.remove";
|
|
11
11
|
/** A tagged operator. `value` is the operand the helper stored. */
|
|
12
12
|
export type Tagged<Name extends OperatorName, V> = {
|
|
13
13
|
readonly [brand]: Name;
|
|
@@ -38,16 +38,23 @@ export type PathValue<V> = {
|
|
|
38
38
|
};
|
|
39
39
|
/** `col #>> segments` compared with `op`. */
|
|
40
40
|
export type Path<V extends string | number | boolean> = Tagged<"path", PathValue<V>>;
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
/**
|
|
42
|
+
* How search text is matched.
|
|
43
|
+
*
|
|
44
|
+
* `natural` is web-search style. `all-words` requires every word. `phrase`
|
|
45
|
+
* keeps the words in order. `advanced` is PostgreSQL query syntax.
|
|
46
|
+
*/
|
|
47
|
+
export type SearchMatch = "natural" | "all-words" | "phrase" | "advanced";
|
|
48
|
+
/** Text to look for, how to match it, and the text search language when one was passed. */
|
|
44
49
|
export type MatchValue = {
|
|
45
50
|
readonly query: string;
|
|
46
|
-
readonly
|
|
47
|
-
readonly
|
|
51
|
+
readonly match: SearchMatch;
|
|
52
|
+
readonly language: string | undefined;
|
|
48
53
|
};
|
|
49
|
-
/** `@@` against a
|
|
54
|
+
/** `@@` against a search column. */
|
|
50
55
|
export type Matches = Tagged<"matches", MatchValue>;
|
|
56
|
+
/** Order by how well a search column matches. Most relevant first. */
|
|
57
|
+
export type Relevance = Tagged<"relevance", MatchValue>;
|
|
51
58
|
/** Text stored on a `pg_trgm` operator. `schema` is the extension's install schema. */
|
|
52
59
|
export type TrigramQuery = {
|
|
53
60
|
readonly query: string;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time bucket for `aggregate` `groupBy` (spec §10, §13 tool 4).
|
|
3
|
+
*
|
|
4
|
+
* The brand is a symbol. JSON cannot create one, so a request cannot add a
|
|
5
|
+
* bucket. A plain object in `groupBy` stays OKM1120. The SQL loads with the
|
|
6
|
+
* first `aggregate()` whose `groupBy` contains a bucket.
|
|
7
|
+
*/
|
|
8
|
+
declare const brand: unique symbol;
|
|
9
|
+
/** Calendar and clock units `bucket` accepts. */
|
|
10
|
+
export type BucketUnit = "second" | "minute" | "hour" | "day" | "week" | "month" | "quarter" | "year";
|
|
11
|
+
/** Week that starts on Monday (ISO), Sunday, or Saturday. */
|
|
12
|
+
export type WeekStart = "monday" | "sunday" | "saturday";
|
|
13
|
+
/**
|
|
14
|
+
* A `bucket()` call.
|
|
15
|
+
*
|
|
16
|
+
* `C` is the column, `U` the unit, and `A` the result key.
|
|
17
|
+
*/
|
|
18
|
+
export type Bucket<C extends string, U extends string, A extends string> = {
|
|
19
|
+
readonly [brand]: C;
|
|
20
|
+
readonly unit: U;
|
|
21
|
+
readonly as: A;
|
|
22
|
+
};
|
|
23
|
+
/** What {@link bucket} stores. The aggregate chunk reads this. */
|
|
24
|
+
export type BucketInput = {
|
|
25
|
+
readonly column: unknown;
|
|
26
|
+
readonly unit: unknown;
|
|
27
|
+
readonly as: unknown;
|
|
28
|
+
readonly tz: unknown;
|
|
29
|
+
readonly weekStart: unknown;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Groups a timestamp or date column by a calendar or clock unit.
|
|
33
|
+
*
|
|
34
|
+
* `tz` is required for `timestamptz` and refused for `date`. `timestamp`
|
|
35
|
+
* without a zone is refused. `as` is the result key. `__proto__`, `constructor`,
|
|
36
|
+
* `toString`, and `hasOwnProperty` are refused when the aggregate runs.
|
|
37
|
+
* `weekStart` applies only
|
|
38
|
+
* to `week` and defaults to Monday. A NULL timestamp is its own group: the
|
|
39
|
+
* `as` key is present and the value is null.
|
|
40
|
+
*
|
|
41
|
+
* Day, week, month, quarter, and year come back as `Temporal.PlainDate` (the
|
|
42
|
+
* local date the period starts). Second, minute, and hour come back as
|
|
43
|
+
* `Temporal.Instant` (the period start).
|
|
44
|
+
*
|
|
45
|
+
* @typeParam C - Column name
|
|
46
|
+
* @typeParam U - Unit
|
|
47
|
+
* @typeParam A - Result key
|
|
48
|
+
* @param column - Field to bucket
|
|
49
|
+
* @param unit - Period
|
|
50
|
+
* @param options - Zone, result key, and week start
|
|
51
|
+
* @returns A tagged bucket. Pass it in `groupBy`
|
|
52
|
+
*/
|
|
53
|
+
export declare function bucket<const C extends string, const U extends BucketUnit, const A extends string>(column: C, unit: U, options: {
|
|
54
|
+
readonly tz?: string;
|
|
55
|
+
readonly as: A;
|
|
56
|
+
readonly weekStart?: WeekStart;
|
|
57
|
+
}): Bucket<C, U, A>;
|
|
58
|
+
/**
|
|
59
|
+
* Reports whether `value` is a {@link bucket} call.
|
|
60
|
+
*
|
|
61
|
+
* @param value - One `groupBy` entry
|
|
62
|
+
* @returns `true` when {@link bucket} created it
|
|
63
|
+
*/
|
|
64
|
+
export declare function isBucket(value: unknown): value is BucketInput;
|
|
65
|
+
export {};
|
|
@@ -2,9 +2,9 @@ import { type Tagged } from "../operators.js";
|
|
|
2
2
|
/** Adds to the stored number. `undefined` in `set` still leaves the field unchanged. */
|
|
3
3
|
export type Inc<V> = Tagged<"inc", V>;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Adds to a stored number in `update` `set` (spec §11).
|
|
6
6
|
*
|
|
7
|
-
* JSON and array operators are not this helper.
|
|
7
|
+
* A null number stays null. JSON and array operators are not this helper.
|
|
8
8
|
*
|
|
9
9
|
* @typeParam V - Amount
|
|
10
10
|
* @param value - Amount to add
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Matches } from "../operators.js";
|
|
2
|
+
import { type SearchOptions } from "./search-query.js";
|
|
2
3
|
/**
|
|
3
|
-
* Full-text match
|
|
4
|
+
* Full-text match for a search column.
|
|
4
5
|
*
|
|
5
|
-
* The default
|
|
6
|
-
*
|
|
7
|
-
* A text column is not searched here.
|
|
6
|
+
* The default match is natural, which does not throw on user input. A plain
|
|
7
|
+
* text column is not searched here. `relevance` orders by the same match.
|
|
8
8
|
*
|
|
9
|
-
* @param query -
|
|
10
|
-
* @param options -
|
|
11
|
-
* @returns A tagged operator
|
|
9
|
+
* @param query - Text to look for
|
|
10
|
+
* @param options - How to match, and the text search language
|
|
11
|
+
* @returns A tagged operator for `where`
|
|
12
12
|
*/
|
|
13
|
-
export declare function matches(query: string, options?:
|
|
14
|
-
readonly mode?: MatchMode;
|
|
15
|
-
readonly config?: string;
|
|
16
|
-
}): Matches;
|
|
13
|
+
export declare function matches(query: string, options?: SearchOptions): Matches;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Relevance } from "../operators.js";
|
|
2
|
+
import { type SearchOptions } from "./search-query.js";
|
|
3
|
+
/**
|
|
4
|
+
* Orders a search column by how well it matches.
|
|
5
|
+
*
|
|
6
|
+
* Most relevant first. Pass it as an `orderBy` value. `find({ search })`
|
|
7
|
+
* compiles to `matches` plus this, so the SQL is the same.
|
|
8
|
+
*
|
|
9
|
+
* @param query - Text to look for
|
|
10
|
+
* @param options - How to match, and the text search language. Same words as `matches`
|
|
11
|
+
* @returns A tagged order
|
|
12
|
+
*/
|
|
13
|
+
export declare function relevance(query: string, options?: SearchOptions): Relevance;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared operand for `matches` and `relevance`.
|
|
3
|
+
*
|
|
4
|
+
* Both helpers store this shape. The SQL compiler reads it once, so `search`
|
|
5
|
+
* and the two helpers emit the same text.
|
|
6
|
+
*/
|
|
7
|
+
import type { MatchValue, SearchMatch } from "../operators.js";
|
|
8
|
+
/** Options `matches` and `relevance` take. */
|
|
9
|
+
export type SearchOptions = {
|
|
10
|
+
/** How to match. Omitted means `natural`. */
|
|
11
|
+
readonly match?: SearchMatch;
|
|
12
|
+
/** Text search language, such as `english`. Omitted uses the database default. */
|
|
13
|
+
readonly language?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Stores the text, the match, and the language.
|
|
17
|
+
*
|
|
18
|
+
* @param query - Text to look for
|
|
19
|
+
* @param options - Match and language. Omitted means natural, database language
|
|
20
|
+
* @returns The operand both helpers tag
|
|
21
|
+
*/
|
|
22
|
+
export declare function searchValue(query: string, options?: SearchOptions): MatchValue;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Window helpers for `select` (spec §10, §13 tool 12).
|
|
3
|
+
*
|
|
4
|
+
* The brand is a symbol. JSON cannot create one, so a request cannot add a
|
|
5
|
+
* window. A plain object in `select` stays OKM1120. The SQL loads on the first
|
|
6
|
+
* `find` or `one` whose `select` contains one.
|
|
7
|
+
*/
|
|
8
|
+
declare const brand: unique symbol;
|
|
9
|
+
/** `asc` is nulls last and `desc` is nulls first unless `nulls` is set. */
|
|
10
|
+
type SortDir = "asc" | "desc" | {
|
|
11
|
+
readonly dir: "asc" | "desc";
|
|
12
|
+
readonly nulls?: "first" | "last";
|
|
13
|
+
};
|
|
14
|
+
/** Columns the window orders by. Names are checked when the call runs. */
|
|
15
|
+
export type WindowOrder = {
|
|
16
|
+
readonly [field: string]: SortDir | undefined;
|
|
17
|
+
};
|
|
18
|
+
/** What a window helper stores. The planner reads this. */
|
|
19
|
+
export type WindowCall = {
|
|
20
|
+
readonly label: "rowNumber" | "rank" | "denseRank" | "runningTotal";
|
|
21
|
+
readonly fn: "row_number" | "rank" | "dense_rank" | "sum";
|
|
22
|
+
readonly column: string | undefined;
|
|
23
|
+
readonly partitionBy: readonly string[] | undefined;
|
|
24
|
+
readonly orderBy: unknown;
|
|
25
|
+
readonly as: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* A window helper.
|
|
29
|
+
*
|
|
30
|
+
* `A` is the result key. `V` is `number` for a rank, or the source column for
|
|
31
|
+
* a running total.
|
|
32
|
+
*/
|
|
33
|
+
export type Window<A extends string, V extends string | number> = {
|
|
34
|
+
readonly [brand]: V;
|
|
35
|
+
readonly as: A;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Options every window helper takes.
|
|
39
|
+
*
|
|
40
|
+
* `partitionBy` is the group. Omit it to number the whole result. `orderBy`
|
|
41
|
+
* is the order inside that group. The primary key breaks ties. `as` is the
|
|
42
|
+
* result key. `__proto__`, `constructor`, `toString`, and `hasOwnProperty`
|
|
43
|
+
* are refused when the call runs.
|
|
44
|
+
*/
|
|
45
|
+
type WindowOptions<A extends string> = {
|
|
46
|
+
readonly partitionBy?: readonly string[];
|
|
47
|
+
readonly orderBy: WindowOrder;
|
|
48
|
+
readonly as: A;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Reports whether `value` is a window helper.
|
|
52
|
+
*
|
|
53
|
+
* @param value - One `select` entry
|
|
54
|
+
* @returns `true` when a helper in this module created it
|
|
55
|
+
*/
|
|
56
|
+
export declare function isWindow(value: unknown): value is WindowCall;
|
|
57
|
+
/**
|
|
58
|
+
* Row number inside a group, starting at 1.
|
|
59
|
+
*
|
|
60
|
+
* Ties get distinct numbers. The primary key breaks them.
|
|
61
|
+
*
|
|
62
|
+
* @typeParam A - Result key
|
|
63
|
+
* @param options - Group, order, and result key
|
|
64
|
+
* @returns A tagged window. Pass it in `select` on `find` or `one`
|
|
65
|
+
*/
|
|
66
|
+
export declare function rowNumber<const A extends string>(options: WindowOptions<A>): Window<A, number>;
|
|
67
|
+
/**
|
|
68
|
+
* Rank inside a group, with gaps after a tie.
|
|
69
|
+
*
|
|
70
|
+
* Two rows with the same order share a rank. The next rank skips. The primary
|
|
71
|
+
* key breaks the order when you need a stable row, and it does not split the
|
|
72
|
+
* rank.
|
|
73
|
+
*
|
|
74
|
+
* @typeParam A - Result key
|
|
75
|
+
* @param options - Group, order, and result key
|
|
76
|
+
* @returns A tagged window. Pass it in `select` on `find` or `one`
|
|
77
|
+
*/
|
|
78
|
+
export declare function rank<const A extends string>(options: WindowOptions<A>): Window<A, number>;
|
|
79
|
+
/**
|
|
80
|
+
* Rank inside a group, without gaps after a tie.
|
|
81
|
+
*
|
|
82
|
+
* Two rows with the same order share a rank. The next rank is the next number.
|
|
83
|
+
*
|
|
84
|
+
* @typeParam A - Result key
|
|
85
|
+
* @param options - Group, order, and result key
|
|
86
|
+
* @returns A tagged window. Pass it in `select` on `find` or `one`
|
|
87
|
+
*/
|
|
88
|
+
export declare function denseRank<const A extends string>(options: WindowOptions<A>): Window<A, number>;
|
|
89
|
+
/**
|
|
90
|
+
* Running total of a number column.
|
|
91
|
+
*
|
|
92
|
+
* The total follows `orderBy` inside the group. A null number does not add.
|
|
93
|
+
* The result uses the column's value type: a number, or the exact decimal
|
|
94
|
+
* string of a `numeric` column.
|
|
95
|
+
*
|
|
96
|
+
* @typeParam C - Column
|
|
97
|
+
* @typeParam A - Result key
|
|
98
|
+
* @param column - Field to total
|
|
99
|
+
* @param options - Group, order, and result key
|
|
100
|
+
* @returns A tagged window. Pass it in `select` on `find` or `one`
|
|
101
|
+
*/
|
|
102
|
+
export declare function runningTotal<const C extends string, const A extends string>(column: C, options: WindowOptions<A>): Window<A, C>;
|
|
103
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table ownership marks (`external` and `ignored`).
|
|
3
|
+
*
|
|
4
|
+
* The mark lives on the table value, not in `table()` options. `schema()` does
|
|
5
|
+
* not read it, so a featureless app does not load this module. Tooling stamps
|
|
6
|
+
* the catalog before it plans.
|
|
7
|
+
*/
|
|
8
|
+
import type { Catalog, Owner } from "../../contracts/catalog/types.js";
|
|
9
|
+
import type { AnyTable } from "./table.js";
|
|
10
|
+
/** Owners a declaration may set. `managed` stays the default. */
|
|
11
|
+
export type DeclaredOwner = Exclude<Owner, "managed">;
|
|
12
|
+
/**
|
|
13
|
+
* Marks a table `external` or `ignored`.
|
|
14
|
+
*
|
|
15
|
+
* `external` is known and queryable, and a plan never creates, alters, or
|
|
16
|
+
* drops it. `ignored` is invisible to diffs, plans, and `okm check`. The
|
|
17
|
+
* table stays on the schema, so the client can still name it.
|
|
18
|
+
*
|
|
19
|
+
* @param table - A `table()` value
|
|
20
|
+
* @param owner - `external` or `ignored`
|
|
21
|
+
* @returns The same table
|
|
22
|
+
*/
|
|
23
|
+
export declare function withOwner<T extends AnyTable>(table: T, owner: DeclaredOwner): T;
|
|
24
|
+
/**
|
|
25
|
+
* Reads the mark {@link withOwner} stored.
|
|
26
|
+
*
|
|
27
|
+
* @param table - A table value
|
|
28
|
+
* @returns The mark, or `undefined` when the table is managed
|
|
29
|
+
*/
|
|
30
|
+
export declare function tableOwner(table: object): DeclaredOwner | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Copies `owner` onto a table and the objects that belong to it.
|
|
33
|
+
*
|
|
34
|
+
* Columns, indexes, constraints, triggers, policies, and sequences that
|
|
35
|
+
* depend on the table follow the table. A catalog with no marks is returned
|
|
36
|
+
* as itself.
|
|
37
|
+
*
|
|
38
|
+
* @param source - Catalog from `schema()`
|
|
39
|
+
* @param marks - SQL table name to owner
|
|
40
|
+
* @returns The catalog planning and drift should read
|
|
41
|
+
*/
|
|
42
|
+
export declare function stampOwnership(source: Catalog, marks: ReadonlyMap<string, DeclaredOwner>): Catalog;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marks the table a path ends on.
|
|
3
|
+
*
|
|
4
|
+
* The symbol lives here so a column-only app and a featureless app do not
|
|
5
|
+
* load it. `archivable()` reads it. Compile hashes named fields, so the mark
|
|
6
|
+
* stays out of the catalog.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Property set on the tenant table a path ends on.
|
|
10
|
+
*
|
|
11
|
+
* An options spread does not copy it. The rewrite sets it on the table object.
|
|
12
|
+
*/
|
|
13
|
+
export declare const pathEndpoint: unique symbol;
|
|
14
|
+
/**
|
|
15
|
+
* Records that `table` is the end of a path.
|
|
16
|
+
*
|
|
17
|
+
* @param table - The rewritten tenant table
|
|
18
|
+
* @returns The same table, marked
|
|
19
|
+
*/
|
|
20
|
+
export declare function markPathEndpoint<T extends object>(table: T): T;
|
|
@@ -44,7 +44,7 @@ export type Preset<Row> = (q: PresetQuery<Row>, ...args: never[]) => PresetQuery
|
|
|
44
44
|
* The first group are client methods. The second is reserved for later
|
|
45
45
|
* releases. `then` would make a table handle look like a promise.
|
|
46
46
|
*/
|
|
47
|
-
export type ReservedPreset = "find" | "one" | "page" | "aggregate" | "count" | "exists" | "insert" | "update" | "delete" | "archive" | "restore" | "withArchived" | "onlyArchived" | "then" | "lock" | "watch" | "subscribe" | "stream" | "inspect" | "explain" | "with" | "for" | "as";
|
|
47
|
+
export type ReservedPreset = "find" | "one" | "page" | "aggregate" | "count" | "exists" | "insert" | "update" | "delete" | "descendants" | "ancestors" | "sync" | "archive" | "restore" | "withArchived" | "onlyArchived" | "then" | "lock" | "watch" | "subscribe" | "stream" | "inspect" | "explain" | "with" | "for" | "as";
|
|
48
48
|
/**
|
|
49
49
|
* The `presets` option. A reserved name is a type error here, and OKM1040 when
|
|
50
50
|
* the schema is used.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `one`, `many`, and `
|
|
2
|
+
* `one`, `many`, `manyThrough`, and `morph` relations.
|
|
3
3
|
*
|
|
4
4
|
* They name a table. `schema()` resolves the foreign key. An ambiguous key
|
|
5
|
-
* is OKM1021. `manyThrough`
|
|
6
|
-
*
|
|
5
|
+
* is OKM1021. `manyThrough` and `morph` carry their own resolvers, so a schema
|
|
6
|
+
* that never calls one does not pay for it.
|
|
7
7
|
*/
|
|
8
8
|
import type { RelationModel } from "./model.js";
|
|
9
9
|
/** A to-one relation. `field` is the local foreign key when the table has several. */
|
|
@@ -28,6 +28,26 @@ export type RelationEdge = {
|
|
|
28
28
|
/** Referenced SQL names, in the same order. */
|
|
29
29
|
readonly remote: readonly string[];
|
|
30
30
|
};
|
|
31
|
+
/** A table as a morph resolver reads it. Foreign-key resolvers ignore this. */
|
|
32
|
+
export type RelationDescribed = {
|
|
33
|
+
readonly tsName: string;
|
|
34
|
+
readonly sqlName: string;
|
|
35
|
+
/** Primary-key SQL names, in catalog order. */
|
|
36
|
+
readonly primary: readonly string[];
|
|
37
|
+
readonly byField: ReadonlyMap<string, {
|
|
38
|
+
readonly field: string;
|
|
39
|
+
readonly sqlName: string;
|
|
40
|
+
readonly dataType: string;
|
|
41
|
+
readonly nullable: boolean;
|
|
42
|
+
}>;
|
|
43
|
+
readonly bySql: ReadonlyMap<string, {
|
|
44
|
+
readonly field: string;
|
|
45
|
+
readonly sqlName: string;
|
|
46
|
+
readonly dataType: string;
|
|
47
|
+
}>;
|
|
48
|
+
/** Relation calls stored on the table, before they are resolved. */
|
|
49
|
+
readonly relationOptions: unknown;
|
|
50
|
+
};
|
|
31
51
|
/** What a relation's own resolver reads from `schema()`. */
|
|
32
52
|
export type RelationScope = {
|
|
33
53
|
/** The table that declares the relation. */
|
|
@@ -37,6 +57,19 @@ export type RelationScope = {
|
|
|
37
57
|
readonly edges: readonly RelationEdge[];
|
|
38
58
|
/** Every table name in the schema, sorted. */
|
|
39
59
|
readonly tables: readonly string[];
|
|
60
|
+
/**
|
|
61
|
+
* Looks up a table's columns.
|
|
62
|
+
*
|
|
63
|
+
* Present when `schema()` resolves relations. A resolver that only needs
|
|
64
|
+
* foreign keys ignores it. The value is the prepared table; morph narrows it.
|
|
65
|
+
*/
|
|
66
|
+
readonly describe?: (table: string) => unknown;
|
|
67
|
+
/**
|
|
68
|
+
* Tenant fields tenancy added to a primary key.
|
|
69
|
+
*
|
|
70
|
+
* A morph id matches the key that remains. Absent when the schema has no tenancy.
|
|
71
|
+
*/
|
|
72
|
+
readonly scopeFields?: readonly string[];
|
|
40
73
|
};
|
|
41
74
|
/**
|
|
42
75
|
* A to-many relation through a join table.
|
|
@@ -100,3 +133,67 @@ export declare function isRelationCall(value: unknown): value is RelationCall;
|
|
|
100
133
|
export declare function manyThrough<const TTable extends string>(table: TTable, options: {
|
|
101
134
|
readonly through: string;
|
|
102
135
|
} & ThroughKeys): ManyThroughRelation<TTable>;
|
|
136
|
+
/**
|
|
137
|
+
* A polymorphic to-one relation.
|
|
138
|
+
*
|
|
139
|
+
* `name` is the column stem: the table declares `${name}Type` and `${name}Id`.
|
|
140
|
+
* The type column stores a target table name. The id column stores that
|
|
141
|
+
* table's primary key. Include returns one row of the matching target, or
|
|
142
|
+
* null, as a flat union discriminated by the type field.
|
|
143
|
+
*
|
|
144
|
+
* @typeParam TName - Column stem
|
|
145
|
+
* @typeParam TTargets - Closed list of target tables
|
|
146
|
+
* @param name - Column stem
|
|
147
|
+
* @param targets - Target table names, each with one primary-key column
|
|
148
|
+
* @returns The relation `schema()` resolves
|
|
149
|
+
*/
|
|
150
|
+
export declare function morph<const TName extends string, const TTargets extends readonly [string, ...string[]]>(name: TName, targets: TTargets): MorphRelation<TName, TTargets>;
|
|
151
|
+
/**
|
|
152
|
+
* The reverse of {@link morph}: many owner rows that point at this table.
|
|
153
|
+
*
|
|
154
|
+
* Declare it on each target. `table` is the table that holds the type and id
|
|
155
|
+
* columns, and `name` is the stem passed to `morph`.
|
|
156
|
+
*
|
|
157
|
+
* @typeParam TTable - Table that holds the type and id columns
|
|
158
|
+
* @param table - That table
|
|
159
|
+
* @param name - Column stem
|
|
160
|
+
* @returns The relation `schema()` resolves
|
|
161
|
+
*/
|
|
162
|
+
export declare function morphMany<const TTable extends string>(table: TTable, name: string): MorphManyRelation<TTable>;
|
|
163
|
+
/**
|
|
164
|
+
* A polymorphic relation declared with {@link morph}.
|
|
165
|
+
*
|
|
166
|
+
* It is a {@link OneRelation} so the relation map stays assignable. `morph`
|
|
167
|
+
* is what include reads to build the union.
|
|
168
|
+
*/
|
|
169
|
+
export type MorphRelation<TName extends string = string, TTargets extends readonly string[] = readonly string[]> = OneRelation<TTargets[number]> & {
|
|
170
|
+
readonly morph: {
|
|
171
|
+
readonly name: TName;
|
|
172
|
+
readonly targets: TTargets;
|
|
173
|
+
readonly typeField: `${TName}Type`;
|
|
174
|
+
};
|
|
175
|
+
readonly resolve: (scope: RelationScope) => RelationModel;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* The reverse many declared with {@link morphMany}.
|
|
179
|
+
*
|
|
180
|
+
* It is a {@link ManyRelation}, so include, `has`, `none`, and `every` read it as one.
|
|
181
|
+
*/
|
|
182
|
+
export type MorphManyRelation<TTable extends string = string> = ManyRelation<TTable> & {
|
|
183
|
+
readonly resolve: (scope: RelationScope) => RelationModel;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Sets a morph's type and id columns together.
|
|
187
|
+
*
|
|
188
|
+
* @typeParam TName - Column stem
|
|
189
|
+
* @typeParam TType - Target table name
|
|
190
|
+
* @param name - Column stem passed to `morph`
|
|
191
|
+
* @param type - Target table name
|
|
192
|
+
* @param id - That table's primary key
|
|
193
|
+
* @returns The two fields an insert or update spreads in
|
|
194
|
+
*/
|
|
195
|
+
export declare function morphTo<const TName extends string, const TType extends string>(name: TName, type: TType, id: string): {
|
|
196
|
+
readonly [K in `${TName}Type`]: TType;
|
|
197
|
+
} & {
|
|
198
|
+
readonly [K in `${TName}Id`]: string;
|
|
199
|
+
};
|