remult 0.27.8-next.2 → 0.27.8-next.3
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/esm/remult-mongo.js +25 -30
- package/esm/src/data-api.js +21 -14
- package/esm/src/data-providers/array-entity-data-provider.js +94 -52
- package/esm/src/data-providers/rest-data-provider.js +3 -0
- package/esm/src/data-providers/sql-database.js +30 -36
- package/esm/src/remult3/RepositoryImplementation.js +25 -4
- package/esm/src/remult3/remult3.js +8 -0
- package/index.d.ts +1 -1
- package/package.json +1 -1
- package/remult-mongo.js +59 -58
- package/src/data-api.js +63 -35
- package/src/data-interfaces.d.ts +5 -2
- package/src/data-providers/array-entity-data-provider.js +119 -77
- package/src/data-providers/rest-data-provider.js +8 -5
- package/src/data-providers/sql-database.js +138 -96
- package/src/remult3/RepositoryImplementation.d.ts +3 -6
- package/src/remult3/RepositoryImplementation.js +283 -245
- package/src/remult3/remult3.d.ts +49 -9
- package/src/remult3/remult3.js +9 -1
package/esm/remult-mongo.js
CHANGED
|
@@ -5,7 +5,7 @@ import { remult as remultContext } from './src/remult-proxy.js';
|
|
|
5
5
|
import { getRepository } from './src/remult3/RepositoryImplementation.js';
|
|
6
6
|
import { getRepositoryInternals } from './src/remult3/repository-internals.js';
|
|
7
7
|
import { getRowAfterUpdate } from './src/data-providers/sql-database.js';
|
|
8
|
-
import { AggregateCountMember } from './src/remult3/remult3.js';
|
|
8
|
+
import { AggregateCountMember, AggregateOperators, } from './src/remult3/remult3.js';
|
|
9
9
|
export class MongoDataProvider {
|
|
10
10
|
db;
|
|
11
11
|
client;
|
|
@@ -115,6 +115,8 @@ class MongoEntityDataProvider {
|
|
|
115
115
|
resultRow[AggregateCountMember] = mongoRow.__count;
|
|
116
116
|
});
|
|
117
117
|
pipeLine.push({ $group });
|
|
118
|
+
const $addFields = {};
|
|
119
|
+
pipeLine.push({ $addFields });
|
|
118
120
|
if (options?.groupBy) {
|
|
119
121
|
$group._id = {};
|
|
120
122
|
for (const element of options.groupBy) {
|
|
@@ -128,28 +130,23 @@ class MongoEntityDataProvider {
|
|
|
128
130
|
else {
|
|
129
131
|
$group._id = null;
|
|
130
132
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
resultRow[element.key] = {
|
|
149
|
-
...resultRow[element.key],
|
|
150
|
-
avg: element.valueConverter.fromDb(mongoRow[name]),
|
|
151
|
-
};
|
|
152
|
-
});
|
|
133
|
+
for (const operator of AggregateOperators) {
|
|
134
|
+
if (options?.[operator]) {
|
|
135
|
+
for (const element of options[operator]) {
|
|
136
|
+
const name = e.$dbNameOf(element) + '_' + operator;
|
|
137
|
+
if (operator === 'distinctCount') {
|
|
138
|
+
$group[name + '_temp'] = { $addToSet: `$${e.$dbNameOf(element)}` };
|
|
139
|
+
$addFields[name] = { $size: `$${name + '_temp'}` };
|
|
140
|
+
}
|
|
141
|
+
else
|
|
142
|
+
$group[name] = { ['$' + operator]: `$${e.$dbNameOf(element)}` };
|
|
143
|
+
processResultRow.push((mongoRow, resultRow) => {
|
|
144
|
+
resultRow[element.key] = {
|
|
145
|
+
...resultRow[element.key],
|
|
146
|
+
[operator]: mongoRow[name],
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
153
150
|
}
|
|
154
151
|
}
|
|
155
152
|
if (options?.orderBy) {
|
|
@@ -157,17 +154,15 @@ class MongoEntityDataProvider {
|
|
|
157
154
|
for (const x of options.orderBy) {
|
|
158
155
|
const direction = x.isDescending ? -1 : 1;
|
|
159
156
|
switch (x.operation) {
|
|
160
|
-
case 'sum':
|
|
161
|
-
sort[e.$dbNameOf(x.field) + '_sum'] = direction;
|
|
162
|
-
break;
|
|
163
|
-
case 'avg':
|
|
164
|
-
sort[e.$dbNameOf(x.field) + '_avg'] = direction;
|
|
165
|
-
break;
|
|
166
157
|
case 'count':
|
|
167
158
|
sort['__count'] = direction;
|
|
168
159
|
break;
|
|
169
|
-
|
|
160
|
+
case undefined:
|
|
170
161
|
sort['_id.' + e.$dbNameOf(x.field)] = direction;
|
|
162
|
+
break;
|
|
163
|
+
default:
|
|
164
|
+
sort[e.$dbNameOf(x.field) + '_' + x.operation] = direction;
|
|
165
|
+
break;
|
|
171
166
|
}
|
|
172
167
|
}
|
|
173
168
|
pipeLine.push({ $sort: sort });
|
package/esm/src/data-api.js
CHANGED
|
@@ -2,7 +2,7 @@ import { doTransaction } from './context.js';
|
|
|
2
2
|
import { findOptionsToJson, liveQueryAction, } from './data-providers/rest-data-provider.js';
|
|
3
3
|
import { Filter, buildFilterFromRequestParameters, customUrlToken, } from './filter/filter-interfaces.js';
|
|
4
4
|
import { getRelationFieldInfo } from './remult3/relationInfoMember.js';
|
|
5
|
-
import { AggregateCountMember, } from './remult3/remult3.js';
|
|
5
|
+
import { AggregateCountMember, AggregateForApiKey, } from './remult3/remult3.js';
|
|
6
6
|
import { ForbiddenError } from './server-action.js';
|
|
7
7
|
export class DataApi {
|
|
8
8
|
repository;
|
|
@@ -110,39 +110,46 @@ export class DataApi {
|
|
|
110
110
|
for (const element of body?.orderBy) {
|
|
111
111
|
const direction = element.isDescending ? 'desc' : 'asc';
|
|
112
112
|
switch (element.operation) {
|
|
113
|
-
case
|
|
114
|
-
orderBy[element.field] =
|
|
115
|
-
...orderBy[element.field],
|
|
116
|
-
sum: direction,
|
|
117
|
-
};
|
|
118
|
-
break;
|
|
119
|
-
case 'avg':
|
|
120
|
-
orderBy[element.field] = {
|
|
121
|
-
...orderBy[element.field],
|
|
122
|
-
avg: direction,
|
|
123
|
-
};
|
|
113
|
+
case undefined:
|
|
114
|
+
orderBy[element.field] = direction;
|
|
124
115
|
break;
|
|
125
116
|
case 'count':
|
|
126
117
|
orderBy[AggregateCountMember] = direction;
|
|
127
118
|
break;
|
|
128
119
|
default:
|
|
129
|
-
orderBy[element.field] =
|
|
120
|
+
orderBy[element.field] = {
|
|
121
|
+
...orderBy[element.field],
|
|
122
|
+
[element.operation]: direction,
|
|
123
|
+
};
|
|
130
124
|
break;
|
|
131
125
|
}
|
|
132
126
|
}
|
|
133
127
|
}
|
|
128
|
+
const groupBy = body?.groupBy?.filter((x) => this.repository.fields.find(x).includedInApi());
|
|
134
129
|
let result = await this.repository.aggregate({
|
|
135
130
|
where: findOptions.where,
|
|
136
131
|
limit: findOptions.limit,
|
|
137
132
|
page: findOptions.page,
|
|
138
|
-
|
|
133
|
+
//@ts-expect-error internal key
|
|
134
|
+
[AggregateForApiKey]: true,
|
|
135
|
+
groupBy,
|
|
139
136
|
sum: body?.sum?.filter((x) => this.repository.fields.find(x).includedInApi()),
|
|
140
137
|
avg: body?.avg?.filter((x) => this.repository.fields.find(x).includedInApi()),
|
|
138
|
+
min: body?.min?.filter((x) => this.repository.fields.find(x).includedInApi()),
|
|
139
|
+
max: body?.max?.filter((x) => this.repository.fields.find(x).includedInApi()),
|
|
140
|
+
distinctCount: body?.distinctCount?.filter((x) => this.repository.fields.find(x).includedInApi()),
|
|
141
141
|
orderBy: orderBy,
|
|
142
142
|
});
|
|
143
143
|
if (!Array.isArray(result)) {
|
|
144
144
|
result = [result];
|
|
145
145
|
}
|
|
146
|
+
else {
|
|
147
|
+
result.forEach((x) => {
|
|
148
|
+
for (const f of groupBy) {
|
|
149
|
+
x[f] = this.repository.fields.find(f).valueConverter.toJson(x[f]);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
146
153
|
response.success(result);
|
|
147
154
|
}
|
|
148
155
|
async getArrayImpl(response, request, body) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CompoundIdField } from '../CompoundIdField.js';
|
|
2
2
|
import { dbNamesOf, isDbReadonly, } from '../filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
3
|
import { Filter, customDatabaseFilterToken, } from '../filter/filter-interfaces.js';
|
|
4
|
-
import { AggregateCountMember, } from '../remult3/remult3.js';
|
|
4
|
+
import { AggregateCountMember, AggregateOperators, } from '../remult3/remult3.js';
|
|
5
5
|
import { compareForSort, Sort } from '../sort.js';
|
|
6
6
|
export class ArrayEntityDataProvider {
|
|
7
7
|
entity;
|
|
@@ -29,54 +29,95 @@ export class ArrayEntityDataProvider {
|
|
|
29
29
|
let first = true;
|
|
30
30
|
let count = 0;
|
|
31
31
|
let aggregates = [];
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
32
|
+
const operatorImpl = {
|
|
33
|
+
sum: (key) => {
|
|
34
|
+
let sum = 0;
|
|
35
|
+
return {
|
|
36
|
+
process(row) {
|
|
37
|
+
const val = row[key];
|
|
38
|
+
if (val !== undefined && val !== null)
|
|
39
|
+
sum += row[key];
|
|
40
|
+
},
|
|
41
|
+
finishGroup(result) {
|
|
42
|
+
result[key] = { ...result[key], sum };
|
|
43
|
+
sum = 0;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
avg: (key) => {
|
|
48
|
+
let sum = 0;
|
|
49
|
+
let count = 0;
|
|
50
|
+
return {
|
|
51
|
+
process(row) {
|
|
52
|
+
const val = row[key];
|
|
53
|
+
if (val !== undefined && val !== null) {
|
|
54
|
+
sum += row[key];
|
|
55
|
+
count++;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
finishGroup(result) {
|
|
59
|
+
result[key] = {
|
|
60
|
+
...result[key],
|
|
61
|
+
avg: sum / count,
|
|
62
|
+
};
|
|
63
|
+
sum = 0;
|
|
64
|
+
count = 0;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
min: (key) => {
|
|
69
|
+
let min = undefined;
|
|
70
|
+
return {
|
|
71
|
+
process(row) {
|
|
72
|
+
const val = row[key];
|
|
73
|
+
if (val !== undefined && val !== null) {
|
|
74
|
+
if (min === undefined || val < min)
|
|
75
|
+
min = val;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
finishGroup(result) {
|
|
79
|
+
result[key] = { ...result[key], min };
|
|
80
|
+
min = undefined;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
max: (key) => {
|
|
85
|
+
let max = undefined;
|
|
86
|
+
return {
|
|
87
|
+
process(row) {
|
|
88
|
+
const val = row[key];
|
|
89
|
+
if (val !== undefined && val !== null) {
|
|
90
|
+
if (max === undefined || val > max)
|
|
91
|
+
max = val;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
finishGroup(result) {
|
|
95
|
+
result[key] = { ...result[key], max };
|
|
96
|
+
max = undefined;
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
distinctCount: (key) => {
|
|
101
|
+
let distinct = new Set();
|
|
102
|
+
return {
|
|
103
|
+
process(row) {
|
|
104
|
+
const val = row[key];
|
|
105
|
+
if (val !== undefined && val !== null)
|
|
106
|
+
distinct.add(val);
|
|
107
|
+
},
|
|
108
|
+
finishGroup(result) {
|
|
109
|
+
result[key] = { ...result[key], distinctCount: distinct.size };
|
|
110
|
+
distinct.clear();
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
for (let operator of AggregateOperators) {
|
|
116
|
+
if (options?.[operator]) {
|
|
117
|
+
for (const element of options[operator]) {
|
|
118
|
+
aggregates.push(operatorImpl[operator](element.key));
|
|
75
119
|
}
|
|
76
120
|
}
|
|
77
|
-
for (const element of options.avg) {
|
|
78
|
-
aggregates.push(new Avg(element.key));
|
|
79
|
-
}
|
|
80
121
|
}
|
|
81
122
|
function finishGroup() {
|
|
82
123
|
const r = { ...group, $count: count };
|
|
@@ -120,13 +161,14 @@ export class ArrayEntityDataProvider {
|
|
|
120
161
|
}
|
|
121
162
|
else {
|
|
122
163
|
switch (x.operation) {
|
|
123
|
-
case '
|
|
124
|
-
return row[
|
|
125
|
-
case
|
|
126
|
-
return row[x.field.key]
|
|
164
|
+
case 'count':
|
|
165
|
+
return row[AggregateCountMember];
|
|
166
|
+
case undefined:
|
|
167
|
+
return row[x.field.key];
|
|
168
|
+
default:
|
|
169
|
+
return row[x.field.key][x.operation];
|
|
127
170
|
}
|
|
128
171
|
}
|
|
129
|
-
return row[x.field.key];
|
|
130
172
|
};
|
|
131
173
|
let compare = compareForSort(getValue(a), getValue(b), x.isDescending);
|
|
132
174
|
if (compare != 0)
|
|
@@ -111,6 +111,9 @@ export class RestEntityDataProvider {
|
|
|
111
111
|
groupBy: options?.groupBy?.map((x) => x.key),
|
|
112
112
|
sum: options?.sum?.map((x) => x.key),
|
|
113
113
|
avg: options?.avg?.map((x) => x.key),
|
|
114
|
+
min: options?.min?.map((x) => x.key),
|
|
115
|
+
max: options?.max?.map((x) => x.key),
|
|
116
|
+
distinctCount: options?.distinctCount?.map((x) => x.key),
|
|
114
117
|
orderBy: options?.orderBy?.map((x) => ({ ...x, field: x.field?.key })),
|
|
115
118
|
};
|
|
116
119
|
const result = await run('aggregate', Object.keys(body).length > 0 ? body : undefined);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FilterConsumerBridgeToSqlRequest, dbNamesOfWithForceSqlExpression, isDbReadonly, } from '../filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { Filter, customDatabaseFilterToken, } from '../filter/filter-interfaces.js';
|
|
3
3
|
import { remult as defaultRemult } from '../remult-proxy.js';
|
|
4
|
-
import { AggregateCountMember, } from '../remult3/remult3.js';
|
|
4
|
+
import { AggregateCountMember, AggregateOperators, } from '../remult3/remult3.js';
|
|
5
5
|
import { getRepository, isAutoIncrement, } from '../remult3/RepositoryImplementation.js';
|
|
6
6
|
import { Sort } from '../sort.js';
|
|
7
7
|
import { ValueConverters } from '../valueConverters.js';
|
|
@@ -566,28 +566,21 @@ export async function aggregateImpl(options, e, r, orderByNullFirst, limitSyntax
|
|
|
566
566
|
theResult[x.key] = x.valueConverter.fromDb(sqlResult);
|
|
567
567
|
});
|
|
568
568
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
if (x.isServerExpression) {
|
|
583
|
-
}
|
|
584
|
-
else {
|
|
585
|
-
select += ', avg(' + e.$dbNameOf(x) + ') as ' + x.key + '_avg';
|
|
569
|
+
for (const operator of AggregateOperators) {
|
|
570
|
+
const fields = options?.[operator];
|
|
571
|
+
if (fields)
|
|
572
|
+
for (const x of fields) {
|
|
573
|
+
if (x.isServerExpression) {
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
const dbName = await e.$dbNameOf(x);
|
|
577
|
+
select += `, ${aggregateSqlSyntax(operator, dbName)} as ${x.key}_${operator}`;
|
|
578
|
+
}
|
|
579
|
+
processResultRow.push((sqlResult, theResult) => {
|
|
580
|
+
theResult[x.key] = { ...theResult[x.key], [operator]: sqlResult };
|
|
581
|
+
});
|
|
586
582
|
}
|
|
587
|
-
|
|
588
|
-
theResult[x.key] = { ...theResult[x.key], avg: sqlResult };
|
|
589
|
-
});
|
|
590
|
-
}
|
|
583
|
+
}
|
|
591
584
|
select += '\n from ' + e.$entityName;
|
|
592
585
|
if (options?.where) {
|
|
593
586
|
let where = new FilterConsumerBridgeToSqlRequest(r, e);
|
|
@@ -603,21 +596,17 @@ export async function aggregateImpl(options, e, r, orderByNullFirst, limitSyntax
|
|
|
603
596
|
orderBy = ' order by ';
|
|
604
597
|
else
|
|
605
598
|
orderBy += ', ';
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
case 'avg':
|
|
616
|
-
field = 'avg(' + field + ')';
|
|
617
|
-
break;
|
|
618
|
-
}
|
|
619
|
-
orderBy += field;
|
|
599
|
+
let field = x.field && (await e.$dbNameOf(x.field));
|
|
600
|
+
switch (x.operation) {
|
|
601
|
+
case 'count':
|
|
602
|
+
field = x.operation + '(*)';
|
|
603
|
+
break;
|
|
604
|
+
case undefined:
|
|
605
|
+
break;
|
|
606
|
+
default:
|
|
607
|
+
field = aggregateSqlSyntax(x.operation, field);
|
|
620
608
|
}
|
|
609
|
+
orderBy += field;
|
|
621
610
|
if (x.isDescending)
|
|
622
611
|
orderBy += ' desc';
|
|
623
612
|
if (orderByNullFirst) {
|
|
@@ -644,4 +633,9 @@ export async function aggregateImpl(options, e, r, orderByNullFirst, limitSyntax
|
|
|
644
633
|
processResultRow.forEach((x, i) => x(sql[result.getColumnKeyInResultForIndexInSelect(i)], theResult));
|
|
645
634
|
return theResult;
|
|
646
635
|
});
|
|
636
|
+
function aggregateSqlSyntax(operator, dbName) {
|
|
637
|
+
return operator === 'distinctCount'
|
|
638
|
+
? `count (distinct ${dbName})`
|
|
639
|
+
: `${operator}( ${dbName} )`;
|
|
640
|
+
}
|
|
647
641
|
}
|
|
@@ -3,6 +3,7 @@ import { CompoundIdField } from '../CompoundIdField.js';
|
|
|
3
3
|
import { Remult, isBackend, queryConfig } from '../context.js';
|
|
4
4
|
import { Filter } from '../filter/filter-interfaces.js';
|
|
5
5
|
import { Sort } from '../sort.js';
|
|
6
|
+
import { AggregateForApiKey, } from './remult3.js';
|
|
6
7
|
import { assign } from '../../assign.js';
|
|
7
8
|
import { ValueConverters } from '../valueConverters.js';
|
|
8
9
|
import { findOptionsToJson } from '../data-providers/rest-data-provider.js';
|
|
@@ -149,6 +150,9 @@ export class RepositoryImplementation {
|
|
|
149
150
|
groupBy: options?.groupBy?.map(getField),
|
|
150
151
|
sum: options?.sum?.map(getFieldNotInGroupBy),
|
|
151
152
|
avg: options?.avg?.map(getFieldNotInGroupBy),
|
|
153
|
+
min: options?.min?.map(getFieldNotInGroupBy),
|
|
154
|
+
max: options?.max?.map(getFieldNotInGroupBy),
|
|
155
|
+
distinctCount: options?.distinctCount?.map(getFieldNotInGroupBy),
|
|
152
156
|
};
|
|
153
157
|
if (options?.orderBy) {
|
|
154
158
|
dpOptions.orderBy = [];
|
|
@@ -181,6 +185,18 @@ export class RepositoryImplementation {
|
|
|
181
185
|
const result = await this._edp.aggregate(dpOptions);
|
|
182
186
|
if (!options?.groupBy)
|
|
183
187
|
return result[0];
|
|
188
|
+
//@ts-expect-error an internal option
|
|
189
|
+
if (!options?.[AggregateForApiKey]) {
|
|
190
|
+
const loaderOptions = {
|
|
191
|
+
include: {},
|
|
192
|
+
};
|
|
193
|
+
for (const key of options.groupBy) {
|
|
194
|
+
loaderOptions.include[key] = true;
|
|
195
|
+
}
|
|
196
|
+
const loader = new RelationLoader();
|
|
197
|
+
await this.populateRelationsForFields(dpOptions.groupBy, loaderOptions, result, loader);
|
|
198
|
+
await loader.resolveAll();
|
|
199
|
+
}
|
|
184
200
|
return result;
|
|
185
201
|
}
|
|
186
202
|
_idCache = new Map();
|
|
@@ -535,7 +551,12 @@ export class RepositoryImplementation {
|
|
|
535
551
|
}
|
|
536
552
|
}
|
|
537
553
|
let result = await promiseAll(rawRows, async (r) => await this._mapRawDataToResult(r, loadFields));
|
|
538
|
-
|
|
554
|
+
const fields = this.metadata.fields.toArray();
|
|
555
|
+
this.populateRelationsForFields(fields, loadOptions, result, loader);
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
558
|
+
populateRelationsForFields(fields, loadOptions, result, loader) {
|
|
559
|
+
for (const col of fields) {
|
|
539
560
|
let rel = getRelationFieldInfo(col);
|
|
540
561
|
let incl = col.options
|
|
541
562
|
.defaultIncluded;
|
|
@@ -573,7 +594,6 @@ export class RepositoryImplementation {
|
|
|
573
594
|
}
|
|
574
595
|
}
|
|
575
596
|
}
|
|
576
|
-
return result;
|
|
577
597
|
}
|
|
578
598
|
/*@internal */
|
|
579
599
|
_findOptionsBasedOnRelation(rel, field, moreFindOptions, row, otherRepo) {
|
|
@@ -605,8 +625,9 @@ export class RepositoryImplementation {
|
|
|
605
625
|
}
|
|
606
626
|
const relFields = rel.getFields();
|
|
607
627
|
const getFieldValue = (key) => {
|
|
608
|
-
|
|
609
|
-
|
|
628
|
+
const ref = getEntityRef(row, false);
|
|
629
|
+
let val = rel.type === 'reference' && ref
|
|
630
|
+
? ref.fields.find(field.key).getId()
|
|
610
631
|
: row[key];
|
|
611
632
|
if (rel.type === 'toOne' || rel.type === 'reference') {
|
|
612
633
|
if (val === null)
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
export const AggregateCountMember = '$count';
|
|
2
|
+
export const AggregateForApiKey = Symbol.for('AggregateForApiKey');
|
|
3
|
+
export const AggregateOperators = [
|
|
4
|
+
'sum',
|
|
5
|
+
'avg',
|
|
6
|
+
'min',
|
|
7
|
+
'max',
|
|
8
|
+
'distinctCount',
|
|
9
|
+
];
|
|
2
10
|
export const flags = {
|
|
3
11
|
error500RetryCount: 4,
|
|
4
12
|
};
|
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ClassType } from './classType.js';
|
|
|
2
2
|
import type { DataProvider } from './src/data-interfaces.js';
|
|
3
3
|
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider.js';
|
|
4
4
|
export type { ClassType } from './classType.js';
|
|
5
|
-
export { ValidateFieldEvent, MembersOnly, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
|
|
5
|
+
export { ValidateFieldEvent, MembersOnly, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, Repository, AggregateOptions, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
|
|
6
6
|
LifecycleEvent, FieldsRefBase, FieldsRefForEntityBase, RepositoryRelationsForEntityBase, ControllerRefForControllerBase, ControllerRefBase, ControllerRef, EntityRefForEntityBase, IdMetadata, FindFirstOptionsBase, } from './src/remult3/remult3.js';
|
|
7
7
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation.js';
|
|
8
8
|
export { Entity } from './src/remult3/entity.js';
|