remult 3.4.0-next.5 → 3.4.0-next.7
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/SseSubscriptionServer.d.ts +2 -0
- package/SseSubscriptionServer.js +40 -0
- package/esm/SseSubscriptionServer.js +13 -0
- package/esm/remult-mongo.js +18 -12
- package/esm/server/remult-api-server.js +15 -14
- package/esm/src/data-api.js +6 -6
- package/esm/src/data-providers/sql-database.js +165 -106
- package/esm/src/remult3/Fields.js +12 -2
- package/esm/src/remult3/RepositoryImplementation.js +20 -2
- package/index.d.ts +1 -0
- package/internals.d.ts +2 -0
- package/package.json +1 -1
- package/remult-mongo.js +23 -16
- package/server/remult-api-server.d.ts +12 -0
- package/server/remult-api-server.js +19 -39
- package/src/column-interfaces.d.ts +5 -1
- package/src/data-api.d.ts +2 -5
- package/src/data-api.js +80 -69
- package/src/data-providers/sql-database.d.ts +46 -2
- package/src/data-providers/sql-database.js +337 -215
- package/src/live-query/SubscriptionServer.d.ts +4 -0
- package/src/remult3/Fields.js +6 -0
- package/src/remult3/RepositoryImplementation.d.ts +3 -0
- package/src/remult3/RepositoryImplementation.js +19 -2
- package/src/remult3/repository-internals.d.ts +4 -2
package/internals.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export declare const actionInfo: {
|
|
|
14
14
|
};
|
|
15
15
|
export { isOfType } from './src/isOfType.js';
|
|
16
16
|
export type { ClassType } from './classType.js';
|
|
17
|
+
export type { SubscriptionServerRouteApi, SubscriptionServerRouteHandlerArgs, } from './server/remult-api-server.js';
|
|
18
|
+
export type { DataApiResponse } from './src/data-api.js';
|
|
17
19
|
export { flags } from './src/remult3/remult3.js';
|
|
18
20
|
export { SseSubscriptionClient } from './src/live-query/SseSubscriptionClient.js';
|
|
19
21
|
export { DataProviderPromiseWrapper } from './src/data-interfaces.js';
|
package/package.json
CHANGED
package/remult-mongo.js
CHANGED
|
@@ -228,6 +228,8 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
228
228
|
try {
|
|
229
229
|
for (var _b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
230
230
|
var col = _c.value;
|
|
231
|
+
if (col.dbReadOnly || col.isServerExpression)
|
|
232
|
+
continue;
|
|
231
233
|
var val = toDb(col, row[col.key]);
|
|
232
234
|
if (val === null)
|
|
233
235
|
val = NULL;
|
|
@@ -494,7 +496,7 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
494
496
|
f_1 = _c.value;
|
|
495
497
|
if (!f_1.dbReadOnly && !f_1.isServerExpression) {
|
|
496
498
|
if (keys.includes(f_1.key)) {
|
|
497
|
-
newR[f_1
|
|
499
|
+
newR[e.$dbNameOf(f_1)] = toDb(f_1, data[f_1.key]);
|
|
498
500
|
}
|
|
499
501
|
}
|
|
500
502
|
}
|
|
@@ -797,27 +799,32 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
|
|
|
797
799
|
this.add(col, val, '$lt');
|
|
798
800
|
};
|
|
799
801
|
FilterConsumerBridgeToMongo.prototype.containsCaseInsensitive = function (col, val) {
|
|
800
|
-
this.
|
|
802
|
+
this.addRegex(col, val);
|
|
801
803
|
};
|
|
802
804
|
FilterConsumerBridgeToMongo.prototype.notContainsCaseInsensitive = function (col, val) {
|
|
803
|
-
|
|
804
|
-
this.result.push(function () {
|
|
805
|
-
var _a;
|
|
806
|
-
return (_a = {},
|
|
807
|
-
_a[_this.nameProvider.$dbNameOf(col)] = {
|
|
808
|
-
$not: {
|
|
809
|
-
$regex: isNull(val) ? val : toDb(col, val),
|
|
810
|
-
$options: 'i',
|
|
811
|
-
},
|
|
812
|
-
},
|
|
813
|
-
_a);
|
|
814
|
-
});
|
|
805
|
+
this.addRegex(col, val, '', '', true);
|
|
815
806
|
};
|
|
816
807
|
FilterConsumerBridgeToMongo.prototype.startsWithCaseInsensitive = function (col, val) {
|
|
817
|
-
this.
|
|
808
|
+
this.addRegex(col, val, '^');
|
|
818
809
|
};
|
|
819
810
|
FilterConsumerBridgeToMongo.prototype.endsWithCaseInsensitive = function (col, val) {
|
|
820
|
-
this.
|
|
811
|
+
this.addRegex(col, val, '', '$');
|
|
812
|
+
};
|
|
813
|
+
FilterConsumerBridgeToMongo.prototype.addRegex = function (col, val, start, end, negate) {
|
|
814
|
+
var _this = this;
|
|
815
|
+
if (start === void 0) { start = ''; }
|
|
816
|
+
if (end === void 0) { end = ''; }
|
|
817
|
+
if (negate === void 0) { negate = false; }
|
|
818
|
+
this.result.push(function () {
|
|
819
|
+
var _a;
|
|
820
|
+
var regex = {
|
|
821
|
+
$regex: start + toDb(col, val).replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + end,
|
|
822
|
+
$options: 'i',
|
|
823
|
+
};
|
|
824
|
+
return _a = {},
|
|
825
|
+
_a[_this.nameProvider.$dbNameOf(col)] = negate ? { $not: regex } : regex,
|
|
826
|
+
_a;
|
|
827
|
+
});
|
|
821
828
|
};
|
|
822
829
|
FilterConsumerBridgeToMongo.prototype.add = function (col, val, operator, moreOptions) {
|
|
823
830
|
var _this = this;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ClassType } from '../classType.js';
|
|
2
2
|
import type { Allowed, UserInfo } from '../src/context.js';
|
|
3
3
|
import { Remult } from '../src/context.js';
|
|
4
|
+
import type { DataApiResponse } from '../src/data-api.js';
|
|
4
5
|
import type { DataProvider } from '../src/data-interfaces.js';
|
|
5
6
|
import type { LiveQueryStorage, SubscriptionServer } from '../src/live-query/SubscriptionServer.js';
|
|
6
7
|
import { IdEntity } from '../src/remult3/IdEntity.js';
|
|
@@ -167,6 +168,17 @@ export interface GenericResponse {
|
|
|
167
168
|
status(statusCode: number): GenericResponse;
|
|
168
169
|
end(): void;
|
|
169
170
|
}
|
|
171
|
+
export interface SubscriptionServerRouteApi {
|
|
172
|
+
rootPath: string;
|
|
173
|
+
addRoute(relativePath: string, method: 'get' | 'post', handler: (args: SubscriptionServerRouteHandlerArgs) => Promise<void>): void;
|
|
174
|
+
}
|
|
175
|
+
export interface SubscriptionServerRouteHandlerArgs {
|
|
176
|
+
remult: Remult;
|
|
177
|
+
res: DataApiResponse;
|
|
178
|
+
req: GenericRequestInfo;
|
|
179
|
+
origRes: GenericResponse;
|
|
180
|
+
getBody(): Promise<any>;
|
|
181
|
+
}
|
|
170
182
|
export interface queuedJobInfo {
|
|
171
183
|
info: queuedJobInfoResponse;
|
|
172
184
|
userId: string;
|
|
@@ -441,45 +441,25 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
441
441
|
r.route(this.options.rootPath + '/me').get(this.process(function (remult, req, res) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a; return tslib_1.__generator(this, function (_b) {
|
|
442
442
|
return [2 /*return*/, res.success((_a = remult.user) !== null && _a !== void 0 ? _a : null)];
|
|
443
443
|
}); }); }));
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
return [2 /*return*/];
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
}); }));
|
|
467
|
-
r.route(streamPath + '/unsubscribe').post(this.process(function (remult, req, res, reqInfo, origRes, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
468
|
-
var _a, _b;
|
|
469
|
-
return tslib_1.__generator(this, function (_c) {
|
|
470
|
-
switch (_c.label) {
|
|
471
|
-
case 0:
|
|
472
|
-
;
|
|
473
|
-
_b = (_a = remult.subscriptionServer).subscribeToChannel;
|
|
474
|
-
return [4 /*yield*/, this.coreOptions.getRequestBody(origReq)];
|
|
475
|
-
case 1:
|
|
476
|
-
_b.apply(_a, [_c.sent(), res,
|
|
477
|
-
remult,
|
|
478
|
-
true]);
|
|
479
|
-
return [2 /*return*/];
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
}); }));
|
|
444
|
+
var subscriptionServer = this.options.subscriptionServer;
|
|
445
|
+
if (subscriptionServer === null || subscriptionServer === void 0 ? void 0 : subscriptionServer.initApiServer) {
|
|
446
|
+
subscriptionServer.initApiServer({
|
|
447
|
+
rootPath: this.options.rootPath,
|
|
448
|
+
addRoute: function (relativePath, method, handler) {
|
|
449
|
+
r.route(_this.options.rootPath + relativePath)[method](_this.process(function (remult, _, res, req, origRes, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
450
|
+
var _this = this;
|
|
451
|
+
return tslib_1.__generator(this, function (_a) {
|
|
452
|
+
return [2 /*return*/, handler({
|
|
453
|
+
remult: remult,
|
|
454
|
+
res: res,
|
|
455
|
+
req: req,
|
|
456
|
+
origRes: origRes,
|
|
457
|
+
getBody: function () { return _this.coreOptions.getRequestBody(origReq); },
|
|
458
|
+
})];
|
|
459
|
+
});
|
|
460
|
+
}); }));
|
|
461
|
+
},
|
|
462
|
+
});
|
|
483
463
|
}
|
|
484
464
|
r.route(this.options.rootPath + '/' + SubscriptionChannel_js_1.liveQueryKeepAliveRoute).post(this.process(function (remult, req, res, reqInfo, origRes, origReq) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
485
465
|
var body, queryIds, result;
|
|
@@ -58,7 +58,11 @@ export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
|
58
58
|
* @type {AllowedForInstance<entityType>}
|
|
59
59
|
*/
|
|
60
60
|
allowApiUpdate?: AllowedForInstance<entityType>;
|
|
61
|
-
/** An arrow function that'll be used to perform validations on it
|
|
61
|
+
/** An arrow function that'll be used to perform validations on it.
|
|
62
|
+
*
|
|
63
|
+
* `validate` from several option objects is additive: each one is appended.
|
|
64
|
+
* A function option is the only way to replace validators already set, including a built-in one:
|
|
65
|
+
* `(options) => { options.validate = ... }`.
|
|
62
66
|
* @example
|
|
63
67
|
* @Fields.string({
|
|
64
68
|
* validate: Validators.required
|
package/src/data-api.d.ts
CHANGED
|
@@ -5,13 +5,10 @@ export declare class DataApi<T = unknown> {
|
|
|
5
5
|
private repository;
|
|
6
6
|
private remult;
|
|
7
7
|
constructor(repository: Repository<T>, remult: Remult);
|
|
8
|
-
httpGet(res: DataApiResponse, req: DataApiRequest, serializeContext: () => Promise<any>):
|
|
8
|
+
httpGet(res: DataApiResponse, req: DataApiRequest, serializeContext: () => Promise<any>): Promise<void>;
|
|
9
9
|
httpPost(res: DataApiResponse, req: DataApiRequest, body: any, serializeContext: () => Promise<any>): Promise<void>;
|
|
10
10
|
upsertMany(response: DataApiResponse, request: DataApiRequest, body: any): Promise<void>;
|
|
11
|
-
query(response: DataApiResponse, request: DataApiRequest, body: any): Promise<
|
|
12
|
-
items: any[];
|
|
13
|
-
aggregates: import("./remult3/remult3.js").GroupByResult<T, any[], any[], any[], any[], any[], any[]>;
|
|
14
|
-
} | undefined>;
|
|
11
|
+
query(response: DataApiResponse, request: DataApiRequest, body: any): Promise<void>;
|
|
15
12
|
static defaultGetLimit: number;
|
|
16
13
|
get(response: DataApiResponse, id: any): Promise<void>;
|
|
17
14
|
count(response: DataApiResponse, request: DataApiRequest, body?: any): Promise<void>;
|
package/src/data-api.js
CHANGED
|
@@ -17,25 +17,39 @@ var DataApi = /** @class */ (function () {
|
|
|
17
17
|
this.remult = remult;
|
|
18
18
|
}
|
|
19
19
|
DataApi.prototype.httpGet = function (res, req, serializeContext) {
|
|
20
|
-
|
|
21
|
-
var action
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
20
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
21
|
+
var action, _a, _b, _c, err_1;
|
|
22
|
+
return tslib_1.__generator(this, function (_d) {
|
|
23
|
+
switch (_d.label) {
|
|
24
|
+
case 0:
|
|
25
|
+
_d.trys.push([0, 5, , 6]);
|
|
26
|
+
action = req === null || req === void 0 ? void 0 : req.get('__action');
|
|
27
|
+
if (action === null || action === void 0 ? void 0 : action.startsWith(rest_data_provider_js_1.liveQueryAction))
|
|
28
|
+
return [2 /*return*/, this.liveQuery(res, req, undefined, serializeContext, action.substring(rest_data_provider_js_1.liveQueryAction.length))];
|
|
29
|
+
_a = action;
|
|
30
|
+
switch (_a) {
|
|
31
|
+
case 'get': return [3 /*break*/, 1];
|
|
32
|
+
case 'count': return [3 /*break*/, 1];
|
|
33
|
+
case 'groupBy': return [3 /*break*/, 2];
|
|
34
|
+
}
|
|
35
|
+
return [3 /*break*/, 4];
|
|
36
|
+
case 1: return [2 /*return*/, this.count(res, req, undefined)];
|
|
37
|
+
case 2:
|
|
38
|
+
_c = (_b = res).success;
|
|
39
|
+
return [4 /*yield*/, this.groupBy(req, undefined)];
|
|
40
|
+
case 3: return [2 /*return*/, _c.apply(_b, [_d.sent()])];
|
|
41
|
+
case 4: return [2 /*return*/, this.getArray(res, req, undefined)];
|
|
42
|
+
case 5:
|
|
43
|
+
err_1 = _d.sent();
|
|
44
|
+
if (err_1.isForbiddenError)
|
|
45
|
+
res.forbidden(err_1.message);
|
|
46
|
+
else
|
|
47
|
+
res.error(err_1, this.repository.metadata);
|
|
48
|
+
return [3 /*break*/, 6];
|
|
49
|
+
case 6: return [2 /*return*/];
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
39
53
|
};
|
|
40
54
|
DataApi.prototype.httpPost = function (res, req, body, serializeContext) {
|
|
41
55
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
@@ -47,14 +61,14 @@ var DataApi = /** @class */ (function () {
|
|
|
47
61
|
};
|
|
48
62
|
}
|
|
49
63
|
}
|
|
50
|
-
var action, _a, _b, _c, _d, _e,
|
|
51
|
-
return tslib_1.__generator(this, function (
|
|
52
|
-
switch (
|
|
64
|
+
var action, _a, _b, _c, _d, _e, err_2;
|
|
65
|
+
return tslib_1.__generator(this, function (_f) {
|
|
66
|
+
switch (_f.label) {
|
|
53
67
|
case 0:
|
|
54
68
|
action = req === null || req === void 0 ? void 0 : req.get('__action');
|
|
55
|
-
|
|
69
|
+
_f.label = 1;
|
|
56
70
|
case 1:
|
|
57
|
-
|
|
71
|
+
_f.trys.push([1, 15, , 16]);
|
|
58
72
|
if (action === null || action === void 0 ? void 0 : action.startsWith(rest_data_provider_js_1.liveQueryAction)) {
|
|
59
73
|
validateWhereInBody();
|
|
60
74
|
return [2 /*return*/, this.liveQuery(res, req, body, serializeContext, action.substring(rest_data_provider_js_1.liveQueryAction.length))];
|
|
@@ -70,7 +84,7 @@ var DataApi = /** @class */ (function () {
|
|
|
70
84
|
case 'endLiveQuery': return [3 /*break*/, 9];
|
|
71
85
|
case 'query': return [3 /*break*/, 11];
|
|
72
86
|
}
|
|
73
|
-
return [3 /*break*/,
|
|
87
|
+
return [3 /*break*/, 12];
|
|
74
88
|
case 2:
|
|
75
89
|
validateWhereInBody();
|
|
76
90
|
return [2 /*return*/, this.getArray(res, req, body)];
|
|
@@ -80,7 +94,7 @@ var DataApi = /** @class */ (function () {
|
|
|
80
94
|
case 4:
|
|
81
95
|
_c = (_b = res).success;
|
|
82
96
|
return [4 /*yield*/, this.groupBy(req, body)];
|
|
83
|
-
case 5: return [2 /*return*/, _c.apply(_b, [
|
|
97
|
+
case 5: return [2 /*return*/, _c.apply(_b, [_f.sent()])];
|
|
84
98
|
case 6:
|
|
85
99
|
validateWhereInBody();
|
|
86
100
|
return [2 /*return*/, this.deleteMany(res, req, body)];
|
|
@@ -90,26 +104,23 @@ var DataApi = /** @class */ (function () {
|
|
|
90
104
|
case 8: return [2 /*return*/, this.upsertMany(res, req, body)];
|
|
91
105
|
case 9: return [4 /*yield*/, this.remult.liveQueryStorage.remove(body.id)];
|
|
92
106
|
case 10:
|
|
93
|
-
|
|
107
|
+
_f.sent();
|
|
94
108
|
res.success('ok');
|
|
95
109
|
return [2 /*return*/];
|
|
96
|
-
case 11:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
case 12: return [2 /*return*/, _e.apply(_d, [_h.sent()])];
|
|
100
|
-
case 13:
|
|
101
|
-
_g = (_f = res).created;
|
|
110
|
+
case 11: return [2 /*return*/, this.query(res, req, body)];
|
|
111
|
+
case 12:
|
|
112
|
+
_e = (_d = res).created;
|
|
102
113
|
return [4 /*yield*/, this.post(body, req)];
|
|
103
|
-
case
|
|
104
|
-
case
|
|
105
|
-
case
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
res.forbidden(
|
|
114
|
+
case 13: return [2 /*return*/, _e.apply(_d, [_f.sent()])];
|
|
115
|
+
case 14: return [3 /*break*/, 16];
|
|
116
|
+
case 15:
|
|
117
|
+
err_2 = _f.sent();
|
|
118
|
+
if (err_2.isForbiddenError)
|
|
119
|
+
res.forbidden(err_2.message);
|
|
109
120
|
else
|
|
110
|
-
res.error(
|
|
111
|
-
return [3 /*break*/,
|
|
112
|
-
case
|
|
121
|
+
res.error(err_2, this.repository.metadata);
|
|
122
|
+
return [3 /*break*/, 16];
|
|
123
|
+
case 16: return [2 /*return*/];
|
|
113
124
|
}
|
|
114
125
|
});
|
|
115
126
|
});
|
|
@@ -187,7 +198,7 @@ var DataApi = /** @class */ (function () {
|
|
|
187
198
|
};
|
|
188
199
|
DataApi.prototype.query = function (response, request, body) {
|
|
189
200
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
190
|
-
var aggregate, rest, aggregateRequest, _a, r, _b, aggregates,
|
|
201
|
+
var aggregate, rest, aggregateRequest, _a, r, _b, aggregates, err_3;
|
|
191
202
|
return tslib_1.__generator(this, function (_c) {
|
|
192
203
|
switch (_c.label) {
|
|
193
204
|
case 0:
|
|
@@ -215,16 +226,16 @@ var DataApi = /** @class */ (function () {
|
|
|
215
226
|
])];
|
|
216
227
|
case 2:
|
|
217
228
|
_a = tslib_1.__read.apply(void 0, [_c.sent(), 2]), r = _a[0].r, _b = tslib_1.__read(_a[1], 1), aggregates = _b[0];
|
|
218
|
-
return [2 /*return*/, {
|
|
229
|
+
return [2 /*return*/, response.success({
|
|
219
230
|
items: r,
|
|
220
231
|
aggregates: aggregates,
|
|
221
|
-
}];
|
|
232
|
+
})];
|
|
222
233
|
case 3:
|
|
223
|
-
|
|
224
|
-
if (
|
|
234
|
+
err_3 = _c.sent();
|
|
235
|
+
if (err_3.isForbiddenError)
|
|
225
236
|
response.forbidden();
|
|
226
237
|
else
|
|
227
|
-
response.error(
|
|
238
|
+
response.error(err_3, this.repository.metadata);
|
|
228
239
|
return [3 /*break*/, 4];
|
|
229
240
|
case 4: return [2 /*return*/];
|
|
230
241
|
}
|
|
@@ -253,7 +264,7 @@ var DataApi = /** @class */ (function () {
|
|
|
253
264
|
};
|
|
254
265
|
DataApi.prototype.count = function (response, request, body) {
|
|
255
266
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
256
|
-
var _a, _b, _c, _d,
|
|
267
|
+
var _a, _b, _c, _d, err_4;
|
|
257
268
|
var _e;
|
|
258
269
|
return tslib_1.__generator(this, function (_f) {
|
|
259
270
|
switch (_f.label) {
|
|
@@ -275,8 +286,8 @@ var DataApi = /** @class */ (function () {
|
|
|
275
286
|
_e)]);
|
|
276
287
|
return [3 /*break*/, 5];
|
|
277
288
|
case 4:
|
|
278
|
-
|
|
279
|
-
response.error(
|
|
289
|
+
err_4 = _f.sent();
|
|
290
|
+
response.error(err_4, this.repository.metadata);
|
|
280
291
|
return [3 /*break*/, 5];
|
|
281
292
|
case 5: return [2 /*return*/];
|
|
282
293
|
}
|
|
@@ -285,7 +296,7 @@ var DataApi = /** @class */ (function () {
|
|
|
285
296
|
};
|
|
286
297
|
DataApi.prototype.deleteMany = function (response, request, body) {
|
|
287
298
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
288
|
-
var deleted_1, where_1,
|
|
299
|
+
var deleted_1, where_1, err_5;
|
|
289
300
|
var _this = this;
|
|
290
301
|
return tslib_1.__generator(this, function (_a) {
|
|
291
302
|
switch (_a.label) {
|
|
@@ -347,8 +358,8 @@ var DataApi = /** @class */ (function () {
|
|
|
347
358
|
}); })];
|
|
348
359
|
case 2: return [2 /*return*/, _a.sent()];
|
|
349
360
|
case 3:
|
|
350
|
-
|
|
351
|
-
response.error(
|
|
361
|
+
err_5 = _a.sent();
|
|
362
|
+
response.error(err_5, this.repository.metadata);
|
|
352
363
|
return [3 /*break*/, 4];
|
|
353
364
|
case 4: return [2 /*return*/];
|
|
354
365
|
}
|
|
@@ -635,7 +646,7 @@ var DataApi = /** @class */ (function () {
|
|
|
635
646
|
};
|
|
636
647
|
DataApi.prototype.getArray = function (response, request, body) {
|
|
637
648
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
638
|
-
var r,
|
|
649
|
+
var r, err_6;
|
|
639
650
|
return tslib_1.__generator(this, function (_a) {
|
|
640
651
|
switch (_a.label) {
|
|
641
652
|
case 0:
|
|
@@ -652,11 +663,11 @@ var DataApi = /** @class */ (function () {
|
|
|
652
663
|
response.success(r);
|
|
653
664
|
return [3 /*break*/, 4];
|
|
654
665
|
case 3:
|
|
655
|
-
|
|
656
|
-
if (
|
|
657
|
-
response.forbidden(
|
|
666
|
+
err_6 = _a.sent();
|
|
667
|
+
if (err_6.isForbiddenError)
|
|
668
|
+
response.forbidden(err_6.message);
|
|
658
669
|
else
|
|
659
|
-
response.error(
|
|
670
|
+
response.error(err_6, this.repository.metadata);
|
|
660
671
|
return [3 /*break*/, 4];
|
|
661
672
|
case 4: return [2 /*return*/];
|
|
662
673
|
}
|
|
@@ -665,7 +676,7 @@ var DataApi = /** @class */ (function () {
|
|
|
665
676
|
};
|
|
666
677
|
DataApi.prototype.liveQuery = function (response, request, body, serializeContext, queryChannel) {
|
|
667
678
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
668
|
-
var r, data,
|
|
679
|
+
var r, data, err_7;
|
|
669
680
|
var _a;
|
|
670
681
|
var _this = this;
|
|
671
682
|
return tslib_1.__generator(this, function (_b) {
|
|
@@ -699,11 +710,11 @@ var DataApi = /** @class */ (function () {
|
|
|
699
710
|
response.success(r.r);
|
|
700
711
|
return [3 /*break*/, 6];
|
|
701
712
|
case 5:
|
|
702
|
-
|
|
703
|
-
if (
|
|
713
|
+
err_7 = _b.sent();
|
|
714
|
+
if (err_7.isForbiddenError)
|
|
704
715
|
response.forbidden();
|
|
705
716
|
else
|
|
706
|
-
response.error(
|
|
717
|
+
response.error(err_7, this.repository.metadata);
|
|
707
718
|
return [3 /*break*/, 6];
|
|
708
719
|
case 6: return [2 /*return*/];
|
|
709
720
|
}
|
|
@@ -766,7 +777,7 @@ var DataApi = /** @class */ (function () {
|
|
|
766
777
|
};
|
|
767
778
|
DataApi.prototype.doOnId = function (response, id, what) {
|
|
768
779
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
769
|
-
var where, _a, _b,
|
|
780
|
+
var where, _a, _b, err_8;
|
|
770
781
|
var _this = this;
|
|
771
782
|
return tslib_1.__generator(this, function (_c) {
|
|
772
783
|
switch (_c.label) {
|
|
@@ -816,8 +827,8 @@ var DataApi = /** @class */ (function () {
|
|
|
816
827
|
_c.sent();
|
|
817
828
|
return [3 /*break*/, 6];
|
|
818
829
|
case 5:
|
|
819
|
-
|
|
820
|
-
response.error(
|
|
830
|
+
err_8 = _c.sent();
|
|
831
|
+
response.error(err_8, this.repository.metadata);
|
|
821
832
|
return [3 /*break*/, 6];
|
|
822
833
|
case 6: return [2 /*return*/];
|
|
823
834
|
}
|
|
@@ -841,7 +852,7 @@ var DataApi = /** @class */ (function () {
|
|
|
841
852
|
};
|
|
842
853
|
DataApi.prototype.updateManyImplementation = function (response, request, body) {
|
|
843
854
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
844
|
-
var where_2,
|
|
855
|
+
var where_2, err_9;
|
|
845
856
|
var _this = this;
|
|
846
857
|
return tslib_1.__generator(this, function (_a) {
|
|
847
858
|
switch (_a.label) {
|
|
@@ -905,8 +916,8 @@ var DataApi = /** @class */ (function () {
|
|
|
905
916
|
}); })];
|
|
906
917
|
case 2: return [2 /*return*/, _a.sent()];
|
|
907
918
|
case 3:
|
|
908
|
-
|
|
909
|
-
response.error(
|
|
919
|
+
err_9 = _a.sent();
|
|
920
|
+
response.error(err_9, this.repository.metadata);
|
|
910
921
|
return [3 /*break*/, 4];
|
|
911
922
|
case 4: return [2 /*return*/];
|
|
912
923
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { DataProvider, EntityDataProvider, EntityDataProviderGroupByOptions } from '../data-interfaces.js';
|
|
1
|
+
import type { DataProvider, EntityDataProvider, EntityDataProviderGroupByOptions, EntityDataProviderFindOptions } from '../data-interfaces.js';
|
|
2
2
|
import type { HasWrapIdentifier, SqlCommand, SqlCommandFactory, SqlCommandWithParameters, SqlImplementation, SqlResult } from '../sql-command.js';
|
|
3
|
+
import type { FieldMetadata } from '../column-interfaces.js';
|
|
3
4
|
import type { CustomSqlFilterBuilderFunction, EntityDbNamesBase } from '../filter/filter-consumer-bridge-to-sql-request.js';
|
|
4
|
-
import { type EntityFilter, type EntityMetadata } from '../remult3/remult3.js';
|
|
5
|
+
import { type EntityFilter, type EntityMetadata, type FindOptions, type GroupByOptions, type GroupByResult, type MembersOnly, type NumericKeys } from '../remult3/remult3.js';
|
|
5
6
|
import type { RepositoryOverloads } from '../remult3/RepositoryImplementation.js';
|
|
6
7
|
import type { CanBuildMigrations, MigrationBuilder, MigrationCode } from '../../migrations/migration-types.js';
|
|
7
8
|
/**
|
|
@@ -67,6 +68,24 @@ export declare class SqlDatabase implements DataProvider, HasWrapIdentifier, Can
|
|
|
67
68
|
|
|
68
69
|
*/
|
|
69
70
|
static filterToRaw<entityType>(repo: RepositoryOverloads<entityType>, condition: EntityFilter<entityType>, sqlCommand?: SqlCommandWithParameters, dbNames?: EntityDbNamesBase, wrapIdentifier?: (name: string) => string): Promise<string>;
|
|
71
|
+
/**
|
|
72
|
+
* Builds the select that `repo.groupBy` would run, without running it - for a statement remult cannot run on its own, such as one `UNION ALL` over several databases.
|
|
73
|
+
* @returns `sql`, and `toResult`, which maps a result row (read by column alias) to the shape `groupBy` returns.
|
|
74
|
+
* @see [Building a select with remult](https://remult.dev/docs/running-sql-on-the-server#building-a-select-with-remult)
|
|
75
|
+
*/
|
|
76
|
+
static groupByToRaw<entityType, groupByFields extends (keyof MembersOnly<entityType>)[] | undefined = undefined, sumFields extends NumericKeys<entityType>[] | undefined = undefined, averageFields extends NumericKeys<entityType>[] | undefined = undefined, minFields extends (keyof MembersOnly<entityType>)[] | undefined = undefined, maxFields extends (keyof MembersOnly<entityType>)[] | undefined = undefined, distinctCountFields extends (keyof MembersOnly<entityType>)[] | undefined = undefined>(repo: RepositoryOverloads<entityType>, options: GroupByOptions<entityType, groupByFields extends undefined ? never : groupByFields, sumFields extends undefined ? never : sumFields, averageFields extends undefined ? never : averageFields, minFields extends undefined ? never : minFields, maxFields extends undefined ? never : maxFields, distinctCountFields extends undefined ? never : distinctCountFields>, sql?: RawSelectOptions): Promise<{
|
|
77
|
+
sql: string;
|
|
78
|
+
toResult: (row: Record<string, any>) => GroupByResult<entityType, groupByFields extends undefined ? never : groupByFields, sumFields extends undefined ? never : sumFields, averageFields extends undefined ? never : averageFields, minFields extends undefined ? never : minFields, maxFields extends undefined ? never : maxFields, distinctCountFields extends undefined ? never : distinctCountFields>;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Builds the select that `repo.find` would run, without running it. Columns are aliased by field key; no default order is added, so the sql can be a branch of a `UNION`.
|
|
82
|
+
* @returns `sql`, and `toResult`, which maps a result row (read by column alias) to the fields' values.
|
|
83
|
+
* @see [Building a select with remult](https://remult.dev/docs/running-sql-on-the-server#building-a-select-with-remult)
|
|
84
|
+
*/
|
|
85
|
+
static selectToRaw<entityType>(repo: RepositoryOverloads<entityType>, options?: FindOptions<entityType>, sql?: RawSelectOptions): Promise<{
|
|
86
|
+
sql: string;
|
|
87
|
+
toResult: (row: Record<string, any>) => Partial<MembersOnly<entityType>>;
|
|
88
|
+
}>;
|
|
70
89
|
/**
|
|
71
90
|
* `false` _(default)_ - No logging
|
|
72
91
|
*
|
|
@@ -94,5 +113,30 @@ export declare class SqlDatabase implements DataProvider, HasWrapIdentifier, Can
|
|
|
94
113
|
private createdEntities;
|
|
95
114
|
end: () => Promise<void>;
|
|
96
115
|
}
|
|
116
|
+
/** Where a raw select is built: the command that collects its parameters, the names it addresses the table and columns by, and the dialect's paging syntax. */
|
|
117
|
+
export interface RawSelectOptions {
|
|
118
|
+
sqlCommand?: SqlCommandWithParameters;
|
|
119
|
+
/** Replace `$entityName` here to address another database or an alias: `{ ...await dbNamesOf(Task), $entityName: '[other].dbo.tasks' }`. */
|
|
120
|
+
dbNames?: EntityDbNamesBase;
|
|
121
|
+
wrapIdentifier?: (name: string) => string;
|
|
122
|
+
/** Required only with `limit`: `(limit, offset) => 'limit 10 offset 20'`. */
|
|
123
|
+
limitSyntax?: (limit: number, offset: number) => string;
|
|
124
|
+
}
|
|
97
125
|
export declare function getRowAfterUpdate<entityType>(meta: EntityMetadata<entityType>, dataProvider: EntityDataProvider, data: any, id: any, operation: string): any;
|
|
126
|
+
/** The select that `find` runs, and the mapping of one result row to field values. With `aliasColumns`, every column is aliased through `wrapIdentifier`, so a row can be read by alias as well as by position. */
|
|
127
|
+
export declare function buildFindSql(entity: EntityMetadata, options: EntityDataProviderFindOptions | undefined, e: EntityDbNamesBase, r: SqlCommandWithParameters, orderByNullsFirst: boolean | undefined, limitSyntax: (limit: number, offset: number) => string, { aliasColumns, defaultOrderBy }?: {
|
|
128
|
+
aliasColumns?: boolean | undefined;
|
|
129
|
+
defaultOrderBy?: boolean | undefined;
|
|
130
|
+
}): Promise<{
|
|
131
|
+
select: string;
|
|
132
|
+
colKeys: FieldMetadata<unknown, unknown>[];
|
|
133
|
+
/** `valueAt` reads one column of a result row, by its position in the select or by its alias (the field key). */
|
|
134
|
+
toResult(valueAt: (indexInSelect: number, alias: string) => any): any;
|
|
135
|
+
}>;
|
|
98
136
|
export declare function groupByImpl(options: EntityDataProviderGroupByOptions | undefined, e: EntityDbNamesBase, r: SqlCommand, orderByNullFirst: boolean | undefined, limitSyntax: (limit: number, offset: number) => string): Promise<any[]>;
|
|
137
|
+
/** The select that `groupBy` runs, and the mapping of one result row back to a `GroupByResult`. Every column is aliased through `wrapIdentifier`, so a row can be read by alias as well as by position. */
|
|
138
|
+
export declare function buildGroupBySql(options: EntityDataProviderGroupByOptions | undefined, e: EntityDbNamesBase, r: SqlCommandWithParameters, orderByNullFirst: boolean | undefined, limitSyntax: (limit: number, offset: number) => string): Promise<{
|
|
139
|
+
select: string;
|
|
140
|
+
/** `valueAt` reads one column of a result row, by its position in the select or by its alias. */
|
|
141
|
+
toResult(valueAt: (indexInSelect: number, alias: string) => any): any;
|
|
142
|
+
}>;
|