uql-orm 0.69.0 → 0.70.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/dist/browser/querier/httpQuerier.d.ts +7 -7
- package/dist/browser/type/clientQuerier.d.ts +5 -5
- package/dist/browser/uql-browser.min.js +2 -2
- package/dist/browser/uql-browser.min.js.map +4 -4
- package/dist/cockroachdb/cockroachDialect.js +2 -2
- package/dist/dialect/abstractDialect.d.ts +8 -2
- package/dist/dialect/abstractDialect.js +17 -1
- package/dist/dialect/abstractSqlDialect.d.ts +16 -5
- package/dist/dialect/abstractSqlDialect.js +82 -44
- package/dist/dialect/aliases.d.ts +10 -7
- package/dist/dialect/aliases.js +10 -7
- package/dist/dialect/mysqlLikeSqlDialect.js +3 -2
- package/dist/dialect/pgLikeSqlDialect.js +1 -0
- package/dist/dialect/queryJoins.d.ts +8 -1
- package/dist/dialect/queryJoins.js +33 -10
- package/dist/entity/decorator/members.d.ts +25 -11
- package/dist/entity/metadata/definition.d.ts +8 -3
- package/dist/migrate/codegen/entityCodeGenerator.js +4 -2
- package/dist/migrate/migrator.d.ts +2 -1
- package/dist/migrate/migrator.js +5 -3
- package/dist/mongo/mongoDialect.d.ts +31 -27
- package/dist/mongo/mongoDialect.js +172 -112
- package/dist/mongo/mongodbQuerier.d.ts +0 -2
- package/dist/mongo/mongodbQuerier.js +12 -11
- package/dist/mssql/mssqlDialect.js +3 -2
- package/dist/postgres/postgresDialect.js +2 -2
- package/dist/querier/abstractQuerier.d.ts +16 -11
- package/dist/querier/abstractQuerier.js +28 -8
- package/dist/querier/abstractQuerierPool.d.ts +9 -9
- package/dist/querier/abstractSqlQuerier.d.ts +1 -1
- package/dist/querier/abstractSqlQuerier.js +3 -3
- package/dist/sqlite/sqliteDialect.js +1 -0
- package/dist/turso/tursoDialect.d.ts +1 -1
- package/dist/turso/tursoDialect.js +6 -2
- package/dist/type/dialect.d.ts +6 -0
- package/dist/type/entity.d.ts +31 -2
- package/dist/type/migration.d.ts +7 -0
- package/dist/type/query.d.ts +6 -0
- package/dist/type/queryAggregate.d.ts +77 -42
- package/dist/type/queryAggregate.js +4 -21
- package/dist/type/universalQuerier.d.ts +9 -9
- package/dist/util/dialect.util.d.ts +6 -2
- package/dist/util/dialect.util.js +19 -5
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntityId, EntityWrite, FieldKey, RelationKey, UpdateWrite, WrittenId } from './entity.js';
|
|
2
2
|
import type { QueryConflictPaths, QueryFilter, QueryFindResult, QueryOneProjected, QueryOptions, QueryPage, QueryProjected, QuerySearch, QueryUpsertOneResult, QueryUpsertManyResult } from './query.js';
|
|
3
3
|
import type { QueryAggMap, QueryAggregate, QueryAggregateResult, QueryGroupMap } from './queryAggregate.js';
|
|
4
4
|
import type { Type } from './utility.js';
|
|
@@ -31,9 +31,9 @@ export interface SharedQuerier<W extends QuerierTransport, O, DO = O> {
|
|
|
31
31
|
/** Whether any record matches: a count capped at one row, so the engine stops at the first match. */
|
|
32
32
|
exists<E extends object>(entity: Type<E>, q?: QueryFilter<E, QuerierRaw<W>>, opts?: O): QuerierResult<W, boolean>;
|
|
33
33
|
/** Update the record with the given primary key; resolves to the number of affected rows. */
|
|
34
|
-
updateOneById<E extends object>(entity: Type<E>, id: EntityId<E>, payload:
|
|
34
|
+
updateOneById<E extends object>(entity: Type<E>, id: EntityId<E>, payload: UpdateWrite<E, QuerierRaw<W>>, opts?: O): QuerierResult<W, number>;
|
|
35
35
|
/** Update the records matching the query; resolves to the number of affected rows. */
|
|
36
|
-
updateMany<E extends object>(entity: Type<E>, q: QuerySearch<E, QuerierRaw<W>>, payload:
|
|
36
|
+
updateMany<E extends object>(entity: Type<E>, q: QuerySearch<E, QuerierRaw<W>>, payload: UpdateWrite<E, QuerierRaw<W>>, opts?: O): QuerierResult<W, number>;
|
|
37
37
|
/**
|
|
38
38
|
* delete or SoftDelete a record.
|
|
39
39
|
* @param entity the entity to persist on
|
|
@@ -59,31 +59,31 @@ export interface UniversalQuerier extends SharedQuerier<'server', QueryOptions>
|
|
|
59
59
|
*/
|
|
60
60
|
findManyStream<E extends object, const S extends FieldKey<E> = never, const V = true, const X extends FieldKey<E> = never, const P extends RelationKey<E> = never, const C extends RelationKey<E> = never>(entity: Type<E>, q: QueryProjected<E, S, V, X, P, C>, opts?: QueryOptions): AsyncIterable<QueryFindResult<E, S, V, X, P, C>>;
|
|
61
61
|
/** Insert a record and resolve to its id. See {@link UniversalQuerier.insertMany}. */
|
|
62
|
-
insertOne<E extends object>(entity: Type<E>, payload:
|
|
62
|
+
insertOne<E extends object>(entity: Type<E>, payload: EntityWrite<E>): Promise<WrittenId<E> | undefined>;
|
|
63
63
|
/**
|
|
64
64
|
* Insert records in as few statements as the bind limit allows, resolving to their ids in payload order.
|
|
65
65
|
* Ids are exact everywhere but MySQL, which infers them from its header and reports `undefined` rather
|
|
66
66
|
* than a guess where it cannot: a batch naming some keys, or a key that is not `AUTO_INCREMENT`.
|
|
67
67
|
*/
|
|
68
|
-
insertMany<E extends object>(entity: Type<E>, payload:
|
|
68
|
+
insertMany<E extends object>(entity: Type<E>, payload: EntityWrite<E>[]): Promise<(WrittenId<E> | undefined)[]>;
|
|
69
69
|
/** Insert or update a record by its conflict paths; resolves to its id and whether it was created. */
|
|
70
|
-
upsertOne<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload:
|
|
70
|
+
upsertOne<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: EntityWrite<E>): Promise<QueryUpsertOneResult<E>>;
|
|
71
71
|
/** Insert or update records by their conflict paths; resolves to their ids in payload order. */
|
|
72
|
-
upsertMany<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload:
|
|
72
|
+
upsertMany<E extends object>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: EntityWrite<E>[]): Promise<QueryUpsertManyResult<E>>;
|
|
73
73
|
/**
|
|
74
74
|
* insert or update a record.
|
|
75
75
|
* @param entity the entity to persist on
|
|
76
76
|
* @param payload the data to be persisted
|
|
77
77
|
* @return the ID
|
|
78
78
|
*/
|
|
79
|
-
saveOne<E extends object>(entity: Type<E>, payload:
|
|
79
|
+
saveOne<E extends object>(entity: Type<E>, payload: EntityWrite<E>): Promise<WrittenId<E> | undefined>;
|
|
80
80
|
/**
|
|
81
81
|
* Insert or update records.
|
|
82
82
|
* @param entity the entity to persist on
|
|
83
83
|
* @param payload the data to be persisted
|
|
84
84
|
* @return the IDs
|
|
85
85
|
*/
|
|
86
|
-
saveMany<E extends object>(entity: Type<E>, payload:
|
|
86
|
+
saveMany<E extends object>(entity: Type<E>, payload: EntityWrite<E>[]): Promise<(WrittenId<E> | undefined)[]>;
|
|
87
87
|
/**
|
|
88
88
|
* Restore soft-deleted records (sets the soft-delete field back to `null`). Throws if the
|
|
89
89
|
* entity has no soft-delete field.
|
|
@@ -104,9 +104,11 @@ export declare function applyFilters<E>(meta: EntityMeta<E>, whereMap: QueryWher
|
|
|
104
104
|
/**
|
|
105
105
|
* Parsed entry from a `$group` map - either a raw group key or an aggregate function call.
|
|
106
106
|
*/
|
|
107
|
-
export type ParsedGroupEntry = {
|
|
107
|
+
export type ParsedGroupEntry<E = object> = {
|
|
108
108
|
readonly kind: 'key';
|
|
109
109
|
readonly alias: string;
|
|
110
|
+
/** The field it reads, behind the to-one relations leading to it: `['transaction', 'orderId']`. */
|
|
111
|
+
readonly path: readonly string[];
|
|
110
112
|
} | {
|
|
111
113
|
readonly kind: 'fn';
|
|
112
114
|
readonly alias: string;
|
|
@@ -114,6 +116,8 @@ export type ParsedGroupEntry = {
|
|
|
114
116
|
readonly fieldRef: string;
|
|
115
117
|
/** `true` for a flat distinct op (`$countDistinct`, ...) -> `COUNT(DISTINCT field)`. */
|
|
116
118
|
readonly distinct: boolean;
|
|
119
|
+
/** The rows it reads, where not all of the statement's. */
|
|
120
|
+
readonly where?: QueryWhere<E>;
|
|
117
121
|
};
|
|
118
122
|
/**
|
|
119
123
|
* The `$size` of a relation condition, `{ comments: { $size: { $gte: 2 } } }`, or `undefined` where it
|
|
@@ -130,7 +134,7 @@ export declare function parseSortByCount(val: unknown): unknown;
|
|
|
130
134
|
* Parse the `$group` (grouped columns) and `$select` (computed aggregates) maps into structured
|
|
131
135
|
* entries consumable by any dialect. Grouped columns come first, then computed columns.
|
|
132
136
|
*/
|
|
133
|
-
export declare function parseGroupMap<E>(group?: QueryGroupMap<E>, select?: QueryAggMap<E>): ParsedGroupEntry[];
|
|
137
|
+
export declare function parseGroupMap<E>(group?: QueryGroupMap<E>, select?: QueryAggMap<E>): ParsedGroupEntry<E>[];
|
|
134
138
|
/**
|
|
135
139
|
* Whether `value` is a map of comparison operators rather than a value to compare against. Only a
|
|
136
140
|
* plain object qualifies: `Date`, `QueryRaw`, `Uint8Array` and arrays are all `typeof 'object'`, and
|
|
@@ -344,22 +344,36 @@ export function parseGroupMap(group, select) {
|
|
|
344
344
|
const entries = [];
|
|
345
345
|
const groupMap = group ?? {};
|
|
346
346
|
for (const alias of getKeys(groupMap)) {
|
|
347
|
-
|
|
348
|
-
|
|
347
|
+
const ref = groupMap[alias];
|
|
348
|
+
if (ref) {
|
|
349
|
+
entries.push({ kind: 'key', alias, path: ref === true ? [alias] : groupRefPath(alias, ref) });
|
|
349
350
|
}
|
|
350
351
|
}
|
|
351
352
|
if (!select) {
|
|
352
353
|
return entries;
|
|
353
354
|
}
|
|
354
355
|
for (const alias of getKeys(select)) {
|
|
355
|
-
const
|
|
356
|
-
const
|
|
356
|
+
const { $where: where } = select[alias];
|
|
357
|
+
const call = select[alias];
|
|
358
|
+
const key = getKeys(call).find((name) => name !== '$where');
|
|
359
|
+
if (key === undefined) {
|
|
360
|
+
throw new TypeError(`aggregate '${alias}' names no op, only a $where`);
|
|
361
|
+
}
|
|
357
362
|
// Flat DISTINCT ops (`$countDistinct`, ...) normalize to their base op + a `distinct` flag.
|
|
358
363
|
const { op, distinct } = resolveAggregateOp(key);
|
|
359
|
-
|
|
364
|
+
const fieldRef = aggregateFieldRef(alias, call[key]);
|
|
365
|
+
entries.push({ kind: 'fn', alias, op, fieldRef, distinct, ...(where && hasKeys(where) ? { where } : {}) });
|
|
360
366
|
}
|
|
361
367
|
return entries;
|
|
362
368
|
}
|
|
369
|
+
/** The path a group key's `{ transaction: { orderId: true } }` names, one key at each level. */
|
|
370
|
+
function groupRefPath(alias, ref) {
|
|
371
|
+
const [key, ...rest] = isRecord(ref) ? getKeys(ref) : [];
|
|
372
|
+
if (!isRecord(ref) || key === undefined || rest.length) {
|
|
373
|
+
throw new TypeError(`$group '${alias}' names one field by the path to it: got ${JSON.stringify(ref)}`);
|
|
374
|
+
}
|
|
375
|
+
return ref[key] === true ? [key] : [key, ...groupRefPath(alias, ref[key])];
|
|
376
|
+
}
|
|
363
377
|
/** The column an aggregate reads: `'*'`, or the one field its `{ field: true }` names. */
|
|
364
378
|
function aggregateFieldRef(alias, arg) {
|
|
365
379
|
const [field, ...rest] = arg === '*' ? [arg] : namedKeys(arg);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"homepage": "https://uql-orm.dev",
|
|
4
4
|
"description": "The JSON-native TypeScript ORM for Bun, Browsers, Edge, Deno, Node, Workers. Supports PostgreSQL, PGlite, MySQL, MariaDB, SQLite, CockroachDB, SQL Server, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.70.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"engines": {
|
|
9
9
|
"node": ">=24"
|