@getstrata/core 0.5.99 → 0.5.101
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 +14 -0
- package/dist/core/database/baseRepository.d.ts +5 -1
- package/dist/core/database/index.d.ts +3 -3
- package/dist/core/database/model.d.ts +23 -2
- package/dist/core/database/relationQuery.d.ts +22 -3
- package/dist/core/database/relationships.d.ts +25 -3
- package/dist/core/database/repositoryQuery.d.ts +4 -1
- package/dist/entries/database/model.js +225 -24
- package/dist/entries/database/relationships.js +114 -21
- package/dist/entries/database/repositoryQuery.js +268 -6
- package/dist/entries/openapi/generator.js +22 -2
- package/dist/index.js +330 -37
- package/package.json +1 -1
|
@@ -18,32 +18,80 @@ function belongsTo(definition) {
|
|
|
18
18
|
...definition
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
+
function hasManyThrough(definition) {
|
|
22
|
+
return {
|
|
23
|
+
type: "hasManyThrough",
|
|
24
|
+
throughParentKey: "__through_parent_id",
|
|
25
|
+
...definition
|
|
26
|
+
};
|
|
27
|
+
}
|
|
21
28
|
function belongsToMany(definition) {
|
|
22
29
|
return {
|
|
23
30
|
type: "belongsToMany",
|
|
24
31
|
...definition
|
|
25
32
|
};
|
|
26
33
|
}
|
|
34
|
+
function relationMatchKey(value) {
|
|
35
|
+
if (value === null || value === undefined) {
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
if (typeof value === "bigint") {
|
|
39
|
+
return value.toString();
|
|
40
|
+
}
|
|
41
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
42
|
+
return String(value);
|
|
43
|
+
}
|
|
44
|
+
if (typeof value === "string" && /^-?\d+$/.test(value)) {
|
|
45
|
+
return BigInt(value).toString();
|
|
46
|
+
}
|
|
47
|
+
return String(value);
|
|
48
|
+
}
|
|
49
|
+
function getByRelationKey(map, key) {
|
|
50
|
+
if (map.has(key)) {
|
|
51
|
+
return map.get(key);
|
|
52
|
+
}
|
|
53
|
+
const want = relationMatchKey(key);
|
|
54
|
+
if (want === "") {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const [existing, value] of map) {
|
|
58
|
+
if (relationMatchKey(existing) === want) {
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
27
64
|
function indexHasManyRelation(parents, children, relation) {
|
|
28
65
|
const groups = new Map;
|
|
66
|
+
const originalKeys = new Map;
|
|
29
67
|
for (const parent of parents) {
|
|
30
|
-
|
|
68
|
+
const key = relationMatchKey(parent[relation.localKey]);
|
|
69
|
+
if (!groups.has(key)) {
|
|
70
|
+
groups.set(key, []);
|
|
71
|
+
originalKeys.set(key, parent[relation.localKey]);
|
|
72
|
+
}
|
|
31
73
|
}
|
|
32
74
|
for (const child of children) {
|
|
33
|
-
const
|
|
34
|
-
const group = groups.get(key);
|
|
75
|
+
const group = groups.get(relationMatchKey(child[relation.foreignKey]));
|
|
35
76
|
if (!group) {
|
|
36
77
|
continue;
|
|
37
78
|
}
|
|
38
79
|
group.push(child);
|
|
39
80
|
}
|
|
40
|
-
|
|
81
|
+
const result = new Map;
|
|
82
|
+
for (const [key, group] of groups) {
|
|
83
|
+
const original = originalKeys.get(key);
|
|
84
|
+
if (original !== undefined) {
|
|
85
|
+
result.set(original, group);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
41
89
|
}
|
|
42
90
|
function indexHasOneRelation(parents, children, relation) {
|
|
43
91
|
const grouped = indexHasManyRelation(parents, children, relation);
|
|
44
92
|
const result = new Map;
|
|
45
93
|
for (const parent of parents) {
|
|
46
|
-
const matches = grouped
|
|
94
|
+
const matches = getByRelationKey(grouped, parent[relation.localKey]) ?? [];
|
|
47
95
|
result.set(parent[relation.localKey], matches[0]);
|
|
48
96
|
}
|
|
49
97
|
return result;
|
|
@@ -51,12 +99,12 @@ function indexHasOneRelation(parents, children, relation) {
|
|
|
51
99
|
function indexBelongsToRelation(children, parents, relation) {
|
|
52
100
|
const parentsById = new Map;
|
|
53
101
|
for (const parent of parents) {
|
|
54
|
-
parentsById.set(parent[relation.ownerKey], parent);
|
|
102
|
+
parentsById.set(relationMatchKey(parent[relation.ownerKey]), parent);
|
|
55
103
|
}
|
|
56
104
|
const result = new Map;
|
|
57
105
|
for (const child of children) {
|
|
58
106
|
const foreignKey = child[relation.foreignKey];
|
|
59
|
-
const parent = parentsById.get(foreignKey);
|
|
107
|
+
const parent = parentsById.get(relationMatchKey(foreignKey));
|
|
60
108
|
if (parent) {
|
|
61
109
|
result.set(foreignKey, parent);
|
|
62
110
|
}
|
|
@@ -66,23 +114,33 @@ function indexBelongsToRelation(children, parents, relation) {
|
|
|
66
114
|
function indexBelongsToManyRelation(parents, pivotRows, relatedRows, relation) {
|
|
67
115
|
const relatedById = new Map;
|
|
68
116
|
for (const related of relatedRows) {
|
|
69
|
-
relatedById.set(related[relation.relatedKey], related);
|
|
117
|
+
relatedById.set(relationMatchKey(related[relation.relatedKey]), related);
|
|
70
118
|
}
|
|
71
119
|
const groups = new Map;
|
|
120
|
+
const originalKeys = new Map;
|
|
72
121
|
for (const parent of parents) {
|
|
73
|
-
|
|
122
|
+
const key = relationMatchKey(parent[relation.parentKey]);
|
|
123
|
+
if (!groups.has(key)) {
|
|
124
|
+
groups.set(key, []);
|
|
125
|
+
originalKeys.set(key, parent[relation.parentKey]);
|
|
126
|
+
}
|
|
74
127
|
}
|
|
75
128
|
for (const pivot of pivotRows) {
|
|
76
|
-
const
|
|
77
|
-
const
|
|
78
|
-
const group = groups.get(parentId);
|
|
79
|
-
const related = relatedById.get(relatedId);
|
|
129
|
+
const group = groups.get(relationMatchKey(pivot[relation.foreignPivotKey]));
|
|
130
|
+
const related = relatedById.get(relationMatchKey(pivot[relation.relatedPivotKey]));
|
|
80
131
|
if (!group || !related) {
|
|
81
132
|
continue;
|
|
82
133
|
}
|
|
83
134
|
group.push(related);
|
|
84
135
|
}
|
|
85
|
-
|
|
136
|
+
const result = new Map;
|
|
137
|
+
for (const [key, group] of groups) {
|
|
138
|
+
const original = originalKeys.get(key);
|
|
139
|
+
if (original !== undefined) {
|
|
140
|
+
result.set(original, group);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
86
144
|
}
|
|
87
145
|
function morphMany(definition) {
|
|
88
146
|
return {
|
|
@@ -104,31 +162,62 @@ function morphTo(definition) {
|
|
|
104
162
|
}
|
|
105
163
|
function indexMorphManyRelation(parents, children, relation) {
|
|
106
164
|
const groups = new Map;
|
|
165
|
+
const originalKeys = new Map;
|
|
107
166
|
for (const parent of parents) {
|
|
108
|
-
|
|
167
|
+
const key = relationMatchKey(parent[relation.localKey]);
|
|
168
|
+
if (!groups.has(key)) {
|
|
169
|
+
groups.set(key, []);
|
|
170
|
+
originalKeys.set(key, parent[relation.localKey]);
|
|
171
|
+
}
|
|
109
172
|
}
|
|
110
173
|
for (const child of children) {
|
|
111
174
|
if (child[relation.morphTypeKey] !== relation.morphType) {
|
|
112
175
|
continue;
|
|
113
176
|
}
|
|
114
|
-
const
|
|
115
|
-
const group = groups.get(key);
|
|
177
|
+
const group = groups.get(relationMatchKey(child[relation.morphIdKey]));
|
|
116
178
|
if (!group) {
|
|
117
179
|
continue;
|
|
118
180
|
}
|
|
119
181
|
group.push(child);
|
|
120
182
|
}
|
|
121
|
-
|
|
183
|
+
const result = new Map;
|
|
184
|
+
for (const [key, group] of groups) {
|
|
185
|
+
const original = originalKeys.get(key);
|
|
186
|
+
if (original !== undefined) {
|
|
187
|
+
result.set(original, group);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
122
191
|
}
|
|
123
192
|
function indexMorphOneRelation(parents, children, relation) {
|
|
124
193
|
const grouped = indexMorphManyRelation(parents, children, relation);
|
|
125
194
|
const result = new Map;
|
|
126
195
|
for (const parent of parents) {
|
|
127
|
-
const matches = grouped
|
|
196
|
+
const matches = getByRelationKey(grouped, parent[relation.localKey]) ?? [];
|
|
128
197
|
result.set(parent[relation.localKey], matches[0]);
|
|
129
198
|
}
|
|
130
199
|
return result;
|
|
131
200
|
}
|
|
201
|
+
function indexHasManyThroughRelation(parents, children, relation) {
|
|
202
|
+
const throughKey = relation.throughParentKey ?? "__through_parent_id";
|
|
203
|
+
const grouped = new Map;
|
|
204
|
+
for (const child of children) {
|
|
205
|
+
const key = relationMatchKey(child[throughKey]);
|
|
206
|
+
if (key === "") {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const existing = grouped.get(key) ?? [];
|
|
210
|
+
const { [throughKey]: _through, ...far } = child;
|
|
211
|
+
existing.push(far);
|
|
212
|
+
grouped.set(key, existing);
|
|
213
|
+
}
|
|
214
|
+
const result = new Map;
|
|
215
|
+
for (const parent of parents) {
|
|
216
|
+
const key = relationMatchKey(parent[relation.localKey]);
|
|
217
|
+
result.set(parent[relation.localKey], grouped.get(key) ?? []);
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
132
221
|
function indexMorphToRelation(children, parentsByType, relation) {
|
|
133
222
|
const result = new Map;
|
|
134
223
|
for (const child of children) {
|
|
@@ -137,7 +226,7 @@ function indexMorphToRelation(children, parentsByType, relation) {
|
|
|
137
226
|
if (!parents) {
|
|
138
227
|
continue;
|
|
139
228
|
}
|
|
140
|
-
const parent = parents
|
|
229
|
+
const parent = getByRelationKey(parents, child[relation.morphIdKey]);
|
|
141
230
|
if (parent) {
|
|
142
231
|
result.set(child[relation.morphIdKey], parent);
|
|
143
232
|
}
|
|
@@ -147,16 +236,20 @@ function indexMorphToRelation(children, parentsByType, relation) {
|
|
|
147
236
|
export {
|
|
148
237
|
belongsTo,
|
|
149
238
|
belongsToMany,
|
|
239
|
+
getByRelationKey,
|
|
150
240
|
hasMany,
|
|
241
|
+
hasManyThrough,
|
|
151
242
|
hasOne,
|
|
152
243
|
indexBelongsToManyRelation,
|
|
153
244
|
indexBelongsToRelation,
|
|
154
245
|
indexHasManyRelation,
|
|
246
|
+
indexHasManyThroughRelation,
|
|
155
247
|
indexHasOneRelation,
|
|
156
248
|
indexMorphManyRelation,
|
|
157
249
|
indexMorphOneRelation,
|
|
158
250
|
indexMorphToRelation,
|
|
159
251
|
morphMany,
|
|
160
252
|
morphOne,
|
|
161
|
-
morphTo
|
|
253
|
+
morphTo,
|
|
254
|
+
relationMatchKey
|
|
162
255
|
};
|
|
@@ -422,6 +422,241 @@ function buildDeleteByIdQuery(table, id) {
|
|
|
422
422
|
};
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
+
// ../../src/core/database/relationships.ts
|
|
426
|
+
function hasMany(definition) {
|
|
427
|
+
return {
|
|
428
|
+
type: "hasMany",
|
|
429
|
+
...definition
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
function hasOne(definition) {
|
|
433
|
+
return {
|
|
434
|
+
type: "hasOne",
|
|
435
|
+
...definition
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function belongsTo(definition) {
|
|
439
|
+
return {
|
|
440
|
+
type: "belongsTo",
|
|
441
|
+
...definition
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function hasManyThrough(definition) {
|
|
445
|
+
return {
|
|
446
|
+
type: "hasManyThrough",
|
|
447
|
+
throughParentKey: "__through_parent_id",
|
|
448
|
+
...definition
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
function belongsToMany(definition) {
|
|
452
|
+
return {
|
|
453
|
+
type: "belongsToMany",
|
|
454
|
+
...definition
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function relationMatchKey(value) {
|
|
458
|
+
if (value === null || value === undefined) {
|
|
459
|
+
return "";
|
|
460
|
+
}
|
|
461
|
+
if (typeof value === "bigint") {
|
|
462
|
+
return value.toString();
|
|
463
|
+
}
|
|
464
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
465
|
+
return String(value);
|
|
466
|
+
}
|
|
467
|
+
if (typeof value === "string" && /^-?\d+$/.test(value)) {
|
|
468
|
+
return BigInt(value).toString();
|
|
469
|
+
}
|
|
470
|
+
return String(value);
|
|
471
|
+
}
|
|
472
|
+
function getByRelationKey(map, key) {
|
|
473
|
+
if (map.has(key)) {
|
|
474
|
+
return map.get(key);
|
|
475
|
+
}
|
|
476
|
+
const want = relationMatchKey(key);
|
|
477
|
+
if (want === "") {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
for (const [existing, value] of map) {
|
|
481
|
+
if (relationMatchKey(existing) === want) {
|
|
482
|
+
return value;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
function indexHasManyRelation(parents, children, relation) {
|
|
488
|
+
const groups = new Map;
|
|
489
|
+
const originalKeys = new Map;
|
|
490
|
+
for (const parent of parents) {
|
|
491
|
+
const key = relationMatchKey(parent[relation.localKey]);
|
|
492
|
+
if (!groups.has(key)) {
|
|
493
|
+
groups.set(key, []);
|
|
494
|
+
originalKeys.set(key, parent[relation.localKey]);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
for (const child of children) {
|
|
498
|
+
const group = groups.get(relationMatchKey(child[relation.foreignKey]));
|
|
499
|
+
if (!group) {
|
|
500
|
+
continue;
|
|
501
|
+
}
|
|
502
|
+
group.push(child);
|
|
503
|
+
}
|
|
504
|
+
const result = new Map;
|
|
505
|
+
for (const [key, group] of groups) {
|
|
506
|
+
const original = originalKeys.get(key);
|
|
507
|
+
if (original !== undefined) {
|
|
508
|
+
result.set(original, group);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return result;
|
|
512
|
+
}
|
|
513
|
+
function indexHasOneRelation(parents, children, relation) {
|
|
514
|
+
const grouped = indexHasManyRelation(parents, children, relation);
|
|
515
|
+
const result = new Map;
|
|
516
|
+
for (const parent of parents) {
|
|
517
|
+
const matches = getByRelationKey(grouped, parent[relation.localKey]) ?? [];
|
|
518
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
519
|
+
}
|
|
520
|
+
return result;
|
|
521
|
+
}
|
|
522
|
+
function indexBelongsToRelation(children, parents, relation) {
|
|
523
|
+
const parentsById = new Map;
|
|
524
|
+
for (const parent of parents) {
|
|
525
|
+
parentsById.set(relationMatchKey(parent[relation.ownerKey]), parent);
|
|
526
|
+
}
|
|
527
|
+
const result = new Map;
|
|
528
|
+
for (const child of children) {
|
|
529
|
+
const foreignKey = child[relation.foreignKey];
|
|
530
|
+
const parent = parentsById.get(relationMatchKey(foreignKey));
|
|
531
|
+
if (parent) {
|
|
532
|
+
result.set(foreignKey, parent);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return result;
|
|
536
|
+
}
|
|
537
|
+
function indexBelongsToManyRelation(parents, pivotRows, relatedRows, relation) {
|
|
538
|
+
const relatedById = new Map;
|
|
539
|
+
for (const related of relatedRows) {
|
|
540
|
+
relatedById.set(relationMatchKey(related[relation.relatedKey]), related);
|
|
541
|
+
}
|
|
542
|
+
const groups = new Map;
|
|
543
|
+
const originalKeys = new Map;
|
|
544
|
+
for (const parent of parents) {
|
|
545
|
+
const key = relationMatchKey(parent[relation.parentKey]);
|
|
546
|
+
if (!groups.has(key)) {
|
|
547
|
+
groups.set(key, []);
|
|
548
|
+
originalKeys.set(key, parent[relation.parentKey]);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
for (const pivot of pivotRows) {
|
|
552
|
+
const group = groups.get(relationMatchKey(pivot[relation.foreignPivotKey]));
|
|
553
|
+
const related = relatedById.get(relationMatchKey(pivot[relation.relatedPivotKey]));
|
|
554
|
+
if (!group || !related) {
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
group.push(related);
|
|
558
|
+
}
|
|
559
|
+
const result = new Map;
|
|
560
|
+
for (const [key, group] of groups) {
|
|
561
|
+
const original = originalKeys.get(key);
|
|
562
|
+
if (original !== undefined) {
|
|
563
|
+
result.set(original, group);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return result;
|
|
567
|
+
}
|
|
568
|
+
function morphMany(definition) {
|
|
569
|
+
return {
|
|
570
|
+
type: "morphMany",
|
|
571
|
+
...definition
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
function morphOne(definition) {
|
|
575
|
+
return {
|
|
576
|
+
type: "morphOne",
|
|
577
|
+
...definition
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
function morphTo(definition) {
|
|
581
|
+
return {
|
|
582
|
+
type: "morphTo",
|
|
583
|
+
...definition
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
function indexMorphManyRelation(parents, children, relation) {
|
|
587
|
+
const groups = new Map;
|
|
588
|
+
const originalKeys = new Map;
|
|
589
|
+
for (const parent of parents) {
|
|
590
|
+
const key = relationMatchKey(parent[relation.localKey]);
|
|
591
|
+
if (!groups.has(key)) {
|
|
592
|
+
groups.set(key, []);
|
|
593
|
+
originalKeys.set(key, parent[relation.localKey]);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
for (const child of children) {
|
|
597
|
+
if (child[relation.morphTypeKey] !== relation.morphType) {
|
|
598
|
+
continue;
|
|
599
|
+
}
|
|
600
|
+
const group = groups.get(relationMatchKey(child[relation.morphIdKey]));
|
|
601
|
+
if (!group) {
|
|
602
|
+
continue;
|
|
603
|
+
}
|
|
604
|
+
group.push(child);
|
|
605
|
+
}
|
|
606
|
+
const result = new Map;
|
|
607
|
+
for (const [key, group] of groups) {
|
|
608
|
+
const original = originalKeys.get(key);
|
|
609
|
+
if (original !== undefined) {
|
|
610
|
+
result.set(original, group);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
return result;
|
|
614
|
+
}
|
|
615
|
+
function indexMorphOneRelation(parents, children, relation) {
|
|
616
|
+
const grouped = indexMorphManyRelation(parents, children, relation);
|
|
617
|
+
const result = new Map;
|
|
618
|
+
for (const parent of parents) {
|
|
619
|
+
const matches = getByRelationKey(grouped, parent[relation.localKey]) ?? [];
|
|
620
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
621
|
+
}
|
|
622
|
+
return result;
|
|
623
|
+
}
|
|
624
|
+
function indexHasManyThroughRelation(parents, children, relation) {
|
|
625
|
+
const throughKey = relation.throughParentKey ?? "__through_parent_id";
|
|
626
|
+
const grouped = new Map;
|
|
627
|
+
for (const child of children) {
|
|
628
|
+
const key = relationMatchKey(child[throughKey]);
|
|
629
|
+
if (key === "") {
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
const existing = grouped.get(key) ?? [];
|
|
633
|
+
const { [throughKey]: _through, ...far } = child;
|
|
634
|
+
existing.push(far);
|
|
635
|
+
grouped.set(key, existing);
|
|
636
|
+
}
|
|
637
|
+
const result = new Map;
|
|
638
|
+
for (const parent of parents) {
|
|
639
|
+
const key = relationMatchKey(parent[relation.localKey]);
|
|
640
|
+
result.set(parent[relation.localKey], grouped.get(key) ?? []);
|
|
641
|
+
}
|
|
642
|
+
return result;
|
|
643
|
+
}
|
|
644
|
+
function indexMorphToRelation(children, parentsByType, relation) {
|
|
645
|
+
const result = new Map;
|
|
646
|
+
for (const child of children) {
|
|
647
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
648
|
+
const parents = parentsByType.get(morphType);
|
|
649
|
+
if (!parents) {
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
const parent = getByRelationKey(parents, child[relation.morphIdKey]);
|
|
653
|
+
if (parent) {
|
|
654
|
+
result.set(child[relation.morphIdKey], parent);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
return result;
|
|
658
|
+
}
|
|
659
|
+
|
|
425
660
|
// ../../src/core/database/whereBuilder.ts
|
|
426
661
|
class WhereBuilder {
|
|
427
662
|
nodes = [];
|
|
@@ -589,6 +824,24 @@ class RepositoryQuery {
|
|
|
589
824
|
});
|
|
590
825
|
return this;
|
|
591
826
|
}
|
|
827
|
+
withHasManyThrough(as, relation, farRepository, options = {}) {
|
|
828
|
+
this.eagerLoads.push({
|
|
829
|
+
kind: "hasManyThrough",
|
|
830
|
+
as,
|
|
831
|
+
relation,
|
|
832
|
+
repository: farRepository,
|
|
833
|
+
options
|
|
834
|
+
});
|
|
835
|
+
return this;
|
|
836
|
+
}
|
|
837
|
+
withTrashed() {
|
|
838
|
+
this.queryOptions = { ...this.queryOptions, withTrashed: true };
|
|
839
|
+
return this;
|
|
840
|
+
}
|
|
841
|
+
onlyTrashed() {
|
|
842
|
+
this.queryOptions = { ...this.queryOptions, onlyTrashed: true };
|
|
843
|
+
return this;
|
|
844
|
+
}
|
|
592
845
|
async get() {
|
|
593
846
|
const rows = await this.repository.findAll(this.buildOptions());
|
|
594
847
|
return await this.attach(rows);
|
|
@@ -652,7 +905,7 @@ class RepositoryQuery {
|
|
|
652
905
|
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadHasManyForParents(rows, relation2, load.options);
|
|
653
906
|
result = result.map((row) => ({
|
|
654
907
|
...row,
|
|
655
|
-
[load.as]: grouped2
|
|
908
|
+
[load.as]: getByRelationKey(grouped2, row[relation2.localKey]) ?? []
|
|
656
909
|
}));
|
|
657
910
|
continue;
|
|
658
911
|
}
|
|
@@ -661,7 +914,7 @@ class RepositoryQuery {
|
|
|
661
914
|
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphManyForParents(rows, relation2, load.options);
|
|
662
915
|
result = result.map((row) => ({
|
|
663
916
|
...row,
|
|
664
|
-
[load.as]: grouped2
|
|
917
|
+
[load.as]: getByRelationKey(grouped2, row[relation2.localKey]) ?? []
|
|
665
918
|
}));
|
|
666
919
|
continue;
|
|
667
920
|
}
|
|
@@ -670,7 +923,16 @@ class RepositoryQuery {
|
|
|
670
923
|
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphOneForParents(rows, relation2, load.options);
|
|
671
924
|
result = result.map((row) => ({
|
|
672
925
|
...row,
|
|
673
|
-
[load.as]: grouped2
|
|
926
|
+
[load.as]: getByRelationKey(grouped2, row[relation2.localKey])
|
|
927
|
+
}));
|
|
928
|
+
continue;
|
|
929
|
+
}
|
|
930
|
+
if (load.kind === "hasManyThrough") {
|
|
931
|
+
const relation2 = load.relation;
|
|
932
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadHasManyThroughForParents(rows, relation2, load.options);
|
|
933
|
+
result = result.map((row) => ({
|
|
934
|
+
...row,
|
|
935
|
+
[load.as]: getByRelationKey(grouped2, row[relation2.localKey]) ?? []
|
|
674
936
|
}));
|
|
675
937
|
continue;
|
|
676
938
|
}
|
|
@@ -679,7 +941,7 @@ class RepositoryQuery {
|
|
|
679
941
|
const grouped2 = await this.repository.loadBelongsToManyForParents(rows, relation2, load.repository, load.options);
|
|
680
942
|
result = result.map((row) => ({
|
|
681
943
|
...row,
|
|
682
|
-
[load.as]: grouped2
|
|
944
|
+
[load.as]: getByRelationKey(grouped2, row[relation2.parentKey]) ?? []
|
|
683
945
|
}));
|
|
684
946
|
continue;
|
|
685
947
|
}
|
|
@@ -688,7 +950,7 @@ class RepositoryQuery {
|
|
|
688
950
|
const grouped2 = await this.repository.loadMorphToForChildren(rows, relation2, load.morphRepositories ?? new Map, load.options);
|
|
689
951
|
result = result.map((row) => ({
|
|
690
952
|
...row,
|
|
691
|
-
[load.as]: grouped2
|
|
953
|
+
[load.as]: getByRelationKey(grouped2, row[relation2.morphIdKey])
|
|
692
954
|
}));
|
|
693
955
|
continue;
|
|
694
956
|
}
|
|
@@ -696,7 +958,7 @@ class RepositoryQuery {
|
|
|
696
958
|
const grouped = await this.repository.loadBelongsToForParents(rows, relation, load.repository, load.options);
|
|
697
959
|
result = result.map((row) => ({
|
|
698
960
|
...row,
|
|
699
|
-
[load.as]: grouped
|
|
961
|
+
[load.as]: getByRelationKey(grouped, row[relation.foreignKey])
|
|
700
962
|
}));
|
|
701
963
|
}
|
|
702
964
|
return result;
|
|
@@ -94,10 +94,30 @@ var PUBLIC_ROUTE_DESCRIPTIONS = {
|
|
|
94
94
|
"POST /billing/webhooks/stripe": "Stripe webhook receiver (stub)",
|
|
95
95
|
"GET /scim/v2/Users": "SCIM list users",
|
|
96
96
|
"POST /scim/v2/Users": "SCIM create user",
|
|
97
|
-
"GET /scim/v2/Groups": "SCIM list groups (organizations)",
|
|
98
97
|
"GET /health": "Liveness probe",
|
|
99
98
|
"GET /ready": "Readiness probe",
|
|
100
|
-
"GET /metrics": "Prometheus metrics"
|
|
99
|
+
"GET /metrics": "Prometheus metrics",
|
|
100
|
+
"GET /api/user": "Current authenticated HiroApp user",
|
|
101
|
+
"POST /api/login": "Login with email and password",
|
|
102
|
+
"POST /api/logout": "Log out the current cookie session",
|
|
103
|
+
"POST /api/auth/two-factor-challenge": "Complete staff two-factor login challenge",
|
|
104
|
+
"GET /api/users/me": "Current user profile",
|
|
105
|
+
"PATCH /api/users/me": "Update profile name and email",
|
|
106
|
+
"PUT /api/users/me/password": "Change password",
|
|
107
|
+
"GET /api/users/me/sessions": "List cookie browser sessions",
|
|
108
|
+
"DELETE /api/users/me/sessions/:id": "Revoke one cookie browser session",
|
|
109
|
+
"GET /api/auth/tokens": "List API tokens",
|
|
110
|
+
"POST /api/auth/tokens": "Create API token",
|
|
111
|
+
"DELETE /api/auth/tokens/:id": "Revoke API token",
|
|
112
|
+
"GET /api/applications": "List applications",
|
|
113
|
+
"POST /api/applications": "Submit an application",
|
|
114
|
+
"GET /api/positions": "List hiring positions",
|
|
115
|
+
"GET /api/departments": "List departments",
|
|
116
|
+
"GET /api/webhooks": "List hiring webhooks",
|
|
117
|
+
"POST /api/webhooks": "Create a hiring webhook",
|
|
118
|
+
"GET /api/audit-logs": "List hiring audit log entries",
|
|
119
|
+
"GET /api/billing/subscription": "Current tenant subscription",
|
|
120
|
+
"GET /scim/v2/Groups": "SCIM list groups (departments)"
|
|
101
121
|
};
|
|
102
122
|
function toOpenApiPath(path) {
|
|
103
123
|
return path.replace(/:([A-Za-z_]+)/g, "{$1}");
|