uql-orm 0.67.1 → 0.68.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/dist/browser/http/http.js +5 -8
- package/dist/browser/querier/httpQuerier.d.ts +9 -9
- package/dist/browser/uql-browser.min.js +2 -2
- package/dist/browser/uql-browser.min.js.map +9 -8
- package/dist/cockroachdb/cockroachDialect.d.ts +6 -4
- package/dist/cockroachdb/cockroachDialect.js +7 -3
- package/dist/d1/d1Querier.d.ts +5 -5
- package/dist/d1/d1QuerierPool.d.ts +3 -3
- package/dist/d1/d1SqliteDialect.d.ts +1 -1
- package/dist/d1/d1SqliteDialect.js +1 -1
- package/dist/dialect/abstractSqlDialect.d.ts +107 -97
- package/dist/dialect/abstractSqlDialect.js +250 -293
- package/dist/dialect/hydrateColumn.js +33 -30
- package/dist/dialect/jsonSql.d.ts +32 -23
- package/dist/dialect/jsonSql.js +42 -31
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +19 -23
- package/dist/dialect/mysqlLikeSqlDialect.js +34 -51
- package/dist/dialect/pgLikeSqlDialect.d.ts +24 -17
- package/dist/dialect/pgLikeSqlDialect.js +53 -26
- package/dist/dialect/vectorCast.d.ts +2 -0
- package/dist/dialect/vectorCast.js +25 -5
- package/dist/dialect/vectorSqlDialect.d.ts +8 -8
- package/dist/dialect/vectorSqlDialect.js +11 -11
- package/dist/http/query.d.ts +10 -2
- package/dist/http/query.js +26 -1
- package/dist/maria/mariaDialect.d.ts +16 -11
- package/dist/maria/mariaDialect.js +23 -19
- package/dist/migrate/ddl/indexDdl.d.ts +3 -1
- package/dist/migrate/ddl/indexDdl.js +5 -1
- package/dist/migrate/ddl/mysqlIndexDdl.d.ts +7 -2
- package/dist/migrate/ddl/mysqlIndexDdl.js +28 -6
- package/dist/migrate/ddl/pgIndexDdl.d.ts +0 -9
- package/dist/migrate/ddl/pgIndexDdl.js +2 -6
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.d.ts +12 -1
- package/dist/migrate/introspection/abstractSqlSchemaIntrospector.js +13 -3
- package/dist/migrate/introspection/mssqlIntrospector.d.ts +2 -9
- package/dist/migrate/introspection/mssqlIntrospector.js +2 -9
- package/dist/migrate/introspection/mysqlIntrospector.d.ts +2 -9
- package/dist/migrate/introspection/mysqlIntrospector.js +2 -8
- package/dist/mongo/mongoDialect.d.ts +22 -10
- package/dist/mongo/mongoDialect.js +86 -38
- package/dist/mssql/mssqlDialect.d.ts +22 -18
- package/dist/mssql/mssqlDialect.js +54 -43
- package/dist/mysql/mysqlDialect.d.ts +16 -1
- package/dist/mysql/mysqlDialect.js +18 -2
- package/dist/sqlite/sqliteDialect.d.ts +17 -16
- package/dist/sqlite/sqliteDialect.js +35 -39
- package/dist/type/dialect.d.ts +0 -4
- package/dist/type/entity.d.ts +12 -7
- package/dist/type/query.d.ts +29 -24
- package/dist/type/queryWhere.d.ts +20 -20
- package/dist/type/universalQuerier.d.ts +10 -10
- package/dist/type/vector.d.ts +5 -7
- package/dist/type/wire.d.ts +9 -0
- package/dist/util/dialect.util.d.ts +2 -0
- package/dist/util/dialect.util.js +6 -2
- package/dist/util/object.util.d.ts +2 -4
- package/dist/util/object.util.js +4 -9
- package/package.json +2 -2
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts +0 -2
- package/dist/dialect/jsonArrayElemMatchUtils.js +0 -7
- package/dist/dialect/pgVectorMetrics.d.ts +0 -13
- package/dist/dialect/pgVectorMetrics.js +0 -17
- package/dist/maria/mariaVectorMetrics.d.ts +0 -8
- package/dist/maria/mariaVectorMetrics.js +0 -10
|
@@ -26,10 +26,10 @@ export type QueryTextSearchOptions<E> = {
|
|
|
26
26
|
* entity's keys so each stays linked for rename. An object and nothing else, so a wrong value is
|
|
27
27
|
* reported on its key: ids go through `{ id: 1 }` or the by-id methods.
|
|
28
28
|
*/
|
|
29
|
-
export type QueryWhere<E, K extends keyof E = FieldKey<E> | RelationKey<E>> = QueryWhereRootOperator<E> & {
|
|
30
|
-
[P in K]?: P extends FieldKey<E> ? QueryWhereFieldValue<E[P]> : QueryWhere<RelationTarget<E[P]
|
|
29
|
+
export type QueryWhere<E, Raw = QueryRaw, K extends keyof E = FieldKey<E> | RelationKey<E>> = QueryWhereRootOperator<E, Raw> & {
|
|
30
|
+
[P in K]?: P extends FieldKey<E> ? QueryWhereFieldValue<E[P], Raw> : QueryWhere<RelationTarget<E[P]>, Raw> | QueryRelationSizeFilter;
|
|
31
31
|
} & ([JsonFieldPaths<E>] extends [never] ? unknown : {
|
|
32
|
-
[P in JsonFieldPaths<E>]?: QueryWhereFieldValue<JsonFieldPathValue<E, P
|
|
32
|
+
[P in JsonFieldPaths<E>]?: QueryWhereFieldValue<JsonFieldPathValue<E, P>, Raw>;
|
|
33
33
|
});
|
|
34
34
|
/**
|
|
35
35
|
* Filter a to-many relation by its row count.
|
|
@@ -39,24 +39,24 @@ export type QueryWhere<E, K extends keyof E = FieldKey<E> | RelationKey<E>> = Qu
|
|
|
39
39
|
export type QueryRelationSizeFilter = {
|
|
40
40
|
readonly $size: number | QuerySizeComparisonOps;
|
|
41
41
|
};
|
|
42
|
-
export type QueryWhereRootOperator<E> = {
|
|
42
|
+
export type QueryWhereRootOperator<E, Raw = QueryRaw> = {
|
|
43
43
|
/**
|
|
44
44
|
* joins query clauses with a logical `AND`, returns records that match all the clauses.
|
|
45
45
|
*/
|
|
46
|
-
$and?: QueryWhereArray<E>;
|
|
46
|
+
$and?: QueryWhereArray<E, Raw>;
|
|
47
47
|
/**
|
|
48
48
|
* joins query clauses with a logical `OR`, returns records that match any of the clauses.
|
|
49
49
|
*/
|
|
50
|
-
$or?: QueryWhereArray<E>;
|
|
50
|
+
$or?: QueryWhereArray<E, Raw>;
|
|
51
51
|
/**
|
|
52
52
|
* joins query clauses with a logical `AND`, returns records that do not match all the clauses.
|
|
53
53
|
* @see {@link QueryWhereFieldOperatorMap.$not} for per-field negation.
|
|
54
54
|
*/
|
|
55
|
-
$not?: QueryWhereArray<E>;
|
|
55
|
+
$not?: QueryWhereArray<E, Raw>;
|
|
56
56
|
/**
|
|
57
57
|
* joins query clauses with a logical `OR`, returns records that do not match any of the clauses.
|
|
58
58
|
*/
|
|
59
|
-
$nor?: QueryWhereArray<E>;
|
|
59
|
+
$nor?: QueryWhereArray<E, Raw>;
|
|
60
60
|
/**
|
|
61
61
|
* whether the specified fields match against a full-text search of the given string.
|
|
62
62
|
*/
|
|
@@ -64,11 +64,11 @@ export type QueryWhereRootOperator<E> = {
|
|
|
64
64
|
/**
|
|
65
65
|
* whether the record exists in the given sub-query.
|
|
66
66
|
*/
|
|
67
|
-
$exists?:
|
|
67
|
+
$exists?: Raw;
|
|
68
68
|
/**
|
|
69
69
|
* whether the record does not exists in the given sub-query.
|
|
70
70
|
*/
|
|
71
|
-
$nexists?:
|
|
71
|
+
$nexists?: Raw;
|
|
72
72
|
};
|
|
73
73
|
/**
|
|
74
74
|
* Per-field negation operators. `Pick`'s constraint ties this back to
|
|
@@ -100,7 +100,7 @@ export type QuerySizeComparisonOps = {
|
|
|
100
100
|
export type QueryVectorNear = QueryVectorQuery & {
|
|
101
101
|
[K in QueryOrderedOp]?: NonNullable<QueryWhereFieldOperatorMap<number>[K]>;
|
|
102
102
|
};
|
|
103
|
-
export type QueryWhereFieldOperatorMap<T> = {
|
|
103
|
+
export type QueryWhereFieldOperatorMap<T, Raw = QueryRaw> = {
|
|
104
104
|
/**
|
|
105
105
|
* whether a value is equal to the given value.
|
|
106
106
|
*/
|
|
@@ -113,7 +113,7 @@ export type QueryWhereFieldOperatorMap<T> = {
|
|
|
113
113
|
* negates the given comparison for a single field.
|
|
114
114
|
* @see {@link QueryWhereRootOperator.$not} for root-level clause negation.
|
|
115
115
|
*/
|
|
116
|
-
$not?: QueryWhereFieldValue<T>;
|
|
116
|
+
$not?: QueryWhereFieldValue<T, Raw>;
|
|
117
117
|
/**
|
|
118
118
|
* whether a value is less than the given value.
|
|
119
119
|
*/
|
|
@@ -202,7 +202,7 @@ export type QueryWhereFieldOperatorMap<T> = {
|
|
|
202
202
|
* @example { addresses: { $elemMatch: { city: 'NYC', zip: '10001' } } }
|
|
203
203
|
* @example { addresses: { $elemMatch: { city: { $like: 'New%' } } } }
|
|
204
204
|
*/
|
|
205
|
-
$elemMatch?: unknown extends T ? QueryWhereElemMatch<unknown> : NonNullable<T> extends readonly (infer U)[] ? QueryWhereElemMatch<U> : never;
|
|
205
|
+
$elemMatch?: unknown extends T ? QueryWhereElemMatch<unknown, Raw> : NonNullable<T> extends readonly (infer U)[] ? QueryWhereElemMatch<U, Raw> : never;
|
|
206
206
|
/**
|
|
207
207
|
* whether a vector is within a given distance of the query vector. `$sort` ranks by distance;
|
|
208
208
|
* this filters by it, so "the closest ten" and "everything closer than 0.35" are separate asks.
|
|
@@ -216,10 +216,10 @@ export type QueryWhereFieldOperatorMap<T> = {
|
|
|
216
216
|
* field comparison. An untyped element (`unknown`) accepts any keys but still requires the
|
|
217
217
|
* object-of-conditions shape (a bare scalar is rejected).
|
|
218
218
|
*/
|
|
219
|
-
export type QueryWhereElemMatch<U> = unknown extends U ? {
|
|
220
|
-
[key: string]: QueryWhereFieldValue<unknown> | undefined;
|
|
221
|
-
} : NonNullable<U> extends Scalar ? QueryWhereFieldOperators<NonNullable<U
|
|
222
|
-
[K in keyof NonNullable<U>]?: QueryWhereFieldValue<NonNullable<U>[K]>;
|
|
219
|
+
export type QueryWhereElemMatch<U, Raw = QueryRaw> = unknown extends U ? {
|
|
220
|
+
[key: string]: QueryWhereFieldValue<unknown, Raw> | undefined;
|
|
221
|
+
} : NonNullable<U> extends Scalar ? QueryWhereFieldOperators<NonNullable<U>, Raw> : {
|
|
222
|
+
[K in keyof NonNullable<U>]?: QueryWhereFieldValue<NonNullable<U>[K], Raw>;
|
|
223
223
|
};
|
|
224
224
|
/**
|
|
225
225
|
* Simple relational comparison operators. `Pick`'s constraint ties this back to
|
|
@@ -269,7 +269,7 @@ type QueryAllowedOp<T> = QueryCommonOp | ([NonNullable<T>] extends [QueryCompara
|
|
|
269
269
|
* The operators a field of type `T` takes. `unknown`, and a column typed as every scalar at once (a
|
|
270
270
|
* runtime-defined entity), take all of them, since nothing narrows what they hold.
|
|
271
271
|
*/
|
|
272
|
-
export type QueryWhereFieldOperators<T> = unknown extends T ? QueryWhereFieldOperatorMap<T> : IsUntypedColumn<T> extends true ? QueryWhereFieldOperatorMap<T> : Pick<QueryWhereFieldOperatorMap<T>, QueryAllowedOp<T>>;
|
|
272
|
+
export type QueryWhereFieldOperators<T, Raw = QueryRaw> = unknown extends T ? QueryWhereFieldOperatorMap<T, Raw> : IsUntypedColumn<T> extends true ? QueryWhereFieldOperatorMap<T, Raw> : Pick<QueryWhereFieldOperatorMap<T, Raw>, QueryAllowedOp<T>>;
|
|
273
273
|
/**
|
|
274
274
|
* Whether a column admits every scalar at once, which is what an entity keyed by an index signature
|
|
275
275
|
* says about all of its columns. `Scalar` is the yardstick rather than a parameter: the question is
|
|
@@ -280,9 +280,9 @@ type IsUntypedColumn<T> = [Scalar] extends [NonNullable<T>] ? true : false;
|
|
|
280
280
|
* A field's filter value: the value, `null` where it is optional, a list as an implicit `$in` (not on
|
|
281
281
|
* an array field, where it would be ambiguous), or an operator map.
|
|
282
282
|
*/
|
|
283
|
-
export type QueryWhereFieldValue<T> = T | (undefined extends T ? null : never) | (IsMany<T> extends true ? never : T[]) | QueryWhereFieldOperators<T> |
|
|
283
|
+
export type QueryWhereFieldValue<T, Raw = QueryRaw> = T | (undefined extends T ? null : never) | (IsMany<T> extends true ? never : T[]) | QueryWhereFieldOperators<T, Raw> | Raw;
|
|
284
284
|
/**
|
|
285
285
|
* query filter array - the value every {@link QueryGroupOp} takes.
|
|
286
286
|
*/
|
|
287
|
-
export type QueryWhereArray<E> = (QueryWhere<E> |
|
|
287
|
+
export type QueryWhereArray<E, Raw = QueryRaw> = (QueryWhere<E, Raw> | Raw)[];
|
|
288
288
|
export {};
|
|
@@ -2,38 +2,38 @@ import type { EntityData, EntityId, FieldKey, RelationKey, UpdatePayload, Writte
|
|
|
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';
|
|
5
|
-
import type { QuerierCountedResult, QuerierResult, QuerierTransport } from './wire.js';
|
|
5
|
+
import type { QuerierCountedResult, QuerierRaw, QuerierResult, QuerierTransport } from './wire.js';
|
|
6
6
|
/**
|
|
7
7
|
* The operations the server and the browser client declare alike, per transport `W`, options `O`,
|
|
8
8
|
* and delete options `DO`, which on the client also carry the {@link QueryOptions} it cannot pass otherwise.
|
|
9
9
|
*/
|
|
10
10
|
export interface SharedQuerier<W extends QuerierTransport, O, DO = O> {
|
|
11
11
|
/** Find the record with the given primary key. */
|
|
12
|
-
findOneById<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>, id: EntityId<E>, q?: QueryOneProjected<E, S, V, X, P, C
|
|
12
|
+
findOneById<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>, id: EntityId<E>, q?: QueryOneProjected<E, S, V, X, P, C, QuerierRaw<W>>, opts?: O): QuerierResult<W, QueryFindResult<E, S, V, X, P, C> | undefined>;
|
|
13
13
|
/**
|
|
14
14
|
* obtains the first record matching the given search parameters.
|
|
15
15
|
* @param entity the target entity
|
|
16
16
|
* @param q the criteria options
|
|
17
17
|
* @return the record
|
|
18
18
|
*/
|
|
19
|
-
findOne<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: QueryOneProjected<E, S, V, X, P, C
|
|
19
|
+
findOne<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: QueryOneProjected<E, S, V, X, P, C, QuerierRaw<W>>, opts?: O): QuerierResult<W, QueryFindResult<E, S, V, X, P, C> | undefined>;
|
|
20
20
|
/**
|
|
21
21
|
* obtains the records matching the given search parameters.
|
|
22
22
|
* @param entity the target entity
|
|
23
23
|
* @param q the criteria options
|
|
24
24
|
* @return the records
|
|
25
25
|
*/
|
|
26
|
-
findMany<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
|
|
26
|
+
findMany<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, QuerierRaw<W>>, opts?: O): QuerierResult<W, QueryFindResult<E, S, V, X, P, C>[]>;
|
|
27
27
|
/** Find the records matching the query, and count every match past its page. */
|
|
28
|
-
findManyAndCount<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
|
|
28
|
+
findManyAndCount<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, QuerierRaw<W>>, opts?: O): QuerierCountedResult<W, QueryFindResult<E, S, V, X, P, C>>;
|
|
29
29
|
/** Count the records matching the filter, or those a page of them takes. */
|
|
30
|
-
count<E extends object>(entity: Type<E>, q?: QueryPage<E
|
|
30
|
+
count<E extends object>(entity: Type<E>, q?: QueryPage<E, QuerierRaw<W>>, opts?: O): QuerierResult<W, number>;
|
|
31
31
|
/** Whether any record matches: a count capped at one row, so the engine stops at the first match. */
|
|
32
|
-
exists<E extends object>(entity: Type<E>, q?: QueryFilter<E
|
|
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: UpdatePayload<E
|
|
34
|
+
updateOneById<E extends object>(entity: Type<E>, id: EntityId<E>, payload: UpdatePayload<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
|
|
36
|
+
updateMany<E extends object>(entity: Type<E>, q: QuerySearch<E, QuerierRaw<W>>, payload: UpdatePayload<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
|
|
@@ -47,7 +47,7 @@ export interface SharedQuerier<W extends QuerierTransport, O, DO = O> {
|
|
|
47
47
|
* @param q the criteria to look for the records
|
|
48
48
|
* @return the number of affected records
|
|
49
49
|
*/
|
|
50
|
-
deleteMany<E extends object>(entity: Type<E>, q: QuerySearch<E
|
|
50
|
+
deleteMany<E extends object>(entity: Type<E>, q: QuerySearch<E, QuerierRaw<W>>, opts?: DO): QuerierResult<W, number>;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* A `querier` allows to interact with the datasource to perform persistence operations on any entity.
|
package/dist/type/vector.d.ts
CHANGED
|
@@ -28,20 +28,18 @@ export interface QueryVectorSearch extends QueryVectorQuery {
|
|
|
28
28
|
*/
|
|
29
29
|
export type WithDistance<E, K extends string = '_distance'> = E & Record<K, number>;
|
|
30
30
|
/**
|
|
31
|
-
* How a dialect spells a metric: an operator
|
|
32
|
-
*
|
|
31
|
+
* How a dialect spells a metric: an operator, or a function taking the metric by name where `metricArg`
|
|
32
|
+
* says so, and `index`, how the dialect's vector index names it where it builds one. One map serves the
|
|
33
|
+
* query and the index alike, so its keys say which metrics exist.
|
|
33
34
|
*/
|
|
34
35
|
export type VectorMetric = {
|
|
35
36
|
readonly op: string;
|
|
36
|
-
readonly
|
|
37
|
+
readonly index: string;
|
|
37
38
|
} | {
|
|
38
39
|
readonly fn: string;
|
|
39
40
|
readonly metricArg?: string;
|
|
41
|
+
readonly index?: string;
|
|
40
42
|
};
|
|
41
|
-
/** The operator form, for the pgvector-family dialects whose index DDL also needs `opsSuffix`. */
|
|
42
|
-
export type VectorOperatorMetric = Extract<VectorMetric, {
|
|
43
|
-
op: string;
|
|
44
|
-
}>;
|
|
45
43
|
/** The error every dialect throws for a metric it lacks. */
|
|
46
44
|
export declare function unsupportedVectorMetric(dialectName: string, distance: VectorDistance, indexName?: string): TypeError;
|
|
47
45
|
/**
|
package/dist/type/wire.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { QueryRaw } from './queryRaw.js';
|
|
1
2
|
/**
|
|
2
3
|
* The envelope a wire response wraps its result in.
|
|
3
4
|
*/
|
|
@@ -16,6 +17,14 @@ export type RequestCountedSuccessResponse<E> = RequestSuccessResponse<E> & {
|
|
|
16
17
|
* client one hands back the envelope its transport wrapped it in.
|
|
17
18
|
*/
|
|
18
19
|
export type QuerierTransport = 'server' | 'client';
|
|
20
|
+
/**
|
|
21
|
+
* The `raw` SQL a transport carries. A client's query and payload travel as JSON, which a `raw` fragment
|
|
22
|
+
* is not: it would arrive as `{}`, so the client's types refuse one rather than let it leave.
|
|
23
|
+
*/
|
|
24
|
+
export type QuerierRaw<W extends QuerierTransport> = {
|
|
25
|
+
server: QueryRaw;
|
|
26
|
+
client: never;
|
|
27
|
+
}[W];
|
|
19
28
|
/**
|
|
20
29
|
* A querier method's result on a transport: `Promise<User[]>` on the server, the response envelope on
|
|
21
30
|
* the client. A map indexed by the transport, which resolves away in hovers.
|
|
@@ -138,6 +138,8 @@ export declare function parseGroupMap<E>(group?: QueryGroupMap<E>, select?: Quer
|
|
|
138
138
|
* indices. Shared by the SQL and MongoDB builders, whose `$where` and `$having` all face this.
|
|
139
139
|
*/
|
|
140
140
|
export declare function isOperatorMap(value: unknown): value is Record<string, unknown>;
|
|
141
|
+
/** A JSON object, matched by what it holds: a plain object with no operator key. */
|
|
142
|
+
export declare function isJsonObject(value: unknown): value is Record<string, unknown>;
|
|
141
143
|
/**
|
|
142
144
|
* A page operand, checked before it reaches an engine. These arrive from page arithmetic and from
|
|
143
145
|
* REST query strings (`parseQueryParams` yields `NaN` for a non-numeric one), and each engine's own
|
|
@@ -3,7 +3,7 @@ import { soleIdOf } from '../entity/metadata/definition.js';
|
|
|
3
3
|
import { QueryRaw, resolveAggregateOp, SOFT_DELETE_FILTER, } from '../type/index.js';
|
|
4
4
|
import { VECTOR_INDEX_TYPES } from '../type/vector.js';
|
|
5
5
|
import { isDatabaseWritten } from './field.util.js';
|
|
6
|
-
import { entityName, getFieldKeys, getKeys, hasKeys, isScalarId, isRecord, isWhereMap, someKey, } from './object.util.js';
|
|
6
|
+
import { entityName, getFieldKeys, getKeys, hasKeys, isOperatorObject, isScalarId, isRecord, isWhereMap, someKey, } from './object.util.js';
|
|
7
7
|
/** The keys of `payload` a write persists as columns. */
|
|
8
8
|
export function filterFieldKeys(meta, payload, callbackKey) {
|
|
9
9
|
return getKeys(payload).filter((key) => {
|
|
@@ -226,7 +226,7 @@ const JSON_UPDATE_OPS = [
|
|
|
226
226
|
];
|
|
227
227
|
/** Type guard: checks whether an update payload value is a JSON operator object. */
|
|
228
228
|
export function isJsonUpdateOp(value) {
|
|
229
|
-
return value
|
|
229
|
+
return isRecord(value) && someKey(value, (key) => JSON_UPDATE_OPS.includes(key));
|
|
230
230
|
}
|
|
231
231
|
/**
|
|
232
232
|
* The `$where` naming rows by key: a bare value names the one key column (refused on a composite), a
|
|
@@ -386,6 +386,10 @@ export function isOperatorMap(value) {
|
|
|
386
386
|
!(value instanceof Uint8Array) &&
|
|
387
387
|
!(value instanceof QueryRaw));
|
|
388
388
|
}
|
|
389
|
+
/** A JSON object, matched by what it holds: a plain object with no operator key. */
|
|
390
|
+
export function isJsonObject(value) {
|
|
391
|
+
return isOperatorMap(value) && !isOperatorObject(value);
|
|
392
|
+
}
|
|
389
393
|
/**
|
|
390
394
|
* A page operand, checked before it reaches an engine. These arrive from page arithmetic and from
|
|
391
395
|
* REST query strings (`parseQueryParams` yields `NaN` for a non-numeric one), and each engine's own
|
|
@@ -9,12 +9,10 @@ export declare function hasKeys<T>(obj: T): obj is NonNullable<T>;
|
|
|
9
9
|
* without materializing a key array (unlike `Object.keys(obj).some(pred)`).
|
|
10
10
|
*/
|
|
11
11
|
export declare function someKey<T extends object>(obj: T, pred: (key: keyof T & string) => boolean): boolean;
|
|
12
|
-
/** Whether
|
|
13
|
-
export declare function
|
|
12
|
+
/** Whether `key` names an operator (`$eq`, `$push`...) rather than a field. */
|
|
13
|
+
export declare function isOperatorKey(key: string): boolean;
|
|
14
14
|
/** Whether `value` is a non-empty object with an operator key (`$eq`, `$push`...): the one test every dialect classifies with. */
|
|
15
15
|
export declare function isOperatorObject(value: unknown): value is Record<string, unknown>;
|
|
16
|
-
/** Whether every key of the non-empty object `value` is an operator (no plain field names mixed in). */
|
|
17
|
-
export declare function isOperatorOnlyObject(value: unknown): value is Record<string, unknown>;
|
|
18
16
|
/** Whether `value` is an object that is not an array, whose keys can be read. */
|
|
19
17
|
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
20
18
|
export declare function getKeys<T extends object>(obj: T | null | undefined): (keyof T & string)[];
|
package/dist/util/object.util.js
CHANGED
|
@@ -32,18 +32,13 @@ export function someKey(obj, pred) {
|
|
|
32
32
|
}
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
|
-
/** Whether
|
|
36
|
-
export function
|
|
37
|
-
return
|
|
35
|
+
/** Whether `key` names an operator (`$eq`, `$push`...) rather than a field. */
|
|
36
|
+
export function isOperatorKey(key) {
|
|
37
|
+
return key.startsWith('$');
|
|
38
38
|
}
|
|
39
|
-
const isOperatorKey = (key) => key.startsWith('$');
|
|
40
39
|
/** Whether `value` is a non-empty object with an operator key (`$eq`, `$push`...): the one test every dialect classifies with. */
|
|
41
40
|
export function isOperatorObject(value) {
|
|
42
|
-
return
|
|
43
|
-
}
|
|
44
|
-
/** Whether every key of the non-empty object `value` is an operator (no plain field names mixed in). */
|
|
45
|
-
export function isOperatorOnlyObject(value) {
|
|
46
|
-
return hasKeys(value) && !Array.isArray(value) && !someKey(value, (key) => !isOperatorKey(key));
|
|
41
|
+
return isRecord(value) && someKey(value, isOperatorKey);
|
|
47
42
|
}
|
|
48
43
|
/** Whether `value` is an object that is not an array, whose keys can be read. */
|
|
49
44
|
export function isRecord(value) {
|
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.68.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"engines": {
|
|
9
9
|
"node": ">=24"
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
"repository": {
|
|
162
162
|
"type": "git",
|
|
163
163
|
"url": "git+https://github.com/rogerpadilla/uql.git",
|
|
164
|
-
"directory": "packages/
|
|
164
|
+
"directory": "packages/orm"
|
|
165
165
|
},
|
|
166
166
|
"bugs": {
|
|
167
167
|
"url": "https://github.com/rogerpadilla/uql/issues"
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { isOperatorObject } from '../util/object.util.js';
|
|
2
|
-
/** An `$elemMatch` as per-field conditions, a plain value as `$eq`, so both spellings emit the same SQL. */
|
|
3
|
-
export function buildElemMatchConditions(match, onCondition) {
|
|
4
|
-
return Object.entries(match).flatMap(([field, value]) => isOperatorObject(value)
|
|
5
|
-
? Object.entries(value).map(([op, opVal]) => onCondition(field, op, opVal))
|
|
6
|
-
: onCondition(field, '$eq', value));
|
|
7
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { VectorDistance, VectorOperatorMetric } from '../type/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Each metric's pgvector distance operator and the operator-class suffix its index takes, in one list
|
|
4
|
-
* so a dialect cannot have the operator but not the opclass. Its own module because the two ends live
|
|
5
|
-
* apart: the operator on the dialect, the opclass in the migrator's index DDL.
|
|
6
|
-
*/
|
|
7
|
-
export declare const PG_VECTOR_METRICS: ReadonlyMap<VectorDistance, VectorOperatorMetric>;
|
|
8
|
-
/**
|
|
9
|
-
* CockroachDB's three: `<+>` and `vector_l1_ops` answer "unimplemented: operator class ... is not
|
|
10
|
-
* supported" (verified live on v26.2), tracked at https://github.com/cockroachdb/cockroach/issues/147839.
|
|
11
|
-
* Re-check that issue before adding `l1`; it is omitted on purpose.
|
|
12
|
-
*/
|
|
13
|
-
export declare const COCKROACH_VECTOR_METRICS: ReadonlyMap<VectorDistance, VectorOperatorMetric>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Each metric's pgvector distance operator and the operator-class suffix its index takes, in one list
|
|
3
|
-
* so a dialect cannot have the operator but not the opclass. Its own module because the two ends live
|
|
4
|
-
* apart: the operator on the dialect, the opclass in the migrator's index DDL.
|
|
5
|
-
*/
|
|
6
|
-
export const PG_VECTOR_METRICS = new Map([
|
|
7
|
-
['cosine', { op: '<=>', opsSuffix: 'cosine' }],
|
|
8
|
-
['l2', { op: '<->', opsSuffix: 'l2' }],
|
|
9
|
-
['inner', { op: '<#>', opsSuffix: 'ip' }],
|
|
10
|
-
['l1', { op: '<+>', opsSuffix: 'l1' }],
|
|
11
|
-
]);
|
|
12
|
-
/**
|
|
13
|
-
* CockroachDB's three: `<+>` and `vector_l1_ops` answer "unimplemented: operator class ... is not
|
|
14
|
-
* supported" (verified live on v26.2), tracked at https://github.com/cockroachdb/cockroach/issues/147839.
|
|
15
|
-
* Re-check that issue before adding `l1`; it is omitted on purpose.
|
|
16
|
-
*/
|
|
17
|
-
export const COCKROACH_VECTOR_METRICS = new Map([...PG_VECTOR_METRICS].filter(([metric]) => metric !== 'l1'));
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { VectorDistance } from '../type/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* MariaDB's own name for each metric it supports (`euclidean`, not `l2`), which its index clause and
|
|
4
|
-
* its distance function are both spelled from - one list, so a metric can never be searchable and
|
|
5
|
-
* unindexable or the reverse. Its own module because the two ends now live apart: the distance
|
|
6
|
-
* function on the dialect, the `DISTANCE=` clause in the migrator's index DDL.
|
|
7
|
-
*/
|
|
8
|
-
export declare const MARIA_VECTOR_METRICS: Map<VectorDistance, string>;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MariaDB's own name for each metric it supports (`euclidean`, not `l2`), which its index clause and
|
|
3
|
-
* its distance function are both spelled from - one list, so a metric can never be searchable and
|
|
4
|
-
* unindexable or the reverse. Its own module because the two ends now live apart: the distance
|
|
5
|
-
* function on the dialect, the `DISTANCE=` clause in the migrator's index DDL.
|
|
6
|
-
*/
|
|
7
|
-
export const MARIA_VECTOR_METRICS = new Map([
|
|
8
|
-
['cosine', 'cosine'],
|
|
9
|
-
['l2', 'euclidean'],
|
|
10
|
-
]);
|