remult 0.13.26 → 0.13.29
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/package.json +1 -1
- package/readme.md +18 -6
- package/server/expressBridge.d.ts +1 -0
- package/server/expressBridge.js +4 -1
- package/src/context.d.ts +3 -2
- package/src/context.js +19 -17
- package/src/data-providers/array-entity-data-provider.js +37 -34
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
<a href="https://discord.gg/GXHk7ZfuG5">
|
|
22
22
|
<img alt="chat on discord" src="https://img.shields.io/badge/chat-on%20discord-blueviolet"/>
|
|
23
23
|
</a>
|
|
24
|
+
<a href="https://twitter.com/remultjs">
|
|
25
|
+
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/remultjs?style=social">
|
|
26
|
+
</a>
|
|
24
27
|
</div>
|
|
25
28
|
|
|
26
29
|
## What is Remult?
|
|
@@ -114,24 +117,29 @@ static async increasePriceOfTofu(priceIncrease: number, remult?: Remult) {
|
|
|
114
117
|
### :ballot_box_with_check: Data validation and constraints - defined once
|
|
115
118
|
|
|
116
119
|
```ts
|
|
117
|
-
import { Entity, Fields } from 'remult';
|
|
120
|
+
import { Entity, Fields, Validators } from 'remult';
|
|
118
121
|
|
|
119
122
|
@Entity('products', {
|
|
120
123
|
allowApiCrud: true
|
|
121
124
|
})
|
|
122
125
|
export class Product {
|
|
126
|
+
@Fields.string({
|
|
127
|
+
validate: Validators.required
|
|
128
|
+
})
|
|
129
|
+
name = '';
|
|
130
|
+
|
|
123
131
|
@Fields.string<Product>({
|
|
124
132
|
validate: product => {
|
|
125
|
-
if (product.
|
|
126
|
-
throw
|
|
133
|
+
if (product.description.trim().length < 50)
|
|
134
|
+
throw "too short";
|
|
127
135
|
}
|
|
128
136
|
})
|
|
129
|
-
|
|
137
|
+
description = '';
|
|
130
138
|
|
|
131
139
|
@Fields.number({
|
|
132
140
|
validate: (_, field) => {
|
|
133
141
|
if (field.value < 0)
|
|
134
|
-
throw "must not be less than 0";
|
|
142
|
+
field.error = "must not be less than 0"; // or: throw "must not be less than 0";
|
|
135
143
|
}
|
|
136
144
|
})
|
|
137
145
|
unitPrice = 0;
|
|
@@ -181,7 +189,11 @@ export class Article {
|
|
|
181
189
|
[CRM demo](https://github.com/remult/crm-demo) with a React + [MUI](https://mui.com) front-end and Postgres database.
|
|
182
190
|
|
|
183
191
|
## Contributing
|
|
184
|
-
Contributions are welcome. See [CONTRIBUTING](CONTRIBUTING.md).
|
|
192
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
193
|
+
|
|
194
|
+
* :speech_balloon: Any feedback or suggestions? Start a [discussion](https://github.com/remult/remult/discussions).
|
|
195
|
+
* :muscle: Want to help out? Look for "help wanted" labeled [issues](https://github.com/remult/remult/issues).
|
|
196
|
+
* :star: Give this repo a star.
|
|
185
197
|
|
|
186
198
|
## License
|
|
187
199
|
Remult is [MIT Licensed](LICENSE).
|
|
@@ -21,6 +21,7 @@ export declare function remultExpress(options?: {
|
|
|
21
21
|
entities?: ClassType<any>[];
|
|
22
22
|
controllers?: ClassType<any>[];
|
|
23
23
|
bodyParser?: boolean;
|
|
24
|
+
rootPath?: string;
|
|
24
25
|
}): RemultExpressBridge;
|
|
25
26
|
export interface RemultExpressBridge extends express.RequestHandler {
|
|
26
27
|
getRemult(req: express.Request): Promise<Remult>;
|
package/server/expressBridge.js
CHANGED
|
@@ -61,7 +61,9 @@ function remultExpress(options) {
|
|
|
61
61
|
var bridge = new ExpressBridge(app, new inProcessQueueHandler(options.queueStorage), options.initRequest, dataProvider);
|
|
62
62
|
if (options.logApiEndPoints !== undefined)
|
|
63
63
|
bridge.logApiEndPoints = options.logApiEndPoints;
|
|
64
|
-
|
|
64
|
+
if (options.rootPath === undefined)
|
|
65
|
+
options.rootPath = __1.Remult.apiBaseUrl;
|
|
66
|
+
var apiArea = bridge.addArea(options.rootPath);
|
|
65
67
|
if (!options.disableAutoApi) {
|
|
66
68
|
var actions = [];
|
|
67
69
|
if (options.entities)
|
|
@@ -856,3 +858,4 @@ var JobsInQueueEntity = /** @class */ (function (_super) {
|
|
|
856
858
|
return JobsInQueueEntity;
|
|
857
859
|
}(__1.IdEntity));
|
|
858
860
|
exports.JobsInQueueEntity = JobsInQueueEntity;
|
|
861
|
+
context_1.allEntities.splice(context_1.allEntities.indexOf(JobsInQueueEntity), 1);
|
package/src/context.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export declare class Remult {
|
|
|
44
44
|
sub?: string;
|
|
45
45
|
name?: string;
|
|
46
46
|
permissions?: string[];
|
|
47
|
+
username?: string;
|
|
47
48
|
}): Promise<void>;
|
|
48
49
|
private _user;
|
|
49
50
|
private _userChangeEvent;
|
|
@@ -55,12 +56,12 @@ export declare class Remult {
|
|
|
55
56
|
* @see
|
|
56
57
|
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
57
58
|
*/
|
|
58
|
-
isAllowed(roles
|
|
59
|
+
isAllowed(roles?: Allowed): boolean;
|
|
59
60
|
/** checks if the user matches the allowedForInstance callback
|
|
60
61
|
* @see
|
|
61
62
|
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
62
63
|
*/
|
|
63
|
-
isAllowedForInstance(instance: any,
|
|
64
|
+
isAllowedForInstance(instance: any, allowed?: AllowedForInstance<any>): boolean;
|
|
64
65
|
/** returns a dispatcher object that fires once a user has changed*/
|
|
65
66
|
get userChange(): EventDispatcher;
|
|
66
67
|
private repCache;
|
package/src/context.js
CHANGED
|
@@ -41,28 +41,28 @@ var HttpProviderBridgeToRestDataProviderHttpProvider = /** @class */ (function (
|
|
|
41
41
|
}());
|
|
42
42
|
exports.HttpProviderBridgeToRestDataProviderHttpProvider = HttpProviderBridgeToRestDataProviderHttpProvider;
|
|
43
43
|
function retry(what) {
|
|
44
|
-
var _a, _b, _c;
|
|
44
|
+
var _a, _b, _c, _d;
|
|
45
45
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
46
46
|
var err_1;
|
|
47
|
-
return tslib_1.__generator(this, function (
|
|
48
|
-
switch (
|
|
47
|
+
return tslib_1.__generator(this, function (_e) {
|
|
48
|
+
switch (_e.label) {
|
|
49
49
|
case 0:
|
|
50
50
|
if (!true) return [3 /*break*/, 7];
|
|
51
|
-
|
|
51
|
+
_e.label = 1;
|
|
52
52
|
case 1:
|
|
53
|
-
|
|
53
|
+
_e.trys.push([1, 3, , 6]);
|
|
54
54
|
return [4 /*yield*/, what()];
|
|
55
|
-
case 2: return [2 /*return*/,
|
|
55
|
+
case 2: return [2 /*return*/, _e.sent()];
|
|
56
56
|
case 3:
|
|
57
|
-
err_1 =
|
|
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];
|
|
57
|
+
err_1 = _e.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.includes("http proxy error")) || ((_d = err_1.message) === null || _d === void 0 ? void 0 : _d.startsWith("Gateway Timeout")))) return [3 /*break*/, 5];
|
|
59
59
|
return [4 /*yield*/, new Promise(function (res, req) {
|
|
60
60
|
setTimeout(function () {
|
|
61
61
|
res({});
|
|
62
62
|
}, 250);
|
|
63
63
|
})];
|
|
64
64
|
case 4:
|
|
65
|
-
|
|
65
|
+
_e.sent();
|
|
66
66
|
return [3 /*break*/, 0];
|
|
67
67
|
case 5: throw err_1;
|
|
68
68
|
case 6: return [3 /*break*/, 0];
|
|
@@ -214,6 +214,8 @@ var Remult = /** @class */ (function () {
|
|
|
214
214
|
if (!this._user.roles && auth.permissions) {
|
|
215
215
|
this._user.roles = auth.permissions;
|
|
216
216
|
}
|
|
217
|
+
if (!this._user.name)
|
|
218
|
+
this._user.name = auth.username;
|
|
217
219
|
}
|
|
218
220
|
if (this._user && !this._user.roles)
|
|
219
221
|
this._user.roles = [];
|
|
@@ -271,13 +273,13 @@ var Remult = /** @class */ (function () {
|
|
|
271
273
|
* @see
|
|
272
274
|
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
273
275
|
*/
|
|
274
|
-
Remult.prototype.isAllowedForInstance = function (instance,
|
|
276
|
+
Remult.prototype.isAllowedForInstance = function (instance, allowed) {
|
|
275
277
|
var e_2, _a;
|
|
276
|
-
if (Array.isArray(
|
|
278
|
+
if (Array.isArray(allowed)) {
|
|
277
279
|
{
|
|
278
280
|
try {
|
|
279
|
-
for (var
|
|
280
|
-
var item =
|
|
281
|
+
for (var allowed_1 = tslib_1.__values(allowed), allowed_1_1 = allowed_1.next(); !allowed_1_1.done; allowed_1_1 = allowed_1.next()) {
|
|
282
|
+
var item = allowed_1_1.value;
|
|
281
283
|
if (this.isAllowedForInstance(instance, item))
|
|
282
284
|
return true;
|
|
283
285
|
}
|
|
@@ -285,17 +287,17 @@ var Remult = /** @class */ (function () {
|
|
|
285
287
|
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
286
288
|
finally {
|
|
287
289
|
try {
|
|
288
|
-
if (
|
|
290
|
+
if (allowed_1_1 && !allowed_1_1.done && (_a = allowed_1.return)) _a.call(allowed_1);
|
|
289
291
|
}
|
|
290
292
|
finally { if (e_2) throw e_2.error; }
|
|
291
293
|
}
|
|
292
294
|
}
|
|
293
295
|
}
|
|
294
|
-
else if (typeof (
|
|
295
|
-
return
|
|
296
|
+
else if (typeof (allowed) === "function") {
|
|
297
|
+
return allowed(this, instance);
|
|
296
298
|
}
|
|
297
299
|
else
|
|
298
|
-
return this.isAllowed(
|
|
300
|
+
return this.isAllowed(allowed);
|
|
299
301
|
};
|
|
300
302
|
Object.defineProperty(Remult.prototype, "userChange", {
|
|
301
303
|
/** returns a dispatcher object that fires once a user has changed*/
|
|
@@ -4,7 +4,6 @@ exports.ArrayEntityDataProvider = void 0;
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var filter_interfaces_1 = require("../filter/filter-interfaces");
|
|
6
6
|
var column_1 = require("../column");
|
|
7
|
-
var sort_1 = require("../sort");
|
|
8
7
|
var ArrayEntityDataProvider = /** @class */ (function () {
|
|
9
8
|
function ArrayEntityDataProvider(entity, rows) {
|
|
10
9
|
var e_1, _a;
|
|
@@ -220,34 +219,38 @@ var ArrayEntityDataProvider = /** @class */ (function () {
|
|
|
220
219
|
ArrayEntityDataProvider.prototype.insert = function (data) {
|
|
221
220
|
var _a;
|
|
222
221
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
223
|
-
var idf,
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
222
|
+
var idf, _b, _c, row, j;
|
|
223
|
+
var e_6, _d;
|
|
224
|
+
return tslib_1.__generator(this, function (_e) {
|
|
225
|
+
idf = this.entity.idMetadata.field;
|
|
226
|
+
if (!(idf instanceof column_1.CompoundIdField)) {
|
|
227
|
+
if (((_a = idf.options.valueConverter) === null || _a === void 0 ? void 0 : _a.fieldTypeInDb) === 'autoincrement') {
|
|
228
|
+
data[idf.key] = 1;
|
|
229
|
+
try {
|
|
230
|
+
for (_b = tslib_1.__values(this.rows), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
231
|
+
row = _c.value;
|
|
232
|
+
if (row[idf.key] >= data[idf.key])
|
|
233
|
+
data[idf.key] = row[idf.key] + 1;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
237
|
+
finally {
|
|
238
|
+
try {
|
|
239
|
+
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
|
|
240
|
+
}
|
|
241
|
+
finally { if (e_6) throw e_6.error; }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (data[idf.key])
|
|
245
|
+
this.rows.forEach(function (i) {
|
|
246
|
+
if (data[idf.key] == i[idf.key])
|
|
247
|
+
throw Error("id already exists");
|
|
248
|
+
});
|
|
250
249
|
}
|
|
250
|
+
j = this.translateToJson(data);
|
|
251
|
+
this.verifyThatRowHasAllNotNullColumns(j);
|
|
252
|
+
this.rows.push(j);
|
|
253
|
+
return [2 /*return*/, Promise.resolve(this.translateFromJson(j))];
|
|
251
254
|
});
|
|
252
255
|
});
|
|
253
256
|
};
|
|
@@ -287,7 +290,7 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
287
290
|
throw new Error('Custom Filter should be translated before it gets here');
|
|
288
291
|
};
|
|
289
292
|
FilterConsumerBridgeToObject.prototype.or = function (orElements) {
|
|
290
|
-
var
|
|
293
|
+
var e_7, _a;
|
|
291
294
|
try {
|
|
292
295
|
for (var orElements_1 = tslib_1.__values(orElements), orElements_1_1 = orElements_1.next(); !orElements_1_1.done; orElements_1_1 = orElements_1.next()) {
|
|
293
296
|
var element = orElements_1_1.value;
|
|
@@ -298,12 +301,12 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
298
301
|
}
|
|
299
302
|
}
|
|
300
303
|
}
|
|
301
|
-
catch (
|
|
304
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
302
305
|
finally {
|
|
303
306
|
try {
|
|
304
307
|
if (orElements_1_1 && !orElements_1_1.done && (_a = orElements_1.return)) _a.call(orElements_1);
|
|
305
308
|
}
|
|
306
|
-
finally { if (
|
|
309
|
+
finally { if (e_7) throw e_7.error; }
|
|
307
310
|
}
|
|
308
311
|
this.ok = false;
|
|
309
312
|
};
|
|
@@ -316,7 +319,7 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
316
319
|
this.ok = false;
|
|
317
320
|
};
|
|
318
321
|
FilterConsumerBridgeToObject.prototype.isIn = function (col, val) {
|
|
319
|
-
var
|
|
322
|
+
var e_8, _a;
|
|
320
323
|
try {
|
|
321
324
|
for (var val_1 = tslib_1.__values(val), val_1_1 = val_1.next(); !val_1_1.done; val_1_1 = val_1.next()) {
|
|
322
325
|
var v = val_1_1.value;
|
|
@@ -325,12 +328,12 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
325
328
|
}
|
|
326
329
|
}
|
|
327
330
|
}
|
|
328
|
-
catch (
|
|
331
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
329
332
|
finally {
|
|
330
333
|
try {
|
|
331
334
|
if (val_1_1 && !val_1_1.done && (_a = val_1.return)) _a.call(val_1);
|
|
332
335
|
}
|
|
333
|
-
finally { if (
|
|
336
|
+
finally { if (e_8) throw e_8.error; }
|
|
334
337
|
}
|
|
335
338
|
this.ok = false;
|
|
336
339
|
};
|