ts-prorm-orm 1.2.3 → 2.0.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/CHANGELOG.md +199 -1
- package/README.md +32 -24
- package/dist/compliance/index.d.ts +2 -0
- package/dist/compliance/index.js +13 -1
- package/dist/connection-manager.js +13 -1
- package/dist/core/expressions.d.ts +58 -0
- package/dist/core/expressions.js +83 -0
- package/dist/core/hooks-manager.d.ts +179 -0
- package/dist/core/hooks-manager.js +291 -0
- package/dist/core/types.d.ts +235 -0
- package/dist/core/types.js +9 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +11 -1
- package/dist/diagrams/chen-diagram.d.ts +15 -12
- package/dist/diagrams/chen-diagram.js +76 -85
- package/dist/diagrams/class-diagram.d.ts +9 -8
- package/dist/diagrams/class-diagram.js +60 -82
- package/dist/diagrams/core/index.d.ts +13 -0
- package/dist/diagrams/core/index.js +33 -0
- package/dist/diagrams/core/layout.d.ts +104 -0
- package/dist/diagrams/core/layout.js +223 -0
- package/dist/diagrams/{svg-dom.d.ts → core/svg.d.ts} +8 -20
- package/dist/diagrams/{svg-dom.js → core/svg.js} +21 -29
- package/dist/diagrams/core/theme.d.ts +84 -0
- package/dist/diagrams/core/theme.js +62 -0
- package/dist/diagrams/dependency-diagram.d.ts +15 -14
- package/dist/diagrams/dependency-diagram.js +71 -105
- package/dist/diagrams/er-diagram.d.ts +13 -26
- package/dist/diagrams/er-diagram.js +180 -259
- package/dist/diagrams/flow-diagram.d.ts +16 -11
- package/dist/diagrams/flow-diagram.js +96 -91
- package/dist/diagrams/gantt-diagram.d.ts +10 -5
- package/dist/diagrams/gantt-diagram.js +77 -103
- package/dist/diagrams/index-diagram.d.ts +10 -10
- package/dist/diagrams/index-diagram.js +106 -116
- package/dist/diagrams/index.d.ts +6 -9
- package/dist/diagrams/index.js +9 -24
- package/dist/diagrams/migration-diagram.d.ts +8 -4
- package/dist/diagrams/migration-diagram.js +189 -161
- package/dist/diagrams/model-diagram.d.ts +34 -34
- package/dist/diagrams/model-diagram.js +106 -485
- package/dist/diagrams/package-diagram.d.ts +9 -6
- package/dist/diagrams/package-diagram.js +64 -101
- package/dist/diagrams/relational-diagram.d.ts +12 -10
- package/dist/diagrams/relational-diagram.js +87 -114
- package/dist/diagrams/schemadoc-diagram.d.ts +8 -8
- package/dist/diagrams/schemadoc-diagram.js +71 -93
- package/dist/diagrams/sequence-diagram.d.ts +10 -10
- package/dist/diagrams/sequence-diagram.js +64 -89
- package/dist/diagrams/state-diagram.d.ts +10 -9
- package/dist/diagrams/state-diagram.js +69 -92
- package/dist/diagrams/tree-diagram.d.ts +11 -5
- package/dist/diagrams/tree-diagram.js +41 -65
- package/dist/dialects/clickhouse/index.js +15 -0
- package/dist/dialects/cockroachdb/index.d.ts +1 -1
- package/dist/dialects/cockroachdb/index.js +32 -63
- package/dist/dialects/db2/index.js +23 -8
- package/dist/dialects/dialect.d.ts +29 -5
- package/dist/dialects/duckdb/index.js +9 -2
- package/dist/dialects/hana/index.js +22 -5
- package/dist/dialects/lock-clause-helper.d.ts +167 -0
- package/dist/dialects/lock-clause-helper.js +316 -0
- package/dist/dialects/mariadb/index.d.ts +7 -4
- package/dist/dialects/mariadb/index.js +36 -60
- package/dist/dialects/mssql/index.js +34 -3
- package/dist/dialects/mysql/index.d.ts +1 -1
- package/dist/dialects/mysql/index.js +17 -45
- package/dist/dialects/oracle/index.d.ts +14 -3
- package/dist/dialects/oracle/index.js +66 -36
- package/dist/dialects/order-expression-helper.d.ts +72 -0
- package/dist/dialects/order-expression-helper.js +154 -0
- package/dist/dialects/partial-index.d.ts +52 -0
- package/dist/dialects/partial-index.js +251 -0
- package/dist/dialects/postgres/index.d.ts +1 -1
- package/dist/dialects/postgres/index.js +43 -68
- package/dist/dialects/redshift/index.js +9 -2
- package/dist/dialects/snowflake/index.js +17 -0
- package/dist/dialects/spanner/index.js +7 -2
- package/dist/dialects/sqlite/driver.d.ts +55 -0
- package/dist/dialects/sqlite/driver.js +102 -0
- package/dist/dialects/sqlite/index.d.ts +1 -1
- package/dist/dialects/sqlite/index.js +49 -27
- package/dist/graph/base-graph-dialect.d.ts +24 -3
- package/dist/graph/base-graph-dialect.js +43 -2
- package/dist/graph/dgraph/index.js +6 -0
- package/dist/graph/gremlin/index.d.ts +6 -0
- package/dist/graph/gremlin/index.js +12 -1
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/neo4j/index.d.ts +2 -0
- package/dist/graph/neo4j/index.js +6 -1
- package/dist/graph/types.d.ts +12 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +53 -7
- package/dist/logging/index.d.ts +10 -0
- package/dist/logging/index.js +23 -0
- package/dist/logging/query-logging.d.ts +82 -0
- package/dist/logging/query-logging.js +102 -0
- package/dist/models/decorators.d.ts +39 -3
- package/dist/models/decorators.js +74 -0
- package/dist/models/eager-load.d.ts +99 -0
- package/dist/models/eager-load.js +348 -5
- package/dist/models/indexes.d.ts +3 -2
- package/dist/models/indexes.js +7 -1
- package/dist/models/model.js +69 -43
- package/dist/prorm.d.ts +175 -409
- package/dist/prorm.js +1132 -553
- package/dist/query-builders/order-limit-builder.js +12 -10
- package/dist/query-builders/sql-compiler.d.ts +10 -3
- package/dist/query-builders/sql-compiler.js +14 -43
- package/dist/query-interface.d.ts +2 -1
- package/dist/sql-constants.d.ts +44 -0
- package/dist/sql-constants.js +138 -1
- package/dist/types/index.d.ts +53 -17
- package/dist/types/index.js +10 -15
- package/dist/types/query-types.d.ts +26 -0
- package/dist/types/query-types.js +30 -0
- package/package.json +32 -5
- package/dist/decorators/belongs-to-many.js +0 -115
- package/dist/decorators/belongs-to.js +0 -115
- package/dist/decorators/has-many.js +0 -127
- package/dist/decorators/has-one.js +0 -116
- package/dist/diagrams/palette.d.ts +0 -138
- package/dist/diagrams/palette.js +0 -194
- package/dist/hooks/hooks-manager.d.ts +0 -189
- package/dist/hooks/hooks-manager.js +0 -350
- package/dist/hooks/index.d.ts +0 -8
- package/dist/hooks/index.js +0 -37
- /package/dist/{logging.d.ts → logging/logger.d.ts} +0 -0
- /package/dist/{logging.js → logging/logger.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,16 +5,147 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [2.0.0]
|
|
9
|
+
|
|
10
|
+
### Breaking
|
|
11
|
+
|
|
12
|
+
- **JSON/JSONB columns now return parsed values on every dialect.** Previously
|
|
13
|
+
the PostgreSQL and MySQL drivers returned an object while SQLite (and any
|
|
14
|
+
dialect storing JSON as TEXT) returned the raw string. Reads are now
|
|
15
|
+
consistent, which means **code that called `JSON.parse` on the result under
|
|
16
|
+
SQLite must drop that call** — it will now be parsing an object.
|
|
17
|
+
|
|
18
|
+
This is the only change requiring action on upgrade. Text that isn't valid
|
|
19
|
+
JSON is still returned as-is rather than throwing, so rows written by earlier
|
|
20
|
+
versions read back correctly.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **JSON/JSONB columns now round-trip losslessly, and read back as parsed
|
|
25
|
+
values on every dialect.** Two separate problems, fixed together.
|
|
26
|
+
|
|
27
|
+
*Reads were dialect-specific.* The PostgreSQL and MySQL drivers already
|
|
28
|
+
returned an object; SQLite (and anything else storing JSON as TEXT) returned
|
|
29
|
+
the raw string, so the same model code behaved differently per engine.
|
|
30
|
+
`findAll`/`findOne`/`findByPk` now parse the string form everywhere.
|
|
31
|
+
**If you were calling `JSON.parse` yourself on SQLite, remove it** — the value
|
|
32
|
+
arrives parsed. Values that are already objects are untouched, and text that
|
|
33
|
+
isn't valid JSON is returned as-is rather than throwing, so rows written
|
|
34
|
+
before this release still read back correctly.
|
|
35
|
+
|
|
36
|
+
*Writes were asymmetric with reads.* A string value was written to the column
|
|
37
|
+
**unencoded** while the read side parsed unconditionally, so any string that
|
|
38
|
+
happened to be valid JSON changed type on the way back: `'123'` returned the
|
|
39
|
+
number `123`, `'true'` a boolean, `'{"a":1}'` an object, and
|
|
40
|
+
`'12345678901234567890'` came back as `12345678901234567000` — silent
|
|
41
|
+
precision loss. It also wrote invalid JSON on PostgreSQL, which rejects a bare
|
|
42
|
+
`hello` for a `json` column. Every value is now encoded on write, strings
|
|
43
|
+
included, in both the `define()` and class-based paths.
|
|
44
|
+
|
|
45
|
+
- **JSON/JSONB values were not serialized on write at all in some paths.** A
|
|
46
|
+
plain object survived by accident (the dialect's value escaper stringifies
|
|
47
|
+
objects), but an array was expanded into the `(a, b)` IN-list form and
|
|
48
|
+
produced invalid SQL. `create`, `bulkCreate`, `update` and `upsert` now
|
|
49
|
+
serialize explicitly.
|
|
9
50
|
|
|
10
51
|
### Fixed
|
|
11
52
|
|
|
53
|
+
- **`FindOptions.lock` never reached the dialect.** `findAll({ lock: 'UPDATE',
|
|
54
|
+
transaction: t })` compiled to a plain SELECT, so code written to serialize
|
|
55
|
+
concurrent updates took no lock at all. It is now forwarded, and PostgreSQL /
|
|
56
|
+
MySQL emit `FOR UPDATE` / `FOR SHARE` / `LOCK IN SHARE MODE` as documented.
|
|
57
|
+
Dialects without row-level locking (SQLite) still ignore it.
|
|
58
|
+
- **`FindOptions.union` / `unionType` were silently no-ops** on models built by
|
|
59
|
+
`prorm.define()` — the branches were declared, documented and compiled by the
|
|
60
|
+
dialects, but never passed to them, so only the main query ran.
|
|
61
|
+
- **`FindOptions.using` never worked.** It resolved the target through
|
|
62
|
+
`prorm.connectionManager`, which nothing ever set, so every call threw
|
|
63
|
+
`Connection 'x' not found. Available: none`; the class-based path then called
|
|
64
|
+
`.get()` on a plain object. `ConnectionManager.addConnection()` now registers
|
|
65
|
+
itself on the instance it creates, and `using` is implemented on both query
|
|
66
|
+
paths.
|
|
12
67
|
- **`raw: true` was accepted and ignored.** Rows came back as full model
|
|
13
68
|
instances carrying `save`/`update`/`destroy` and internal bookkeeping fields
|
|
14
69
|
— slower than asked for, and wrong for grouped aggregates that correspond to
|
|
15
70
|
no model instance. It now returns plain row objects.
|
|
16
71
|
- `normalizeOperatorKeys` is exported from the package root, alongside the
|
|
17
72
|
`operatorToWhereKey` and `getOperatorString` helpers it belongs with.
|
|
73
|
+
- **Row locking never compiled from the object form.** `lock: { level: 'UPDATE' }`
|
|
74
|
+
— and any object carrying `nowait` / `skipLocked` — emitted no lock clause at
|
|
75
|
+
all. Every documented shape now compiles across 9 dialects, including SQL
|
|
76
|
+
Server's table-hint syntax (`WITH (UPDLOCK, ROWLOCK, READPAST)`). A level a
|
|
77
|
+
dialect lacks throws naming the supported levels.
|
|
78
|
+
- **Composite unique constraints were never emitted.** Neither the `uniqueKeys`
|
|
79
|
+
model option nor the attribute-level `uniqueKey` grouping produced any SQL, so
|
|
80
|
+
uniqueness the model declared was never enforced by the database. Worse,
|
|
81
|
+
`sync({ alter: true })` *destroyed* constraints that had been emitted, because
|
|
82
|
+
SQLite implements `changeColumn` by rebuilding the table and the rebuild
|
|
83
|
+
dropped the `UNIQUE` clause. Both declaration forms now emit a real
|
|
84
|
+
constraint, and declared keys are re-applied after an alter.
|
|
85
|
+
- **Partial indexes.** `IndexOptions.where` compiled to bound placeholders,
|
|
86
|
+
which no database accepts in a `CREATE INDEX` predicate. Db2, SAP HANA and
|
|
87
|
+
ClickHouse silently dropped the predicate and returned an **unfiltered**
|
|
88
|
+
index; MariaDB and Oracle emitted a `WHERE` clause they have never accepted.
|
|
89
|
+
Predicates are now inlined as escaped literals where supported, and dialects
|
|
90
|
+
without partial indexes throw with the reason.
|
|
91
|
+
- **`ORDER BY` was broken on three dialects.** `[['name','DESC']]` produced
|
|
92
|
+
`ORDER BY [0] NAME, [1] DESC` on SQL Server and Snowflake; on Oracle a plain
|
|
93
|
+
`'name'` emitted one term per *character*. The `asc()` / `desc()` / `random()`
|
|
94
|
+
helpers were silently ignored on every dialect and on all four graph
|
|
95
|
+
dialects. `random()` now resolves per engine — `NEWID()` on SQL Server, where
|
|
96
|
+
`RAND()` is a per-query constant and would not shuffle at all.
|
|
97
|
+
- **Two filtering `include`s on the same parent column** merged into a shape the
|
|
98
|
+
where-builders don't recognise, collapsed to `"id" = ?`, and returned one
|
|
99
|
+
arbitrary parent.
|
|
100
|
+
- **`{ all: true }` includes** were never expanded, and did not compose with
|
|
101
|
+
`required: true`.
|
|
102
|
+
- **A bare-model include** (`include: [Post]`) threw a `TypeError` at the top
|
|
103
|
+
level and silently loaded nothing when nested; 11 documented `IncludeOptions`
|
|
104
|
+
fields were being dropped when include entries were rebuilt.
|
|
105
|
+
- **`findAndCountAll` ignored `union`**, so `count` described only the main
|
|
106
|
+
branch while `rows` covered all of them.
|
|
107
|
+
- **Foreign-key check toggling emitted MySQL syntax on PostgreSQL.** It now
|
|
108
|
+
routes per dialect family, and dialects with no session-level switch throw
|
|
109
|
+
naming their own alternative.
|
|
110
|
+
- **The published package could ship a stale build.** `npm run build` was a
|
|
111
|
+
plain `tsc`, which emits but never deletes, so a leftover `dist/logging.js`
|
|
112
|
+
from a removed source file shadowed `dist/logging/index.js` — Node resolves a
|
|
113
|
+
file before a directory — and the built package threw
|
|
114
|
+
`logQuery is not a function` on `bulkCreate`. The test suite could not catch
|
|
115
|
+
it, because it runs against `src/`. `build` now cleans first, and
|
|
116
|
+
`check:package` fails the publish on any stale output.
|
|
117
|
+
|
|
118
|
+
### Added
|
|
119
|
+
|
|
120
|
+
- **30 previously unreachable exports.** `src/cache`, `src/audit`,
|
|
121
|
+
`src/prisma-migrate`, the `@Audit` decorator, `GraphCapabilityError` and
|
|
122
|
+
`DataLineage` were implemented but not exported, and the `exports` map allowed
|
|
123
|
+
no deep imports either. Five colliding cache type names are aliased so no
|
|
124
|
+
existing export changed meaning. `ts-prorm-orm/cache`, `/audit`, `/graph` and
|
|
125
|
+
`/prisma-migrate` subpaths expose them under their real names.
|
|
126
|
+
- **Bun support.** The SQLite dialect now resolves its driver per runtime:
|
|
127
|
+
`better-sqlite3` on Node, the built-in `bun:sqlite` on Bun. Bun needs no
|
|
128
|
+
native build step, and under Bun the better-sqlite3 addon may not be
|
|
129
|
+
installable at all. The two APIs differ in one place — bun:sqlite has no
|
|
130
|
+
`db.pragma()` — so the driver module adds it, keeping a single shape for the
|
|
131
|
+
dialect to code against with no runtime branching in the SQL layer. Under Bun
|
|
132
|
+
it still falls back to better-sqlite3 if that is what a project already
|
|
133
|
+
depends on. `scripts/bun-smoke.ts` exercises CRUD, operators, eager loading,
|
|
134
|
+
ordering, JSON, aggregates, paranoid deletes and transactions on Bun.
|
|
135
|
+
- **Documentation.** 29 developer guides plus an index, with every SQL example
|
|
136
|
+
captured from the running code rather than written from memory.
|
|
137
|
+
- **Tests.** ~4,000 connection-free tests across dialects, models, query
|
|
138
|
+
builders, compliance, optimizers, schema, graph and the CLI. `collectCoverageFrom`
|
|
139
|
+
now scopes coverage to shipped source (`src/test.ts` was inflating the
|
|
140
|
+
denominator despite being excluded from the build); no coverage threshold is
|
|
141
|
+
enforced.
|
|
142
|
+
|
|
143
|
+
### Removed
|
|
144
|
+
|
|
145
|
+
- **`docs-next`** and its entire Vercel deployment pipeline. Documentation is
|
|
146
|
+
now a static React viewer published to GitLab Pages, and database image
|
|
147
|
+
mirroring moved to the project's own GitLab Container Registry.
|
|
148
|
+
|
|
18
149
|
|
|
19
150
|
## [1.2.2]
|
|
20
151
|
|
|
@@ -42,6 +173,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
173
|
### Added
|
|
43
174
|
|
|
44
175
|
- **`avg()`** — the one standard aggregate that was missing.
|
|
176
|
+
- Removed `src/hooks/` — a 488-line model-level hook system imported by nothing
|
|
177
|
+
and exported from nowhere, the third such parallel implementation found (after
|
|
178
|
+
the association decorators and the duplicate eager-loaders). Its `HookName`
|
|
179
|
+
union was salvaged into `core/types`.
|
|
45
180
|
- `exports` now permits `ts-prorm-orm/package.json`, which build tooling and
|
|
46
181
|
version checks commonly read.
|
|
47
182
|
|
|
@@ -142,6 +277,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
142
277
|
|
|
143
278
|
## [Unreleased]
|
|
144
279
|
|
|
280
|
+
### Fixed
|
|
281
|
+
|
|
282
|
+
- **Query logging fired twice and ignored per-query overrides.** The user's
|
|
283
|
+
`logging` callback was handed to the internal Logger as well as being invoked
|
|
284
|
+
by the query path, so it ran on both - and the Logger's copy honoured no
|
|
285
|
+
per-query setting, making `findAll({ logging: false })` log anyway. The
|
|
286
|
+
internal Logger now handles only slow-query detection and its own levels.
|
|
287
|
+
- **Four operations logged nothing at all.** `count`, `bulkCreate`, `increment`
|
|
288
|
+
and the aggregates never emitted a line, so turning logging on showed an
|
|
289
|
+
incomplete picture of what the ORM was doing. Every operation now routes
|
|
290
|
+
through one path.
|
|
291
|
+
- **`instance.validate({ hooks: true })` ran no hooks.** It read a
|
|
292
|
+
`_hooksManager` property that nothing ever assigned, so the flag was accepted
|
|
293
|
+
and both `beforeValidate` and `afterValidate` were skipped. Both call sites
|
|
294
|
+
(prorm.ts and models/model.ts) now use the model's declared hooks, the same
|
|
295
|
+
source every other lifecycle hook comes from.
|
|
296
|
+
|
|
297
|
+
### Added
|
|
298
|
+
|
|
299
|
+
- **Sequelize-compatible query logging.** `logging` accepts `false`, `true` or a
|
|
300
|
+
`(sql, timing)` function at instance level, overridable per query - so one
|
|
301
|
+
noisy call can be traced without enabling logging globally, and one call can
|
|
302
|
+
be silenced without disabling it. Adds `benchmark` (append elapsed time) and
|
|
303
|
+
`logQueryParameters` (append bound values, off by default since bound values
|
|
304
|
+
routinely contain credentials). The resolution logic lives in
|
|
305
|
+
`src/logging/query-logging.ts` and is exported: `logQuery`,
|
|
306
|
+
`resolveQueryLogger`, `formatQueryLog`.
|
|
307
|
+
- **`unset<Association>()` on belongsTo** — clears the foreign key and persists
|
|
308
|
+
it. `set<Association>(null)` does the same thing and now explicitly accepts
|
|
309
|
+
null, but reads as an assignment rather than a removal.
|
|
310
|
+
- **`HookName` / `ModelHookMap` types** — hook names as a union rather than
|
|
311
|
+
`string`, so a misspelled hook is a compile error instead of a callback that
|
|
312
|
+
silently never runs.
|
|
313
|
+
- **`@AbstractModel`** — a base class that defines fields shared by several
|
|
314
|
+
models without getting a table of its own. Columns declared on it, and any
|
|
315
|
+
`@PrimaryKey` / `@AutoIncrement` / defaults on them, are inherited by the
|
|
316
|
+
concrete models that extend it; a subclass may redeclare a column to override
|
|
317
|
+
it. Passing the abstract class to `addModel()` is an error naming the class.
|
|
318
|
+
- **Finders**: `findOneOrFail` / `findByPkOrFail` (throw `EmptyResultError`
|
|
319
|
+
rather than returning null), `findLast` (inverts the ordering), `exists(where)`
|
|
320
|
+
(a COUNT rather than fetching a row), and `findInBatches` / `findEach` for
|
|
321
|
+
walking a large set without holding it in memory. Batching pages by primary
|
|
322
|
+
key rather than OFFSET, so per-batch cost stays flat and concurrent writes
|
|
323
|
+
cannot cause a page to be skipped.
|
|
324
|
+
- **Eleven lifecycle hooks that never fired for model-level operations**:
|
|
325
|
+
`beforeUpdate`/`afterUpdate`, `beforeDestroy`/`afterDestroy`,
|
|
326
|
+
`beforeSave`/`afterSave`, `beforeFind`/`afterFind`, `beforeCount`, and
|
|
327
|
+
`beforeUpsert`/`afterUpsert`. They existed for instance methods only, so
|
|
328
|
+
`Model.update(...)` bypassed them entirely. `beforeFind` may return replacement
|
|
329
|
+
options and `afterFind` a replacement result set.
|
|
330
|
+
- **`Model.increment()` / `Model.decrement()`** — add to or subtract from
|
|
331
|
+
numeric columns with `SET n = n + 1` in a single statement, so two concurrent
|
|
332
|
+
callers each apply their delta. Previously only per-instance helpers existed,
|
|
333
|
+
leaving a read-modify-write that silently drops one of two simultaneous
|
|
334
|
+
updates. Accepts a column, a list, or a per-column map; honours `where` and
|
|
335
|
+
paranoid filtering.
|
|
336
|
+
- **`Model.bulkUpdate(rows)`** — write different values to many rows in one
|
|
337
|
+
statement, compiled as a `CASE` per column (portable across every supported
|
|
338
|
+
dialect) rather than one UPDATE per row. Columns a row omits keep their
|
|
339
|
+
current value; rows not listed are untouched. Identify rows by a non-primary
|
|
340
|
+
column with `{ key }`.
|
|
341
|
+
|
|
342
|
+
|
|
145
343
|
### Comprehensive Feature Reference
|
|
146
344
|
|
|
147
345
|
This section provides a complete reference of all ORM features organized by category.
|
package/README.md
CHANGED
|
@@ -29,6 +29,13 @@ A TypeScript ORM supporting multiple database dialects with full TypeScript supp
|
|
|
29
29
|
- **Validation**: Built-in and custom validators
|
|
30
30
|
- **Stored Procedures**: Create and call stored procedures (across supported dialects)
|
|
31
31
|
- **Triggers**: Database triggers with FOR EACH ROW and WHEN clauses (across supported dialects)
|
|
32
|
+
- **Query logging**: Sequelize-compatible `logging` (`false` / `true` / a
|
|
33
|
+
`(sql, timing)` function), overridable per query, plus `benchmark` for elapsed
|
|
34
|
+
time and `logQueryParameters` for bound values. Every operation logs, not just
|
|
35
|
+
some
|
|
36
|
+
- **Bulk writes**: `increment`/`decrement` do the arithmetic in the database, so
|
|
37
|
+
concurrent updates don't lose each other; `bulkUpdate` writes different values
|
|
38
|
+
to many rows in one statement instead of one round trip per row
|
|
32
39
|
- **Aggregates**: `count`, `sum`, `avg`, `min`, `max` — all issuing real SQL
|
|
33
40
|
aggregates and honouring `where`, scopes, soft-deletes and relation filters;
|
|
34
41
|
`group` + `having` for grouped results
|
|
@@ -646,29 +653,30 @@ npm run diagram:model
|
|
|
646
653
|
|
|
647
654
|
## Documentation
|
|
648
655
|
|
|
649
|
-
Full documentation is
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
- [
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
- [
|
|
667
|
-
- [
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
- [
|
|
671
|
-
- [
|
|
656
|
+
Full documentation is in the [`docs/`](./docs/README.md) directory — start
|
|
657
|
+
there for the complete index.
|
|
658
|
+
|
|
659
|
+
**Core**
|
|
660
|
+
- [Defining models](./docs/guides/models.md) · [Data types](./docs/guides/data-types.md) · [Querying](./docs/guides/querying.md) · [Query operators](./docs/guides/query-operators.md)
|
|
661
|
+
- [SQL function builders](./docs/guides/sql-functions.md) · [Associations](./docs/guides/associations.md) · [Eager loading](./docs/guides/eager-loading.md) · [Scopes](./docs/guides/scopes.md) · [Hooks](./docs/guides/hooks.md) · [Validation](./docs/guides/validation.md) · [Virtual fields](./docs/guides/virtual-fields.md)
|
|
662
|
+
- [Transactions](./docs/guides/transactions.md) · [Bulk operations](./docs/guides/bulk-operations.md) · [Raw queries](./docs/guides/raw-queries.md) · [Streaming](./docs/guides/streams.md) · [Error handling](./docs/guides/error-handling.md)
|
|
663
|
+
|
|
664
|
+
**Schema**
|
|
665
|
+
- [Indexes & constraints](./docs/guides/indexes-and-constraints.md) · [Schema objects](./docs/guides/schema-objects.md) (views, triggers, procedures, sequences, RLS, partitions)
|
|
666
|
+
- [Migrations](./docs/guides/migrations.md) · [QueryInterface](./docs/guides/query-interface.md) · [Schema diffing](./docs/guides/schema-diffing.md) · [Prisma import](./docs/guides/prisma-import.md)
|
|
667
|
+
|
|
668
|
+
**Connections & performance**
|
|
669
|
+
- [Connection pooling](./docs/guides/connection-pooling.md) · [Multiple databases](./docs/guides/multiple-databases.md) · [Read replicas](./docs/guides/replication.md)
|
|
670
|
+
- [Caching](./docs/guides/caching.md) · [Query optimization](./docs/guides/query-optimization.md) · [Logging](./docs/guides/logging.md)
|
|
671
|
+
|
|
672
|
+
**Extending & operating**
|
|
673
|
+
- [Decorators](./docs/guides/decorators.md) · [TypeScript types](./docs/guides/typescript-types.md) · [External fields](./docs/guides/external-fields.md) · [SQL constants](./docs/guides/sql-constants.md) · [Extension catalogue](./docs/guides/extensions.md)
|
|
674
|
+
- [Audit logging](./docs/guides/audit-logging.md) · [User management](./docs/guides/user-management.md) · [Compliance](./docs/guides/compliance.md) · [Foreign data wrappers](./docs/guides/foreign-data-wrappers.md) · [Runbooks](./docs/runbooks/README.md)
|
|
675
|
+
|
|
676
|
+
**Databases & tooling**
|
|
677
|
+
- [Database types](./docs/database-types.md) · [SQL dialects](./docs/dialects/README.md) ([SQLite](./docs/dialects/sqlite.md), [PostgreSQL](./docs/dialects/postgres.md), [MySQL](./docs/dialects/mysql.md), [MariaDB](./docs/dialects/mariadb.md), [Oracle](./docs/dialects/oracle.md), [MSSQL](./docs/dialects/mssql.md), …)
|
|
678
|
+
- [Store adapters](./docs/stores/README.md) · [Graph databases](./docs/guides/graph-databases.md) · [SQLite advanced](./docs/guides/sqlite-advanced.md)
|
|
679
|
+
- [CLI](./docs/guides/cli.md) · [Diagrams](./docs/diagrams/README.md) · [Docker & sandboxes](./docs/guides/docker/)
|
|
672
680
|
|
|
673
681
|
### Architecture / Component Guides
|
|
674
682
|
|
|
@@ -676,7 +684,7 @@ In-depth, code-level reference docs for each major subsystem, living alongside t
|
|
|
676
684
|
|
|
677
685
|
- [Dialects](src/dialects/README.md) - The `Dialect` interface and per-database (SQLite/MySQL/PostgreSQL/MariaDB/Oracle/MSSQL/CockroachDB/Redshift/Db2/Snowflake/ClickHouse/DuckDB/HANA/Spanner) implementations of connections, DDL, views, partitioning, RLS, and query building.
|
|
678
686
|
- [Models](src/models/README.md) - The model layer: attribute/data types, `prorm.define()`, associations, scopes, indexes/constraints, and the model registry.
|
|
679
|
-
- [Query Builders](src/query-builders/README.md) - Translates `where`/`order`/`limit`/`include` options into dialect-specific SQL strings and bound parameter values. Includes a typed SQL function-builder library (`src/query-builders/functions/**` - window functions, date/time, JSON paths, string/math functions, CASE expressions, cross-dialect aggregates, full-text search) usable via `import { ... } from 'ts-prorm-orm'`; see [
|
|
687
|
+
- [Query Builders](src/query-builders/README.md) - Translates `where`/`order`/`limit`/`include` options into dialect-specific SQL strings and bound parameter values. Includes a typed SQL function-builder library (`src/query-builders/functions/**` - window functions, date/time, JSON paths, string/math functions, CASE expressions, cross-dialect aggregates, full-text search) usable via `import { ... } from 'ts-prorm-orm'`; see [`src/query-builders/README.md`](src/query-builders/README.md) for the function list.
|
|
680
688
|
- [Extension Catalog](src/extensions/README.md) - A discoverability reference (not executable code) of ~124 verified real extensions/plugins/licensed features across dialects, queryable via `findExtension()`/`listExtensionsForDialect()`/`listExtensionsByCategory()`/`searchExtensions()`.
|
|
681
689
|
- [Query Optimizers](src/query-optimizers/README.md) - Opt-in performance tooling (query hints, explain plans, slow-query logging, batch optimization, prepared-statement/result caching).
|
|
682
690
|
- [Migrations](src/migrations/README.md) - Migration files, the `Migrator`, `PrormMeta` history tracking, seeders, `QueryInterface`, and schema diffing (`src/schema/`).
|
|
@@ -91,3 +91,5 @@ export { DSARWorkflow, DSARRequest, RequestStatus, RequestType, FulfillmentOptio
|
|
|
91
91
|
export { PrivacyImpactAssessment, AssessmentStatus, RiskSeverity, PIARecord, RiskRecord, PIACreateOptions, RiskRecordOptions, } from './privacy-impact-assessment';
|
|
92
92
|
export { BackupVerification, BackupSource, BackupConfig, BackupMetadata, VerificationResult, VerificationSchedule, VerificationHistoryEntry, } from './backup-verification';
|
|
93
93
|
export { QueryFirewall, FirewallRule, FirewallRuleType, FirewallMode, FirewallModeEnum, FirewallOptions, QueryAnalysis, QueryOperation, BlockedQuery, getRecommendedRules, FIREWALL_RULES, OWASP_SQL_INJECTION_PATTERNS, CIS_BENCHMARK_RULES, PCI_DSS_RULES, HIPAA_RULES, SOX_RULES, NIST_CSF_RULES, POSTGRESQL_RULES, MYSQL_RULES, MARIADB_RULES, MSSQL_RULES, ORACLE_RULES, SQLITE_RULES, DATABASE_RULES, DatabaseType, FirewallRules, FirewallRuleDecoratorOptions, PostgreSQLFirewall, MySQLFirewall, MariaDBFirewall, MSSQLFirewall, OracleFirewall, SQLiteFirewall, applyFirewallRulesToModel, } from './query-firewall';
|
|
94
|
+
export { DataLineage, LineageTrack, getLineageFields, getLineageOptions, createDerivedRecord, createComputedRecord, applyHooks as applyLineageHooks, } from './data-lineage';
|
|
95
|
+
export type { DataSource, TransformationRecord, LineageRecord, LineageChain, LineageOptions, LineageTrackOptions, } from './data-lineage';
|
package/dist/compliance/index.js
CHANGED
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
71
71
|
exports.getPIIFields = exports.getClassification = exports.FieldClassification = exports.Classify = exports.DataClassifier = exports.createDSARResponse = exports.exportStream = exports.exportData = exports.DataPortabilityExporter = exports.applyPseudonymizationHooks = exports.Pseudonymize = exports.detokenize = exports.tokenize = exports.configure = exports.PseudonymizationService = exports.isImmutable = exports.enableVersioning = exports.makeImmutable = exports.ImmutableRecord = exports.applyMaskingHooks = exports.maskMany = exports.mask = exports.maskValue = exports.maskField = exports.Mask = exports.MaskPatternEnum = exports.DataMasker = exports.registerHooks = exports.rlsMiddleware = exports.runInContext = exports.getContext = exports.setContext = exports.apply = exports.initRLS = exports.RLS = exports.RowLevelSecurity = exports.ConsentVersioning = exports.LegalBasisEnum = exports.ConsentRecord = exports.RightToErasure = exports.DataRetentionPolicy = exports.TLSEnforcer = exports.getEncryptedFields = exports.applyEncryptionHooks = exports.Encrypt = exports.decryptValue = exports.encryptValue = exports.configureFieldEncryption = exports.FieldEncryption = exports.ComplianceAuditTrail = void 0;
|
|
72
72
|
exports.SensitiveDataDiscovery = exports.getRecommendedLimits = exports.satisfiesCompliance = exports.checkRateLimit = exports.initRateLimiter = exports.getGlobalLimiter = exports.getRateLimitOptions = exports.RateLimit = exports.RateLimiter = exports.isArchived = exports.isFrozen = exports.applyWORMHooks = exports.getWORMOptions = exports.WORM = exports.WORMStorage = exports.getTenantIsolationOptions = exports.getTenantAuditMetadata = exports.sessionIsolationMiddleware = exports.TenantIsolation = exports.SessionIsolation = exports.initBreachDetector = exports.getGlobalBreachDetector = exports.BreachDetector = exports.analyzeQuerySecurity = exports.initSecurityMonitor = exports.getGlobalMonitor = exports.ComplianceSecurityMonitor = exports.SecurityMonitor = exports.isImmutableModel = exports.hasAudit = exports.getSecurityFrameworks = exports.getDatabaseSecurity = exports.getTableSecurity = exports.DatabaseSecurity = exports.Table = exports.setupAllSecurity = exports.setupSecurity = exports.getAllFrameworks = exports.getFrameworkCategory = exports.isValidFramework = exports.FrameworkCount = exports.FrameworkRequirements = exports.FrameworkCategories = exports.AllFrameworks = exports.SecurityFramework = exports.Security = exports.autoDiscover = exports.isSensitive = exports.getPCIFields = exports.getPHIFields = void 0;
|
|
73
|
-
exports.applyFirewallRulesToModel = exports.SQLiteFirewall = exports.OracleFirewall = exports.MSSQLFirewall = exports.MariaDBFirewall = exports.MySQLFirewall = exports.PostgreSQLFirewall = exports.FirewallRules = exports.DATABASE_RULES = exports.SQLITE_RULES = exports.ORACLE_RULES = exports.MSSQL_RULES = exports.MARIADB_RULES = exports.MYSQL_RULES = exports.POSTGRESQL_RULES = exports.NIST_CSF_RULES = exports.SOX_RULES = exports.HIPAA_RULES = exports.PCI_DSS_RULES = exports.CIS_BENCHMARK_RULES = exports.OWASP_SQL_INJECTION_PATTERNS = exports.FIREWALL_RULES = exports.getRecommendedRules = exports.FirewallModeEnum = exports.QueryFirewall = exports.BackupVerification = exports.PrivacyImpactAssessment = exports.DSARWorkflow = exports.generateTransferReport = exports.getComplianceTransfers = exports.CrossBorderLog = exports.generateComplianceReport = exports.getPatterns = exports.unregisterPattern = exports.registerPattern = void 0;
|
|
73
|
+
exports.applyLineageHooks = exports.createComputedRecord = exports.createDerivedRecord = exports.getLineageOptions = exports.getLineageFields = exports.LineageTrack = exports.DataLineage = exports.applyFirewallRulesToModel = exports.SQLiteFirewall = exports.OracleFirewall = exports.MSSQLFirewall = exports.MariaDBFirewall = exports.MySQLFirewall = exports.PostgreSQLFirewall = exports.FirewallRules = exports.DATABASE_RULES = exports.SQLITE_RULES = exports.ORACLE_RULES = exports.MSSQL_RULES = exports.MARIADB_RULES = exports.MYSQL_RULES = exports.POSTGRESQL_RULES = exports.NIST_CSF_RULES = exports.SOX_RULES = exports.HIPAA_RULES = exports.PCI_DSS_RULES = exports.CIS_BENCHMARK_RULES = exports.OWASP_SQL_INJECTION_PATTERNS = exports.FIREWALL_RULES = exports.getRecommendedRules = exports.FirewallModeEnum = exports.QueryFirewall = exports.BackupVerification = exports.PrivacyImpactAssessment = exports.DSARWorkflow = exports.generateTransferReport = exports.getComplianceTransfers = exports.CrossBorderLog = exports.generateComplianceReport = exports.getPatterns = exports.unregisterPattern = exports.registerPattern = void 0;
|
|
74
74
|
// Audit Trail
|
|
75
75
|
var audit_trail_1 = require("./audit-trail");
|
|
76
76
|
Object.defineProperty(exports, "ComplianceAuditTrail", { enumerable: true, get: function () { return audit_trail_1.ComplianceAuditTrail; } });
|
|
@@ -258,3 +258,15 @@ Object.defineProperty(exports, "MSSQLFirewall", { enumerable: true, get: functio
|
|
|
258
258
|
Object.defineProperty(exports, "OracleFirewall", { enumerable: true, get: function () { return query_firewall_1.OracleFirewall; } });
|
|
259
259
|
Object.defineProperty(exports, "SQLiteFirewall", { enumerable: true, get: function () { return query_firewall_1.SQLiteFirewall; } });
|
|
260
260
|
Object.defineProperty(exports, "applyFirewallRulesToModel", { enumerable: true, get: function () { return query_firewall_1.applyFirewallRulesToModel; } });
|
|
261
|
+
// Data Lineage
|
|
262
|
+
// `applyHooks` is aliased to `applyLineageHooks` for the same reason
|
|
263
|
+
// data-masker's and pseudonymization's are: three modules in this barrel each
|
|
264
|
+
// export a function by that name.
|
|
265
|
+
var data_lineage_1 = require("./data-lineage");
|
|
266
|
+
Object.defineProperty(exports, "DataLineage", { enumerable: true, get: function () { return data_lineage_1.DataLineage; } });
|
|
267
|
+
Object.defineProperty(exports, "LineageTrack", { enumerable: true, get: function () { return data_lineage_1.LineageTrack; } });
|
|
268
|
+
Object.defineProperty(exports, "getLineageFields", { enumerable: true, get: function () { return data_lineage_1.getLineageFields; } });
|
|
269
|
+
Object.defineProperty(exports, "getLineageOptions", { enumerable: true, get: function () { return data_lineage_1.getLineageOptions; } });
|
|
270
|
+
Object.defineProperty(exports, "createDerivedRecord", { enumerable: true, get: function () { return data_lineage_1.createDerivedRecord; } });
|
|
271
|
+
Object.defineProperty(exports, "createComputedRecord", { enumerable: true, get: function () { return data_lineage_1.createComputedRecord; } });
|
|
272
|
+
Object.defineProperty(exports, "applyLineageHooks", { enumerable: true, get: function () { return data_lineage_1.applyHooks; } });
|
|
@@ -37,6 +37,12 @@ class ConnectionManager {
|
|
|
37
37
|
throw new Error(`Connection with name '${name}' already exists`);
|
|
38
38
|
}
|
|
39
39
|
const prorm = new prorm_1.Prorm(options);
|
|
40
|
+
// Let the instance find its siblings. This is what makes
|
|
41
|
+
// `Model.findAll({ using: 'other' })` resolvable: the query path looks the
|
|
42
|
+
// target connection up through `prorm.connectionManager`, which nothing
|
|
43
|
+
// used to set, so `using` failed with "Available: none" no matter how many
|
|
44
|
+
// connections had been added.
|
|
45
|
+
prorm.connectionManager = this;
|
|
40
46
|
this.connections.set(name, prorm);
|
|
41
47
|
// Set as default if it's the first connection
|
|
42
48
|
if (this._defaultConnection === null) {
|
|
@@ -78,8 +84,11 @@ class ConnectionManager {
|
|
|
78
84
|
if (!prorm) {
|
|
79
85
|
return false;
|
|
80
86
|
}
|
|
81
|
-
// Close the connection
|
|
87
|
+
// Close the connection and detach it from this manager, so a model still
|
|
88
|
+
// holding a reference to it can't route a `using` query through a
|
|
89
|
+
// registry it is no longer a member of.
|
|
82
90
|
await prorm.close();
|
|
91
|
+
prorm.connectionManager = null;
|
|
83
92
|
this.connections.delete(name);
|
|
84
93
|
// Update default if needed
|
|
85
94
|
if (this._defaultConnection === name) {
|
|
@@ -167,6 +176,9 @@ class ConnectionManager {
|
|
|
167
176
|
async closeAll() {
|
|
168
177
|
const closePromises = Array.from(this.connections.values()).map((seq) => seq.close());
|
|
169
178
|
await Promise.all(closePromises);
|
|
179
|
+
for (const prorm of this.connections.values()) {
|
|
180
|
+
prorm.connectionManager = null;
|
|
181
|
+
}
|
|
170
182
|
this.connections.clear();
|
|
171
183
|
this._defaultConnection = null;
|
|
172
184
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw SQL expression wrappers used by the Prorm instance API.
|
|
3
|
+
*
|
|
4
|
+
* `Literal` embeds SQL verbatim; `Col` references a column without quoting it
|
|
5
|
+
* as a value. Note that `src/operators.ts` also exposes `literal()`/`col()`
|
|
6
|
+
* factories producing a different shape - the dialects consume the operators
|
|
7
|
+
* form, so prefer those in new code.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Represents a raw SQL literal value
|
|
11
|
+
* Used for inserting raw SQL expressions into queries
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Use in default values
|
|
15
|
+
* createdAt: { type: DATE, defaultValue: prorm.literal('NOW()') }
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Use in updates
|
|
19
|
+
* User.update({ count: prorm.literal('count + 1') }, {...})
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Use in select with calculations
|
|
23
|
+
* User.findAll({ attributes: [[prorm.literal('1 + 1'), 'two']] })
|
|
24
|
+
*/
|
|
25
|
+
export declare class Literal {
|
|
26
|
+
readonly val: string;
|
|
27
|
+
constructor(sql: string);
|
|
28
|
+
/**
|
|
29
|
+
* Get the raw SQL string
|
|
30
|
+
*/
|
|
31
|
+
toString(): string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Class representing a column reference for use with Prorm functions
|
|
35
|
+
* Used to create properly quoted column identifiers
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Single column: col('name') -> "name"
|
|
39
|
+
* // Table and column: col('User', 'name') -> "User"."name"
|
|
40
|
+
* // Dot notation: col('table.column') -> "table"."column"
|
|
41
|
+
*/
|
|
42
|
+
export declare class Col {
|
|
43
|
+
private readonly col;
|
|
44
|
+
/**
|
|
45
|
+
* Create a column reference
|
|
46
|
+
* @param tableOrColumn - Table name (if second param provided) or column name
|
|
47
|
+
* @param column - Column name (if first param is table name)
|
|
48
|
+
*/
|
|
49
|
+
constructor(tableOrColumn: string, column?: string);
|
|
50
|
+
/**
|
|
51
|
+
* Get the SQL representation of the column
|
|
52
|
+
*/
|
|
53
|
+
toSql(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Get the column as a string
|
|
56
|
+
*/
|
|
57
|
+
toString(): string;
|
|
58
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Raw SQL expression wrappers used by the Prorm instance API.
|
|
4
|
+
*
|
|
5
|
+
* `Literal` embeds SQL verbatim; `Col` references a column without quoting it
|
|
6
|
+
* as a value. Note that `src/operators.ts` also exposes `literal()`/`col()`
|
|
7
|
+
* factories producing a different shape - the dialects consume the operators
|
|
8
|
+
* form, so prefer those in new code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.Col = exports.Literal = void 0;
|
|
12
|
+
/**
|
|
13
|
+
* Represents a raw SQL literal value
|
|
14
|
+
* Used for inserting raw SQL expressions into queries
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Use in default values
|
|
18
|
+
* createdAt: { type: DATE, defaultValue: prorm.literal('NOW()') }
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Use in updates
|
|
22
|
+
* User.update({ count: prorm.literal('count + 1') }, {...})
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // Use in select with calculations
|
|
26
|
+
* User.findAll({ attributes: [[prorm.literal('1 + 1'), 'two']] })
|
|
27
|
+
*/
|
|
28
|
+
class Literal {
|
|
29
|
+
constructor(sql) {
|
|
30
|
+
this.val = sql;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the raw SQL string
|
|
34
|
+
*/
|
|
35
|
+
toString() {
|
|
36
|
+
return this.val;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.Literal = Literal;
|
|
40
|
+
/**
|
|
41
|
+
* Class representing a column reference for use with Prorm functions
|
|
42
|
+
* Used to create properly quoted column identifiers
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Single column: col('name') -> "name"
|
|
46
|
+
* // Table and column: col('User', 'name') -> "User"."name"
|
|
47
|
+
* // Dot notation: col('table.column') -> "table"."column"
|
|
48
|
+
*/
|
|
49
|
+
class Col {
|
|
50
|
+
/**
|
|
51
|
+
* Create a column reference
|
|
52
|
+
* @param tableOrColumn - Table name (if second param provided) or column name
|
|
53
|
+
* @param column - Column name (if first param is table name)
|
|
54
|
+
*/
|
|
55
|
+
constructor(tableOrColumn, column) {
|
|
56
|
+
if (column !== undefined) {
|
|
57
|
+
// col('User', 'name') -> "User"."name"
|
|
58
|
+
this.col = `"${tableOrColumn}"."${column}"`;
|
|
59
|
+
}
|
|
60
|
+
else if (tableOrColumn.includes('.')) {
|
|
61
|
+
// col('table.column') -> "table"."column"
|
|
62
|
+
const [table, col] = tableOrColumn.split('.');
|
|
63
|
+
this.col = `"${table}"."${col}"`;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// col('name') -> "name"
|
|
67
|
+
this.col = `"${tableOrColumn}"`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the SQL representation of the column
|
|
72
|
+
*/
|
|
73
|
+
toSql() {
|
|
74
|
+
return this.col;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the column as a string
|
|
78
|
+
*/
|
|
79
|
+
toString() {
|
|
80
|
+
return this.col;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.Col = Col;
|