remult 0.13.19 → 0.13.22
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/graphql.js +3 -3
- package/package.json +2 -2
- package/readme.md +32 -19
- package/server/expressBridge.d.ts +4 -4
- package/server/expressBridge.js +2 -0
- package/src/column-interfaces.d.ts +51 -10
- package/src/column.d.ts +0 -1
- package/src/column.js +0 -12
- package/src/context.d.ts +57 -14
- package/src/context.js +103 -75
- package/src/data-providers/rest-data-provider.d.ts +3 -2
- package/src/data-providers/rest-data-provider.js +56 -51
- package/src/data-providers/sql-database.js +2 -6
- package/src/entity.d.ts +31 -28
- package/src/remult3/RepositoryImplementation.d.ts +41 -4
- package/src/remult3/RepositoryImplementation.js +208 -138
- package/src/remult3/remult3.d.ts +100 -34
- package/src/server-action.d.ts +5 -1
- package/src/server-action.js +1 -0
- package/src/shared-tests/db-tests.db-tests.js +52 -1
- package/src/shared-tests/entityWithValidations.js +5 -19
- package/src/tests/TestDataApiResponse.js +6 -6
- package/src/tests/d.d.ts +0 -1
- package/src/tests/d.js +0 -16
- package/src/tests/testHelper.spec.js +2 -2
- package/src/tests/testModel/models.d.ts +0 -1
- package/src/tests/testModel/models.js +0 -3
package/src/context.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EventSource = exports.queryConfig = exports.Allow = exports.setControllerSettings = exports.MethodHelper = exports.ClassHelper = exports.classHelpers = exports.allEntities = exports.Remult = exports.isBackend = exports.processHttpException = exports.toPromise = void 0;
|
|
3
|
+
exports.EventSource = exports.queryConfig = exports.Allow = exports.setControllerSettings = exports.MethodHelper = exports.ClassHelper = exports.classHelpers = exports.allEntities = exports.Remult = exports.isBackend = exports.processHttpException = exports.toPromise = exports.retry = exports.HttpProviderBridgeToRestDataProviderHttpProvider = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var server_action_1 = require("./server-action");
|
|
6
6
|
var rest_data_provider_1 = require("./data-providers/rest-data-provider");
|
|
@@ -39,29 +39,30 @@ var HttpProviderBridgeToRestDataProviderHttpProvider = /** @class */ (function (
|
|
|
39
39
|
};
|
|
40
40
|
return HttpProviderBridgeToRestDataProviderHttpProvider;
|
|
41
41
|
}());
|
|
42
|
+
exports.HttpProviderBridgeToRestDataProviderHttpProvider = HttpProviderBridgeToRestDataProviderHttpProvider;
|
|
42
43
|
function retry(what) {
|
|
43
|
-
var _a, _b;
|
|
44
|
+
var _a, _b, _c;
|
|
44
45
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
45
46
|
var err_1;
|
|
46
|
-
return tslib_1.__generator(this, function (
|
|
47
|
-
switch (
|
|
47
|
+
return tslib_1.__generator(this, function (_d) {
|
|
48
|
+
switch (_d.label) {
|
|
48
49
|
case 0:
|
|
49
50
|
if (!true) return [3 /*break*/, 7];
|
|
50
|
-
|
|
51
|
+
_d.label = 1;
|
|
51
52
|
case 1:
|
|
52
|
-
|
|
53
|
+
_d.trys.push([1, 3, , 6]);
|
|
53
54
|
return [4 /*yield*/, what()];
|
|
54
|
-
case 2: return [2 /*return*/,
|
|
55
|
+
case 2: return [2 /*return*/, _d.sent()];
|
|
55
56
|
case 3:
|
|
56
|
-
err_1 =
|
|
57
|
-
if (!(((_a = err_1.message) === null || _a === void 0 ? void 0 : _a.startsWith("Error occurred while trying to proxy")) || ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.startsWith("Error occured while trying to proxy")))) return [3 /*break*/, 5];
|
|
57
|
+
err_1 = _d.sent();
|
|
58
|
+
if (!(((_a = err_1.message) === null || _a === void 0 ? void 0 : _a.startsWith("Error occurred while trying to proxy")) || ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.startsWith("Error occured while trying to proxy")) || ((_c = err_1.message) === null || _c === void 0 ? void 0 : _c.startsWith("Gateway Timeout")))) return [3 /*break*/, 5];
|
|
58
59
|
return [4 /*yield*/, new Promise(function (res, req) {
|
|
59
60
|
setTimeout(function () {
|
|
60
61
|
res({});
|
|
61
62
|
}, 250);
|
|
62
63
|
})];
|
|
63
64
|
case 4:
|
|
64
|
-
|
|
65
|
+
_d.sent();
|
|
65
66
|
return [3 /*break*/, 0];
|
|
66
67
|
case 5: throw err_1;
|
|
67
68
|
case 6: return [3 /*break*/, 0];
|
|
@@ -70,6 +71,7 @@ function retry(what) {
|
|
|
70
71
|
});
|
|
71
72
|
});
|
|
72
73
|
}
|
|
74
|
+
exports.retry = retry;
|
|
73
75
|
function toPromise(p) {
|
|
74
76
|
var _this = this;
|
|
75
77
|
var r;
|
|
@@ -139,6 +141,12 @@ function isBackend() {
|
|
|
139
141
|
}
|
|
140
142
|
exports.isBackend = isBackend;
|
|
141
143
|
var Remult = /** @class */ (function () {
|
|
144
|
+
/** Creates a new instance of the `remult` object.
|
|
145
|
+
*
|
|
146
|
+
* Can receive either an HttpProvider or a DataProvider as a parameter - which will be used to fetch data from.
|
|
147
|
+
*
|
|
148
|
+
* If no provider is specified, `fetch` will be used as an http provider
|
|
149
|
+
*/
|
|
142
150
|
function Remult(provider) {
|
|
143
151
|
this._userChangeEvent = new EventSource();
|
|
144
152
|
this.repCache = new Map();
|
|
@@ -158,16 +166,26 @@ var Remult = /** @class */ (function () {
|
|
|
158
166
|
if (!server_action_1.Action.provider)
|
|
159
167
|
server_action_1.Action.provider = dataProvider;
|
|
160
168
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Remult.prototype.
|
|
168
|
-
|
|
169
|
+
/**Return's a `Repository` of the specific entity type
|
|
170
|
+
* @example
|
|
171
|
+
* const taskRepo = remult.repo(Task);
|
|
172
|
+
* @see [Repository](https://remult.dev/docs/ref_repository.html)
|
|
173
|
+
*
|
|
174
|
+
*/
|
|
175
|
+
Remult.prototype.repo = function (entity, dataProvider) {
|
|
176
|
+
if (dataProvider === undefined)
|
|
177
|
+
dataProvider = this._dataSource;
|
|
178
|
+
var dpCache = this.repCache.get(dataProvider);
|
|
179
|
+
if (!dpCache)
|
|
180
|
+
this.repCache.set(dataProvider, dpCache = new Map());
|
|
181
|
+
var r = dpCache.get(entity);
|
|
182
|
+
if (!r) {
|
|
183
|
+
dpCache.set(entity, r = new RepositoryImplementation_1.RepositoryImplementation(entity, this, dataProvider));
|
|
184
|
+
}
|
|
185
|
+
return r;
|
|
169
186
|
};
|
|
170
187
|
Object.defineProperty(Remult.prototype, "user", {
|
|
188
|
+
/** Returns the current user's info */
|
|
171
189
|
get: function () {
|
|
172
190
|
if (this._user === undefined) {
|
|
173
191
|
return {
|
|
@@ -181,70 +199,44 @@ var Remult = /** @class */ (function () {
|
|
|
181
199
|
enumerable: false,
|
|
182
200
|
configurable: true
|
|
183
201
|
});
|
|
184
|
-
|
|
185
|
-
get: function () {
|
|
186
|
-
return this._userChangeEvent.dispatcher;
|
|
187
|
-
},
|
|
188
|
-
enumerable: false,
|
|
189
|
-
configurable: true
|
|
190
|
-
});
|
|
202
|
+
/** Set's the current user info */
|
|
191
203
|
Remult.prototype.setUser = function (info) {
|
|
192
|
-
var _a;
|
|
193
204
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
194
205
|
var auth;
|
|
195
|
-
return tslib_1.__generator(this, function (
|
|
196
|
-
switch (
|
|
206
|
+
return tslib_1.__generator(this, function (_a) {
|
|
207
|
+
switch (_a.label) {
|
|
197
208
|
case 0:
|
|
198
209
|
this._user = info;
|
|
199
210
|
auth = info;
|
|
200
211
|
if (auth) {
|
|
201
212
|
if (!this._user.id && auth.sub)
|
|
202
213
|
this._user.id = auth.sub;
|
|
203
|
-
if (!this._user.name && auth.name)
|
|
204
|
-
this._user.name = auth.name;
|
|
205
214
|
if (!this._user.roles && auth.permissions) {
|
|
206
215
|
this._user.roles = auth.permissions;
|
|
207
216
|
}
|
|
208
217
|
}
|
|
209
|
-
if (this._user && !
|
|
218
|
+
if (this._user && !this._user.roles)
|
|
210
219
|
this._user.roles = [];
|
|
211
220
|
return [4 /*yield*/, this._userChangeEvent.fire()];
|
|
212
221
|
case 1:
|
|
213
|
-
|
|
222
|
+
_a.sent();
|
|
214
223
|
return [2 /*return*/];
|
|
215
224
|
}
|
|
216
225
|
});
|
|
217
226
|
});
|
|
218
227
|
};
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
{
|
|
223
|
-
try {
|
|
224
|
-
for (var x_1 = tslib_1.__values(x), x_1_1 = x_1.next(); !x_1_1.done; x_1_1 = x_1.next()) {
|
|
225
|
-
var item = x_1_1.value;
|
|
226
|
-
if (this.isAllowedForInstance(instance, item))
|
|
227
|
-
return true;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
231
|
-
finally {
|
|
232
|
-
try {
|
|
233
|
-
if (x_1_1 && !x_1_1.done && (_a = x_1.return)) _a.call(x_1);
|
|
234
|
-
}
|
|
235
|
-
finally { if (e_1) throw e_1.error; }
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
else if (typeof (x) === "function") {
|
|
240
|
-
return x(this, instance);
|
|
241
|
-
}
|
|
242
|
-
else
|
|
243
|
-
return this.isAllowed(x);
|
|
228
|
+
/** Checks if a user was authenticated */
|
|
229
|
+
Remult.prototype.authenticated = function () {
|
|
230
|
+
return this.user.id !== undefined;
|
|
244
231
|
};
|
|
232
|
+
/** checks if the user has any of the roles specified in the parameters
|
|
233
|
+
* @example
|
|
234
|
+
* remult.isAllowed("admin")
|
|
235
|
+
* @see
|
|
236
|
+
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
237
|
+
*/
|
|
245
238
|
Remult.prototype.isAllowed = function (roles) {
|
|
246
|
-
var
|
|
247
|
-
var _b, _c;
|
|
239
|
+
var e_1, _a;
|
|
248
240
|
if (roles == undefined)
|
|
249
241
|
return undefined;
|
|
250
242
|
if (roles instanceof Array) {
|
|
@@ -256,12 +248,12 @@ var Remult = /** @class */ (function () {
|
|
|
256
248
|
}
|
|
257
249
|
}
|
|
258
250
|
}
|
|
259
|
-
catch (
|
|
251
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
260
252
|
finally {
|
|
261
253
|
try {
|
|
262
254
|
if (roles_1_1 && !roles_1_1.done && (_a = roles_1.return)) _a.call(roles_1);
|
|
263
255
|
}
|
|
264
|
-
finally { if (
|
|
256
|
+
finally { if (e_1) throw e_1.error; }
|
|
265
257
|
}
|
|
266
258
|
return false;
|
|
267
259
|
}
|
|
@@ -270,27 +262,63 @@ var Remult = /** @class */ (function () {
|
|
|
270
262
|
}
|
|
271
263
|
if (typeof roles === 'boolean')
|
|
272
264
|
return roles;
|
|
273
|
-
if (!this.user)
|
|
274
|
-
return false;
|
|
275
265
|
if (typeof roles === 'string')
|
|
276
|
-
if (
|
|
266
|
+
if (this.user.roles.indexOf(roles.toString()) >= 0)
|
|
277
267
|
return true;
|
|
278
268
|
return false;
|
|
279
269
|
};
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
270
|
+
/** checks if the user matches the allowedForInstance callback
|
|
271
|
+
* @see
|
|
272
|
+
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
273
|
+
*/
|
|
274
|
+
Remult.prototype.isAllowedForInstance = function (instance, x) {
|
|
275
|
+
var e_2, _a;
|
|
276
|
+
if (Array.isArray(x)) {
|
|
277
|
+
{
|
|
278
|
+
try {
|
|
279
|
+
for (var x_1 = tslib_1.__values(x), x_1_1 = x_1.next(); !x_1_1.done; x_1_1 = x_1.next()) {
|
|
280
|
+
var item = x_1_1.value;
|
|
281
|
+
if (this.isAllowedForInstance(instance, item))
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
286
|
+
finally {
|
|
287
|
+
try {
|
|
288
|
+
if (x_1_1 && !x_1_1.done && (_a = x_1.return)) _a.call(x_1);
|
|
289
|
+
}
|
|
290
|
+
finally { if (e_2) throw e_2.error; }
|
|
291
|
+
}
|
|
292
|
+
}
|
|
289
293
|
}
|
|
290
|
-
|
|
294
|
+
else if (typeof (x) === "function") {
|
|
295
|
+
return x(this, instance);
|
|
296
|
+
}
|
|
297
|
+
else
|
|
298
|
+
return this.isAllowed(x);
|
|
291
299
|
};
|
|
292
|
-
Remult.
|
|
300
|
+
Object.defineProperty(Remult.prototype, "userChange", {
|
|
301
|
+
/** returns a dispatcher object that fires once a user has changed*/
|
|
302
|
+
get: function () {
|
|
303
|
+
return this._userChangeEvent.dispatcher;
|
|
304
|
+
},
|
|
305
|
+
enumerable: false,
|
|
306
|
+
configurable: true
|
|
307
|
+
});
|
|
308
|
+
/** sets the current data provider */
|
|
309
|
+
Remult.prototype.setDataProvider = function (dataProvider) {
|
|
310
|
+
this._dataSource = dataProvider;
|
|
311
|
+
};
|
|
312
|
+
Remult.prototype.clearAllCache = function () {
|
|
313
|
+
this.repCache.clear();
|
|
314
|
+
};
|
|
315
|
+
/** The api Base Url to be used in all remult calls. by default it's set to `/api`.
|
|
316
|
+
*
|
|
317
|
+
* Set this property in case you want to determine a non relative api url
|
|
318
|
+
*/
|
|
293
319
|
Remult.apiBaseUrl = '/api';
|
|
320
|
+
/** A helper callback that can be used to debug and trace all find operations. Useful in debugging scenarios */
|
|
321
|
+
Remult.onFind = function (metadata, options) { };
|
|
294
322
|
return Remult;
|
|
295
323
|
}());
|
|
296
324
|
exports.Remult = Remult;
|
|
@@ -24,11 +24,12 @@ export declare class RestEntityDataProvider implements EntityDataProvider {
|
|
|
24
24
|
insert(data: any): Promise<any>;
|
|
25
25
|
}
|
|
26
26
|
export declare class RestDataProviderHttpProviderUsingFetch implements RestDataProviderHttpProvider {
|
|
27
|
-
private
|
|
28
|
-
constructor(
|
|
27
|
+
private fetch?;
|
|
28
|
+
constructor(fetch?: (input: RequestInfo, init?: RequestInit) => Promise<Response>);
|
|
29
29
|
get(url: string): Promise<any>;
|
|
30
30
|
put(url: string, data: any): Promise<any>;
|
|
31
31
|
delete(url: string): Promise<any>;
|
|
32
32
|
post(url: string, data: any): Promise<any>;
|
|
33
|
+
myFetch(url: string, init?: RequestInit): Promise<any>;
|
|
33
34
|
}
|
|
34
35
|
export declare function addFilterToUrlAndReturnTrueIfSuccessful(filter: any, url: UrlBuilder): boolean;
|
|
@@ -4,6 +4,7 @@ exports.addFilterToUrlAndReturnTrueIfSuccessful = exports.RestDataProviderHttpPr
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var urlBuilder_1 = require("../../urlBuilder");
|
|
6
6
|
var filter_interfaces_1 = require("../filter/filter-interfaces");
|
|
7
|
+
var context_1 = require("../context");
|
|
7
8
|
var RestDataProvider = /** @class */ (function () {
|
|
8
9
|
function RestDataProvider(url, http) {
|
|
9
10
|
this.url = url;
|
|
@@ -152,67 +153,76 @@ var RestEntityDataProvider = /** @class */ (function () {
|
|
|
152
153
|
return RestEntityDataProvider;
|
|
153
154
|
}());
|
|
154
155
|
exports.RestEntityDataProvider = RestEntityDataProvider;
|
|
155
|
-
function JsonContent(add) {
|
|
156
|
-
add('Content-type', "application/json");
|
|
157
|
-
}
|
|
158
156
|
var RestDataProviderHttpProviderUsingFetch = /** @class */ (function () {
|
|
159
|
-
function RestDataProviderHttpProviderUsingFetch(
|
|
160
|
-
this.
|
|
161
|
-
if (!addRequestHeader)
|
|
162
|
-
this.addRequestHeader = function () { };
|
|
157
|
+
function RestDataProviderHttpProviderUsingFetch(fetch) {
|
|
158
|
+
this.fetch = fetch;
|
|
163
159
|
}
|
|
164
160
|
RestDataProviderHttpProviderUsingFetch.prototype.get = function (url) {
|
|
165
|
-
return
|
|
166
|
-
|
|
161
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
162
|
+
var _this = this;
|
|
163
|
+
return tslib_1.__generator(this, function (_a) {
|
|
164
|
+
switch (_a.label) {
|
|
165
|
+
case 0: return [4 /*yield*/, context_1.retry(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
166
|
+
return tslib_1.__generator(this, function (_a) {
|
|
167
|
+
return [2 /*return*/, this.myFetch(url).then(function (r) {
|
|
168
|
+
return r;
|
|
169
|
+
})];
|
|
170
|
+
});
|
|
171
|
+
}); })];
|
|
172
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
173
|
+
}
|
|
174
|
+
});
|
|
167
175
|
});
|
|
168
176
|
};
|
|
169
177
|
RestDataProviderHttpProviderUsingFetch.prototype.put = function (url, data) {
|
|
170
|
-
return myFetch(url, {
|
|
178
|
+
return this.myFetch(url, {
|
|
171
179
|
method: 'put',
|
|
172
180
|
body: JSON.stringify(data)
|
|
173
|
-
}
|
|
181
|
+
});
|
|
174
182
|
};
|
|
175
183
|
RestDataProviderHttpProviderUsingFetch.prototype.delete = function (url) {
|
|
176
|
-
|
|
177
|
-
this.addRequestHeader(function (name, value) { return h.append(name, value); });
|
|
178
|
-
return fetch(url, { method: 'delete', credentials: 'include' }).then(onSuccess, onError);
|
|
184
|
+
return this.myFetch(url, { method: 'delete', credentials: 'include' });
|
|
179
185
|
};
|
|
180
186
|
RestDataProviderHttpProviderUsingFetch.prototype.post = function (url, data) {
|
|
181
|
-
return
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
188
|
+
var _this = this;
|
|
189
|
+
return tslib_1.__generator(this, function (_a) {
|
|
190
|
+
switch (_a.label) {
|
|
191
|
+
case 0: return [4 /*yield*/, context_1.retry(function () { return _this.myFetch(url, {
|
|
192
|
+
method: 'post',
|
|
193
|
+
body: JSON.stringify(data)
|
|
194
|
+
}); })];
|
|
195
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
RestDataProviderHttpProviderUsingFetch.prototype.myFetch = function (url, init) {
|
|
201
|
+
var _this = this;
|
|
202
|
+
if (!init)
|
|
203
|
+
init = {};
|
|
204
|
+
if (!init.headers)
|
|
205
|
+
init.headers = new Headers();
|
|
206
|
+
var h = init.headers;
|
|
207
|
+
h.append('Content-type', "application/json");
|
|
208
|
+
init.credentials = 'include';
|
|
209
|
+
return (this.fetch || fetch)(url, init).then(function (response) {
|
|
210
|
+
return onSuccess(response);
|
|
211
|
+
}).catch(function (error) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
212
|
+
var r;
|
|
213
|
+
return tslib_1.__generator(this, function (_a) {
|
|
214
|
+
switch (_a.label) {
|
|
215
|
+
case 0: return [4 /*yield*/, error];
|
|
216
|
+
case 1:
|
|
217
|
+
r = _a.sent();
|
|
218
|
+
throw r;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}); });
|
|
185
222
|
};
|
|
186
223
|
return RestDataProviderHttpProviderUsingFetch;
|
|
187
224
|
}());
|
|
188
225
|
exports.RestDataProviderHttpProviderUsingFetch = RestDataProviderHttpProviderUsingFetch;
|
|
189
|
-
function myFetch(url, init) {
|
|
190
|
-
var _this = this;
|
|
191
|
-
var addRequestHeader = [];
|
|
192
|
-
for (var _i = 2; _i < arguments.length; _i++) {
|
|
193
|
-
addRequestHeader[_i - 2] = arguments[_i];
|
|
194
|
-
}
|
|
195
|
-
if (!init)
|
|
196
|
-
init = {};
|
|
197
|
-
if (!init.headers)
|
|
198
|
-
init.headers = new Headers();
|
|
199
|
-
var h = init.headers;
|
|
200
|
-
addRequestHeader.forEach(function (x) { return x(function (n, v) { return h.append(n, v); }); });
|
|
201
|
-
init.credentials = 'include';
|
|
202
|
-
return fetch(url, init).then(function (response) {
|
|
203
|
-
return onSuccess(response);
|
|
204
|
-
}).catch(function (error) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
205
|
-
var r;
|
|
206
|
-
return tslib_1.__generator(this, function (_a) {
|
|
207
|
-
switch (_a.label) {
|
|
208
|
-
case 0: return [4 /*yield*/, error];
|
|
209
|
-
case 1:
|
|
210
|
-
r = _a.sent();
|
|
211
|
-
throw r;
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}); });
|
|
215
|
-
}
|
|
216
226
|
function onSuccess(response) {
|
|
217
227
|
if (response.status == 204)
|
|
218
228
|
return;
|
|
@@ -220,9 +230,7 @@ function onSuccess(response) {
|
|
|
220
230
|
return response.json();
|
|
221
231
|
else {
|
|
222
232
|
throw response.json().then(function (x) {
|
|
223
|
-
|
|
224
|
-
x.message = response.statusText;
|
|
225
|
-
return x;
|
|
233
|
+
return tslib_1.__assign(tslib_1.__assign({}, x), { message: x.message || response.statusText, url: response.url, status: response.status });
|
|
226
234
|
}).catch(function () {
|
|
227
235
|
throw {
|
|
228
236
|
message: response.statusText,
|
|
@@ -232,9 +240,6 @@ function onSuccess(response) {
|
|
|
232
240
|
});
|
|
233
241
|
}
|
|
234
242
|
}
|
|
235
|
-
function onError(error) {
|
|
236
|
-
throw Promise.resolve(error);
|
|
237
|
-
}
|
|
238
243
|
function addFilterToUrlAndReturnTrueIfSuccessful(filter, url) {
|
|
239
244
|
for (var key in filter) {
|
|
240
245
|
if (Object.prototype.hasOwnProperty.call(filter, key)) {
|
|
@@ -121,17 +121,13 @@ var LogSQLCommand = /** @class */ (function () {
|
|
|
121
121
|
if (this.allQueries) {
|
|
122
122
|
d = new Date().valueOf() - start.valueOf();
|
|
123
123
|
if (d > SqlDatabase.durationThreshold) {
|
|
124
|
-
console.log(
|
|
125
|
-
console.log("Arguments:", this.args);
|
|
126
|
-
console.log("Duration", d / 1000);
|
|
124
|
+
console.log({ query: sql, arguments: this.args, duration: d / 1000 });
|
|
127
125
|
}
|
|
128
126
|
}
|
|
129
127
|
return [2 /*return*/, r];
|
|
130
128
|
case 2:
|
|
131
129
|
err_1 = _a.sent();
|
|
132
|
-
console.error(
|
|
133
|
-
console.error('Query:', sql);
|
|
134
|
-
console.error("Arguments", this.args);
|
|
130
|
+
console.error({ error: err_1, query: sql, arguments: this.args });
|
|
135
131
|
throw err_1;
|
|
136
132
|
case 3: return [2 /*return*/];
|
|
137
133
|
}
|
package/src/entity.d.ts
CHANGED
|
@@ -2,39 +2,35 @@ import { Allowed, AllowedForInstance } from "./context";
|
|
|
2
2
|
import { FieldMetadata as FieldMetadata } from './column-interfaces';
|
|
3
3
|
import { EntityOrderBy, FieldsMetadata, EntityFilter, EntityRef } from "./remult3";
|
|
4
4
|
export interface EntityOptions<entityType = any> {
|
|
5
|
-
id?: (entity: FieldsMetadata<entityType>) => FieldMetadata;
|
|
6
|
-
/**
|
|
7
|
-
* The name of the table in the database that holds the data for this entity.
|
|
8
|
-
* If no name is set, the `key` will be used instead.
|
|
9
|
-
* @example
|
|
10
|
-
* dbName:'myProducts'
|
|
11
|
-
*/
|
|
12
|
-
dbName?: string;
|
|
13
|
-
sqlExpression?: string | ((entity: FieldsMetadata<entityType>) => string | Promise<string>);
|
|
14
5
|
/**A human readable name for the entity */
|
|
15
6
|
caption?: string;
|
|
16
7
|
/**
|
|
17
8
|
* Determines if this Entity is available for get requests using Rest Api
|
|
18
|
-
* @see [allowed](http://remult.dev/
|
|
9
|
+
* @see [allowed](http://remult.dev/docs/allowed.html)*/
|
|
19
10
|
allowApiRead?: Allowed;
|
|
20
11
|
/**
|
|
21
12
|
* Determines if this entity can be updated through the api.
|
|
22
|
-
* @see [allowed](http://remult.dev/
|
|
13
|
+
* @see [allowed](http://remult.dev/docs/allowed.html)*/
|
|
23
14
|
allowApiUpdate?: AllowedForInstance<entityType>;
|
|
24
|
-
/**
|
|
15
|
+
/** Determines if entries for this entity can be deleted through the api.
|
|
16
|
+
* @see [allowed](http://remult.dev/docs/allowed.html)*/
|
|
25
17
|
allowApiDelete?: AllowedForInstance<entityType>;
|
|
26
|
-
/**
|
|
18
|
+
/** Determines if new entries for this entity can be posted through the api.
|
|
19
|
+
* @see [allowed](http://remult.dev/docs/allowed.html)*/
|
|
27
20
|
allowApiInsert?: AllowedForInstance<entityType>;
|
|
28
21
|
/** sets the `allowApiUpdate`, `allowApiDelete` and `allowApiInsert` properties in a single set */
|
|
29
22
|
allowApiCrud?: Allowed;
|
|
30
23
|
/** A filter that determines which rows can be queries using the api.
|
|
31
|
-
|
|
24
|
+
* @example
|
|
25
|
+
* apiPrefilter: { archive:false }
|
|
26
|
+
*
|
|
27
|
+
* @see [EntityFilter](http://remult.dev/docs/entityFilter.html)
|
|
32
28
|
*/
|
|
33
29
|
apiPrefilter?: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
|
|
34
|
-
|
|
35
|
-
/** A filter that will be used for all queries from this entity both from the API and from within the server.
|
|
30
|
+
/** A filter that will be used for all queries from this entity both from the API and from within the backend.
|
|
36
31
|
* @example
|
|
37
|
-
* fixedWhereFilter:
|
|
32
|
+
* fixedWhereFilter: { archive:false }
|
|
33
|
+
* @see [EntityFilter](http://remult.dev/docs/entityFilter.html)
|
|
38
34
|
*/
|
|
39
35
|
backendPrefilter?: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
|
|
40
36
|
/** An order by to be used, in case no order by was specified
|
|
@@ -42,23 +38,18 @@ export interface EntityOptions<entityType = any> {
|
|
|
42
38
|
* defaultOrderBy: { name: "asc" }
|
|
43
39
|
*
|
|
44
40
|
* @example
|
|
45
|
-
* defaultOrderBy: { price: "asc", name: "asc" }
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
41
|
* defaultOrderBy: { price: "desc", name: "asc" }
|
|
49
42
|
*/
|
|
50
43
|
defaultOrderBy?: EntityOrderBy<entityType>;
|
|
51
44
|
/** An event that will be fired before the Entity will be saved to the database.
|
|
52
|
-
* If the `
|
|
45
|
+
* If the `error` property of the entity's ref or any of it's fields will be set, the save will be aborted and an exception will be thrown.
|
|
53
46
|
* this is the place to run logic that we want to run in any case before an entity is saved.
|
|
54
47
|
* @example
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* }
|
|
61
|
-
* }
|
|
48
|
+
* .@Entity<Task>("tasks", {
|
|
49
|
+
* saving: async task => {
|
|
50
|
+
* task.lastUpdated = new Date()
|
|
51
|
+
* }
|
|
52
|
+
*})
|
|
62
53
|
*/
|
|
63
54
|
saving?: (row: entityType, proceedWithoutSavingToDb: () => void) => Promise<any> | any;
|
|
64
55
|
/** will be called after the Entity was saved to the data source. */
|
|
@@ -67,6 +58,18 @@ export interface EntityOptions<entityType = any> {
|
|
|
67
58
|
deleting?: (row: entityType) => Promise<any> | any;
|
|
68
59
|
/** Will be called after an Entity is deleted */
|
|
69
60
|
deleted?: (row: entityType) => Promise<any> | any;
|
|
61
|
+
/** Will be called when the entity is being validated, usually prior to the `saving` event */
|
|
70
62
|
validation?: (row: entityType, ref: EntityRef<entityType>) => Promise<any> | any;
|
|
63
|
+
/** The name of the table in the database that holds the data for this entity.
|
|
64
|
+
* If no name is set, the `key` will be used instead.
|
|
65
|
+
* @example
|
|
66
|
+
* dbName:'myProducts'
|
|
67
|
+
*/
|
|
68
|
+
dbName?: string;
|
|
69
|
+
/** For entities that are based on SQL expressions instead of a physical table or view*/
|
|
70
|
+
sqlExpression?: string | ((entity: FieldsMetadata<entityType>) => string | Promise<string>);
|
|
71
|
+
/** An arrow function that identifies the `id` column to use for this entity */
|
|
72
|
+
id?: (entity: FieldsMetadata<entityType>) => FieldMetadata;
|
|
71
73
|
entityRefInit?: (ref: EntityRef<entityType>, row: entityType) => void;
|
|
74
|
+
apiRequireId?: Allowed;
|
|
72
75
|
}
|
|
@@ -26,17 +26,17 @@ export declare class RepositoryImplementation<entityType> implements Repository<
|
|
|
26
26
|
query(options?: QueryOptions<entityType>): QueryResult<entityType>;
|
|
27
27
|
getEntityRef(entity: entityType): EntityRef<entityType>;
|
|
28
28
|
delete(id: (entityType extends {
|
|
29
|
-
id
|
|
29
|
+
id?: number;
|
|
30
30
|
} ? number : entityType extends {
|
|
31
|
-
id
|
|
31
|
+
id?: string;
|
|
32
32
|
} ? string : (string | number))): Promise<void>;
|
|
33
33
|
delete(item: entityType): Promise<void>;
|
|
34
34
|
insert(item: Partial<OmitEB<entityType>>[]): Promise<entityType[]>;
|
|
35
35
|
insert(item: Partial<OmitEB<entityType>>): Promise<entityType>;
|
|
36
36
|
update(id: (entityType extends {
|
|
37
|
-
id
|
|
37
|
+
id?: number;
|
|
38
38
|
} ? number : entityType extends {
|
|
39
|
-
id
|
|
39
|
+
id?: string;
|
|
40
40
|
} ? string : (string | number)), entity: Partial<OmitEB<entityType>>): Promise<entityType>;
|
|
41
41
|
private getRefForExistingRow;
|
|
42
42
|
save(item: Partial<OmitEB<entityType>>[]): Promise<entityType[]>;
|
|
@@ -157,6 +157,7 @@ export declare class FieldRefImplementation<entityType, valueType> implements Fi
|
|
|
157
157
|
get originalValue(): any;
|
|
158
158
|
private rawOriginalValue;
|
|
159
159
|
setId(id: (string | number)): void;
|
|
160
|
+
getId(): any;
|
|
160
161
|
get inputValue(): string;
|
|
161
162
|
set inputValue(val: string);
|
|
162
163
|
valueChanged(): boolean;
|
|
@@ -249,6 +250,19 @@ export declare class ValueListInfo<T extends ValueListItem> implements ValueConv
|
|
|
249
250
|
export declare function getValueList<T>(field: FieldRef<T>): T[];
|
|
250
251
|
export declare function getValueList<T>(field: FieldMetadata<T>): T[];
|
|
251
252
|
export declare function getValueList<T>(type: ClassType<T>): T[];
|
|
253
|
+
/**Decorates fields that should be used as fields.
|
|
254
|
+
* for more info see: [Field Types](https://remult.dev/docs/field-types.html)
|
|
255
|
+
*
|
|
256
|
+
* FieldOptions can be set in two ways:
|
|
257
|
+
* @example
|
|
258
|
+
* // as an object
|
|
259
|
+
* .@Fields.string({ includeInApi:false })
|
|
260
|
+
* title='';
|
|
261
|
+
* @example
|
|
262
|
+
* // as an arrow function that receives `remult` as a parameter
|
|
263
|
+
* .@Fields.string((options,remult) => options.includeInApi = true)
|
|
264
|
+
* title='';
|
|
265
|
+
*/
|
|
252
266
|
export declare function Field<entityType = any, valueType = any>(valueType: () => ClassType<valueType>, ...options: (FieldOptions<entityType, valueType> | ((options: FieldOptions<entityType, valueType>, remult: Remult) => void))[]): (target: any, key: any, c?: any) => void;
|
|
253
267
|
export declare const storableMember: unique symbol;
|
|
254
268
|
export declare function decorateColumnSettings<valueType>(settings: FieldOptions<any, valueType>, remult: Remult): FieldOptions<any, valueType>;
|
|
@@ -260,6 +274,29 @@ export declare type BuildEntityFields<entityType> = {
|
|
|
260
274
|
[Properties in keyof Partial<OmitEB<entityType>>]: any;
|
|
261
275
|
};
|
|
262
276
|
export declare function BuildEntity<entityType>(c: ClassType<entityType>, key: string, fields: BuildEntityFields<entityType>, ...options: (EntityOptions<entityType> | ((options: EntityOptions<entityType>, remult: Remult) => void))[]): void;
|
|
277
|
+
/**Decorates classes that should be used as entities.
|
|
278
|
+
* Receives a key and an array of EntityOptions.
|
|
279
|
+
* @example
|
|
280
|
+
* import { Entity, Fields } from "remult";
|
|
281
|
+
* @Entity("tasks", {
|
|
282
|
+
* allowApiCrud: true
|
|
283
|
+
* })
|
|
284
|
+
* export class Task {
|
|
285
|
+
* @Fields.uuid()
|
|
286
|
+
* id!: string;
|
|
287
|
+
* @Fields.string()
|
|
288
|
+
* title = '';
|
|
289
|
+
* @Fields.boolean()
|
|
290
|
+
* completed = false;
|
|
291
|
+
* }
|
|
292
|
+
* *EntityOptions can be set in two ways:*
|
|
293
|
+
* @example
|
|
294
|
+
* // as an object
|
|
295
|
+
* .@Entity("tasks",{ allowApiCrud:true })
|
|
296
|
+
* @example
|
|
297
|
+
* // as an arrow function that receives `remult` as a parameter
|
|
298
|
+
* .@Entity("tasks", (options,remult) => options.allowApiCrud = true)
|
|
299
|
+
*/
|
|
263
300
|
export declare function Entity<entityType>(key: string, ...options: (EntityOptions<entityType> | ((options: EntityOptions<entityType>, remult: Remult) => void))[]): (target: any) => any;
|
|
264
301
|
export declare class EntityBase {
|
|
265
302
|
get _(): EntityRef<this>;
|