okmodel 0.6.0 → 0.8.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 -1131
- package/dist/adapters/capabilities.d.ts +35 -0
- package/dist/adapters/failure.d.ts +13 -2
- package/dist/adapters/lazy-errors.d.ts +22 -0
- package/dist/adapters/pg/bun-sql.d.ts +53 -0
- package/dist/adapters/pg/bunsql-extra.d.ts +54 -3
- package/dist/adapters/pg/bunsql.d.ts +15 -2
- package/dist/adapters/pg/cursor.d.ts +17 -0
- package/dist/adapters/pg/neon-extra.d.ts +18 -0
- package/dist/adapters/pg/neon.d.ts +104 -0
- package/dist/adapters/pg/no-inflight-timeout.d.ts +11 -8
- 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 +27 -11
- package/dist/adapters/pg/reserved.d.ts +42 -0
- package/dist/adapters/pg/session.d.ts +0 -18
- package/dist/contracts/connection.d.ts +7 -6
- package/dist/contracts/error.d.ts +1 -1
- package/dist/dialects/pg/floor.d.ts +68 -0
- package/dist/dialects/pg/fn/index.d.ts +39 -1
- package/dist/dialects/pg/fn/index.js +118 -26
- package/dist/dialects/pg/index.d.ts +8 -1
- package/dist/dialects/pg/index.js +435 -170
- package/dist/dialects/pg/introspect.d.ts +11 -0
- package/dist/dialects/pg/keys.d.ts +11 -8
- package/dist/dialects/pg/model.d.ts +40 -0
- 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/fragment.d.ts +119 -0
- package/dist/dialects/pg/ops/inc.d.ts +2 -2
- package/dist/dialects/pg/ops/lane.d.ts +49 -0
- 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/preset.d.ts +1 -1
- package/dist/dialects/pg/relations.d.ts +100 -3
- package/dist/dialects/pg/schema.d.ts +31 -3
- package/dist/dialects/pg/view/client.d.ts +14 -6
- package/dist/dialects/pg/view/index.d.ts +73 -1
- package/dist/dialects/pg/view/index.js +156 -5
- package/dist/dialects/pg/view/scratch.d.ts +8 -5
- package/dist/runtime/aggregate.d.ts +8 -2
- package/dist/runtime/bucket-group.d.ts +70 -0
- package/dist/runtime/conflict.d.ts +22 -4
- package/dist/runtime/include.d.ts +0 -8
- package/dist/runtime/inflight.d.ts +1 -1
- package/dist/runtime/otel.d.ts +105 -0
- package/dist/runtime/otel.js +97 -0
- package/dist/runtime/page.d.ts +4 -1
- package/dist/runtime/pg/bun.js +12 -6
- package/dist/runtime/pg/neon.d.ts +38 -0
- package/dist/runtime/pg/neon.js +64 -0
- package/dist/runtime/pg/pg.js +5 -5
- package/dist/runtime/pg/pglite.d.ts +1 -0
- package/dist/runtime/pg/pglite.js +9 -9
- package/dist/runtime/pg/postgresjs.js +5 -5
- package/dist/runtime/plan.d.ts +95 -5
- package/dist/runtime/read-stream.d.ts +13 -16
- package/dist/runtime/result-name.d.ts +17 -0
- 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/sql-fragment.d.ts +43 -0
- package/dist/runtime/sync.d.ts +70 -0
- package/dist/runtime/tenancy/index.js +15 -13
- package/dist/runtime/text-search.d.ts +20 -0
- package/dist/runtime/topology.d.ts +1 -1
- package/dist/runtime/traits/index.d.ts +80 -0
- package/dist/runtime/traits/index.js +184 -21
- package/dist/runtime/tree.d.ts +38 -0
- package/dist/runtime/types.d.ts +232 -22
- 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 +54 -2
- package/dist/shared/{929h19xp.js → 0wrea3jq.js} +141 -13
- package/dist/shared/{qq3899ht.js → 12z7aznj.js} +243 -14
- package/dist/shared/{1z04fa85.js → 14x60fbf.js} +12 -57
- package/dist/shared/{ek2wt2dz.js → 16kvjebh.js} +4 -4
- package/dist/shared/{wynzeggs.js → 195pzzzz.js} +8 -8
- package/dist/shared/1d9q9cv2.js +312 -0
- package/dist/shared/2c13q96h.js +18 -0
- package/dist/shared/{b4v57v3x.js → 2d3xq4ps.js} +2 -2
- package/dist/shared/{1f0xa3cb.js → 3449rcae.js} +5 -5
- package/dist/shared/{wkme6tep.js → 35q0n9tz.js} +8 -16
- package/dist/shared/3bb7wsqt.js +99 -0
- package/dist/shared/3t6kw83m.js +249 -0
- package/dist/shared/{5j36z8dn.js → 4m6hskg8.js} +39 -70
- package/dist/shared/{n076ydsc.js → 4vbf83xx.js} +69 -28
- package/dist/shared/{vmfkhszw.js → 63f4ksbz.js} +33 -26
- package/dist/shared/{c58secgj.js → 63qtkrca.js} +38 -4
- package/dist/shared/6m78c8ss.js +6 -0
- package/dist/shared/{x3jc53kg.js → 760ppr76.js} +15 -7
- package/dist/shared/7ghwamrf.js +40 -0
- package/dist/shared/7kms6fvj.js +20 -0
- package/dist/shared/7n7ddwt4.js +6 -0
- package/dist/shared/9a4ae4p8.js +31 -0
- package/dist/shared/{hazqqecq.js → 9dr2qnx7.js} +63 -34
- package/dist/shared/{h15jx9bc.js → 9dvh1dr6.js} +1 -1
- package/dist/shared/a62rb2da.js +13 -0
- package/dist/shared/{cgbamx3e.js → ae4j5f42.js} +23 -4
- package/dist/shared/agsfb86s.js +233 -0
- package/dist/shared/{8x72s86k.js → b6d6p0zc.js} +13 -7
- package/dist/shared/{ag4c7516.js → b76b8d95.js} +2 -2
- package/dist/shared/{j60w0dvr.js → bah9nbg3.js} +58 -38
- package/dist/shared/bnby0esn.js +10 -0
- package/dist/shared/bsek72fg.js +225 -0
- package/dist/shared/{2cg3wnxc.js → bxas03mq.js} +608 -141
- package/dist/shared/{31vm914h.js → cm3w0ywp.js} +15 -16
- package/dist/shared/{gwn6v667.js → cnkky55j.js} +25 -14
- package/dist/shared/{dk8v79p3.js → d5nmj7vv.js} +1 -1
- package/dist/shared/{ttmg09vd.js → dpc2r7rb.js} +8 -8
- package/dist/shared/dzj09cye.js +10 -0
- package/dist/shared/{sbdme3vy.js → e8zyaqvj.js} +60 -10
- package/dist/shared/{2jd1sn0e.js → ecn8mfdq.js} +6 -6
- package/dist/shared/exn3sd90.js +359 -0
- package/dist/shared/{t3g0k88x.js → f4jy1j7x.js} +39 -22
- package/dist/shared/{y2t3jktd.js → fjpnhqan.js} +20 -13
- package/dist/shared/g5yc06ka.js +272 -0
- package/dist/shared/ga9j92qj.js +25 -0
- package/dist/shared/{3fqwmr09.js → hfqmpasr.js} +6 -6
- package/dist/shared/{wt5rzv1h.js → hm5f8jby.js} +7 -7
- package/dist/shared/{ys0xzyaj.js → hqpxf4a4.js} +224 -19
- package/dist/shared/jebgrkeq.js +179 -0
- package/dist/shared/{09p049xa.js → jp36k7dp.js} +44 -16
- package/dist/shared/jx2m62cs.js +96 -0
- package/dist/shared/{r11n8grd.js → k86n8vq3.js} +7 -4
- package/dist/shared/{2z7wv5tj.js → kgwp4jdd.js} +56 -35
- package/dist/shared/{knmes2kh.js → kj9d8maq.js} +1 -1
- package/dist/shared/{g90m9b0g.js → m4xff2a6.js} +6 -5
- package/dist/shared/{r6nwkxnt.js → m7n9h2a5.js} +4 -4
- package/dist/shared/mfedzr74.js +145 -0
- package/dist/shared/{f0f1n281.js → mkrn359n.js} +60 -11
- package/dist/shared/{p248q79y.js → mnvjvqyp.js} +10 -10
- package/dist/shared/{672t5vym.js → mss6ctgv.js} +2 -2
- package/dist/shared/{4az561fn.js → mtw6jz76.js} +8 -23
- package/dist/shared/n05z9nwz.js +313 -0
- package/dist/shared/{pjr6xrm5.js → n0jmpgj1.js} +20 -17
- package/dist/shared/{p6bjzq9q.js → n41w4fbz.js} +14 -6
- package/dist/shared/{b3awxn7h.js → n454kcnw.js} +1 -1
- package/dist/shared/n7kg8mmx.js +61 -0
- package/dist/shared/nbw1z4yd.js +18 -0
- package/dist/shared/needfe47.js +66 -0
- package/dist/shared/{1nw1f3vs.js → njga14v4.js} +9 -9
- package/dist/shared/{5yv4k6a6.js → nmnsgj7x.js} +145 -3
- package/dist/shared/{vjpnzwjz.js → p3xbdcvt.js} +14 -18
- package/dist/shared/p5nh3r8q.js +622 -0
- package/dist/shared/{nx9hh281.js → pan0370z.js} +13 -12
- package/dist/shared/q0cqt2sp.js +12 -0
- package/dist/shared/qd9hhd8f.js +37 -0
- package/dist/shared/{mb2ycs1p.js → qfw14tna.js} +15 -15
- package/dist/shared/{9s0ypp87.js → sjk86yrx.js} +1 -1
- package/dist/shared/th3be82n.js +208 -0
- package/dist/shared/{ed0b8k4s.js → typ3vy7t.js} +1 -1
- package/dist/shared/{5d8t84hg.js → v1wad97q.js} +14 -14
- package/dist/shared/{x72jb7ad.js → v8g1vgv8.js} +1 -1
- package/dist/shared/{9628a9xt.js → vk7rag46.js} +1 -1
- package/dist/shared/{ze4hxsmy.js → w9ejzaqf.js} +1 -1
- package/dist/shared/{q3j1tq7a.js → wcrheftc.js} +148 -23
- package/dist/shared/wvdjznah.js +213 -0
- package/dist/shared/wz2a78mp.js +8 -0
- package/dist/shared/xfhe73sb.js +436 -0
- package/dist/shared/{r1fdd0f6.js → z581d7ny.js} +5 -2
- package/dist/shared/{8etn7d8w.js → z7s6fpxv.js} +1 -1
- package/dist/shared/{32cnm7kn.js → zbqbmmrp.js} +76 -40
- package/dist/shared/{n7mcc1gk.js → zchaghkf.js} +4 -3
- package/dist/shared/{xq0mvhts.js → zgex00fd.js} +6 -6
- package/dist/shared/{nsva2a6b.js → znm0bpp5.js} +3 -0
- package/dist/shared/zq1he88x.js +155 -0
- package/dist/tooling/cli.js +26 -13
- package/dist/tooling/driver-run.js +4971 -0
- package/dist/tooling/driver-test.d.ts +36 -0
- package/dist/tooling/migrate/commands.d.ts +2 -2
- package/dist/tooling/migrate/engine.d.ts +3 -2
- package/dist/tooling/migrate/index.js +9 -9
- package/dist/tooling/migrate/project.d.ts +3 -0
- package/dist/tooling/shared/03k6res6.js +210 -0
- package/dist/tooling/shared/08kemxjd.js +10 -0
- package/dist/tooling/shared/2revefqt.js +209 -0
- package/dist/tooling/shared/2wtvc7rw.js +1425 -0
- package/dist/tooling/shared/345tbc2k.js +16 -0
- package/dist/tooling/shared/3m1hkg7z.js +344 -0
- package/dist/tooling/shared/3rrw5w8f.js +81 -0
- package/dist/tooling/shared/3tq8pnb8.js +131 -0
- package/dist/tooling/shared/417zdsk7.js +194 -0
- package/dist/tooling/shared/4d2w25vw.js +40 -0
- package/dist/tooling/shared/54tqkxja.js +51 -0
- package/dist/tooling/shared/5bvw2nev.js +12 -0
- package/dist/tooling/shared/6nyfyw70.js +231 -0
- package/dist/tooling/shared/72fyg4zv.js +160 -0
- package/dist/tooling/shared/733a1tq3.js +38 -0
- package/dist/tooling/shared/7ae7rjmn.js +20 -0
- package/dist/tooling/shared/7kms6fvj.js +20 -0
- package/dist/tooling/shared/8sqrsw3s.js +49 -0
- package/dist/tooling/shared/96ps4g1z.js +32 -0
- package/dist/tooling/shared/9kazs5p6.js +195 -0
- package/dist/tooling/shared/9xzm7hjg.js +38 -0
- package/dist/tooling/shared/a6pp9d12.js +49 -0
- package/dist/tooling/shared/a7q7t4n3.js +22 -0
- package/dist/tooling/shared/aftb2mwr.js +18 -0
- package/dist/tooling/shared/bz2dqhab.js +311 -0
- package/dist/tooling/shared/cmptmb4f.js +12 -0
- package/dist/tooling/shared/ddjtfgnx.js +177 -0
- package/dist/tooling/shared/djydjpqt.js +261 -0
- package/dist/tooling/shared/dw08f3m8.js +9 -0
- package/dist/tooling/shared/dy672fz6.js +16 -0
- package/dist/tooling/shared/dzx85q70.js +66 -0
- package/dist/tooling/shared/ec71zqgt.js +270 -0
- package/dist/{shared/d5azex6s.js → tooling/shared/ep8zh3bk.js} +1 -1
- package/dist/tooling/shared/f9mphxej.js +3789 -0
- package/dist/tooling/shared/fb9k2qwd.js +89 -0
- package/dist/tooling/shared/g9ad4n80.js +211 -0
- package/dist/tooling/shared/gfvtj6d0.js +94 -0
- package/dist/tooling/shared/gmcf9cxf.js +294 -0
- package/dist/tooling/shared/htnaj77v.js +17 -0
- package/dist/tooling/shared/j9t5s12a.js +7 -0
- package/dist/tooling/shared/jne7b93p.js +42 -0
- package/dist/tooling/shared/ma2340rx.js +118 -0
- package/dist/tooling/shared/mtrqn2hn.js +505 -0
- package/dist/tooling/shared/n4jqhpqz.js +27 -0
- package/dist/tooling/shared/nf7jmhfa.js +20 -0
- package/dist/tooling/shared/p7f08ktn.js +332 -0
- package/dist/tooling/shared/ppnnnvj8.js +13 -0
- package/dist/tooling/shared/pqy21k24.js +312 -0
- package/dist/tooling/shared/pw8fgahx.js +69 -0
- package/dist/tooling/shared/pwsytxm5.js +17 -0
- package/dist/tooling/shared/rf83gr2d.js +94 -0
- package/dist/tooling/shared/rq5kk8j6.js +401 -0
- package/dist/tooling/shared/rs1jb051.js +12 -0
- package/dist/tooling/shared/smn6kz1p.js +157 -0
- package/dist/tooling/shared/spk1jg3r.js +1696 -0
- package/dist/tooling/shared/tn8gay14.js +143 -0
- package/dist/tooling/shared/vraj6d74.js +42 -0
- package/dist/tooling/shared/vs0t6qt8.js +64 -0
- package/dist/tooling/shared/vx86qjv8.js +150 -0
- package/dist/tooling/shared/w7qe8sj1.js +140 -0
- package/dist/tooling/shared/wt7j7nf6.js +15 -0
- package/dist/tooling/shared/wwnekq5n.js +6 -0
- package/dist/tooling/shared/xhrnjch9.js +185 -0
- package/dist/tooling/shared/xjs6zqtc.js +190 -0
- package/dist/tooling/shared/y031jct9.js +16 -0
- package/dist/tooling/shared/y5656f0e.js +233 -0
- package/dist/tooling/shared/yfr8hzhm.js +604 -0
- package/dist/tooling/shared/yk9mp7vb.js +250 -0
- package/dist/tooling/shared/yw30vnq2.js +139 -0
- package/dist/tooling/shared/z8d7ptht.js +618 -0
- package/dist/tooling/shared/zhwnfyb2.js +9 -0
- package/dist/tooling/shared/zvnhh1n0.js +198 -0
- package/dist/tooling/testing/index.js +3 -3
- package/package.json +17 -3
- package/dist/shared/3qnhc7w5.js +0 -38
- package/dist/shared/7m88x3e9.js +0 -45
- package/dist/shared/8dqhth8c.js +0 -12
- package/dist/shared/j3rkk835.js +0 -99
- package/dist/shared/k68eedmy.js +0 -85
- package/dist/shared/venqrjna.js +0 -216
- package/dist/shared/wxr8cwns.js +0 -6
- package/dist/shared/y34a8714.js +0 -150
- package/dist/shared/zm0mafk4.js +0 -92
- package/dist/shared/zy8r7qvz.js +0 -116
- package/dist/shared/{ywr8hmey.js → 606g0nbf.js} +3 -3
- package/dist/shared/{rpycarcr.js → gcefca6p.js} +4 -4
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `okm driver test`.
|
|
3
|
+
*
|
|
4
|
+
* The runner lives in the harness and reuses the conformance suites. This
|
|
5
|
+
* file only finds that runner and prints what it writes. Tooling does not
|
|
6
|
+
* import the harness.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Runs the conformance suites for the driver named on the command line.
|
|
10
|
+
*
|
|
11
|
+
* `<driver>` is `pglite`, `postgresjs`, `pg`, `bun`, `neon`, or a module path.
|
|
12
|
+
* `--url` is the Postgres URL. `pglite` does not use it. The other built-in
|
|
13
|
+
* drivers need `--url` or `DATABASE_URL`. A module whose export sets
|
|
14
|
+
* `memory: true` does not need a URL.
|
|
15
|
+
*
|
|
16
|
+
* The report is one header (`driver`, `dialect postgres`) and one row per
|
|
17
|
+
* case: id, behavior, result (`pass`, `fail`, or `unsupported`), and the
|
|
18
|
+
* capability when the result is unsupported. A failure exits through
|
|
19
|
+
* {@link OkmError}. An unsupported case does not.
|
|
20
|
+
*
|
|
21
|
+
* @param args - Arguments after `driver test`
|
|
22
|
+
* @param stdout - Where the report is written
|
|
23
|
+
*/
|
|
24
|
+
export declare function driverTest(args: readonly string[], stdout: (text: string) => void): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Path of the `okm driver test` runner.
|
|
27
|
+
*
|
|
28
|
+
* A source checkout finds `packages/harness/src/driver-run.ts` and the
|
|
29
|
+
* command spawns `bun`. The packed build writes
|
|
30
|
+
* `dist/tooling/driver-run.js`. Splitting puts this module in
|
|
31
|
+
* `dist/shared/`, so that file is one directory up from the chunk.
|
|
32
|
+
*
|
|
33
|
+
* @param here - Directory of this module
|
|
34
|
+
* @returns Runner path. The caller checks that the file exists
|
|
35
|
+
*/
|
|
36
|
+
export declare function driverRunnerPath(here: string): string;
|
|
@@ -22,8 +22,8 @@ export declare function formatFailure(error: unknown, verbose?: boolean): string
|
|
|
22
22
|
* Runs one `okm` invocation.
|
|
23
23
|
*
|
|
24
24
|
* `--version` stays in the bin. This function handles `build`, `check`,
|
|
25
|
-
* `generate`, `dev`, `push`, `seed`, `ext list`, `ext check`, `doctor`,
|
|
26
|
-
* `migrate plan`, `apply`, `status`, and `check`.
|
|
25
|
+
* `generate`, `dev`, `push`, `seed`, `ext list`, `ext check`, `doctor`,
|
|
26
|
+
* `driver test`, and `migrate plan`, `apply`, `status`, and `check`.
|
|
27
27
|
*
|
|
28
28
|
* @param argv - Arguments after the program name
|
|
29
29
|
* @param io - Working directory and stdout. Defaults to the process
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Engine-version checks `okm migrate apply` runs before the first statement.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* An explicit `uuidv7()` database default needs {@link UUIDV7_POSTGRES}.
|
|
5
|
+
* A bare `t.id()` stores `gen_random_uuid()` and does not match here.
|
|
6
|
+
* Nothing here is reachable from `connect()`.
|
|
6
7
|
*/
|
|
7
8
|
import type { DriverConnection } from "../../contracts/driver.js";
|
|
8
9
|
import type { StoredMigration } from "./files.js";
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import"../../shared/
|
|
2
|
-
import"../../shared/
|
|
1
|
+
import"../../shared/35q0n9tz.js";
|
|
2
|
+
import"../../shared/12z7aznj.js";
|
|
3
3
|
import"../../shared/n442h54c.js";
|
|
4
4
|
import {
|
|
5
5
|
applyTarget2,
|
|
6
6
|
backfillTiming2
|
|
7
|
-
} from "../../shared/
|
|
7
|
+
} from "../../shared/pan0370z.js";
|
|
8
8
|
import {
|
|
9
9
|
readReference
|
|
10
|
-
} from "../../shared/
|
|
11
|
-
import"../../shared/
|
|
12
|
-
import"../../shared/
|
|
10
|
+
} from "../../shared/mnvjvqyp.js";
|
|
11
|
+
import"../../shared/kj9d8maq.js";
|
|
12
|
+
import"../../shared/p3xbdcvt.js";
|
|
13
13
|
import {
|
|
14
14
|
projectPath,
|
|
15
15
|
loadMigrations,
|
|
16
16
|
loadHeadSnapshot,
|
|
17
17
|
loadBuiltSchema,
|
|
18
18
|
loadConfig
|
|
19
|
-
} from "../../shared/
|
|
19
|
+
} from "../../shared/f4jy1j7x.js";
|
|
20
20
|
import {
|
|
21
21
|
assertTargetPolicy,
|
|
22
22
|
selectTarget
|
|
23
|
-
} from "../../shared/
|
|
24
|
-
import"../../shared/
|
|
23
|
+
} from "../../shared/dpc2r7rb.js";
|
|
24
|
+
import"../../shared/sjk86yrx.js";
|
|
25
25
|
import {
|
|
26
26
|
OkmError2
|
|
27
27
|
} from "../../shared/52szzakm.js";
|
|
@@ -72,6 +72,9 @@ export declare function checkProject(cwd: string, flags?: InvokeFlags): Promise<
|
|
|
72
72
|
/**
|
|
73
73
|
* Table files whose names do not appear in the schema module.
|
|
74
74
|
*
|
|
75
|
+
* The stem is compared without case, so `Tasks.ts` matches `tasks` in the
|
|
76
|
+
* schema text. A case-insensitive volume still loads that import.
|
|
77
|
+
*
|
|
75
78
|
* @param schemaSource - Source text of the schema module
|
|
76
79
|
* @param fileNames - File names in the tables directory
|
|
77
80
|
* @returns Files `okm check` reports as OKM1024
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OkmError,
|
|
3
|
+
tag
|
|
4
|
+
} from "./f9mphxej.js";
|
|
5
|
+
|
|
6
|
+
// src/dialects/pg/filter-parse.ts
|
|
7
|
+
var PARSED = [
|
|
8
|
+
"eq",
|
|
9
|
+
"in",
|
|
10
|
+
"inList",
|
|
11
|
+
"notIn",
|
|
12
|
+
"lt",
|
|
13
|
+
"lte",
|
|
14
|
+
"gt",
|
|
15
|
+
"gte",
|
|
16
|
+
"between",
|
|
17
|
+
"startsWith",
|
|
18
|
+
"endsWith",
|
|
19
|
+
"contains",
|
|
20
|
+
"like",
|
|
21
|
+
"ilike",
|
|
22
|
+
"not",
|
|
23
|
+
"containedBy",
|
|
24
|
+
"overlaps",
|
|
25
|
+
"hasKey",
|
|
26
|
+
"hasAnyKey"
|
|
27
|
+
];
|
|
28
|
+
var PARSED_OPS = `,${PARSED.join(",")},`;
|
|
29
|
+
var PARSED_FIX = "Use eq, in, notIn, lt, lte, gt, gte, between, startsWith, endsWith, contains, like, ilike, not, containedBy, overlaps, hasKey, or hasAnyKey.";
|
|
30
|
+
function parseQuery(allow, sort, query, relations) {
|
|
31
|
+
if (typeof query !== "object" || query === null || Array.isArray(query)) {
|
|
32
|
+
throw new OkmError("OKM1121", "filters parse expects an object of fields.");
|
|
33
|
+
}
|
|
34
|
+
for (const field of Object.keys(allow)) {
|
|
35
|
+
for (const op of allow[field] ?? []) {
|
|
36
|
+
if (PARSED_OPS.includes(`,${op},`))
|
|
37
|
+
continue;
|
|
38
|
+
throw new OkmError("OKM1120", `filters() cannot apply ${op} on ${field}.`, {
|
|
39
|
+
fix: { summary: PARSED_FIX }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const nested = relations ?? {};
|
|
44
|
+
const whereParts = [];
|
|
45
|
+
let orderBy;
|
|
46
|
+
for (const key of Object.keys(query)) {
|
|
47
|
+
const value = query[key];
|
|
48
|
+
if (key === "sort" && typeof value === "string" && sort.includes(value)) {
|
|
49
|
+
orderBy = { [value]: "asc" };
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (Object.hasOwn(allow, key)) {
|
|
53
|
+
whereParts.push(...clauses(key, allow[key] ?? [], value));
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (Object.hasOwn(nested, key)) {
|
|
57
|
+
whereParts.push(relationClause(key, nested[key] ?? [], value));
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
throw new OkmError("OKM1123", `Field ${key} is not in the allow list.`, {
|
|
61
|
+
fix: { summary: "Remove the field, or add it to filters({ allow }) or relations." }
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const where = combine(whereParts);
|
|
65
|
+
return orderBy === undefined ? { where } : { where, orderBy };
|
|
66
|
+
}
|
|
67
|
+
function clauses(field, ops, value) {
|
|
68
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
69
|
+
if (!ops.includes("eq")) {
|
|
70
|
+
throw new OkmError("OKM1120", `filters() cannot apply eq on ${field}.`, {
|
|
71
|
+
fix: { summary: "Add eq to that field, or send an object of allowed operators." }
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return [{ [field]: value }];
|
|
75
|
+
}
|
|
76
|
+
const applied = [];
|
|
77
|
+
for (const op of Object.keys(value)) {
|
|
78
|
+
if (!Object.hasOwn(value, op))
|
|
79
|
+
continue;
|
|
80
|
+
if (!ops.includes(op) && !(op === "inList" && ops.includes("in"))) {
|
|
81
|
+
throw new OkmError("OKM1120", `filters() cannot apply ${op} on ${field}.`, {
|
|
82
|
+
fix: { summary: "Send an operator that field's allow list names." }
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
applied.push(one(field, op, value[op]));
|
|
86
|
+
}
|
|
87
|
+
if (applied.length === 0) {
|
|
88
|
+
throw new OkmError("OKM1120", `filters() cannot apply a value on ${field}.`, {
|
|
89
|
+
fix: { summary: "Send eq as a scalar, or an object of allowed operators." }
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return applied;
|
|
93
|
+
}
|
|
94
|
+
function one(field, op, value) {
|
|
95
|
+
switch (op) {
|
|
96
|
+
case "eq":
|
|
97
|
+
return {
|
|
98
|
+
[field]: value !== null && typeof value === "object" ? tag("eq", value) : value
|
|
99
|
+
};
|
|
100
|
+
case "in":
|
|
101
|
+
case "inList":
|
|
102
|
+
return { [field]: tag("inList", list(value, op)) };
|
|
103
|
+
case "notIn":
|
|
104
|
+
return { [field]: tag("notIn", list(value, op)) };
|
|
105
|
+
case "lt":
|
|
106
|
+
return { [field]: tag("lt", value) };
|
|
107
|
+
case "lte":
|
|
108
|
+
return { [field]: tag("lte", value) };
|
|
109
|
+
case "gt":
|
|
110
|
+
return { [field]: tag("gt", value) };
|
|
111
|
+
case "gte":
|
|
112
|
+
return { [field]: tag("gte", value) };
|
|
113
|
+
case "between": {
|
|
114
|
+
if (!Array.isArray(value) || value.length !== 2) {
|
|
115
|
+
throw new OkmError("OKM1120", `between on ${field} needs two bounds.`, {
|
|
116
|
+
fix: { summary: "Send between as [from, to]." }
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return { [field]: tag("between", [value[0], value[1]]) };
|
|
120
|
+
}
|
|
121
|
+
case "startsWith":
|
|
122
|
+
return { [field]: tag("startsWith", text(value, op)) };
|
|
123
|
+
case "endsWith":
|
|
124
|
+
return { [field]: tag("endsWith", text(value, op)) };
|
|
125
|
+
case "contains":
|
|
126
|
+
return { [field]: tag("contains", value) };
|
|
127
|
+
case "not":
|
|
128
|
+
if (value !== null && typeof value === "object") {
|
|
129
|
+
throw new OkmError("OKM1120", `not on ${field} takes a scalar.`, {
|
|
130
|
+
fix: { summary: "Send not a scalar or null. Nested operators are not accepted." }
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return { [field]: tag("not", value) };
|
|
134
|
+
case "containedBy":
|
|
135
|
+
return { [field]: tag("containedBy", value) };
|
|
136
|
+
case "overlaps":
|
|
137
|
+
return { [field]: tag("overlaps", value) };
|
|
138
|
+
case "hasKey":
|
|
139
|
+
return { [field]: tag("hasKey", text(value, "hasKey")) };
|
|
140
|
+
case "hasAnyKey":
|
|
141
|
+
return { [field]: tag("hasAnyKey", strings(value, field)) };
|
|
142
|
+
case "like":
|
|
143
|
+
return { [field]: tag("like", text(value, op)) };
|
|
144
|
+
case "ilike":
|
|
145
|
+
return { [field]: tag("ilike", text(value, op)) };
|
|
146
|
+
default:
|
|
147
|
+
throw new OkmError("OKM1120", `filters() cannot apply ${op} on ${field}.`, {
|
|
148
|
+
fix: { summary: "Use an operator parse applies." }
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function relationClause(name, fields, value) {
|
|
153
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
154
|
+
throw new OkmError("OKM1120", `filters() cannot apply a value on ${name}.`, {
|
|
155
|
+
fix: { summary: "Send the relation an object of allowlisted fields." }
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const parts = [];
|
|
159
|
+
for (const field of Object.keys(value)) {
|
|
160
|
+
if (!Object.hasOwn(value, field))
|
|
161
|
+
continue;
|
|
162
|
+
if (!fields.includes(field)) {
|
|
163
|
+
throw new OkmError("OKM1123", `Field ${field} is not in the allow list.`, {
|
|
164
|
+
fix: { summary: "Remove the field, or add it to filters({ relations })." }
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
parts.push(...clauses(field, PARSED, value[field]));
|
|
168
|
+
}
|
|
169
|
+
if (parts.length === 0) {
|
|
170
|
+
throw new OkmError("OKM1120", `filters() cannot apply a value on ${name}.`, {
|
|
171
|
+
fix: { summary: "Send the relation an object of allowlisted fields." }
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return { [name]: tag("has", combine(parts)) };
|
|
175
|
+
}
|
|
176
|
+
function combine(parts) {
|
|
177
|
+
const first = parts[0];
|
|
178
|
+
if (first === undefined)
|
|
179
|
+
return {};
|
|
180
|
+
if (parts.length === 1)
|
|
181
|
+
return first;
|
|
182
|
+
return tag("and", parts);
|
|
183
|
+
}
|
|
184
|
+
function list(value, op) {
|
|
185
|
+
if (!Array.isArray(value)) {
|
|
186
|
+
throw new OkmError("OKM1120", `${op} needs an array.`, {
|
|
187
|
+
fix: { summary: "Send that operator an array of values." }
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return value;
|
|
191
|
+
}
|
|
192
|
+
function strings(value, field) {
|
|
193
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
194
|
+
throw new OkmError("OKM1120", `hasAnyKey on ${field} needs an array of strings.`, {
|
|
195
|
+
fix: { summary: "Send hasAnyKey an array of strings." }
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
function text(value, op) {
|
|
201
|
+
if (typeof value !== "string") {
|
|
202
|
+
throw new OkmError("OKM1120", `${op} needs a string.`, {
|
|
203
|
+
fix: { summary: "Send that operator a string." }
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
parseQuery
|
|
210
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import {
|
|
2
|
+
refusePrototypeKey
|
|
3
|
+
} from "./ppnnnvj8.js";
|
|
4
|
+
import {
|
|
5
|
+
throwNamed,
|
|
6
|
+
parseOrder,
|
|
7
|
+
projectExpr,
|
|
8
|
+
quote,
|
|
9
|
+
list,
|
|
10
|
+
isRecord,
|
|
11
|
+
fail2
|
|
12
|
+
} from "./f9mphxej.js";
|
|
13
|
+
|
|
14
|
+
// src/dialects/pg/ops/bucket.ts
|
|
15
|
+
var RUNTIME = Symbol.for("okmodel.bucket");
|
|
16
|
+
function isBucket(value) {
|
|
17
|
+
return typeof value === "object" && value !== null && RUNTIME in value;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/runtime/bucket-group.ts
|
|
21
|
+
function readBucket(table, value, fields, aliases) {
|
|
22
|
+
if (!isBucket(value))
|
|
23
|
+
fail2("OKM1120", "bucket group");
|
|
24
|
+
const column = typeof value.column === "string" ? table.columns.get(value.column) : undefined;
|
|
25
|
+
if (typeof value.column !== "string" || column === undefined) {
|
|
26
|
+
throwNamed("OKM1120", String(value.column), table.names, `Field ${String(value.column)} is not on ${table.model.name}. Accepted names: ${list(table.names)}.`);
|
|
27
|
+
}
|
|
28
|
+
if (column.hidden) {
|
|
29
|
+
fail2("OKM1120", `Field ${column.field} is hidden, so groupBy cannot read it.`);
|
|
30
|
+
}
|
|
31
|
+
const unit = unitOf(value.unit);
|
|
32
|
+
if (unit === undefined) {
|
|
33
|
+
fail2("OKM1120", `bucket() unit ${String(value.unit)} is not a time unit. Accepted units: second, minute, hour, day, week, month, quarter, year.`);
|
|
34
|
+
}
|
|
35
|
+
const shift = weekShift(value.weekStart, unit);
|
|
36
|
+
const kind = temporalKind(column.dataType);
|
|
37
|
+
if (kind !== "timestamptz" && kind !== "date") {
|
|
38
|
+
fail2("OKM1120", `bucket() does not apply to ${kind === "timestamp" ? "timestamp" : column.dataType} column ${column.field}. Use timestamptz or date.`);
|
|
39
|
+
}
|
|
40
|
+
if (kind === "date" && clockUnit(unit)) {
|
|
41
|
+
fail2("OKM1120", `bucket() unit ${unit} does not apply to date column ${column.field}. Accepted units: day, week, month, quarter, year.`);
|
|
42
|
+
}
|
|
43
|
+
let tz;
|
|
44
|
+
if (kind === "timestamptz") {
|
|
45
|
+
if (typeof value.tz !== "string") {
|
|
46
|
+
fail2("OKM1120", `bucket() on timestamptz column ${column.field} needs tz, an IANA time zone.`);
|
|
47
|
+
}
|
|
48
|
+
if (!iana(value.tz))
|
|
49
|
+
fail2("OKM1120", `bucket() tz ${value.tz} is not an IANA time zone.`);
|
|
50
|
+
tz = value.tz;
|
|
51
|
+
} else if (value.tz !== undefined) {
|
|
52
|
+
fail2("OKM1120", `bucket() on date column ${column.field} does not take tz.`);
|
|
53
|
+
}
|
|
54
|
+
if (typeof value.as !== "string" || value.as.length === 0) {
|
|
55
|
+
fail2("OKM1120", "bucket() needs as, the name of the result key.");
|
|
56
|
+
}
|
|
57
|
+
refusePrototypeKey(value.as, "bucket as");
|
|
58
|
+
if (value.as === "count" || value.as === "sum" || value.as === "avg" || value.as === "min" || value.as === "max") {
|
|
59
|
+
fail2("OKM1120", `bucket as ${value.as} clashes with an aggregate key.`);
|
|
60
|
+
}
|
|
61
|
+
if (fields.has(value.as) || aliases.has(value.as)) {
|
|
62
|
+
fail2("OKM1120", `bucket as ${value.as} clashes with another group.`);
|
|
63
|
+
}
|
|
64
|
+
aliases.add(value.as);
|
|
65
|
+
return { kind: "bucket", column, unit, tz, as: value.as, shift, clock: clockUnit(unit) };
|
|
66
|
+
}
|
|
67
|
+
function writeBucket(sink, outputs, wrote, group) {
|
|
68
|
+
if (wrote.at > 0)
|
|
69
|
+
sink.text(", ");
|
|
70
|
+
if (group.clock)
|
|
71
|
+
emitClock(sink, group);
|
|
72
|
+
else
|
|
73
|
+
emitCalendar(sink, group);
|
|
74
|
+
outputs?.fields.push({
|
|
75
|
+
key: `g:${group.as}`,
|
|
76
|
+
at: wrote.at,
|
|
77
|
+
decode: bucketDecode(group)
|
|
78
|
+
});
|
|
79
|
+
wrote.at += 1;
|
|
80
|
+
}
|
|
81
|
+
function writeGrouped(sink, names, orderBy) {
|
|
82
|
+
sink.text(ordinals(names.length));
|
|
83
|
+
if (isRecord(orderBy) && Object.keys(orderBy).length > 0) {
|
|
84
|
+
sink.text(" order by ");
|
|
85
|
+
const keys = Object.keys(orderBy);
|
|
86
|
+
for (let index = 0;index < keys.length; index += 1) {
|
|
87
|
+
const key = keys[index];
|
|
88
|
+
if (key === undefined)
|
|
89
|
+
continue;
|
|
90
|
+
const parsed = parseOrder(key, orderBy[key]);
|
|
91
|
+
if (index > 0)
|
|
92
|
+
sink.text(", ");
|
|
93
|
+
sink.text(String(names.indexOf(key) + 1));
|
|
94
|
+
sink.text(parsed.dir === "asc" ? " asc" : " desc");
|
|
95
|
+
sink.text(parsed.nulls === "first" ? " nulls first" : " nulls last");
|
|
96
|
+
sink.mark(`o:${key}:${parsed.dir}:${parsed.nulls}`);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
sink.text(" order by ");
|
|
101
|
+
const parts = [];
|
|
102
|
+
for (let index = 1;index <= names.length; index += 1) {
|
|
103
|
+
parts.push(`${String(index)} asc nulls last`);
|
|
104
|
+
}
|
|
105
|
+
sink.text(parts.join(", "));
|
|
106
|
+
}
|
|
107
|
+
function unitOf(value) {
|
|
108
|
+
if (value === "second" || value === "minute" || value === "hour" || value === "day" || value === "week" || value === "month" || value === "quarter" || value === "year") {
|
|
109
|
+
return value;
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
function clockUnit(unit) {
|
|
114
|
+
return unit === "second" || unit === "minute" || unit === "hour";
|
|
115
|
+
}
|
|
116
|
+
function weekShift(value, unit) {
|
|
117
|
+
if (value === undefined)
|
|
118
|
+
return 0;
|
|
119
|
+
if (unit !== "week")
|
|
120
|
+
fail2("OKM1120", "bucket() weekStart applies to unit week.");
|
|
121
|
+
if (value === "monday")
|
|
122
|
+
return 0;
|
|
123
|
+
if (value === "sunday")
|
|
124
|
+
return 1;
|
|
125
|
+
if (value === "saturday")
|
|
126
|
+
return 2;
|
|
127
|
+
return fail2("OKM1120", "bucket() weekStart must be monday, sunday, or saturday.");
|
|
128
|
+
}
|
|
129
|
+
function temporalKind(dataType) {
|
|
130
|
+
if (dataType === "date")
|
|
131
|
+
return "date";
|
|
132
|
+
if (dataType === "timestamptz" || dataType.startsWith("timestamptz("))
|
|
133
|
+
return "timestamptz";
|
|
134
|
+
if (dataType === "timestamp" || dataType.startsWith("timestamp("))
|
|
135
|
+
return "timestamp";
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
function iana(tz) {
|
|
139
|
+
try {
|
|
140
|
+
Intl.DateTimeFormat("en-US", { timeZone: tz });
|
|
141
|
+
return true;
|
|
142
|
+
} catch {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function bucketDecode(group) {
|
|
147
|
+
if (group.clock || !group.column.dataType.startsWith("timestamptz"))
|
|
148
|
+
return group.column.decode;
|
|
149
|
+
return decodeDay;
|
|
150
|
+
}
|
|
151
|
+
function decodeDay(wire) {
|
|
152
|
+
const temporal = globalThis.Temporal;
|
|
153
|
+
if (typeof temporal !== "object" || temporal === null || !("PlainDate" in temporal)) {
|
|
154
|
+
return fail2("OKM1120", "Date and time codecs need the Temporal global. okmodel does not ship a polyfill. Use a runtime that provides Temporal, or assign a polyfill to globalThis.Temporal before using these columns.");
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
return temporal.PlainDate.from(wire);
|
|
158
|
+
} catch {
|
|
159
|
+
return fail2("OKM1120", `date ${wire} must be YYYY-MM-DD.`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
var ZONE = "\x00";
|
|
163
|
+
function emitClock(sink, group) {
|
|
164
|
+
const column = `t.${quote(group.column.sql)}`;
|
|
165
|
+
const wrapped = projectExpr(`date_trunc('${group.unit}', ${column}, ${ZONE})`, "timestamptz");
|
|
166
|
+
const at = wrapped.indexOf(ZONE);
|
|
167
|
+
sink.text(wrapped.slice(0, at));
|
|
168
|
+
sink.param(group.tz ?? "");
|
|
169
|
+
sink.text(wrapped.slice(at + ZONE.length));
|
|
170
|
+
}
|
|
171
|
+
function emitCalendar(sink, group) {
|
|
172
|
+
const column = `t.${quote(group.column.sql)}`;
|
|
173
|
+
sink.text("(date_trunc('");
|
|
174
|
+
sink.text(group.unit);
|
|
175
|
+
sink.text("', ");
|
|
176
|
+
emitLocal(sink, column, group.tz);
|
|
177
|
+
if (group.shift === 0) {
|
|
178
|
+
sink.text("))::date");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const days = group.shift === 1 ? "1 day" : "2 days";
|
|
182
|
+
sink.text(" + interval '");
|
|
183
|
+
sink.text(days);
|
|
184
|
+
sink.text("') - interval '");
|
|
185
|
+
sink.text(days);
|
|
186
|
+
sink.text("')::date");
|
|
187
|
+
}
|
|
188
|
+
function emitLocal(sink, column, tz) {
|
|
189
|
+
if (tz === undefined) {
|
|
190
|
+
sink.text(column);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
sink.text("(");
|
|
194
|
+
sink.text(column);
|
|
195
|
+
sink.text(" AT TIME ZONE ");
|
|
196
|
+
sink.param(tz);
|
|
197
|
+
sink.text(")");
|
|
198
|
+
}
|
|
199
|
+
function ordinals(count) {
|
|
200
|
+
const parts = [];
|
|
201
|
+
for (let index = 1;index <= count; index += 1)
|
|
202
|
+
parts.push(String(index));
|
|
203
|
+
return parts.join(", ");
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
readBucket,
|
|
207
|
+
writeBucket,
|
|
208
|
+
writeGrouped
|
|
209
|
+
};
|