arkormx 2.0.0-next.21 → 2.0.0-next.23
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.cjs +135 -12
- package/dist/index.d.cts +49 -0
- package/dist/index.d.mts +49 -0
- package/dist/index.mjs +135 -12
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2384,7 +2384,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
2384
2384
|
relationLoads: false,
|
|
2385
2385
|
relationAggregates: true,
|
|
2386
2386
|
relationFilters: true,
|
|
2387
|
-
rawWhere:
|
|
2387
|
+
rawWhere: true
|
|
2388
2388
|
};
|
|
2389
2389
|
constructor(db, mapping = {}) {
|
|
2390
2390
|
this.db = db;
|
|
@@ -2669,6 +2669,18 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
2669
2669
|
if (condition.operator === "ends-with") return kysely.sql`${column} like ${`%${String(condition.value ?? "")}`}`;
|
|
2670
2670
|
return kysely.sql`${column} ${condition.operator === "!=" ? kysely.sql.raw("!=") : kysely.sql.raw(condition.operator)} ${condition.value}`;
|
|
2671
2671
|
}
|
|
2672
|
+
buildRawWhereCondition(condition) {
|
|
2673
|
+
const segments = condition.sql.split("?");
|
|
2674
|
+
const bindings = condition.bindings ?? [];
|
|
2675
|
+
if (segments.length !== bindings.length + 1) throw new ArkormException("Raw where bindings do not match the number of placeholders.");
|
|
2676
|
+
const parts = [];
|
|
2677
|
+
segments.forEach((segment, index) => {
|
|
2678
|
+
if (segment.length > 0) parts.push(kysely.sql.raw(segment));
|
|
2679
|
+
if (index < bindings.length) parts.push(kysely.sql`${bindings[index]}`);
|
|
2680
|
+
});
|
|
2681
|
+
if (parts.length === 0) return kysely.sql`1 = 1`;
|
|
2682
|
+
return kysely.sql`${kysely.sql.join(parts, kysely.sql``)}`;
|
|
2683
|
+
}
|
|
2672
2684
|
buildWhereCondition(target, condition) {
|
|
2673
2685
|
if (!condition) return kysely.sql`1 = 1`;
|
|
2674
2686
|
if (condition.type === "comparison") return this.buildComparisonCondition(target, condition);
|
|
@@ -2685,13 +2697,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
2685
2697
|
const notCondition = condition;
|
|
2686
2698
|
return kysely.sql`not (${this.buildWhereCondition(target, notCondition.condition)})`;
|
|
2687
2699
|
}
|
|
2688
|
-
|
|
2689
|
-
operation: "adapter.where",
|
|
2690
|
-
meta: {
|
|
2691
|
-
feature: "rawWhere",
|
|
2692
|
-
sql: condition.sql
|
|
2693
|
-
}
|
|
2694
|
-
});
|
|
2700
|
+
return this.buildRawWhereCondition(condition);
|
|
2695
2701
|
}
|
|
2696
2702
|
buildWhereClause(target, condition) {
|
|
2697
2703
|
if (!condition) return kysely.sql``;
|
|
@@ -6004,7 +6010,7 @@ var RelationTableLoader = class {
|
|
|
6004
6010
|
* @author Legacy (3m1n3nc3)
|
|
6005
6011
|
* @since 2.0.0-next.2
|
|
6006
6012
|
*/
|
|
6007
|
-
var SetBasedEagerLoader = class {
|
|
6013
|
+
var SetBasedEagerLoader = class SetBasedEagerLoader {
|
|
6008
6014
|
constructor(models, relations) {
|
|
6009
6015
|
this.models = models;
|
|
6010
6016
|
this.relations = relations;
|
|
@@ -6016,10 +6022,18 @@ var SetBasedEagerLoader = class {
|
|
|
6016
6022
|
*/
|
|
6017
6023
|
async load() {
|
|
6018
6024
|
if (this.models.length === 0) return;
|
|
6019
|
-
|
|
6020
|
-
|
|
6025
|
+
const relationTree = this.buildRelationTree(this.relations);
|
|
6026
|
+
await Promise.all(Array.from(relationTree.entries()).map(async ([name, node]) => {
|
|
6027
|
+
await this.loadRelationNode(name, node);
|
|
6021
6028
|
}));
|
|
6022
6029
|
}
|
|
6030
|
+
async loadRelationNode(name, node) {
|
|
6031
|
+
await this.loadRelation(name, node.constraint);
|
|
6032
|
+
if (node.children.size === 0) return;
|
|
6033
|
+
const relatedModels = this.collectLoadedRelationModels(name);
|
|
6034
|
+
if (relatedModels.length === 0) return;
|
|
6035
|
+
await new SetBasedEagerLoader(relatedModels, this.relationTreeToMap(node.children)).load();
|
|
6036
|
+
}
|
|
6023
6037
|
/**
|
|
6024
6038
|
* Loads a specific relationship for the set of models based on the relationship name
|
|
6025
6039
|
* and an optional constraint.
|
|
@@ -6063,9 +6077,58 @@ var SetBasedEagerLoader = class {
|
|
|
6063
6077
|
*/
|
|
6064
6078
|
resolveRelationResolver(name) {
|
|
6065
6079
|
const resolver = this.models[0][name];
|
|
6066
|
-
if (typeof resolver !== "function")
|
|
6080
|
+
if (typeof resolver !== "function") {
|
|
6081
|
+
const modelName = this.models[0].constructor?.name ?? "Model";
|
|
6082
|
+
throw new RelationResolutionException(`Relation [${name}] is not defined on the model.`, {
|
|
6083
|
+
operation: "eagerLoad",
|
|
6084
|
+
model: modelName,
|
|
6085
|
+
relation: name
|
|
6086
|
+
});
|
|
6087
|
+
}
|
|
6067
6088
|
return resolver;
|
|
6068
6089
|
}
|
|
6090
|
+
buildRelationTree(relations) {
|
|
6091
|
+
const tree = /* @__PURE__ */ new Map();
|
|
6092
|
+
Object.entries(relations).forEach(([path, constraint]) => {
|
|
6093
|
+
const segments = path.split(".").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
6094
|
+
if (segments.length === 0) return;
|
|
6095
|
+
let current = tree;
|
|
6096
|
+
segments.forEach((segment, index) => {
|
|
6097
|
+
const existing = current.get(segment) ?? {
|
|
6098
|
+
constraint: void 0,
|
|
6099
|
+
children: /* @__PURE__ */ new Map()
|
|
6100
|
+
};
|
|
6101
|
+
if (index === segments.length - 1 && constraint) existing.constraint = constraint;
|
|
6102
|
+
current.set(segment, existing);
|
|
6103
|
+
current = existing.children;
|
|
6104
|
+
});
|
|
6105
|
+
});
|
|
6106
|
+
return tree;
|
|
6107
|
+
}
|
|
6108
|
+
relationTreeToMap(tree, prefix = "") {
|
|
6109
|
+
return Array.from(tree.entries()).reduce((all, [name, node]) => {
|
|
6110
|
+
const path = prefix ? `${prefix}.${name}` : name;
|
|
6111
|
+
all[path] = node.constraint;
|
|
6112
|
+
Object.assign(all, this.relationTreeToMap(node.children, path));
|
|
6113
|
+
return all;
|
|
6114
|
+
}, {});
|
|
6115
|
+
}
|
|
6116
|
+
collectLoadedRelationModels(name) {
|
|
6117
|
+
return this.models.reduce((all, model) => {
|
|
6118
|
+
const loaded = model.getAttribute(name);
|
|
6119
|
+
if (loaded instanceof ArkormCollection) {
|
|
6120
|
+
loaded.all().forEach((item) => {
|
|
6121
|
+
if (this.isEagerLoadableModel(item)) all.push(item);
|
|
6122
|
+
});
|
|
6123
|
+
return all;
|
|
6124
|
+
}
|
|
6125
|
+
if (this.isEagerLoadableModel(loaded)) all.push(loaded);
|
|
6126
|
+
return all;
|
|
6127
|
+
}, []);
|
|
6128
|
+
}
|
|
6129
|
+
isEagerLoadableModel(value) {
|
|
6130
|
+
return typeof value === "object" && value !== null && typeof value.getAttribute === "function" && typeof value.setLoadedRelation === "function";
|
|
6131
|
+
}
|
|
6069
6132
|
/**
|
|
6070
6133
|
* Loads a "belongs to" relationship for the set of models.
|
|
6071
6134
|
*
|
|
@@ -6701,6 +6764,36 @@ var QueryBuilder = class QueryBuilder {
|
|
|
6701
6764
|
return this.where({ [key]: { notIn: values } });
|
|
6702
6765
|
}
|
|
6703
6766
|
/**
|
|
6767
|
+
* Adds a string contains clause for a single attribute key.
|
|
6768
|
+
*
|
|
6769
|
+
* @param key
|
|
6770
|
+
* @param value
|
|
6771
|
+
* @returns
|
|
6772
|
+
*/
|
|
6773
|
+
whereLike(key, value) {
|
|
6774
|
+
return this.where({ [key]: { contains: value } });
|
|
6775
|
+
}
|
|
6776
|
+
/**
|
|
6777
|
+
* Adds a string starts-with clause for a single attribute key.
|
|
6778
|
+
*
|
|
6779
|
+
* @param key
|
|
6780
|
+
* @param value
|
|
6781
|
+
* @returns
|
|
6782
|
+
*/
|
|
6783
|
+
whereStartsWith(key, value) {
|
|
6784
|
+
return this.where({ [key]: { startsWith: value } });
|
|
6785
|
+
}
|
|
6786
|
+
/**
|
|
6787
|
+
* Adds a string ends-with clause for a single attribute key.
|
|
6788
|
+
*
|
|
6789
|
+
* @param key
|
|
6790
|
+
* @param value
|
|
6791
|
+
* @returns
|
|
6792
|
+
*/
|
|
6793
|
+
whereEndsWith(key, value) {
|
|
6794
|
+
return this.where({ [key]: { endsWith: value } });
|
|
6795
|
+
}
|
|
6796
|
+
/**
|
|
6704
6797
|
* Adds a strongly-typed OR NOT IN where clause for a single attribute key.
|
|
6705
6798
|
*
|
|
6706
6799
|
* @param key
|
|
@@ -8825,6 +8918,36 @@ var Relation = class {
|
|
|
8825
8918
|
return this.constrain((query) => query.whereIn(key, values));
|
|
8826
8919
|
}
|
|
8827
8920
|
/**
|
|
8921
|
+
* Add a string contains clause to the relationship query.
|
|
8922
|
+
*
|
|
8923
|
+
* @param key
|
|
8924
|
+
* @param value
|
|
8925
|
+
* @returns
|
|
8926
|
+
*/
|
|
8927
|
+
whereLike(key, value) {
|
|
8928
|
+
return this.constrain((query) => query.whereLike(key, value));
|
|
8929
|
+
}
|
|
8930
|
+
/**
|
|
8931
|
+
* Add a string starts-with clause to the relationship query.
|
|
8932
|
+
*
|
|
8933
|
+
* @param key
|
|
8934
|
+
* @param value
|
|
8935
|
+
* @returns
|
|
8936
|
+
*/
|
|
8937
|
+
whereStartsWith(key, value) {
|
|
8938
|
+
return this.constrain((query) => query.whereStartsWith(key, value));
|
|
8939
|
+
}
|
|
8940
|
+
/**
|
|
8941
|
+
* Add a string ends-with clause to the relationship query.
|
|
8942
|
+
*
|
|
8943
|
+
* @param key
|
|
8944
|
+
* @param value
|
|
8945
|
+
* @returns
|
|
8946
|
+
*/
|
|
8947
|
+
whereEndsWith(key, value) {
|
|
8948
|
+
return this.constrain((query) => query.whereEndsWith(key, value));
|
|
8949
|
+
}
|
|
8950
|
+
/**
|
|
8828
8951
|
* Add an order by clause to the relationship query.
|
|
8829
8952
|
*
|
|
8830
8953
|
* @param orderBy
|
package/dist/index.d.cts
CHANGED
|
@@ -554,6 +554,30 @@ declare abstract class Relation<TModel> {
|
|
|
554
554
|
* @returns
|
|
555
555
|
*/
|
|
556
556
|
whereIn<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, values: ModelAttributes<TModel>[TKey][]): this;
|
|
557
|
+
/**
|
|
558
|
+
* Add a string contains clause to the relationship query.
|
|
559
|
+
*
|
|
560
|
+
* @param key
|
|
561
|
+
* @param value
|
|
562
|
+
* @returns
|
|
563
|
+
*/
|
|
564
|
+
whereLike<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
565
|
+
/**
|
|
566
|
+
* Add a string starts-with clause to the relationship query.
|
|
567
|
+
*
|
|
568
|
+
* @param key
|
|
569
|
+
* @param value
|
|
570
|
+
* @returns
|
|
571
|
+
*/
|
|
572
|
+
whereStartsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
573
|
+
/**
|
|
574
|
+
* Add a string ends-with clause to the relationship query.
|
|
575
|
+
*
|
|
576
|
+
* @param key
|
|
577
|
+
* @param value
|
|
578
|
+
* @returns
|
|
579
|
+
*/
|
|
580
|
+
whereEndsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
557
581
|
/**
|
|
558
582
|
* Add an order by clause to the relationship query.
|
|
559
583
|
*
|
|
@@ -2176,6 +2200,30 @@ declare class QueryBuilder<TModel, TDelegate extends PrismaDelegateLike = Prisma
|
|
|
2176
2200
|
* @returns
|
|
2177
2201
|
*/
|
|
2178
2202
|
whereNotIn<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, values: ModelAttributes<TModel>[TKey][]): this;
|
|
2203
|
+
/**
|
|
2204
|
+
* Adds a string contains clause for a single attribute key.
|
|
2205
|
+
*
|
|
2206
|
+
* @param key
|
|
2207
|
+
* @param value
|
|
2208
|
+
* @returns
|
|
2209
|
+
*/
|
|
2210
|
+
whereLike<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
2211
|
+
/**
|
|
2212
|
+
* Adds a string starts-with clause for a single attribute key.
|
|
2213
|
+
*
|
|
2214
|
+
* @param key
|
|
2215
|
+
* @param value
|
|
2216
|
+
* @returns
|
|
2217
|
+
*/
|
|
2218
|
+
whereStartsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
2219
|
+
/**
|
|
2220
|
+
* Adds a string ends-with clause for a single attribute key.
|
|
2221
|
+
*
|
|
2222
|
+
* @param key
|
|
2223
|
+
* @param value
|
|
2224
|
+
* @returns
|
|
2225
|
+
*/
|
|
2226
|
+
whereEndsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
2179
2227
|
/**
|
|
2180
2228
|
* Adds a strongly-typed OR NOT IN where clause for a single attribute key.
|
|
2181
2229
|
*
|
|
@@ -3162,6 +3210,7 @@ declare class KyselyDatabaseAdapter implements DatabaseAdapter {
|
|
|
3162
3210
|
private buildOrderBy;
|
|
3163
3211
|
private buildConditionValueList;
|
|
3164
3212
|
private buildComparisonCondition;
|
|
3213
|
+
private buildRawWhereCondition;
|
|
3165
3214
|
private buildWhereCondition;
|
|
3166
3215
|
private buildWhereClause;
|
|
3167
3216
|
private buildPaginationClause;
|
package/dist/index.d.mts
CHANGED
|
@@ -554,6 +554,30 @@ declare abstract class Relation<TModel> {
|
|
|
554
554
|
* @returns
|
|
555
555
|
*/
|
|
556
556
|
whereIn<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, values: ModelAttributes<TModel>[TKey][]): this;
|
|
557
|
+
/**
|
|
558
|
+
* Add a string contains clause to the relationship query.
|
|
559
|
+
*
|
|
560
|
+
* @param key
|
|
561
|
+
* @param value
|
|
562
|
+
* @returns
|
|
563
|
+
*/
|
|
564
|
+
whereLike<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
565
|
+
/**
|
|
566
|
+
* Add a string starts-with clause to the relationship query.
|
|
567
|
+
*
|
|
568
|
+
* @param key
|
|
569
|
+
* @param value
|
|
570
|
+
* @returns
|
|
571
|
+
*/
|
|
572
|
+
whereStartsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
573
|
+
/**
|
|
574
|
+
* Add a string ends-with clause to the relationship query.
|
|
575
|
+
*
|
|
576
|
+
* @param key
|
|
577
|
+
* @param value
|
|
578
|
+
* @returns
|
|
579
|
+
*/
|
|
580
|
+
whereEndsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
557
581
|
/**
|
|
558
582
|
* Add an order by clause to the relationship query.
|
|
559
583
|
*
|
|
@@ -2176,6 +2200,30 @@ declare class QueryBuilder<TModel, TDelegate extends PrismaDelegateLike = Prisma
|
|
|
2176
2200
|
* @returns
|
|
2177
2201
|
*/
|
|
2178
2202
|
whereNotIn<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, values: ModelAttributes<TModel>[TKey][]): this;
|
|
2203
|
+
/**
|
|
2204
|
+
* Adds a string contains clause for a single attribute key.
|
|
2205
|
+
*
|
|
2206
|
+
* @param key
|
|
2207
|
+
* @param value
|
|
2208
|
+
* @returns
|
|
2209
|
+
*/
|
|
2210
|
+
whereLike<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
2211
|
+
/**
|
|
2212
|
+
* Adds a string starts-with clause for a single attribute key.
|
|
2213
|
+
*
|
|
2214
|
+
* @param key
|
|
2215
|
+
* @param value
|
|
2216
|
+
* @returns
|
|
2217
|
+
*/
|
|
2218
|
+
whereStartsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
2219
|
+
/**
|
|
2220
|
+
* Adds a string ends-with clause for a single attribute key.
|
|
2221
|
+
*
|
|
2222
|
+
* @param key
|
|
2223
|
+
* @param value
|
|
2224
|
+
* @returns
|
|
2225
|
+
*/
|
|
2226
|
+
whereEndsWith<TKey extends keyof ModelAttributes<TModel> & string>(key: TKey, value: Extract<ModelAttributes<TModel>[TKey], string>): this;
|
|
2179
2227
|
/**
|
|
2180
2228
|
* Adds a strongly-typed OR NOT IN where clause for a single attribute key.
|
|
2181
2229
|
*
|
|
@@ -3162,6 +3210,7 @@ declare class KyselyDatabaseAdapter implements DatabaseAdapter {
|
|
|
3162
3210
|
private buildOrderBy;
|
|
3163
3211
|
private buildConditionValueList;
|
|
3164
3212
|
private buildComparisonCondition;
|
|
3213
|
+
private buildRawWhereCondition;
|
|
3165
3214
|
private buildWhereCondition;
|
|
3166
3215
|
private buildWhereClause;
|
|
3167
3216
|
private buildPaginationClause;
|
package/dist/index.mjs
CHANGED
|
@@ -2355,7 +2355,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
2355
2355
|
relationLoads: false,
|
|
2356
2356
|
relationAggregates: true,
|
|
2357
2357
|
relationFilters: true,
|
|
2358
|
-
rawWhere:
|
|
2358
|
+
rawWhere: true
|
|
2359
2359
|
};
|
|
2360
2360
|
constructor(db, mapping = {}) {
|
|
2361
2361
|
this.db = db;
|
|
@@ -2640,6 +2640,18 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
2640
2640
|
if (condition.operator === "ends-with") return sql`${column} like ${`%${String(condition.value ?? "")}`}`;
|
|
2641
2641
|
return sql`${column} ${condition.operator === "!=" ? sql.raw("!=") : sql.raw(condition.operator)} ${condition.value}`;
|
|
2642
2642
|
}
|
|
2643
|
+
buildRawWhereCondition(condition) {
|
|
2644
|
+
const segments = condition.sql.split("?");
|
|
2645
|
+
const bindings = condition.bindings ?? [];
|
|
2646
|
+
if (segments.length !== bindings.length + 1) throw new ArkormException("Raw where bindings do not match the number of placeholders.");
|
|
2647
|
+
const parts = [];
|
|
2648
|
+
segments.forEach((segment, index) => {
|
|
2649
|
+
if (segment.length > 0) parts.push(sql.raw(segment));
|
|
2650
|
+
if (index < bindings.length) parts.push(sql`${bindings[index]}`);
|
|
2651
|
+
});
|
|
2652
|
+
if (parts.length === 0) return sql`1 = 1`;
|
|
2653
|
+
return sql`${sql.join(parts, sql``)}`;
|
|
2654
|
+
}
|
|
2643
2655
|
buildWhereCondition(target, condition) {
|
|
2644
2656
|
if (!condition) return sql`1 = 1`;
|
|
2645
2657
|
if (condition.type === "comparison") return this.buildComparisonCondition(target, condition);
|
|
@@ -2656,13 +2668,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
2656
2668
|
const notCondition = condition;
|
|
2657
2669
|
return sql`not (${this.buildWhereCondition(target, notCondition.condition)})`;
|
|
2658
2670
|
}
|
|
2659
|
-
|
|
2660
|
-
operation: "adapter.where",
|
|
2661
|
-
meta: {
|
|
2662
|
-
feature: "rawWhere",
|
|
2663
|
-
sql: condition.sql
|
|
2664
|
-
}
|
|
2665
|
-
});
|
|
2671
|
+
return this.buildRawWhereCondition(condition);
|
|
2666
2672
|
}
|
|
2667
2673
|
buildWhereClause(target, condition) {
|
|
2668
2674
|
if (!condition) return sql``;
|
|
@@ -5975,7 +5981,7 @@ var RelationTableLoader = class {
|
|
|
5975
5981
|
* @author Legacy (3m1n3nc3)
|
|
5976
5982
|
* @since 2.0.0-next.2
|
|
5977
5983
|
*/
|
|
5978
|
-
var SetBasedEagerLoader = class {
|
|
5984
|
+
var SetBasedEagerLoader = class SetBasedEagerLoader {
|
|
5979
5985
|
constructor(models, relations) {
|
|
5980
5986
|
this.models = models;
|
|
5981
5987
|
this.relations = relations;
|
|
@@ -5987,10 +5993,18 @@ var SetBasedEagerLoader = class {
|
|
|
5987
5993
|
*/
|
|
5988
5994
|
async load() {
|
|
5989
5995
|
if (this.models.length === 0) return;
|
|
5990
|
-
|
|
5991
|
-
|
|
5996
|
+
const relationTree = this.buildRelationTree(this.relations);
|
|
5997
|
+
await Promise.all(Array.from(relationTree.entries()).map(async ([name, node]) => {
|
|
5998
|
+
await this.loadRelationNode(name, node);
|
|
5992
5999
|
}));
|
|
5993
6000
|
}
|
|
6001
|
+
async loadRelationNode(name, node) {
|
|
6002
|
+
await this.loadRelation(name, node.constraint);
|
|
6003
|
+
if (node.children.size === 0) return;
|
|
6004
|
+
const relatedModels = this.collectLoadedRelationModels(name);
|
|
6005
|
+
if (relatedModels.length === 0) return;
|
|
6006
|
+
await new SetBasedEagerLoader(relatedModels, this.relationTreeToMap(node.children)).load();
|
|
6007
|
+
}
|
|
5994
6008
|
/**
|
|
5995
6009
|
* Loads a specific relationship for the set of models based on the relationship name
|
|
5996
6010
|
* and an optional constraint.
|
|
@@ -6034,9 +6048,58 @@ var SetBasedEagerLoader = class {
|
|
|
6034
6048
|
*/
|
|
6035
6049
|
resolveRelationResolver(name) {
|
|
6036
6050
|
const resolver = this.models[0][name];
|
|
6037
|
-
if (typeof resolver !== "function")
|
|
6051
|
+
if (typeof resolver !== "function") {
|
|
6052
|
+
const modelName = this.models[0].constructor?.name ?? "Model";
|
|
6053
|
+
throw new RelationResolutionException(`Relation [${name}] is not defined on the model.`, {
|
|
6054
|
+
operation: "eagerLoad",
|
|
6055
|
+
model: modelName,
|
|
6056
|
+
relation: name
|
|
6057
|
+
});
|
|
6058
|
+
}
|
|
6038
6059
|
return resolver;
|
|
6039
6060
|
}
|
|
6061
|
+
buildRelationTree(relations) {
|
|
6062
|
+
const tree = /* @__PURE__ */ new Map();
|
|
6063
|
+
Object.entries(relations).forEach(([path, constraint]) => {
|
|
6064
|
+
const segments = path.split(".").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
6065
|
+
if (segments.length === 0) return;
|
|
6066
|
+
let current = tree;
|
|
6067
|
+
segments.forEach((segment, index) => {
|
|
6068
|
+
const existing = current.get(segment) ?? {
|
|
6069
|
+
constraint: void 0,
|
|
6070
|
+
children: /* @__PURE__ */ new Map()
|
|
6071
|
+
};
|
|
6072
|
+
if (index === segments.length - 1 && constraint) existing.constraint = constraint;
|
|
6073
|
+
current.set(segment, existing);
|
|
6074
|
+
current = existing.children;
|
|
6075
|
+
});
|
|
6076
|
+
});
|
|
6077
|
+
return tree;
|
|
6078
|
+
}
|
|
6079
|
+
relationTreeToMap(tree, prefix = "") {
|
|
6080
|
+
return Array.from(tree.entries()).reduce((all, [name, node]) => {
|
|
6081
|
+
const path = prefix ? `${prefix}.${name}` : name;
|
|
6082
|
+
all[path] = node.constraint;
|
|
6083
|
+
Object.assign(all, this.relationTreeToMap(node.children, path));
|
|
6084
|
+
return all;
|
|
6085
|
+
}, {});
|
|
6086
|
+
}
|
|
6087
|
+
collectLoadedRelationModels(name) {
|
|
6088
|
+
return this.models.reduce((all, model) => {
|
|
6089
|
+
const loaded = model.getAttribute(name);
|
|
6090
|
+
if (loaded instanceof ArkormCollection) {
|
|
6091
|
+
loaded.all().forEach((item) => {
|
|
6092
|
+
if (this.isEagerLoadableModel(item)) all.push(item);
|
|
6093
|
+
});
|
|
6094
|
+
return all;
|
|
6095
|
+
}
|
|
6096
|
+
if (this.isEagerLoadableModel(loaded)) all.push(loaded);
|
|
6097
|
+
return all;
|
|
6098
|
+
}, []);
|
|
6099
|
+
}
|
|
6100
|
+
isEagerLoadableModel(value) {
|
|
6101
|
+
return typeof value === "object" && value !== null && typeof value.getAttribute === "function" && typeof value.setLoadedRelation === "function";
|
|
6102
|
+
}
|
|
6040
6103
|
/**
|
|
6041
6104
|
* Loads a "belongs to" relationship for the set of models.
|
|
6042
6105
|
*
|
|
@@ -6672,6 +6735,36 @@ var QueryBuilder = class QueryBuilder {
|
|
|
6672
6735
|
return this.where({ [key]: { notIn: values } });
|
|
6673
6736
|
}
|
|
6674
6737
|
/**
|
|
6738
|
+
* Adds a string contains clause for a single attribute key.
|
|
6739
|
+
*
|
|
6740
|
+
* @param key
|
|
6741
|
+
* @param value
|
|
6742
|
+
* @returns
|
|
6743
|
+
*/
|
|
6744
|
+
whereLike(key, value) {
|
|
6745
|
+
return this.where({ [key]: { contains: value } });
|
|
6746
|
+
}
|
|
6747
|
+
/**
|
|
6748
|
+
* Adds a string starts-with clause for a single attribute key.
|
|
6749
|
+
*
|
|
6750
|
+
* @param key
|
|
6751
|
+
* @param value
|
|
6752
|
+
* @returns
|
|
6753
|
+
*/
|
|
6754
|
+
whereStartsWith(key, value) {
|
|
6755
|
+
return this.where({ [key]: { startsWith: value } });
|
|
6756
|
+
}
|
|
6757
|
+
/**
|
|
6758
|
+
* Adds a string ends-with clause for a single attribute key.
|
|
6759
|
+
*
|
|
6760
|
+
* @param key
|
|
6761
|
+
* @param value
|
|
6762
|
+
* @returns
|
|
6763
|
+
*/
|
|
6764
|
+
whereEndsWith(key, value) {
|
|
6765
|
+
return this.where({ [key]: { endsWith: value } });
|
|
6766
|
+
}
|
|
6767
|
+
/**
|
|
6675
6768
|
* Adds a strongly-typed OR NOT IN where clause for a single attribute key.
|
|
6676
6769
|
*
|
|
6677
6770
|
* @param key
|
|
@@ -8796,6 +8889,36 @@ var Relation = class {
|
|
|
8796
8889
|
return this.constrain((query) => query.whereIn(key, values));
|
|
8797
8890
|
}
|
|
8798
8891
|
/**
|
|
8892
|
+
* Add a string contains clause to the relationship query.
|
|
8893
|
+
*
|
|
8894
|
+
* @param key
|
|
8895
|
+
* @param value
|
|
8896
|
+
* @returns
|
|
8897
|
+
*/
|
|
8898
|
+
whereLike(key, value) {
|
|
8899
|
+
return this.constrain((query) => query.whereLike(key, value));
|
|
8900
|
+
}
|
|
8901
|
+
/**
|
|
8902
|
+
* Add a string starts-with clause to the relationship query.
|
|
8903
|
+
*
|
|
8904
|
+
* @param key
|
|
8905
|
+
* @param value
|
|
8906
|
+
* @returns
|
|
8907
|
+
*/
|
|
8908
|
+
whereStartsWith(key, value) {
|
|
8909
|
+
return this.constrain((query) => query.whereStartsWith(key, value));
|
|
8910
|
+
}
|
|
8911
|
+
/**
|
|
8912
|
+
* Add a string ends-with clause to the relationship query.
|
|
8913
|
+
*
|
|
8914
|
+
* @param key
|
|
8915
|
+
* @param value
|
|
8916
|
+
* @returns
|
|
8917
|
+
*/
|
|
8918
|
+
whereEndsWith(key, value) {
|
|
8919
|
+
return this.constrain((query) => query.whereEndsWith(key, value));
|
|
8920
|
+
}
|
|
8921
|
+
/**
|
|
8799
8922
|
* Add an order by clause to the relationship query.
|
|
8800
8923
|
*
|
|
8801
8924
|
* @param orderBy
|