@getstrata/core 0.5.9 → 0.5.12
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/core/database/baseRepository.d.ts +4 -1
- package/dist/core/database/index.d.ts +2 -2
- package/dist/core/database/relationships.d.ts +46 -2
- package/dist/core/database/repositoryQuery.d.ts +4 -1
- package/dist/core/mail/mailer.d.ts +3 -1
- package/dist/core/mail/markdownMail.d.ts +15 -0
- package/dist/core/mail/markdownMailable.d.ts +13 -0
- package/dist/core/notifications/dispatcher.d.ts +13 -0
- package/dist/core/notifications/index.d.ts +3 -0
- package/dist/core/notifications/notification.d.ts +7 -0
- package/dist/core/notifications/types.d.ts +25 -0
- package/dist/entries/auth/guard.js +176 -1
- package/dist/entries/database.js +182 -1
- package/dist/entries/http/webErrorResponse.js +176 -1
- package/dist/entries/http.js +176 -1
- package/dist/entries/queue/createAppQueue.js +176 -1
- package/dist/entries/queue/publicQueue.js +176 -1
- package/dist/entries/queue/queueMetrics.js +176 -1
- package/dist/entries/view.js +176 -1
- package/dist/framework/public-api.d.ts +9 -3
- package/dist/index.js +360 -14
- package/package.json +1 -1
|
@@ -888,6 +888,66 @@ function indexBelongsToManyRelation(parents, pivotRows, relatedRows, relation) {
|
|
|
888
888
|
}
|
|
889
889
|
return groups;
|
|
890
890
|
}
|
|
891
|
+
function morphMany(definition) {
|
|
892
|
+
return {
|
|
893
|
+
type: "morphMany",
|
|
894
|
+
...definition
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
function morphOne(definition) {
|
|
898
|
+
return {
|
|
899
|
+
type: "morphOne",
|
|
900
|
+
...definition
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function morphTo(definition) {
|
|
904
|
+
return {
|
|
905
|
+
type: "morphTo",
|
|
906
|
+
...definition
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
function indexMorphManyRelation(parents, children, relation) {
|
|
910
|
+
const groups = new Map;
|
|
911
|
+
for (const parent of parents) {
|
|
912
|
+
groups.set(parent[relation.localKey], []);
|
|
913
|
+
}
|
|
914
|
+
for (const child of children) {
|
|
915
|
+
if (child[relation.morphTypeKey] !== relation.morphType) {
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
const key = child[relation.morphIdKey];
|
|
919
|
+
const group = groups.get(key);
|
|
920
|
+
if (!group) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
group.push(child);
|
|
924
|
+
}
|
|
925
|
+
return groups;
|
|
926
|
+
}
|
|
927
|
+
function indexMorphOneRelation(parents, children, relation) {
|
|
928
|
+
const grouped = indexMorphManyRelation(parents, children, relation);
|
|
929
|
+
const result = new Map;
|
|
930
|
+
for (const parent of parents) {
|
|
931
|
+
const matches = grouped.get(parent[relation.localKey]) ?? [];
|
|
932
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
933
|
+
}
|
|
934
|
+
return result;
|
|
935
|
+
}
|
|
936
|
+
function indexMorphToRelation(children, parentsByType, relation) {
|
|
937
|
+
const result = new Map;
|
|
938
|
+
for (const child of children) {
|
|
939
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
940
|
+
const parents = parentsByType.get(morphType);
|
|
941
|
+
if (!parents) {
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
const parent = parents.get(child[relation.morphIdKey]);
|
|
945
|
+
if (parent) {
|
|
946
|
+
result.set(child[relation.morphIdKey], parent);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
return result;
|
|
950
|
+
}
|
|
891
951
|
|
|
892
952
|
// ../../src/config/database.ts
|
|
893
953
|
function readInteger(name, fallback) {
|
|
@@ -1091,6 +1151,37 @@ class RepositoryQuery {
|
|
|
1091
1151
|
});
|
|
1092
1152
|
return this;
|
|
1093
1153
|
}
|
|
1154
|
+
withMorphMany(as, relation, childRepository, options = {}) {
|
|
1155
|
+
this.eagerLoads.push({
|
|
1156
|
+
kind: "morphMany",
|
|
1157
|
+
as,
|
|
1158
|
+
relation,
|
|
1159
|
+
repository: childRepository,
|
|
1160
|
+
options
|
|
1161
|
+
});
|
|
1162
|
+
return this;
|
|
1163
|
+
}
|
|
1164
|
+
withMorphOne(as, relation, childRepository, options = {}) {
|
|
1165
|
+
this.eagerLoads.push({
|
|
1166
|
+
kind: "morphOne",
|
|
1167
|
+
as,
|
|
1168
|
+
relation,
|
|
1169
|
+
repository: childRepository,
|
|
1170
|
+
options
|
|
1171
|
+
});
|
|
1172
|
+
return this;
|
|
1173
|
+
}
|
|
1174
|
+
withMorphTo(as, relation, repositoriesByType, options = {}) {
|
|
1175
|
+
this.eagerLoads.push({
|
|
1176
|
+
kind: "morphTo",
|
|
1177
|
+
as,
|
|
1178
|
+
relation,
|
|
1179
|
+
repository: this.repository,
|
|
1180
|
+
morphRepositories: repositoriesByType,
|
|
1181
|
+
options
|
|
1182
|
+
});
|
|
1183
|
+
return this;
|
|
1184
|
+
}
|
|
1094
1185
|
async get() {
|
|
1095
1186
|
const rows = await this.repository.findAll(this.buildOptions());
|
|
1096
1187
|
return await this.attach(rows);
|
|
@@ -1151,6 +1242,33 @@ class RepositoryQuery {
|
|
|
1151
1242
|
}));
|
|
1152
1243
|
continue;
|
|
1153
1244
|
}
|
|
1245
|
+
if (load.kind === "morphMany") {
|
|
1246
|
+
const relation2 = load.relation;
|
|
1247
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphManyForParents(rows, relation2, load.options);
|
|
1248
|
+
result = result.map((row) => ({
|
|
1249
|
+
...row,
|
|
1250
|
+
[load.as]: grouped2.get(row[relation2.localKey]) ?? []
|
|
1251
|
+
}));
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
if (load.kind === "morphOne") {
|
|
1255
|
+
const relation2 = load.relation;
|
|
1256
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphOneForParents(rows, relation2, load.options);
|
|
1257
|
+
result = result.map((row) => ({
|
|
1258
|
+
...row,
|
|
1259
|
+
[load.as]: grouped2.get(row[relation2.localKey])
|
|
1260
|
+
}));
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
if (load.kind === "morphTo") {
|
|
1264
|
+
const relation2 = load.relation;
|
|
1265
|
+
const grouped2 = await this.repository.loadMorphToForChildren(rows, relation2, load.morphRepositories ?? new Map, load.options);
|
|
1266
|
+
result = result.map((row) => ({
|
|
1267
|
+
...row,
|
|
1268
|
+
[load.as]: grouped2.get(row[relation2.morphIdKey])
|
|
1269
|
+
}));
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1154
1272
|
const relation = load.relation;
|
|
1155
1273
|
const grouped = await this.repository.loadBelongsToForParents(rows, relation, load.repository, load.options);
|
|
1156
1274
|
result = result.map((row) => ({
|
|
@@ -1427,6 +1545,56 @@ class BaseRepository {
|
|
|
1427
1545
|
}, options);
|
|
1428
1546
|
return indexBelongsToRelation(children, parents, relation);
|
|
1429
1547
|
}
|
|
1548
|
+
async loadMorphManyForParents(parents, relation, options = {}) {
|
|
1549
|
+
if (parents.length === 0) {
|
|
1550
|
+
return indexMorphManyRelation(parents, [], relation);
|
|
1551
|
+
}
|
|
1552
|
+
const parentIds = [...new Set(parents.map((parent) => parent[relation.localKey]))];
|
|
1553
|
+
const children = await this.findWhere({
|
|
1554
|
+
[relation.morphTypeKey]: relation.morphType,
|
|
1555
|
+
[relation.morphIdKey]: parentIds
|
|
1556
|
+
}, options);
|
|
1557
|
+
return indexMorphManyRelation(parents, children, relation);
|
|
1558
|
+
}
|
|
1559
|
+
async loadMorphOneForParents(parents, relation, options = {}) {
|
|
1560
|
+
const grouped = await this.loadMorphManyForParents(parents, relation, options);
|
|
1561
|
+
const result = new Map;
|
|
1562
|
+
for (const parent of parents) {
|
|
1563
|
+
const matches = grouped.get(parent[relation.localKey]) ?? [];
|
|
1564
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
1565
|
+
}
|
|
1566
|
+
return result;
|
|
1567
|
+
}
|
|
1568
|
+
async loadMorphToForChildren(children, relation, repositoriesByType, options = {}) {
|
|
1569
|
+
if (children.length === 0) {
|
|
1570
|
+
return new Map;
|
|
1571
|
+
}
|
|
1572
|
+
const idsByType = new Map;
|
|
1573
|
+
for (const child of children) {
|
|
1574
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
1575
|
+
const morphId = child[relation.morphIdKey];
|
|
1576
|
+
const ids = idsByType.get(morphType) ?? new Set;
|
|
1577
|
+
ids.add(morphId);
|
|
1578
|
+
idsByType.set(morphType, ids);
|
|
1579
|
+
}
|
|
1580
|
+
const parentsByType = new Map;
|
|
1581
|
+
for (const [morphType, ids] of idsByType) {
|
|
1582
|
+
const repository = repositoriesByType.get(morphType);
|
|
1583
|
+
if (!repository) {
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
const ownerKey = repository.getTable().primaryKey;
|
|
1587
|
+
const parents = await repository.withConnection(this.connection).findWhere({
|
|
1588
|
+
[ownerKey]: [...ids]
|
|
1589
|
+
}, options);
|
|
1590
|
+
const indexed = new Map;
|
|
1591
|
+
for (const parent of parents) {
|
|
1592
|
+
indexed.set(parent[ownerKey], parent);
|
|
1593
|
+
}
|
|
1594
|
+
parentsByType.set(morphType, indexed);
|
|
1595
|
+
}
|
|
1596
|
+
return indexMorphToRelation(children, parentsByType, relation);
|
|
1597
|
+
}
|
|
1430
1598
|
}
|
|
1431
1599
|
var baseRepository_default = BaseRepository;
|
|
1432
1600
|
// ../../src/core/database/connection.ts
|
|
@@ -2378,8 +2546,15 @@ function defineTable(definition) {
|
|
|
2378
2546
|
return definition;
|
|
2379
2547
|
}
|
|
2380
2548
|
// ../../src/core/database/transaction.ts
|
|
2549
|
+
function supportsTransactions(connection) {
|
|
2550
|
+
return typeof connection.begin === "function";
|
|
2551
|
+
}
|
|
2381
2552
|
async function runInTransaction(operation) {
|
|
2382
|
-
|
|
2553
|
+
const pool = resolveRepositoryConnection();
|
|
2554
|
+
if (!supportsTransactions(pool)) {
|
|
2555
|
+
throw new Error("Active database connection does not support transactions. Bind a client with begin() via bindDatabaseConnection.");
|
|
2556
|
+
}
|
|
2557
|
+
return await pool.begin(async (transaction) => {
|
|
2383
2558
|
return await operation(createDatabaseConnection2(transaction));
|
|
2384
2559
|
});
|
|
2385
2560
|
}
|
package/dist/entries/http.js
CHANGED
|
@@ -888,6 +888,66 @@ function indexBelongsToManyRelation(parents, pivotRows, relatedRows, relation) {
|
|
|
888
888
|
}
|
|
889
889
|
return groups;
|
|
890
890
|
}
|
|
891
|
+
function morphMany(definition) {
|
|
892
|
+
return {
|
|
893
|
+
type: "morphMany",
|
|
894
|
+
...definition
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
function morphOne(definition) {
|
|
898
|
+
return {
|
|
899
|
+
type: "morphOne",
|
|
900
|
+
...definition
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function morphTo(definition) {
|
|
904
|
+
return {
|
|
905
|
+
type: "morphTo",
|
|
906
|
+
...definition
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
function indexMorphManyRelation(parents, children, relation) {
|
|
910
|
+
const groups = new Map;
|
|
911
|
+
for (const parent of parents) {
|
|
912
|
+
groups.set(parent[relation.localKey], []);
|
|
913
|
+
}
|
|
914
|
+
for (const child of children) {
|
|
915
|
+
if (child[relation.morphTypeKey] !== relation.morphType) {
|
|
916
|
+
continue;
|
|
917
|
+
}
|
|
918
|
+
const key = child[relation.morphIdKey];
|
|
919
|
+
const group = groups.get(key);
|
|
920
|
+
if (!group) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
group.push(child);
|
|
924
|
+
}
|
|
925
|
+
return groups;
|
|
926
|
+
}
|
|
927
|
+
function indexMorphOneRelation(parents, children, relation) {
|
|
928
|
+
const grouped = indexMorphManyRelation(parents, children, relation);
|
|
929
|
+
const result = new Map;
|
|
930
|
+
for (const parent of parents) {
|
|
931
|
+
const matches = grouped.get(parent[relation.localKey]) ?? [];
|
|
932
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
933
|
+
}
|
|
934
|
+
return result;
|
|
935
|
+
}
|
|
936
|
+
function indexMorphToRelation(children, parentsByType, relation) {
|
|
937
|
+
const result = new Map;
|
|
938
|
+
for (const child of children) {
|
|
939
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
940
|
+
const parents = parentsByType.get(morphType);
|
|
941
|
+
if (!parents) {
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
const parent = parents.get(child[relation.morphIdKey]);
|
|
945
|
+
if (parent) {
|
|
946
|
+
result.set(child[relation.morphIdKey], parent);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
return result;
|
|
950
|
+
}
|
|
891
951
|
|
|
892
952
|
// ../../src/config/database.ts
|
|
893
953
|
function readInteger(name, fallback) {
|
|
@@ -1091,6 +1151,37 @@ class RepositoryQuery {
|
|
|
1091
1151
|
});
|
|
1092
1152
|
return this;
|
|
1093
1153
|
}
|
|
1154
|
+
withMorphMany(as, relation, childRepository, options = {}) {
|
|
1155
|
+
this.eagerLoads.push({
|
|
1156
|
+
kind: "morphMany",
|
|
1157
|
+
as,
|
|
1158
|
+
relation,
|
|
1159
|
+
repository: childRepository,
|
|
1160
|
+
options
|
|
1161
|
+
});
|
|
1162
|
+
return this;
|
|
1163
|
+
}
|
|
1164
|
+
withMorphOne(as, relation, childRepository, options = {}) {
|
|
1165
|
+
this.eagerLoads.push({
|
|
1166
|
+
kind: "morphOne",
|
|
1167
|
+
as,
|
|
1168
|
+
relation,
|
|
1169
|
+
repository: childRepository,
|
|
1170
|
+
options
|
|
1171
|
+
});
|
|
1172
|
+
return this;
|
|
1173
|
+
}
|
|
1174
|
+
withMorphTo(as, relation, repositoriesByType, options = {}) {
|
|
1175
|
+
this.eagerLoads.push({
|
|
1176
|
+
kind: "morphTo",
|
|
1177
|
+
as,
|
|
1178
|
+
relation,
|
|
1179
|
+
repository: this.repository,
|
|
1180
|
+
morphRepositories: repositoriesByType,
|
|
1181
|
+
options
|
|
1182
|
+
});
|
|
1183
|
+
return this;
|
|
1184
|
+
}
|
|
1094
1185
|
async get() {
|
|
1095
1186
|
const rows = await this.repository.findAll(this.buildOptions());
|
|
1096
1187
|
return await this.attach(rows);
|
|
@@ -1151,6 +1242,33 @@ class RepositoryQuery {
|
|
|
1151
1242
|
}));
|
|
1152
1243
|
continue;
|
|
1153
1244
|
}
|
|
1245
|
+
if (load.kind === "morphMany") {
|
|
1246
|
+
const relation2 = load.relation;
|
|
1247
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphManyForParents(rows, relation2, load.options);
|
|
1248
|
+
result = result.map((row) => ({
|
|
1249
|
+
...row,
|
|
1250
|
+
[load.as]: grouped2.get(row[relation2.localKey]) ?? []
|
|
1251
|
+
}));
|
|
1252
|
+
continue;
|
|
1253
|
+
}
|
|
1254
|
+
if (load.kind === "morphOne") {
|
|
1255
|
+
const relation2 = load.relation;
|
|
1256
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphOneForParents(rows, relation2, load.options);
|
|
1257
|
+
result = result.map((row) => ({
|
|
1258
|
+
...row,
|
|
1259
|
+
[load.as]: grouped2.get(row[relation2.localKey])
|
|
1260
|
+
}));
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1263
|
+
if (load.kind === "morphTo") {
|
|
1264
|
+
const relation2 = load.relation;
|
|
1265
|
+
const grouped2 = await this.repository.loadMorphToForChildren(rows, relation2, load.morphRepositories ?? new Map, load.options);
|
|
1266
|
+
result = result.map((row) => ({
|
|
1267
|
+
...row,
|
|
1268
|
+
[load.as]: grouped2.get(row[relation2.morphIdKey])
|
|
1269
|
+
}));
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1154
1272
|
const relation = load.relation;
|
|
1155
1273
|
const grouped = await this.repository.loadBelongsToForParents(rows, relation, load.repository, load.options);
|
|
1156
1274
|
result = result.map((row) => ({
|
|
@@ -1427,6 +1545,56 @@ class BaseRepository {
|
|
|
1427
1545
|
}, options);
|
|
1428
1546
|
return indexBelongsToRelation(children, parents, relation);
|
|
1429
1547
|
}
|
|
1548
|
+
async loadMorphManyForParents(parents, relation, options = {}) {
|
|
1549
|
+
if (parents.length === 0) {
|
|
1550
|
+
return indexMorphManyRelation(parents, [], relation);
|
|
1551
|
+
}
|
|
1552
|
+
const parentIds = [...new Set(parents.map((parent) => parent[relation.localKey]))];
|
|
1553
|
+
const children = await this.findWhere({
|
|
1554
|
+
[relation.morphTypeKey]: relation.morphType,
|
|
1555
|
+
[relation.morphIdKey]: parentIds
|
|
1556
|
+
}, options);
|
|
1557
|
+
return indexMorphManyRelation(parents, children, relation);
|
|
1558
|
+
}
|
|
1559
|
+
async loadMorphOneForParents(parents, relation, options = {}) {
|
|
1560
|
+
const grouped = await this.loadMorphManyForParents(parents, relation, options);
|
|
1561
|
+
const result = new Map;
|
|
1562
|
+
for (const parent of parents) {
|
|
1563
|
+
const matches = grouped.get(parent[relation.localKey]) ?? [];
|
|
1564
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
1565
|
+
}
|
|
1566
|
+
return result;
|
|
1567
|
+
}
|
|
1568
|
+
async loadMorphToForChildren(children, relation, repositoriesByType, options = {}) {
|
|
1569
|
+
if (children.length === 0) {
|
|
1570
|
+
return new Map;
|
|
1571
|
+
}
|
|
1572
|
+
const idsByType = new Map;
|
|
1573
|
+
for (const child of children) {
|
|
1574
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
1575
|
+
const morphId = child[relation.morphIdKey];
|
|
1576
|
+
const ids = idsByType.get(morphType) ?? new Set;
|
|
1577
|
+
ids.add(morphId);
|
|
1578
|
+
idsByType.set(morphType, ids);
|
|
1579
|
+
}
|
|
1580
|
+
const parentsByType = new Map;
|
|
1581
|
+
for (const [morphType, ids] of idsByType) {
|
|
1582
|
+
const repository = repositoriesByType.get(morphType);
|
|
1583
|
+
if (!repository) {
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
const ownerKey = repository.getTable().primaryKey;
|
|
1587
|
+
const parents = await repository.withConnection(this.connection).findWhere({
|
|
1588
|
+
[ownerKey]: [...ids]
|
|
1589
|
+
}, options);
|
|
1590
|
+
const indexed = new Map;
|
|
1591
|
+
for (const parent of parents) {
|
|
1592
|
+
indexed.set(parent[ownerKey], parent);
|
|
1593
|
+
}
|
|
1594
|
+
parentsByType.set(morphType, indexed);
|
|
1595
|
+
}
|
|
1596
|
+
return indexMorphToRelation(children, parentsByType, relation);
|
|
1597
|
+
}
|
|
1430
1598
|
}
|
|
1431
1599
|
var baseRepository_default = BaseRepository;
|
|
1432
1600
|
// ../../src/core/database/connection.ts
|
|
@@ -2378,8 +2546,15 @@ function defineTable(definition) {
|
|
|
2378
2546
|
return definition;
|
|
2379
2547
|
}
|
|
2380
2548
|
// ../../src/core/database/transaction.ts
|
|
2549
|
+
function supportsTransactions(connection) {
|
|
2550
|
+
return typeof connection.begin === "function";
|
|
2551
|
+
}
|
|
2381
2552
|
async function runInTransaction(operation) {
|
|
2382
|
-
|
|
2553
|
+
const pool = resolveRepositoryConnection();
|
|
2554
|
+
if (!supportsTransactions(pool)) {
|
|
2555
|
+
throw new Error("Active database connection does not support transactions. Bind a client with begin() via bindDatabaseConnection.");
|
|
2556
|
+
}
|
|
2557
|
+
return await pool.begin(async (transaction) => {
|
|
2383
2558
|
return await operation(createDatabaseConnection2(transaction));
|
|
2384
2559
|
});
|
|
2385
2560
|
}
|
|
@@ -1132,6 +1132,66 @@ function indexBelongsToManyRelation(parents, pivotRows, relatedRows, relation) {
|
|
|
1132
1132
|
}
|
|
1133
1133
|
return groups;
|
|
1134
1134
|
}
|
|
1135
|
+
function morphMany(definition) {
|
|
1136
|
+
return {
|
|
1137
|
+
type: "morphMany",
|
|
1138
|
+
...definition
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
function morphOne(definition) {
|
|
1142
|
+
return {
|
|
1143
|
+
type: "morphOne",
|
|
1144
|
+
...definition
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
function morphTo(definition) {
|
|
1148
|
+
return {
|
|
1149
|
+
type: "morphTo",
|
|
1150
|
+
...definition
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
function indexMorphManyRelation(parents, children, relation) {
|
|
1154
|
+
const groups = new Map;
|
|
1155
|
+
for (const parent of parents) {
|
|
1156
|
+
groups.set(parent[relation.localKey], []);
|
|
1157
|
+
}
|
|
1158
|
+
for (const child of children) {
|
|
1159
|
+
if (child[relation.morphTypeKey] !== relation.morphType) {
|
|
1160
|
+
continue;
|
|
1161
|
+
}
|
|
1162
|
+
const key = child[relation.morphIdKey];
|
|
1163
|
+
const group = groups.get(key);
|
|
1164
|
+
if (!group) {
|
|
1165
|
+
continue;
|
|
1166
|
+
}
|
|
1167
|
+
group.push(child);
|
|
1168
|
+
}
|
|
1169
|
+
return groups;
|
|
1170
|
+
}
|
|
1171
|
+
function indexMorphOneRelation(parents, children, relation) {
|
|
1172
|
+
const grouped = indexMorphManyRelation(parents, children, relation);
|
|
1173
|
+
const result = new Map;
|
|
1174
|
+
for (const parent of parents) {
|
|
1175
|
+
const matches = grouped.get(parent[relation.localKey]) ?? [];
|
|
1176
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
1177
|
+
}
|
|
1178
|
+
return result;
|
|
1179
|
+
}
|
|
1180
|
+
function indexMorphToRelation(children, parentsByType, relation) {
|
|
1181
|
+
const result = new Map;
|
|
1182
|
+
for (const child of children) {
|
|
1183
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
1184
|
+
const parents = parentsByType.get(morphType);
|
|
1185
|
+
if (!parents) {
|
|
1186
|
+
continue;
|
|
1187
|
+
}
|
|
1188
|
+
const parent = parents.get(child[relation.morphIdKey]);
|
|
1189
|
+
if (parent) {
|
|
1190
|
+
result.set(child[relation.morphIdKey], parent);
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
return result;
|
|
1194
|
+
}
|
|
1135
1195
|
|
|
1136
1196
|
// ../../src/core/database/boundConnection.ts
|
|
1137
1197
|
var boundConnectionHolder = {
|
|
@@ -1265,6 +1325,37 @@ class RepositoryQuery {
|
|
|
1265
1325
|
});
|
|
1266
1326
|
return this;
|
|
1267
1327
|
}
|
|
1328
|
+
withMorphMany(as, relation, childRepository, options = {}) {
|
|
1329
|
+
this.eagerLoads.push({
|
|
1330
|
+
kind: "morphMany",
|
|
1331
|
+
as,
|
|
1332
|
+
relation,
|
|
1333
|
+
repository: childRepository,
|
|
1334
|
+
options
|
|
1335
|
+
});
|
|
1336
|
+
return this;
|
|
1337
|
+
}
|
|
1338
|
+
withMorphOne(as, relation, childRepository, options = {}) {
|
|
1339
|
+
this.eagerLoads.push({
|
|
1340
|
+
kind: "morphOne",
|
|
1341
|
+
as,
|
|
1342
|
+
relation,
|
|
1343
|
+
repository: childRepository,
|
|
1344
|
+
options
|
|
1345
|
+
});
|
|
1346
|
+
return this;
|
|
1347
|
+
}
|
|
1348
|
+
withMorphTo(as, relation, repositoriesByType, options = {}) {
|
|
1349
|
+
this.eagerLoads.push({
|
|
1350
|
+
kind: "morphTo",
|
|
1351
|
+
as,
|
|
1352
|
+
relation,
|
|
1353
|
+
repository: this.repository,
|
|
1354
|
+
morphRepositories: repositoriesByType,
|
|
1355
|
+
options
|
|
1356
|
+
});
|
|
1357
|
+
return this;
|
|
1358
|
+
}
|
|
1268
1359
|
async get() {
|
|
1269
1360
|
const rows = await this.repository.findAll(this.buildOptions());
|
|
1270
1361
|
return await this.attach(rows);
|
|
@@ -1325,6 +1416,33 @@ class RepositoryQuery {
|
|
|
1325
1416
|
}));
|
|
1326
1417
|
continue;
|
|
1327
1418
|
}
|
|
1419
|
+
if (load.kind === "morphMany") {
|
|
1420
|
+
const relation2 = load.relation;
|
|
1421
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphManyForParents(rows, relation2, load.options);
|
|
1422
|
+
result = result.map((row) => ({
|
|
1423
|
+
...row,
|
|
1424
|
+
[load.as]: grouped2.get(row[relation2.localKey]) ?? []
|
|
1425
|
+
}));
|
|
1426
|
+
continue;
|
|
1427
|
+
}
|
|
1428
|
+
if (load.kind === "morphOne") {
|
|
1429
|
+
const relation2 = load.relation;
|
|
1430
|
+
const grouped2 = await load.repository.withConnection(this.repository.getConnection()).loadMorphOneForParents(rows, relation2, load.options);
|
|
1431
|
+
result = result.map((row) => ({
|
|
1432
|
+
...row,
|
|
1433
|
+
[load.as]: grouped2.get(row[relation2.localKey])
|
|
1434
|
+
}));
|
|
1435
|
+
continue;
|
|
1436
|
+
}
|
|
1437
|
+
if (load.kind === "morphTo") {
|
|
1438
|
+
const relation2 = load.relation;
|
|
1439
|
+
const grouped2 = await this.repository.loadMorphToForChildren(rows, relation2, load.morphRepositories ?? new Map, load.options);
|
|
1440
|
+
result = result.map((row) => ({
|
|
1441
|
+
...row,
|
|
1442
|
+
[load.as]: grouped2.get(row[relation2.morphIdKey])
|
|
1443
|
+
}));
|
|
1444
|
+
continue;
|
|
1445
|
+
}
|
|
1328
1446
|
const relation = load.relation;
|
|
1329
1447
|
const grouped = await this.repository.loadBelongsToForParents(rows, relation, load.repository, load.options);
|
|
1330
1448
|
result = result.map((row) => ({
|
|
@@ -1601,6 +1719,56 @@ class BaseRepository {
|
|
|
1601
1719
|
}, options);
|
|
1602
1720
|
return indexBelongsToRelation(children, parents, relation);
|
|
1603
1721
|
}
|
|
1722
|
+
async loadMorphManyForParents(parents, relation, options = {}) {
|
|
1723
|
+
if (parents.length === 0) {
|
|
1724
|
+
return indexMorphManyRelation(parents, [], relation);
|
|
1725
|
+
}
|
|
1726
|
+
const parentIds = [...new Set(parents.map((parent) => parent[relation.localKey]))];
|
|
1727
|
+
const children = await this.findWhere({
|
|
1728
|
+
[relation.morphTypeKey]: relation.morphType,
|
|
1729
|
+
[relation.morphIdKey]: parentIds
|
|
1730
|
+
}, options);
|
|
1731
|
+
return indexMorphManyRelation(parents, children, relation);
|
|
1732
|
+
}
|
|
1733
|
+
async loadMorphOneForParents(parents, relation, options = {}) {
|
|
1734
|
+
const grouped = await this.loadMorphManyForParents(parents, relation, options);
|
|
1735
|
+
const result = new Map;
|
|
1736
|
+
for (const parent of parents) {
|
|
1737
|
+
const matches = grouped.get(parent[relation.localKey]) ?? [];
|
|
1738
|
+
result.set(parent[relation.localKey], matches[0]);
|
|
1739
|
+
}
|
|
1740
|
+
return result;
|
|
1741
|
+
}
|
|
1742
|
+
async loadMorphToForChildren(children, relation, repositoriesByType, options = {}) {
|
|
1743
|
+
if (children.length === 0) {
|
|
1744
|
+
return new Map;
|
|
1745
|
+
}
|
|
1746
|
+
const idsByType = new Map;
|
|
1747
|
+
for (const child of children) {
|
|
1748
|
+
const morphType = String(child[relation.morphTypeKey]);
|
|
1749
|
+
const morphId = child[relation.morphIdKey];
|
|
1750
|
+
const ids = idsByType.get(morphType) ?? new Set;
|
|
1751
|
+
ids.add(morphId);
|
|
1752
|
+
idsByType.set(morphType, ids);
|
|
1753
|
+
}
|
|
1754
|
+
const parentsByType = new Map;
|
|
1755
|
+
for (const [morphType, ids] of idsByType) {
|
|
1756
|
+
const repository = repositoriesByType.get(morphType);
|
|
1757
|
+
if (!repository) {
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
const ownerKey = repository.getTable().primaryKey;
|
|
1761
|
+
const parents = await repository.withConnection(this.connection).findWhere({
|
|
1762
|
+
[ownerKey]: [...ids]
|
|
1763
|
+
}, options);
|
|
1764
|
+
const indexed = new Map;
|
|
1765
|
+
for (const parent of parents) {
|
|
1766
|
+
indexed.set(parent[ownerKey], parent);
|
|
1767
|
+
}
|
|
1768
|
+
parentsByType.set(morphType, indexed);
|
|
1769
|
+
}
|
|
1770
|
+
return indexMorphToRelation(children, parentsByType, relation);
|
|
1771
|
+
}
|
|
1604
1772
|
}
|
|
1605
1773
|
var baseRepository_default = BaseRepository;
|
|
1606
1774
|
// ../../src/core/database/connection.ts
|
|
@@ -2552,8 +2720,15 @@ function defineTable(definition) {
|
|
|
2552
2720
|
return definition;
|
|
2553
2721
|
}
|
|
2554
2722
|
// ../../src/core/database/transaction.ts
|
|
2723
|
+
function supportsTransactions(connection) {
|
|
2724
|
+
return typeof connection.begin === "function";
|
|
2725
|
+
}
|
|
2555
2726
|
async function runInTransaction(operation) {
|
|
2556
|
-
|
|
2727
|
+
const pool = resolveRepositoryConnection();
|
|
2728
|
+
if (!supportsTransactions(pool)) {
|
|
2729
|
+
throw new Error("Active database connection does not support transactions. Bind a client with begin() via bindDatabaseConnection.");
|
|
2730
|
+
}
|
|
2731
|
+
return await pool.begin(async (transaction) => {
|
|
2557
2732
|
return await operation(createDatabaseConnection2(transaction));
|
|
2558
2733
|
});
|
|
2559
2734
|
}
|