uql-orm 0.19.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/README.md +1 -1
- package/dist/browser/uql-browser.min.js +2 -2
- package/dist/browser/uql-browser.min.js.map +3 -3
- package/dist/bunSql/bunSqlCockroachDialect.d.ts +1 -1
- package/dist/bunSql/bunSqlCockroachDialect.js +1 -1
- package/dist/dialect/abstractSqlDialect.d.ts +130 -58
- package/dist/dialect/abstractSqlDialect.d.ts.map +1 -1
- package/dist/dialect/abstractSqlDialect.js +226 -178
- package/dist/dialect/abstractSqlDialect.js.map +1 -1
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts +5 -6
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts.map +1 -1
- package/dist/dialect/jsonArrayElemMatchUtils.js +9 -19
- package/dist/dialect/jsonArrayElemMatchUtils.js.map +1 -1
- package/dist/dialect/jsonSql.d.ts +44 -0
- package/dist/dialect/jsonSql.d.ts.map +1 -0
- package/dist/dialect/jsonSql.js +57 -0
- package/dist/dialect/jsonSql.js.map +1 -0
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +42 -2
- package/dist/dialect/mysqlLikeSqlDialect.d.ts.map +1 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +73 -22
- package/dist/dialect/mysqlLikeSqlDialect.js.map +1 -1
- package/dist/dialect/pgLikeSqlDialect.d.ts +28 -10
- package/dist/dialect/pgLikeSqlDialect.d.ts.map +1 -1
- package/dist/dialect/pgLikeSqlDialect.js +56 -49
- package/dist/dialect/pgLikeSqlDialect.js.map +1 -1
- package/dist/dialect/queryContext.d.ts +13 -1
- package/dist/dialect/queryContext.d.ts.map +1 -1
- package/dist/dialect/queryContext.js +17 -2
- package/dist/dialect/queryContext.js.map +1 -1
- package/dist/dialect/vectorSqlDialect.d.ts +54 -0
- package/dist/dialect/vectorSqlDialect.d.ts.map +1 -0
- package/dist/dialect/vectorSqlDialect.js +70 -0
- package/dist/dialect/vectorSqlDialect.js.map +1 -0
- package/dist/entity/decorator/index-decorator.d.ts +6 -13
- package/dist/entity/decorator/index-decorator.d.ts.map +1 -1
- package/dist/entity/decorator/index-decorator.js.map +1 -1
- package/dist/http/handler.d.ts +5 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js.map +1 -1
- package/dist/maria/mariaDialect.d.ts +15 -4
- package/dist/maria/mariaDialect.d.ts.map +1 -1
- package/dist/maria/mariaDialect.js +25 -13
- package/dist/maria/mariaDialect.js.map +1 -1
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +1 -1
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts.map +1 -1
- package/dist/mongo/mongoDialect.d.ts +27 -6
- package/dist/mongo/mongoDialect.d.ts.map +1 -1
- package/dist/mongo/mongoDialect.js +107 -14
- package/dist/mongo/mongoDialect.js.map +1 -1
- package/dist/mongo/mongodbQuerier.d.ts.map +1 -1
- package/dist/mongo/mongodbQuerier.js +5 -4
- package/dist/mongo/mongodbQuerier.js.map +1 -1
- package/dist/mysql/mysqlDialect.d.ts +0 -1
- package/dist/mysql/mysqlDialect.d.ts.map +1 -1
- package/dist/mysql/mysqlDialect.js +0 -1
- package/dist/mysql/mysqlDialect.js.map +1 -1
- package/dist/postgres/postgresWireDriverCapabilities.d.ts +1 -1
- package/dist/postgres/postgresWireDriverCapabilities.js +1 -1
- package/dist/schema/schemaAST.d.ts.map +1 -1
- package/dist/schema/schemaAST.js +7 -19
- package/dist/schema/schemaAST.js.map +1 -1
- package/dist/schema/types.d.ts +1 -1
- package/dist/sqlite/sqliteDialect.d.ts +28 -8
- package/dist/sqlite/sqliteDialect.d.ts.map +1 -1
- package/dist/sqlite/sqliteDialect.js +65 -80
- package/dist/sqlite/sqliteDialect.js.map +1 -1
- package/dist/type/dialect.d.ts +199 -0
- package/dist/type/dialect.d.ts.map +1 -0
- package/dist/type/dialect.js +2 -0
- package/dist/type/dialect.js.map +1 -0
- package/dist/type/entity.d.ts +64 -43
- package/dist/type/entity.d.ts.map +1 -1
- package/dist/type/entity.js.map +1 -1
- package/dist/type/index.d.ts +5 -0
- package/dist/type/index.d.ts.map +1 -1
- package/dist/type/index.js +5 -0
- package/dist/type/index.js.map +1 -1
- package/dist/type/querier.d.ts +3 -5
- package/dist/type/querier.d.ts.map +1 -1
- package/dist/type/querier.js.map +1 -1
- package/dist/type/query.d.ts +5 -711
- package/dist/type/query.d.ts.map +1 -1
- package/dist/type/query.js +1 -51
- package/dist/type/query.js.map +1 -1
- package/dist/type/queryAggregate.d.ts +191 -0
- package/dist/type/queryAggregate.d.ts.map +1 -0
- package/dist/type/queryAggregate.js +39 -0
- package/dist/type/queryAggregate.js.map +1 -0
- package/dist/type/queryRaw.d.ts +35 -0
- package/dist/type/queryRaw.d.ts.map +1 -0
- package/dist/type/queryRaw.js +11 -0
- package/dist/type/queryRaw.js.map +1 -0
- package/dist/type/queryWhere.d.ts +271 -0
- package/dist/type/queryWhere.d.ts.map +1 -0
- package/dist/type/queryWhere.js +2 -0
- package/dist/type/queryWhere.js.map +1 -0
- package/dist/type/universalQuerier.d.ts +2 -1
- package/dist/type/universalQuerier.d.ts.map +1 -1
- package/dist/type/utility.d.ts +8 -1
- package/dist/type/utility.d.ts.map +1 -1
- package/dist/type/vector.d.ts +55 -0
- package/dist/type/vector.d.ts.map +1 -0
- package/dist/type/vector.js +2 -0
- package/dist/type/vector.js.map +1 -0
- package/dist/util/ansiSqlLiteral.d.ts +2 -0
- package/dist/util/ansiSqlLiteral.d.ts.map +1 -1
- package/dist/util/ansiSqlLiteral.js +5 -1
- package/dist/util/ansiSqlLiteral.js.map +1 -1
- package/dist/util/dialect.util.d.ts +5 -5
- package/dist/util/dialect.util.d.ts.map +1 -1
- package/dist/util/dialect.util.js +15 -10
- package/dist/util/dialect.util.js.map +1 -1
- package/dist/util/object.util.d.ts +12 -1
- package/dist/util/object.util.d.ts.map +1 -1
- package/dist/util/object.util.js +18 -0
- package/dist/util/object.util.js.map +1 -1
- package/dist/util/relationQuery.util.js +1 -1
- package/dist/util/relationQuery.util.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { AbstractSqlDialect } from '../dialect/abstractSqlDialect.js';
|
|
2
|
-
import {
|
|
2
|
+
import { JSON_ELEM_ALIAS_PREFIX, JSON_PULL_ALIAS, jsonAssignCall, jsonElemExists, jsonPath, jsonRemoveCall, jsonSetTarget, } from '../dialect/jsonSql.js';
|
|
3
3
|
import { getMeta } from '../entity/index.js';
|
|
4
|
-
import { escapeAnsiSqlLiteral } from '../util/ansiSqlLiteral.js';
|
|
5
|
-
import { hasKeys } from '../util/index.js';
|
|
6
4
|
export class SqliteDialect extends AbstractSqlDialect {
|
|
7
5
|
/** Default {@link DialectFeatures} for SQLite and SQLite-derived dialects. */
|
|
8
6
|
featureDefaults = {
|
|
@@ -76,54 +74,39 @@ export class SqliteDialect extends AbstractSqlDialect {
|
|
|
76
74
|
}
|
|
77
75
|
super.compare(ctx, entity, key, val, opts);
|
|
78
76
|
}
|
|
79
|
-
compareFieldOperator(ctx, entity, key, op, val, opts = {}) {
|
|
80
|
-
switch (op) {
|
|
81
|
-
case '$elemMatch':
|
|
82
|
-
this.buildElemMatchCondition(ctx, entity, key, val, opts);
|
|
83
|
-
break;
|
|
84
|
-
case '$all': {
|
|
85
|
-
// SQLite: Check JSON array contains all values using multiple json_each subqueries
|
|
86
|
-
const values = val;
|
|
87
|
-
const conditions = values
|
|
88
|
-
.map((v) => {
|
|
89
|
-
ctx.pushValue(JSON.stringify(v));
|
|
90
|
-
return `EXISTS (SELECT 1 FROM json_each(${this.escapeId(key)}) WHERE value = json(?))`;
|
|
91
|
-
})
|
|
92
|
-
.join(' AND ');
|
|
93
|
-
ctx.append(`(${conditions})`);
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
case '$size':
|
|
97
|
-
// SQLite: Check JSON array length
|
|
98
|
-
// e.g., json_array_length(roles) = 3, or json_array_length(roles) >= 2
|
|
99
|
-
this.buildSizeComparison(ctx, () => {
|
|
100
|
-
ctx.append('json_array_length(');
|
|
101
|
-
this.getComparisonKey(ctx, entity, key, opts);
|
|
102
|
-
ctx.append(')');
|
|
103
|
-
}, val);
|
|
104
|
-
break;
|
|
105
|
-
default:
|
|
106
|
-
super.compareFieldOperator(ctx, entity, key, op, val, opts);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
77
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
78
|
+
* SQLite compares an exploded element as whole JSON text, so containment cannot express "this
|
|
79
|
+
* element includes these keys" - `$elemMatch` always expands to per-field conditions.
|
|
112
80
|
*/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
ctx.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
81
|
+
jsonContainmentIsPartial = false;
|
|
82
|
+
/** `json_each` exposes a JSON boolean as `0`/`1` and a number as a number - already comparable. */
|
|
83
|
+
jsonScalarElemKeepsType = true;
|
|
84
|
+
/**
|
|
85
|
+
* Each element is read back as JSON text through `->` at its own `fullkey`, so it compares
|
|
86
|
+
* correctly whatever its type. `json_each`'s `value` column would not: it unquotes strings (`a`
|
|
87
|
+
* vs `"a"`), flattens booleans to 0/1, and stringifies objects.
|
|
88
|
+
*/
|
|
89
|
+
jsonAll(ctx, jsonField, value) {
|
|
90
|
+
const alias = ctx.nextAlias(JSON_ELEM_ALIAS_PREFIX);
|
|
91
|
+
const from = this.jsonElemFrom(jsonField, [], alias);
|
|
92
|
+
const conditions = value.map((val) => jsonElemExists(from, [`${jsonField} -> ${alias}.fullkey = ${this.jsonScalarParam(ctx, val)}`]));
|
|
93
|
+
return `(${conditions.join(' AND ')})`;
|
|
94
|
+
}
|
|
95
|
+
jsonSize(ctx, jsonField, value) {
|
|
96
|
+
return this.buildFragment(ctx, (fragmentCtx) => this.buildSizeComparison(fragmentCtx, () => fragmentCtx.append(`json_array_length(${jsonField})`), value));
|
|
97
|
+
}
|
|
98
|
+
/** `json_each` yields both scalar and object elements, so one form covers each case. */
|
|
99
|
+
jsonElemFrom(jsonField, _fields, alias) {
|
|
100
|
+
return `json_each(${jsonField}) ${alias}`;
|
|
101
|
+
}
|
|
102
|
+
jsonElemRef(alias, field, asJson = false) {
|
|
103
|
+
if (field === undefined) {
|
|
104
|
+
return `${alias}.value`;
|
|
105
|
+
}
|
|
106
|
+
return asJson ? `${alias}.value -> ${jsonPath(field)}` : `json_extract(${alias}.value, ${jsonPath(field)})`;
|
|
107
|
+
}
|
|
108
|
+
getJsonPathScalarExpr(escapedColumn, jsonPathStr) {
|
|
109
|
+
return `json_extract(${escapedColumn}, ${jsonPath(jsonPathStr)})`;
|
|
127
110
|
}
|
|
128
111
|
numericCast(expr) {
|
|
129
112
|
return `CAST(${expr} AS REAL)`;
|
|
@@ -133,38 +116,40 @@ export class SqliteDialect extends AbstractSqlDialect {
|
|
|
133
116
|
ctx.append(' ' + this.returningId(entity));
|
|
134
117
|
}
|
|
135
118
|
upsert(ctx, entity, conflictPaths, payload) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
this.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
119
|
+
const meta = getMeta(entity);
|
|
120
|
+
const updateCtx = this.createContext();
|
|
121
|
+
const update = this.getUpsertUpdateAssignments(updateCtx, meta, conflictPaths, payload, (name) => `EXCLUDED.${name}`);
|
|
122
|
+
const keysStr = this.getUpsertConflictPathsStr(meta, conflictPaths);
|
|
123
|
+
const onConflict = update ? `DO UPDATE SET ${update}` : 'DO NOTHING';
|
|
124
|
+
// Use the base (non-RETURNING) insert here: the appended RETURNING below would otherwise
|
|
125
|
+
// be doubled by `this.insert`'s own.
|
|
126
|
+
super.insert(ctx, entity, payload);
|
|
127
|
+
ctx.append(` ON CONFLICT (${keysStr}) ${onConflict} ${this.returningId(entity)}`);
|
|
128
|
+
ctx.pushValue(...updateCtx.values);
|
|
129
|
+
}
|
|
130
|
+
jsonCast(operand) {
|
|
131
|
+
return `json(${operand})`;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* `json_replace` leaves an absent key (and a NULL column) untouched. Elements are read back
|
|
135
|
+
* through `->` at their own `fullkey` so each keeps its JSON type - `json_each`'s `value` would
|
|
136
|
+
* flatten booleans to 0/1 and stringify objects.
|
|
137
|
+
*/
|
|
138
|
+
jsonPullKey(ctx, expr, escapedCol, key, value) {
|
|
139
|
+
const path = jsonPath(key);
|
|
140
|
+
const elem = `${escapedCol} -> ${JSON_PULL_ALIAS}.fullkey`;
|
|
141
|
+
const kept = `SELECT json_group_array(json(${elem})) FROM json_each(${escapedCol}, ${path}) ${JSON_PULL_ALIAS} WHERE ${elem} <> ${this.jsonScalarParam(ctx, value)}`;
|
|
142
|
+
return `json_replace(${expr}, ${path}, (${kept}))`;
|
|
143
|
+
}
|
|
144
|
+
jsonSet(ctx, expr, set, field) {
|
|
145
|
+
return jsonAssignCall((value) => this.jsonScalarParam(ctx, value), 'json_set', jsonSetTarget(expr, field, `'{}'`), set);
|
|
146
|
+
}
|
|
147
|
+
/** `[#]` appends, creating the array when the key is absent. */
|
|
148
|
+
jsonPush(ctx, expr, push) {
|
|
149
|
+
return jsonAssignCall((value) => this.jsonScalarParam(ctx, value), 'json_insert', expr, push, '[#]');
|
|
165
150
|
}
|
|
166
|
-
|
|
167
|
-
return
|
|
151
|
+
jsonUnset(_ctx, expr, unset) {
|
|
152
|
+
return jsonRemoveCall('json_remove', expr, unset);
|
|
168
153
|
}
|
|
169
154
|
}
|
|
170
155
|
//# sourceMappingURL=sqliteDialect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqliteDialect.js","sourceRoot":"","sources":["../../src/sqlite/sqliteDialect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,
|
|
1
|
+
{"version":3,"file":"sqliteDialect.js","sourceRoot":"","sources":["../../src/sqlite/sqliteDialect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { UpdatePayload } from './entity.js';
|
|
2
|
+
import type { Query, QueryConflictPaths, QueryOptions, QuerySearch } from './query.js';
|
|
3
|
+
import type { QueryAggMap, QueryAggregate, QueryGroupMap } from './queryAggregate.js';
|
|
4
|
+
import type { Type } from './utility.js';
|
|
5
|
+
/**
|
|
6
|
+
* comparison options.
|
|
7
|
+
*/
|
|
8
|
+
export type QueryComparisonOptions = QueryOptions & {
|
|
9
|
+
/**
|
|
10
|
+
* use precedence for the comparison or not.
|
|
11
|
+
*/
|
|
12
|
+
usePrecedence?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* query filter options.
|
|
16
|
+
*/
|
|
17
|
+
export type QueryWhereOptions = QueryComparisonOptions & {
|
|
18
|
+
/**
|
|
19
|
+
* clause to be used in the filter.
|
|
20
|
+
*/
|
|
21
|
+
clause?: 'WHERE' | 'AND' | false;
|
|
22
|
+
};
|
|
23
|
+
export interface QueryContext {
|
|
24
|
+
append(sql: string): this;
|
|
25
|
+
addValue(value: unknown): this;
|
|
26
|
+
pushValue(...values: unknown[]): this;
|
|
27
|
+
/**
|
|
28
|
+
* A fresh derived-table/subquery alias, unique within this query: `nextAlias('_uql_elem')` returns
|
|
29
|
+
* `'_uql_elem_1'`, then `'_uql_elem_2'`, etc. Needed wherever a hook (e.g. exploding a JSON array)
|
|
30
|
+
* might recurse into itself at a deeper nesting level within the same query - a fixed, reused
|
|
31
|
+
* alias would let the inner occurrence shadow the outer one it needs to correlate against.
|
|
32
|
+
*/
|
|
33
|
+
nextAlias(prefix: string): string;
|
|
34
|
+
readonly sql: string;
|
|
35
|
+
readonly values: unknown[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Capabilities of the database driver (transport layer).
|
|
39
|
+
*/
|
|
40
|
+
export interface DriverCapabilities {
|
|
41
|
+
/**
|
|
42
|
+
* Whether JSON bind parameters are cast via text first (`($n::text)::jsonb`).
|
|
43
|
+
* Bun SQL PostgreSQL uses this for reliable jsonb merge/push; `pg` does not.
|
|
44
|
+
*/
|
|
45
|
+
readonly explicitJsonCast: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the driver natively supports JS arrays for the underlying database type.
|
|
48
|
+
* `PgDialect` keeps this `true` for node-postgres; Bun SQL PostgreSQL uses `false` and
|
|
49
|
+
* `toPgArray` string literals instead.
|
|
50
|
+
*/
|
|
51
|
+
readonly nativeArrays: boolean;
|
|
52
|
+
/** Whether the dialect natively supports the JSONB binary JSON type (Postgres/CockroachDB). */
|
|
53
|
+
readonly supportsJsonb: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* How a dialect surfaces the IDs generated by an INSERT statement:
|
|
57
|
+
* - `'returning'`: the statement itself returns one row per inserted record (`RETURNING`,
|
|
58
|
+
* or MongoDB's `insertedIds`), so IDs are exact for every row.
|
|
59
|
+
* - `'firstId'`: the driver header only exposes the first generated ID (MySQL `insertId`);
|
|
60
|
+
* the remaining IDs are inferred by incrementing it.
|
|
61
|
+
* - `'lastId'`: the driver header only exposes the last generated ID (SQLite `lastInsertRowid`);
|
|
62
|
+
* the remaining IDs are inferred backwards from it.
|
|
63
|
+
*/
|
|
64
|
+
export type InsertIdSource = 'returning' | 'firstId' | 'lastId';
|
|
65
|
+
/**
|
|
66
|
+
* Features of the database engine (SQL syntax layer).
|
|
67
|
+
*/
|
|
68
|
+
export interface EngineFeatures {
|
|
69
|
+
readonly ifNotExists: boolean;
|
|
70
|
+
readonly indexIfNotExists: boolean;
|
|
71
|
+
readonly dropTableCascade: boolean;
|
|
72
|
+
readonly renameColumn: boolean;
|
|
73
|
+
readonly foreignKeyAlter: boolean;
|
|
74
|
+
/** Whether the dialect supports inline COMMENT on columns (MySQL/MariaDB). */
|
|
75
|
+
readonly columnComment: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* How vector indexes are emitted: inline in CREATE TABLE (MySQL/MariaDB), a standalone
|
|
78
|
+
* `CREATE INDEX ... USING <type> (col opclass)` (Postgres/SQLite), or a standalone
|
|
79
|
+
* `CREATE VECTOR INDEX (col opclass)` with no access-method keyword (CockroachDB's native type).
|
|
80
|
+
*/
|
|
81
|
+
readonly vectorIndexStyle: 'inline' | 'create' | 'native';
|
|
82
|
+
/** Whether the dialect requires/allows (n) length constraints on vector types. */
|
|
83
|
+
readonly vectorSupportsLength: boolean;
|
|
84
|
+
/** Whether the dialect natively supports the TIMESTAMPTZ alias/type. */
|
|
85
|
+
readonly supportsTimestamptz: boolean;
|
|
86
|
+
/** Whether the dialect defaults to TEXT for strings when no length is specified (e.g. Postgres). */
|
|
87
|
+
readonly defaultStringAsText: boolean;
|
|
88
|
+
}
|
|
89
|
+
export interface DialectFeatures extends EngineFeatures, DriverCapabilities {
|
|
90
|
+
}
|
|
91
|
+
export interface QueryDialect {
|
|
92
|
+
/**
|
|
93
|
+
* The dialect features.
|
|
94
|
+
*/
|
|
95
|
+
readonly features: DialectFeatures;
|
|
96
|
+
/**
|
|
97
|
+
* obtains the records matching the given search parameters.
|
|
98
|
+
* @param ctx the query context
|
|
99
|
+
* @param entity the target entity
|
|
100
|
+
* @param q the criteria options
|
|
101
|
+
* @param opts the query options
|
|
102
|
+
*/
|
|
103
|
+
find<E>(ctx: QueryContext, entity: Type<E>, q: Query<E>, opts?: QueryOptions): void;
|
|
104
|
+
/**
|
|
105
|
+
* counts the number of records matching the given search parameters.
|
|
106
|
+
* @param ctx the query context
|
|
107
|
+
* @param entity the target entity
|
|
108
|
+
* @param q the criteria options
|
|
109
|
+
* @param opts the query options
|
|
110
|
+
*/
|
|
111
|
+
count<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): void;
|
|
112
|
+
/**
|
|
113
|
+
* insert records.
|
|
114
|
+
* @param ctx the query context
|
|
115
|
+
* @param entity the target entity
|
|
116
|
+
* @param payload the payload
|
|
117
|
+
* @param opts the query options
|
|
118
|
+
*/
|
|
119
|
+
insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void;
|
|
120
|
+
/**
|
|
121
|
+
* update records.
|
|
122
|
+
* @param ctx the query context
|
|
123
|
+
* @param entity the target entity
|
|
124
|
+
* @param q the criteria options
|
|
125
|
+
* @param payload
|
|
126
|
+
* @param opts the query options
|
|
127
|
+
*/
|
|
128
|
+
update<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, payload: UpdatePayload<E>, opts?: QueryOptions): void;
|
|
129
|
+
/**
|
|
130
|
+
* upsert records.
|
|
131
|
+
* @param ctx the query context
|
|
132
|
+
* @param entity the target entity
|
|
133
|
+
* @param conflictPaths the conflict paths
|
|
134
|
+
* @param payload
|
|
135
|
+
*/
|
|
136
|
+
upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[]): void;
|
|
137
|
+
/**
|
|
138
|
+
* delete records.
|
|
139
|
+
* @param ctx the query context
|
|
140
|
+
* @param entity the target entity
|
|
141
|
+
* @param q the criteria options
|
|
142
|
+
* @param opts the query options
|
|
143
|
+
*/
|
|
144
|
+
delete<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): void;
|
|
145
|
+
/**
|
|
146
|
+
* escape an identifier.
|
|
147
|
+
* @param val the value to be escaped
|
|
148
|
+
* @param forbidQualified don't escape dots
|
|
149
|
+
* @param addDot use a dot as suffix
|
|
150
|
+
*/
|
|
151
|
+
escapeId(val: string, forbidQualified?: boolean, addDot?: boolean): string;
|
|
152
|
+
/**
|
|
153
|
+
* escape a value.
|
|
154
|
+
* @param val the value to escape
|
|
155
|
+
*/
|
|
156
|
+
escape(val: unknown): string;
|
|
157
|
+
/**
|
|
158
|
+
* add a value to the query.
|
|
159
|
+
* @param values the values array
|
|
160
|
+
* @param value the value to add
|
|
161
|
+
*/
|
|
162
|
+
addValue(values: unknown[], value: unknown): string;
|
|
163
|
+
/**
|
|
164
|
+
* normalizes a value according to the dialect.
|
|
165
|
+
* @param value the value to normalize
|
|
166
|
+
*/
|
|
167
|
+
normalizeValue(value: unknown): unknown;
|
|
168
|
+
/**
|
|
169
|
+
* create a new query context.
|
|
170
|
+
*/
|
|
171
|
+
createContext(): QueryContext;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Supported SQL dialect identifiers.
|
|
175
|
+
*/
|
|
176
|
+
export type SqlDialectName = 'postgres' | 'cockroachdb' | 'mysql' | 'mariadb' | 'sqlite';
|
|
177
|
+
/**
|
|
178
|
+
* Minimal dialect interface exposing escapeIdChar for SQL operations
|
|
179
|
+
*/
|
|
180
|
+
export interface SqlQueryDialect extends QueryDialect {
|
|
181
|
+
/**
|
|
182
|
+
* The SQL dialect name (postgres, mysql, mariadb, sqlite).
|
|
183
|
+
*/
|
|
184
|
+
readonly dialectName: SqlDialectName;
|
|
185
|
+
/**
|
|
186
|
+
* the escape character for identifiers.
|
|
187
|
+
*/
|
|
188
|
+
readonly escapeIdChar: '"' | '`';
|
|
189
|
+
/**
|
|
190
|
+
* Build an aggregate query.
|
|
191
|
+
*/
|
|
192
|
+
aggregate<E, G extends QueryGroupMap<E>, A extends QueryAggMap<E>>(ctx: QueryContext, entity: Type<E>, q: QueryAggregate<E, G, A>, opts?: QueryOptions): void;
|
|
193
|
+
/**
|
|
194
|
+
* Get the placeholder for a parameter at the given index (1-based).
|
|
195
|
+
* Default: '?' for MySQL/MariaDB/SQLite, '$n' for PostgreSQL.
|
|
196
|
+
*/
|
|
197
|
+
placeholder(index: number): string;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=dialect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialect.d.ts","sourceRoot":"","sources":["../../src/type/dialect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialect.js","sourceRoot":"","sources":["../../src/type/dialect.ts"],"names":[],"mappings":""}
|
package/dist/type/entity.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { IndexType } from '../schema/types.js';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { FilterOptions } from './query.js';
|
|
3
|
+
import type { QueryRaw } from './queryRaw.js';
|
|
4
|
+
import type { Json, Scalar, Type, Unpacked } from './utility.js';
|
|
5
|
+
import type { VectorDistance, VectorIndexOptions, VectorIndexType } from './vector.js';
|
|
4
6
|
/**
|
|
5
7
|
* Allow to customize the name of the property that identifies an entity
|
|
6
8
|
*/
|
|
@@ -33,10 +35,10 @@ type IsJson<T> = '__json' extends keyof T ? true : false;
|
|
|
33
35
|
/** The payload `P` of a branded `Json<P>`, or `never` for any non-JSON type. */
|
|
34
36
|
type UnwrapJson<T> = IsJson<T> extends true ? (T extends Json<infer P> ? P : never) : never;
|
|
35
37
|
/**
|
|
36
|
-
* The `Json` payload of a field value `V`: both `Json<T>` and `Json<T>[]` yield `T
|
|
37
|
-
* `never` when `V` is not a JSON field.
|
|
38
|
+
* The `Json` payload of a field value `V`: both `Json<T>` and `Json<T>[]` yield `T` (via
|
|
39
|
+
* `Unpacked`, a no-op for the non-array case); `never` when `V` is not a JSON field.
|
|
38
40
|
*/
|
|
39
|
-
type JsonPayload<V> = UnwrapJson<NonNullable<
|
|
41
|
+
type JsonPayload<V> = UnwrapJson<NonNullable<Unpacked<NonNullable<V>>>>;
|
|
40
42
|
/**
|
|
41
43
|
* Recursively derives dot-notation key paths from a JSON payload type. Handles every shape at
|
|
42
44
|
* entry: an untyped (`unknown`) payload accepts any suffix via a `string` pattern, scalars are
|
|
@@ -69,46 +71,60 @@ type PathValue<T, P extends string> = unknown extends T ? unknown : NonNullable<
|
|
|
69
71
|
*/
|
|
70
72
|
export type JsonFieldPathValue<E, P extends string> = P extends `${infer F}.${infer Rest}` ? F extends FieldKey<E> ? [JsonPayload<E[F]>] extends [never] ? unknown : PathValue<JsonPayload<E[F]>, Rest> : unknown : unknown;
|
|
71
73
|
/**
|
|
72
|
-
* Extracts only the array-typed keys from `T`, mapping each to its element type
|
|
73
|
-
* Used by `$push` to provide type-safe
|
|
74
|
-
* rest of the JSON machinery, so a `readonly` array payload keeps its `$push` target.
|
|
74
|
+
* Extracts only the array-typed keys from `T`, mapping each to its element type via `Unpacked`.
|
|
75
|
+
* Used by `$push` and `$pull` to provide type-safe element targets.
|
|
75
76
|
*/
|
|
76
|
-
export type
|
|
77
|
-
[K in keyof T as NonNullable<T[K]> extends readonly unknown[] ? K & string : never]?: NonNullable<T[K]
|
|
77
|
+
export type JsonArrayFields<T> = {
|
|
78
|
+
[K in keyof T as NonNullable<T[K]> extends readonly unknown[] ? K & string : never]?: Unpacked<NonNullable<T[K]>>;
|
|
78
79
|
};
|
|
79
80
|
/**
|
|
80
|
-
* Operator shape accepted by JSON/JSONB fields in update payloads
|
|
81
|
-
*
|
|
81
|
+
* Operator shape accepted by JSON/JSONB fields in update payloads: `$set`/`$unset` target object
|
|
82
|
+
* keys, `$push`/`$pull` target array elements. All four are type-safe with IDE autocomplete.
|
|
83
|
+
*
|
|
84
|
+
* `$set` is shallow: it assigns the given top-level keys and leaves the rest untouched (it is not
|
|
85
|
+
* an RFC 7396 recursive merge). `$pull` removes *every* element equal to the given value.
|
|
86
|
+
*
|
|
87
|
+
* Operators are applied `$pull` -> `$set` -> `$push` -> `$unset`, so any combination - including
|
|
88
|
+
* `$pull` and `$push` on the same key - yields the same result on every dialect.
|
|
82
89
|
*
|
|
83
90
|
* @example
|
|
84
91
|
* ```ts
|
|
85
|
-
* //
|
|
86
|
-
* querier.updateOneById(Company, id, { kind: { $
|
|
92
|
+
* // set only - autocompletes keys from the JSON field's inner type
|
|
93
|
+
* querier.updateOneById(Company, id, { kind: { $set: { public: 1 } } });
|
|
87
94
|
* // unset only - autocompletes keys from the JSON field's inner type
|
|
88
95
|
* querier.updateOneById(Company, id, { kind: { $unset: ['private'] } });
|
|
89
|
-
* //
|
|
90
|
-
* querier.updateOneById(Company, id, {
|
|
91
|
-
*
|
|
92
|
-
*
|
|
96
|
+
* // append to / remove from an array - autocompletes array keys, value matches element type
|
|
97
|
+
* querier.updateOneById(Company, id, { kind: { $push: { tags: 'new-tag' } } });
|
|
98
|
+
* querier.updateOneById(Company, id, { kind: { $pull: { tags: 'stale-tag' } } });
|
|
99
|
+
* // combine
|
|
100
|
+
* querier.updateOneById(Company, id, { kind: { $set: { public: 1 }, $push: { tags: 'x' }, $unset: ['private'] } });
|
|
93
101
|
* ```
|
|
94
102
|
*/
|
|
95
103
|
export type JsonUpdateOp<T = unknown> = {
|
|
96
|
-
readonly $
|
|
97
|
-
readonly $unset?: (keyof T & string)[];
|
|
98
|
-
readonly $push?:
|
|
104
|
+
readonly $set?: Partial<T>;
|
|
105
|
+
readonly $unset?: unknown extends T ? string[] : (keyof T & string)[];
|
|
106
|
+
readonly $push?: JsonArrayFields<T>;
|
|
107
|
+
readonly $pull?: JsonArrayFields<T>;
|
|
99
108
|
};
|
|
100
109
|
/**
|
|
101
|
-
*
|
|
102
|
-
* - JSON
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
110
|
+
* The {@link JsonUpdateOp} a field accepts, or `never` where the operators do not apply:
|
|
111
|
+
* - Non-JSON fields. {@link UnwrapJson}'s {@link IsJson} guard avoids the non-discriminating bare
|
|
112
|
+
* `Json<infer T>` match that would otherwise offer `$set`/`$unset` on plain scalar fields.
|
|
113
|
+
* - `Json<T[]>` payloads. All four operators address object keys of the JSON document, so on an
|
|
114
|
+
* array column none is meaningful: PostgreSQL's `||` would concatenate arrays while
|
|
115
|
+
* `JSON_SET(arr, '$.k', v)` is a no-op on MySQL and SQLite. Replace the whole value instead.
|
|
116
|
+
* `Json<unknown>` stays permissive, since `unknown` is not an array.
|
|
106
117
|
*/
|
|
107
|
-
type
|
|
118
|
+
type JsonUpdateOpFor<V, T = UnwrapJson<NonNullable<V>>> = [T] extends [never] ? never : T extends readonly unknown[] ? never : JsonUpdateOp<T>;
|
|
119
|
+
/**
|
|
120
|
+
* Accepted value for a single field in an update payload: the value itself, `QueryRaw` for a raw SQL
|
|
121
|
+
* expression (e.g. `raw('NOW()')`), and - for JSON object fields - the JSON operators.
|
|
122
|
+
*/
|
|
123
|
+
type UpdateFieldValue<V> = V | QueryRaw | JsonUpdateOpFor<V>;
|
|
108
124
|
/**
|
|
109
125
|
* Payload type for update operations.
|
|
110
126
|
* Widens each field to additionally accept `QueryRaw` or `JsonUpdateOp` (for JSON fields),
|
|
111
|
-
* providing IDE autocomplete for `$
|
|
127
|
+
* providing IDE autocomplete for `$set`/`$push`/`$pull` keys via `Json<infer T>`.
|
|
112
128
|
*/
|
|
113
129
|
export type UpdatePayload<E> = {
|
|
114
130
|
[K in FieldKey<E>]?: UpdateFieldValue<E[K]>;
|
|
@@ -308,17 +324,24 @@ export type HookRegistration = {
|
|
|
308
324
|
readonly methodName: string;
|
|
309
325
|
};
|
|
310
326
|
/**
|
|
311
|
-
*
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
* Index type paired with the metric it needs. `distance` is required for {@link VectorIndexType}
|
|
328
|
+
* because omitting it changes the DDL semantics silently: MariaDB's `DISTANCE=` defaults to
|
|
329
|
+
* euclidean (so a cosine query full-scans instead of using the index) and pgvector has no default
|
|
330
|
+
* operator class. MongoDB's `vectorSearch` is excluded - its generator emits no metric at all, so
|
|
331
|
+
* requiring one would demand a value that is dropped.
|
|
332
|
+
*
|
|
333
|
+
* The non-vector arm forbids `distance` (rather than just omitting it) because `VectorIndexOptions`
|
|
334
|
+
* - intersected in below by {@link EntityIndexMeta} - already declares `distance` as optional, for
|
|
335
|
+
* the sake of the migration/introspection schema types that reuse it without this discriminated
|
|
336
|
+
* `type`/`distance` pairing. Without the explicit `never` here, that optional `distance` would
|
|
337
|
+
* survive the intersection and silently typecheck `{ type: 'btree', distance: 'cosine' }`.
|
|
338
|
+
*/
|
|
339
|
+
export type IndexTypeOptions = {
|
|
340
|
+
type: VectorIndexType;
|
|
341
|
+
distance: VectorDistance;
|
|
342
|
+
} | {
|
|
343
|
+
type?: Exclude<IndexType, VectorIndexType>;
|
|
344
|
+
distance?: never;
|
|
322
345
|
};
|
|
323
346
|
/**
|
|
324
347
|
* Index metadata from @Index decorator.
|
|
@@ -330,18 +353,16 @@ export type EntityIndexMeta = {
|
|
|
330
353
|
name?: string;
|
|
331
354
|
/** Whether index is unique; omit or `false` for a non-unique index (default). */
|
|
332
355
|
unique?: boolean;
|
|
333
|
-
/** Index type */
|
|
334
|
-
type?: IndexType;
|
|
335
356
|
/** Partial index condition (WHERE clause) */
|
|
336
357
|
where?: string;
|
|
337
|
-
} & VectorIndexOptions;
|
|
358
|
+
} & VectorIndexOptions & IndexTypeOptions;
|
|
338
359
|
export type EntityMeta<E> = {
|
|
339
360
|
readonly entity: Type<E>;
|
|
340
361
|
name?: string;
|
|
341
362
|
id: IdKey<E>;
|
|
342
363
|
softDelete?: FieldKey<E>;
|
|
343
364
|
/** Named, default-on `$where` filters applied to every query unless bypassed. */
|
|
344
|
-
filters?: Record<string,
|
|
365
|
+
filters?: Record<string, FilterOptions<E>>;
|
|
345
366
|
fields: {
|
|
346
367
|
[K in FieldKey<E>]?: FieldOptions;
|
|
347
368
|
} & {
|