@danceroutine/tango-orm 1.6.0 → 1.7.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/index.js +2 -2
- package/dist/manager/ManagerLike.d.ts +19 -0
- package/dist/manager/ModelManager.d.ts +24 -1
- package/dist/manager/index.js +2 -2
- package/dist/manager-C6oJ2tAF.js +1 -1
- package/dist/query/QuerySet.d.ts +12 -0
- package/dist/query/index.js +1 -1
- package/dist/query/internal/isQNodeLike.d.ts +3 -0
- package/dist/{query-C6So1r6H.js → query-FZJoSCg4.js} +74 -15
- package/dist/query-FZJoSCg4.js.map +1 -0
- package/dist/{registerModelObjects-BKMpfc4Z.js → registerModelObjects-C-1RbUHS.js} +124 -2
- package/dist/registerModelObjects-C-1RbUHS.js.map +1 -0
- package/dist/runtime/index.js +2 -2
- package/dist/runtime-ByXbpVBS.js +1 -1
- package/package.json +6 -6
- package/dist/query-C6So1r6H.js.map +0 -1
- package/dist/registerModelObjects-BKMpfc4Z.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { PostgresAdapter } from "./PostgresAdapter-CMiEpHya.js";
|
|
|
3
3
|
import "./SqliteClient-CjOK9-ki.js";
|
|
4
4
|
import { SqliteAdapter } from "./SqliteAdapter-CeqhyrPC.js";
|
|
5
5
|
import { AdapterRegistry, connectDB, connection_exports, getDefaultAdapterRegistry } from "./connection-B_K2ZAf7.js";
|
|
6
|
-
import { QBuilder, QueryCompiler, QueryResult, QuerySet, query_exports } from "./query-
|
|
6
|
+
import { QBuilder, QueryCompiler, QueryResult, QuerySet, query_exports } from "./query-FZJoSCg4.js";
|
|
7
7
|
import { TangoRuntime, getTangoRuntime, initializeTangoRuntime, resetTangoRuntime } from "./defaultRuntime-BPK9kWEW.js";
|
|
8
|
-
import { ModelManager } from "./registerModelObjects-
|
|
8
|
+
import { ModelManager } from "./registerModelObjects-C-1RbUHS.js";
|
|
9
9
|
import { manager_exports } from "./manager-C6oJ2tAF.js";
|
|
10
10
|
import { runtime_exports } from "./runtime-ByXbpVBS.js";
|
|
11
11
|
import { UnitOfWork, atomic, transaction_exports } from "./transaction-Cs0Z9tbW.js";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { QNode } from '../query/domain/QNode';
|
|
2
|
+
import type { FilterInput } from '../query/domain/FilterInput';
|
|
1
3
|
import type { QuerySet } from '../query/index';
|
|
2
4
|
import type { TableMeta } from '../query/domain/index';
|
|
3
5
|
/**
|
|
@@ -6,6 +8,23 @@ import type { TableMeta } from '../query/domain/index';
|
|
|
6
8
|
export interface ManagerLike<TModelRow extends Record<string, unknown>, TSourceModel = unknown> {
|
|
7
9
|
readonly meta: TableMeta;
|
|
8
10
|
query(): QuerySet<TModelRow, TModelRow, TSourceModel>;
|
|
11
|
+
all(): QuerySet<TModelRow, TModelRow, TSourceModel>;
|
|
12
|
+
getOrCreate(args: {
|
|
13
|
+
where: FilterInput<TModelRow> | QNode<TModelRow>;
|
|
14
|
+
defaults?: Partial<TModelRow>;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
record: TModelRow;
|
|
17
|
+
created: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
updateOrCreate(args: {
|
|
20
|
+
where: FilterInput<TModelRow> | QNode<TModelRow>;
|
|
21
|
+
defaults?: Partial<TModelRow>;
|
|
22
|
+
update?: Partial<TModelRow>;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
record: TModelRow;
|
|
25
|
+
created: boolean;
|
|
26
|
+
updated: boolean;
|
|
27
|
+
}>;
|
|
9
28
|
findById(id: TModelRow[keyof TModelRow]): Promise<TModelRow | null>;
|
|
10
29
|
getOrThrow(id: TModelRow[keyof TModelRow]): Promise<TModelRow>;
|
|
11
30
|
create(input: Partial<TModelRow>): Promise<TModelRow>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { QNode } from '../query/domain/QNode';
|
|
1
2
|
import type { ModelWriteHooks } from '@danceroutine/tango-schema';
|
|
2
3
|
import type { Model as SchemaModel } from '@danceroutine/tango-schema/domain';
|
|
3
|
-
import type { TableMeta } from '../query/domain/index';
|
|
4
|
+
import type { FilterInput, TableMeta } from '../query/domain/index';
|
|
4
5
|
import type { QuerySet } from '../query/index';
|
|
5
6
|
import type { TangoRuntime } from '../runtime/TangoRuntime';
|
|
6
7
|
import type { ManagerLike } from './ManagerLike';
|
|
@@ -39,7 +40,29 @@ export declare class ModelManager<TModelRow extends Record<string, unknown>, TSo
|
|
|
39
40
|
*/
|
|
40
41
|
static isModelManager<TModelRow extends Record<string, unknown>>(value: unknown): value is ModelManager<TModelRow>;
|
|
41
42
|
private static createTableMeta;
|
|
43
|
+
private static mergeCreatePayloadFromWhere;
|
|
44
|
+
private static countNonPkValues;
|
|
45
|
+
private static collectPlainFieldsFromQNode;
|
|
46
|
+
private static omitLookupKeysFromAtom;
|
|
47
|
+
private static mergeCompatiblePartials;
|
|
42
48
|
query(): QuerySet<TModelRow, TModelRow, TSourceModel>;
|
|
49
|
+
all(): QuerySet<TModelRow, TModelRow, TSourceModel>;
|
|
50
|
+
getOrCreate(args: {
|
|
51
|
+
where: FilterInput<TModelRow> | QNode<TModelRow>;
|
|
52
|
+
defaults?: Partial<TModelRow>;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
record: TModelRow;
|
|
55
|
+
created: boolean;
|
|
56
|
+
}>;
|
|
57
|
+
updateOrCreate(args: {
|
|
58
|
+
where: FilterInput<TModelRow> | QNode<TModelRow>;
|
|
59
|
+
defaults?: Partial<TModelRow>;
|
|
60
|
+
update?: Partial<TModelRow>;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
record: TModelRow;
|
|
63
|
+
created: boolean;
|
|
64
|
+
updated: boolean;
|
|
65
|
+
}>;
|
|
43
66
|
findById(id: TModelRow[keyof TModelRow]): Promise<TModelRow | null>;
|
|
44
67
|
getOrThrow(id: TModelRow[keyof TModelRow]): Promise<TModelRow>;
|
|
45
68
|
create(input: Partial<TModelRow>): Promise<TModelRow>;
|
package/dist/manager/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "../PostgresClient-BQJZfEOT.js";
|
|
2
2
|
import "../SqliteClient-CjOK9-ki.js";
|
|
3
|
-
import "../query-
|
|
3
|
+
import "../query-FZJoSCg4.js";
|
|
4
4
|
import "../defaultRuntime-BPK9kWEW.js";
|
|
5
|
-
import { ModelManager, registerModelObjects } from "../registerModelObjects-
|
|
5
|
+
import { ModelManager, registerModelObjects } from "../registerModelObjects-C-1RbUHS.js";
|
|
6
6
|
import "../manager-C6oJ2tAF.js";
|
|
7
7
|
|
|
8
8
|
export { ModelManager, registerModelObjects };
|
package/dist/manager-C6oJ2tAF.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __export } from "./chunk-DLY2FNSh.js";
|
|
2
|
-
import { ModelManager, registerModelObjects } from "./registerModelObjects-
|
|
2
|
+
import { ModelManager, registerModelObjects } from "./registerModelObjects-C-1RbUHS.js";
|
|
3
3
|
|
|
4
4
|
//#region src/manager/index.ts
|
|
5
5
|
var manager_exports = {};
|
package/dist/query/QuerySet.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ export declare class QuerySet<TModel extends Record<string, unknown>, TBaseResul
|
|
|
68
68
|
* Narrow an unknown value to `QuerySet`.
|
|
69
69
|
*/
|
|
70
70
|
static isQuerySet<TModel extends Record<string, unknown>, TResult extends Record<string, unknown> = TModel>(value: unknown): value is QuerySet<TModel, TResult>;
|
|
71
|
+
private static invertOrderSpec;
|
|
71
72
|
/**
|
|
72
73
|
* Add a filter expression to the query.
|
|
73
74
|
*
|
|
@@ -121,6 +122,7 @@ export declare class QuerySet<TModel extends Record<string, unknown>, TBaseResul
|
|
|
121
122
|
* app-local registry current.
|
|
122
123
|
*/
|
|
123
124
|
prefetchRelated<TTargetModel = undefined, const TRelationName extends RelationKeys<PrefetchRelatedRelations<TSourceModel, NoInfer<TTargetModel>>> | GeneratedPrefetchRelatedPathKeys<TSourceModel> = RelationKeys<PrefetchRelatedRelations<TSourceModel, NoInfer<TTargetModel>>> | GeneratedPrefetchRelatedPathKeys<TSourceModel>>(...rels: readonly TRelationName[]): QuerySet<TModel, TBaseResult, TSourceModel, THydrated & MaybeHydratedRelationMap<TSourceModel, PrefetchRelatedRelations<TSourceModel, NoInfer<TTargetModel>>, Extract<TRelationName, RelationKeys<PrefetchRelatedRelations<TSourceModel, NoInfer<TTargetModel>>>>, ManyRelationHydrationCardinality> & GeneratedHydratedRelationMap<TSourceModel, Extract<TRelationName, GeneratedPrefetchRelatedPathKeys<TSourceModel>>>>;
|
|
125
|
+
all(): QuerySet<TModel, TBaseResult, TSourceModel, THydrated>;
|
|
124
126
|
/**
|
|
125
127
|
* Execute the query and optionally shape each row.
|
|
126
128
|
*
|
|
@@ -149,6 +151,15 @@ export declare class QuerySet<TModel extends Record<string, unknown>, TBaseResul
|
|
|
149
151
|
fetchOne<Out>(shape: QueryShapeFunction<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out | null>;
|
|
150
152
|
fetchOne<Out>(shape: QueryShapeParser<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out | null>;
|
|
151
153
|
fetchOne<TShape extends QueryShape<HydratedQueryResult<TBaseResult, THydrated>> | undefined>(shape: TShape): Promise<HydratedQueryResult<TBaseResult, THydrated> | QueryShapeOutput<HydratedQueryResult<TBaseResult, THydrated>, NonNullable<TShape>> | null>;
|
|
154
|
+
first(): Promise<HydratedQueryResult<TBaseResult, THydrated> | null>;
|
|
155
|
+
first<Out>(shape: QueryShapeFunction<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out | null>;
|
|
156
|
+
first<Out>(shape: QueryShapeParser<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out | null>;
|
|
157
|
+
last(): Promise<HydratedQueryResult<TBaseResult, THydrated> | null>;
|
|
158
|
+
last<Out>(shape: QueryShapeFunction<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out | null>;
|
|
159
|
+
last<Out>(shape: QueryShapeParser<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out | null>;
|
|
160
|
+
get(q: FilterInput<TModel> | QNode<TModel>): Promise<HydratedQueryResult<TBaseResult, THydrated>>;
|
|
161
|
+
get<Out>(q: FilterInput<TModel> | QNode<TModel>, shape: QueryShapeFunction<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out>;
|
|
162
|
+
get<Out>(q: FilterInput<TModel> | QNode<TModel>, shape: QueryShapeParser<HydratedQueryResult<TBaseResult, THydrated>, Out>): Promise<Out>;
|
|
152
163
|
/**
|
|
153
164
|
* Execute a `COUNT(*)` query for the current filtered state.
|
|
154
165
|
*/
|
|
@@ -157,6 +168,7 @@ export declare class QuerySet<TModel extends Record<string, unknown>, TBaseResul
|
|
|
157
168
|
* Return whether at least one row matches the current query state.
|
|
158
169
|
*/
|
|
159
170
|
exists(): Promise<boolean>;
|
|
171
|
+
private shapeFetchedRow;
|
|
160
172
|
private getOrCreateEvaluationCache;
|
|
161
173
|
private evaluateRows;
|
|
162
174
|
private normalizeHydratedRowsForParserShape;
|
package/dist/query/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { QBuilder, QueryCompiler, QueryResult, QuerySet, compiler_exports, domain_exports } from "../query-
|
|
1
|
+
import { QBuilder, QueryCompiler, QueryResult, QuerySet, compiler_exports, domain_exports } from "../query-FZJoSCg4.js";
|
|
2
2
|
|
|
3
3
|
export { QBuilder as Q, QBuilder, QueryCompiler, QueryResult, QuerySet, compiler_exports as compiler, domain_exports as domain };
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { __export } from "./chunk-DLY2FNSh.js";
|
|
2
|
-
import { SqlSafetyEngine, getLogger, isError } from "@danceroutine/tango-core";
|
|
2
|
+
import { MultipleObjectsReturned, NotFoundError, SqlSafetyEngine, getLogger, isError } from "@danceroutine/tango-core";
|
|
3
3
|
import { ModelRegistry } from "@danceroutine/tango-schema";
|
|
4
4
|
|
|
5
|
+
//#region src/query/domain/internal/InternalQNodeType.ts
|
|
6
|
+
const InternalQNodeType = {
|
|
7
|
+
ATOM: "atom",
|
|
8
|
+
AND: "and",
|
|
9
|
+
OR: "or",
|
|
10
|
+
NOT: "not"
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
5
14
|
//#region src/query/domain/internal/InternalRelationKind.ts
|
|
6
15
|
const InternalRelationKind = {
|
|
7
16
|
HAS_MANY: "hasMany",
|
|
@@ -83,15 +92,6 @@ const InternalDialect = {
|
|
|
83
92
|
SQLITE: "sqlite"
|
|
84
93
|
};
|
|
85
94
|
|
|
86
|
-
//#endregion
|
|
87
|
-
//#region src/query/domain/internal/InternalQNodeType.ts
|
|
88
|
-
const InternalQNodeType = {
|
|
89
|
-
ATOM: "atom",
|
|
90
|
-
AND: "and",
|
|
91
|
-
OR: "or",
|
|
92
|
-
NOT: "not"
|
|
93
|
-
};
|
|
94
|
-
|
|
95
95
|
//#endregion
|
|
96
96
|
//#region src/query/domain/internal/InternalLookupType.ts
|
|
97
97
|
const InternalLookupType = {
|
|
@@ -821,6 +821,19 @@ const InternalDirection = {
|
|
|
821
821
|
DESC: "desc"
|
|
822
822
|
};
|
|
823
823
|
|
|
824
|
+
//#endregion
|
|
825
|
+
//#region src/query/internal/isQNodeLike.ts
|
|
826
|
+
function isQNodeLike(value) {
|
|
827
|
+
if (typeof value !== "object" || value === null || "__tangoBrand" in value) return false;
|
|
828
|
+
switch (value.kind) {
|
|
829
|
+
case InternalQNodeType.ATOM: return "where" in value;
|
|
830
|
+
case InternalQNodeType.AND:
|
|
831
|
+
case InternalQNodeType.OR: return Array.isArray(value.nodes);
|
|
832
|
+
case InternalQNodeType.NOT: return "node" in value;
|
|
833
|
+
default: return false;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
824
837
|
//#endregion
|
|
825
838
|
//#region src/query/QBuilder.ts
|
|
826
839
|
var QBuilder = class QBuilder {
|
|
@@ -860,7 +873,7 @@ var QBuilder = class QBuilder {
|
|
|
860
873
|
};
|
|
861
874
|
}
|
|
862
875
|
static wrapNode(input) {
|
|
863
|
-
if (input
|
|
876
|
+
if (isQNodeLike(input)) return input;
|
|
864
877
|
return {
|
|
865
878
|
kind: InternalQNodeType.ATOM,
|
|
866
879
|
where: input
|
|
@@ -884,13 +897,20 @@ var QuerySet = class QuerySet {
|
|
|
884
897
|
static isQuerySet(value) {
|
|
885
898
|
return typeof value === "object" && value !== null && value.__tangoBrand === QuerySet.BRAND;
|
|
886
899
|
}
|
|
900
|
+
static invertOrderSpec(order) {
|
|
901
|
+
if (!order?.length) return [];
|
|
902
|
+
return order.map((spec) => ({
|
|
903
|
+
by: spec.by,
|
|
904
|
+
dir: spec.dir === InternalDirection.ASC ? InternalDirection.DESC : InternalDirection.ASC
|
|
905
|
+
}));
|
|
906
|
+
}
|
|
887
907
|
/**
|
|
888
908
|
* Add a filter expression to the query.
|
|
889
909
|
*
|
|
890
910
|
* Multiple `filter()` calls are composed with `AND`.
|
|
891
911
|
*/
|
|
892
912
|
filter(q) {
|
|
893
|
-
const wrapped = q
|
|
913
|
+
const wrapped = isQNodeLike(q) ? q : {
|
|
894
914
|
kind: InternalQNodeType.ATOM,
|
|
895
915
|
where: q
|
|
896
916
|
};
|
|
@@ -906,7 +926,7 @@ var QuerySet = class QuerySet {
|
|
|
906
926
|
* Exclusions are translated to `NOT (...)` predicates.
|
|
907
927
|
*/
|
|
908
928
|
exclude(q) {
|
|
909
|
-
const wrapped = q
|
|
929
|
+
const wrapped = isQNodeLike(q) ? q : {
|
|
910
930
|
kind: InternalQNodeType.ATOM,
|
|
911
931
|
where: q
|
|
912
932
|
};
|
|
@@ -989,6 +1009,9 @@ var QuerySet = class QuerySet {
|
|
|
989
1009
|
prefetchRelated: [...rels]
|
|
990
1010
|
});
|
|
991
1011
|
}
|
|
1012
|
+
all() {
|
|
1013
|
+
return new QuerySet(this.executor, { ...this.state });
|
|
1014
|
+
}
|
|
992
1015
|
async fetch(shape) {
|
|
993
1016
|
const baseResult = await this.getOrCreateEvaluationCache();
|
|
994
1017
|
if (!shape) return baseResult;
|
|
@@ -1012,6 +1035,36 @@ var QuerySet = class QuerySet {
|
|
|
1012
1035
|
for (const row of result) return row;
|
|
1013
1036
|
return null;
|
|
1014
1037
|
}
|
|
1038
|
+
async first(shape) {
|
|
1039
|
+
return this.fetchOne(shape);
|
|
1040
|
+
}
|
|
1041
|
+
async last(shape) {
|
|
1042
|
+
if (this.state.limit !== undefined || this.state.offset !== undefined) {
|
|
1043
|
+
const page = await this.fetch();
|
|
1044
|
+
const row = page.at(-1);
|
|
1045
|
+
if (!row) return null;
|
|
1046
|
+
return this.shapeFetchedRow(row, shape);
|
|
1047
|
+
}
|
|
1048
|
+
const invertedOrder = QuerySet.invertOrderSpec(this.state.order);
|
|
1049
|
+
const effectiveOrder = invertedOrder.length > 0 ? invertedOrder : [{
|
|
1050
|
+
by: this.executor.meta.pk,
|
|
1051
|
+
dir: InternalDirection.DESC
|
|
1052
|
+
}];
|
|
1053
|
+
const qs = new QuerySet(this.executor, {
|
|
1054
|
+
...this.state,
|
|
1055
|
+
order: effectiveOrder
|
|
1056
|
+
});
|
|
1057
|
+
return qs.limit(1).fetchOne(shape);
|
|
1058
|
+
}
|
|
1059
|
+
async get(q, shape) {
|
|
1060
|
+
const limited = this.filter(q).limit(2);
|
|
1061
|
+
const page = await limited.fetch();
|
|
1062
|
+
const rows = page.items;
|
|
1063
|
+
const count = rows.length;
|
|
1064
|
+
if (count === 0) throw new NotFoundError(`${this.executor.meta.table}: no matching record`);
|
|
1065
|
+
if (count > 1) throw new MultipleObjectsReturned(`${this.executor.meta.table}: more than one matching record`);
|
|
1066
|
+
return this.shapeFetchedRow(rows[0], shape);
|
|
1067
|
+
}
|
|
1015
1068
|
/**
|
|
1016
1069
|
* Execute a `COUNT(*)` query for the current filtered state.
|
|
1017
1070
|
*/
|
|
@@ -1029,6 +1082,12 @@ var QuerySet = class QuerySet {
|
|
|
1029
1082
|
const count = await this.count();
|
|
1030
1083
|
return count > 0;
|
|
1031
1084
|
}
|
|
1085
|
+
shapeFetchedRow(row, shape) {
|
|
1086
|
+
if (!shape) return row;
|
|
1087
|
+
if (typeof shape === "function") return shape(row);
|
|
1088
|
+
const normalizedRow = this.normalizeHydratedRowsForParserShape([row])[0] ?? row;
|
|
1089
|
+
return shape.parse(normalizedRow);
|
|
1090
|
+
}
|
|
1032
1091
|
getOrCreateEvaluationCache() {
|
|
1033
1092
|
if (!this.evaluationCache) this.evaluationCache = this.evaluateRows().catch((error) => {
|
|
1034
1093
|
this.evaluationCache = undefined;
|
|
@@ -1194,5 +1253,5 @@ __export(query_exports, {
|
|
|
1194
1253
|
});
|
|
1195
1254
|
|
|
1196
1255
|
//#endregion
|
|
1197
|
-
export { OrmSqlSafetyAdapter, QBuilder, QueryCompiler, QueryResult, QuerySet, TableMetaFactory, compiler_exports, domain_exports, query_exports };
|
|
1198
|
-
//# sourceMappingURL=query-
|
|
1256
|
+
export { InternalQNodeType, OrmSqlSafetyAdapter, QBuilder, QueryCompiler, QueryResult, QuerySet, TableMetaFactory, compiler_exports, domain_exports, isQNodeLike, query_exports };
|
|
1257
|
+
//# sourceMappingURL=query-FZJoSCg4.js.map
|