remult 0.14.31 → 0.14.34
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/{readme.md → README.md} +0 -0
- package/esm/graphql.d.ts +2 -2
- package/esm/remult-express.d.ts +3 -8
- package/esm/remult-express.js +3 -2
- package/esm/remult-fastify.js +5 -10
- package/esm/remult-fresh.d.ts +1 -6
- package/esm/remult-fresh.js +29 -37
- package/esm/server/JsonEntityFileStorage.d.ts +4 -1
- package/esm/server/JsonEntityFileStorage.js +4 -0
- package/esm/server/expressBridge.d.ts +13 -61
- package/esm/server/expressBridge.js +255 -142
- package/esm/server/index.d.ts +2 -4
- package/esm/server/index.js +2 -4
- package/esm/src/backend-tests/test-http-server.backend-spec.js +31 -2
- package/graphql.d.ts +2 -2
- package/package.json +4 -4
- package/remult-express.d.ts +3 -8
- package/remult-express.js +3 -2
- package/remult-fastify.js +5 -10
- package/remult-fresh.d.ts +1 -6
- package/remult-fresh.js +16 -22
- package/server/JsonEntityFileStorage.d.ts +4 -1
- package/server/JsonEntityFileStorage.js +11 -1
- package/server/expressBridge.d.ts +13 -61
- package/server/expressBridge.js +371 -231
- package/server/index.d.ts +2 -4
- package/server/index.js +4 -7
- package/src/backend-tests/test-http-server.backend-spec.js +41 -2
- package/esm/remult-middleware.d.ts +0 -10
- package/esm/remult-middleware.js +0 -117
- package/esm/server/register-actions-on-server.d.ts +0 -3
- package/esm/server/register-actions-on-server.js +0 -24
- package/esm/server/register-entities-on-server.d.ts +0 -3
- package/esm/server/register-entities-on-server.js +0 -15
- package/esm/valueConverters.d.ts +0 -12
- package/esm/valueConverters.js +0 -169
- package/postgres/postgresColumnSyntax.d.ts +0 -2
- package/postgres/postgresColumnSyntax.js +0 -34
- package/remult-middleware.d.ts +0 -10
- package/remult-middleware.js +0 -131
- package/server/register-actions-on-server.d.ts +0 -3
- package/server/register-actions-on-server.js +0 -50
- package/server/register-entities-on-server.d.ts +0 -3
- package/server/register-entities-on-server.js +0 -19
- package/valueConverters.d.ts +0 -12
- package/valueConverters.js +0 -168
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import {
|
|
3
|
-
import { registerEntitiesOnServer } from './register-entities-on-server';
|
|
4
|
-
import { JsonEntityFileStorage } from './JsonEntityFileStorage';
|
|
5
|
-
import { Action, actionInfo } from '../src/server-action';
|
|
2
|
+
import { Action, actionInfo, classBackendMethodsArray, serverActionField } from '../src/server-action';
|
|
6
3
|
import { DataApi, serializeError } from '../src/data-api';
|
|
7
4
|
import { allEntities, Remult } from '../src/context';
|
|
8
5
|
import { Entity, Fields, getEntityKey } from '../src/remult3';
|
|
9
|
-
import { JsonDataProvider } from '../src/data-providers/json-data-provider';
|
|
10
6
|
import { IdEntity } from '../src/id-entity';
|
|
11
|
-
export function buildRemultServer(
|
|
7
|
+
export function buildRemultServer(options) {
|
|
12
8
|
if (!options) {
|
|
13
9
|
options = {};
|
|
14
10
|
}
|
|
@@ -25,10 +21,10 @@ export function buildRemultServer(app, options) {
|
|
|
25
21
|
}
|
|
26
22
|
else
|
|
27
23
|
dataProvider = Promise.resolve(options.dataProvider);
|
|
28
|
-
dataProvider = dataProvider.then(dp => {
|
|
24
|
+
dataProvider = dataProvider.then(async (dp) => {
|
|
29
25
|
if (dp)
|
|
30
26
|
return dp;
|
|
31
|
-
return new
|
|
27
|
+
return new (await import('./JsonEntityFileStorage')).JsonFileDataProvider('./db');
|
|
32
28
|
});
|
|
33
29
|
if (options.initApi) {
|
|
34
30
|
dataProvider = dataProvider.then(async (dp) => {
|
|
@@ -37,33 +33,158 @@ export function buildRemultServer(app, options) {
|
|
|
37
33
|
return dp;
|
|
38
34
|
});
|
|
39
35
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
options.rootPath = Remult.apiBaseUrl;
|
|
45
|
-
let apiArea = bridge.addArea(options.rootPath);
|
|
46
|
-
if (!options.disableAutoApi) {
|
|
47
|
-
let actions = [];
|
|
36
|
+
{
|
|
37
|
+
let allControllers = [];
|
|
38
|
+
if (!options.entities)
|
|
39
|
+
options.entities = [...allEntities];
|
|
48
40
|
if (options.entities)
|
|
49
|
-
|
|
41
|
+
allControllers.push(...options.entities);
|
|
50
42
|
if (options.controllers)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
registerEntitiesOnServer(apiArea, options.entities);
|
|
43
|
+
allControllers.push(...options.controllers);
|
|
44
|
+
options.controllers = allControllers;
|
|
54
45
|
}
|
|
46
|
+
if (options.rootPath === undefined)
|
|
47
|
+
options.rootPath = Remult.apiBaseUrl;
|
|
48
|
+
actionInfo.runningOnServer = true;
|
|
49
|
+
let bridge = new RemultServerImplementation(new inProcessQueueHandler(options.queueStorage), options, dataProvider);
|
|
55
50
|
return bridge;
|
|
56
51
|
}
|
|
57
52
|
;
|
|
58
|
-
class
|
|
59
|
-
constructor(
|
|
60
|
-
this.app = app;
|
|
53
|
+
class RemultServerImplementation {
|
|
54
|
+
constructor(queue, options, dataProvider) {
|
|
61
55
|
this.queue = queue;
|
|
62
56
|
this.options = options;
|
|
63
57
|
this.dataProvider = dataProvider;
|
|
58
|
+
this.registeredRouter = false;
|
|
59
|
+
this.hasQueue = false;
|
|
64
60
|
/* internal */
|
|
65
61
|
this.backendMethodsOpenApi = [];
|
|
66
|
-
|
|
62
|
+
}
|
|
63
|
+
handle(req, gRes) {
|
|
64
|
+
if (!this.routeImpl) {
|
|
65
|
+
this.routeImpl = new RouteImplementation();
|
|
66
|
+
this.registerRouter(this.routeImpl);
|
|
67
|
+
}
|
|
68
|
+
return this.routeImpl.handle(req, gRes);
|
|
69
|
+
}
|
|
70
|
+
registerRouter(r) {
|
|
71
|
+
if (this.registeredRouter)
|
|
72
|
+
throw "Router already registered";
|
|
73
|
+
this.registeredRouter = true;
|
|
74
|
+
{
|
|
75
|
+
for (const c of this.options.controllers) {
|
|
76
|
+
let z = c[classBackendMethodsArray];
|
|
77
|
+
if (z)
|
|
78
|
+
for (const a of z) {
|
|
79
|
+
let x = a[serverActionField];
|
|
80
|
+
if (!x) {
|
|
81
|
+
throw 'failed to set server action, did you forget the BackendMethod Decorator?';
|
|
82
|
+
}
|
|
83
|
+
this.addAction(x, r);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (this.hasQueue)
|
|
87
|
+
this.addAction({
|
|
88
|
+
__register: x => {
|
|
89
|
+
x(Action.apiUrlForJobStatus, false, () => true, async (data, req, res) => {
|
|
90
|
+
let job = await this.queue.getJobInfo(data.queuedJobId);
|
|
91
|
+
let userId = undefined;
|
|
92
|
+
if (req?.user)
|
|
93
|
+
userId = req.user.id;
|
|
94
|
+
if (job.userId == '')
|
|
95
|
+
job.userId = undefined;
|
|
96
|
+
if (userId != job.userId)
|
|
97
|
+
res.forbidden();
|
|
98
|
+
else
|
|
99
|
+
res.success(job.info);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}, r);
|
|
103
|
+
}
|
|
104
|
+
this.options.entities.forEach(e => {
|
|
105
|
+
let key = getEntityKey(e);
|
|
106
|
+
if (key != undefined)
|
|
107
|
+
this.add(key, c => {
|
|
108
|
+
return new DataApi(c.repo(e), c);
|
|
109
|
+
}, r);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
add(key, dataApiFactory, r) {
|
|
113
|
+
let myRoute = this.options.rootPath + '/' + key;
|
|
114
|
+
if (this.options.logApiEndPoints)
|
|
115
|
+
console.log(myRoute);
|
|
116
|
+
r.route(myRoute)
|
|
117
|
+
.get(this.process((c, req, res) => dataApiFactory(c).httpGet(res, req))).put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, '', orig.body)))
|
|
118
|
+
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
|
|
119
|
+
.post(this.process(async (c, req, res, orig) => dataApiFactory(c).httpPost(res, req, orig.body)));
|
|
120
|
+
r.route(myRoute + '/:id')
|
|
121
|
+
//@ts-ignore
|
|
122
|
+
.get(this.process(async (c, req, res, orig) => dataApiFactory(c).get(res, orig.params.id)))
|
|
123
|
+
//@ts-ignore
|
|
124
|
+
.put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, orig.params.id, orig.body)))
|
|
125
|
+
//@ts-ignore
|
|
126
|
+
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, orig.params.id)));
|
|
127
|
+
}
|
|
128
|
+
process(what) {
|
|
129
|
+
return async (req, res) => {
|
|
130
|
+
let myReq = new ExpressRequestBridgeToDataApiRequest(req);
|
|
131
|
+
let myRes = new ExpressResponseBridgeToDataApiResponse(res, req);
|
|
132
|
+
let remult = new Remult();
|
|
133
|
+
remult.setDataProvider(await this.dataProvider);
|
|
134
|
+
if (req) {
|
|
135
|
+
let user;
|
|
136
|
+
if (this.options.getUser)
|
|
137
|
+
user = await this.options.getUser(req);
|
|
138
|
+
else {
|
|
139
|
+
user = req['user'];
|
|
140
|
+
if (!user)
|
|
141
|
+
user = req['auth'];
|
|
142
|
+
}
|
|
143
|
+
if (user)
|
|
144
|
+
remult.setUser(user);
|
|
145
|
+
}
|
|
146
|
+
if (this.options.initRequest) {
|
|
147
|
+
await this.options.initRequest(remult, req);
|
|
148
|
+
}
|
|
149
|
+
what(remult, myReq, myRes, req);
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
;
|
|
153
|
+
async getRemult(req) {
|
|
154
|
+
let remult;
|
|
155
|
+
await this.process(async (c) => {
|
|
156
|
+
remult = c;
|
|
157
|
+
})(req, undefined);
|
|
158
|
+
return remult;
|
|
159
|
+
}
|
|
160
|
+
addAction(action, r) {
|
|
161
|
+
action.__register((url, queue, allowed, what) => {
|
|
162
|
+
let myUrl = this.options.rootPath + '/' + url;
|
|
163
|
+
let tag = (() => {
|
|
164
|
+
let split = url.split('/');
|
|
165
|
+
if (split.length == 1)
|
|
166
|
+
return 'Static Backend Methods';
|
|
167
|
+
else
|
|
168
|
+
return split[0];
|
|
169
|
+
})();
|
|
170
|
+
this.backendMethodsOpenApi.push({ path: myUrl, allowed, tag });
|
|
171
|
+
if (this.options.logApiEndPoints)
|
|
172
|
+
console.log(myUrl);
|
|
173
|
+
if (queue) {
|
|
174
|
+
this.hasQueue = true;
|
|
175
|
+
this.queue.mapQueuedAction(myUrl, what);
|
|
176
|
+
}
|
|
177
|
+
r.route(myUrl).post(this.process(async (remult, req, res, orig) => {
|
|
178
|
+
if (queue) {
|
|
179
|
+
let r = {
|
|
180
|
+
queuedJobId: await this.queue.submitJob(myUrl, remult, orig.body)
|
|
181
|
+
};
|
|
182
|
+
res.success(r);
|
|
183
|
+
}
|
|
184
|
+
else
|
|
185
|
+
return what(orig.body, remult, res);
|
|
186
|
+
}));
|
|
187
|
+
});
|
|
67
188
|
}
|
|
68
189
|
openApiDoc(options) {
|
|
69
190
|
let r = new Remult();
|
|
@@ -115,7 +236,7 @@ class ExpressBridge {
|
|
|
115
236
|
return item;
|
|
116
237
|
}
|
|
117
238
|
};
|
|
118
|
-
for (const e of
|
|
239
|
+
for (const e of this.options.entities) {
|
|
119
240
|
let meta = r.repo(e).metadata;
|
|
120
241
|
let key = getEntityKey(e);
|
|
121
242
|
let parameters = [];
|
|
@@ -352,122 +473,8 @@ class ExpressBridge {
|
|
|
352
473
|
};
|
|
353
474
|
return spec;
|
|
354
475
|
}
|
|
355
|
-
addArea(rootUrl) {
|
|
356
|
-
var r = new SiteArea(this, this.app, rootUrl, this.logApiEndPoints);
|
|
357
|
-
if (!this.firstArea) {
|
|
358
|
-
this.firstArea = r;
|
|
359
|
-
}
|
|
360
|
-
return r;
|
|
361
|
-
}
|
|
362
|
-
async getRemult(req) {
|
|
363
|
-
return this.firstArea.getRemult(req);
|
|
364
|
-
}
|
|
365
476
|
}
|
|
366
|
-
|
|
367
|
-
constructor(bridge, app, rootUrl, logApiEndpoints) {
|
|
368
|
-
this.bridge = bridge;
|
|
369
|
-
this.app = app;
|
|
370
|
-
this.rootUrl = rootUrl;
|
|
371
|
-
this.logApiEndpoints = logApiEndpoints;
|
|
372
|
-
}
|
|
373
|
-
add(key, dataApiFactory) {
|
|
374
|
-
let myRoute = this.rootUrl + '/' + key;
|
|
375
|
-
if (this.logApiEndpoints)
|
|
376
|
-
console.log(myRoute);
|
|
377
|
-
this.app.route(myRoute)
|
|
378
|
-
.get(this.process((c, req, res) => dataApiFactory(c).httpGet(res, req))).put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, '', orig.body)))
|
|
379
|
-
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
|
|
380
|
-
.post(this.process(async (c, req, res, orig) => dataApiFactory(c).httpPost(res, req, orig.body)));
|
|
381
|
-
this.app.route(myRoute + '/:id')
|
|
382
|
-
//@ts-ignore
|
|
383
|
-
.get(this.process(async (c, req, res, orig) => dataApiFactory(c).get(res, orig.params.id)))
|
|
384
|
-
//@ts-ignore
|
|
385
|
-
.put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, orig.params.id, orig.body)))
|
|
386
|
-
//@ts-ignore
|
|
387
|
-
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, orig.params.id)));
|
|
388
|
-
}
|
|
389
|
-
process(what) {
|
|
390
|
-
return async (req, res) => {
|
|
391
|
-
let myReq = new ExpressRequestBridgeToDataApiRequest(req);
|
|
392
|
-
let myRes = new ExpressResponseBridgeToDataApiResponse(res, req);
|
|
393
|
-
let remult = new Remult();
|
|
394
|
-
remult.setDataProvider(await this.bridge.dataProvider);
|
|
395
|
-
if (req) {
|
|
396
|
-
let user;
|
|
397
|
-
if (this.bridge.options.getUser)
|
|
398
|
-
user = await this.bridge.options.getUser(req);
|
|
399
|
-
else {
|
|
400
|
-
user = req['user'];
|
|
401
|
-
if (!user)
|
|
402
|
-
user = req['auth'];
|
|
403
|
-
}
|
|
404
|
-
if (user)
|
|
405
|
-
remult.setUser(user);
|
|
406
|
-
}
|
|
407
|
-
if (this.bridge.options.initRequest) {
|
|
408
|
-
await this.bridge.options.initRequest(remult, req);
|
|
409
|
-
}
|
|
410
|
-
what(remult, myReq, myRes, req);
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
;
|
|
414
|
-
async getRemult(req) {
|
|
415
|
-
let remult;
|
|
416
|
-
await this.process(async (c) => {
|
|
417
|
-
remult = c;
|
|
418
|
-
})(req, undefined);
|
|
419
|
-
return remult;
|
|
420
|
-
}
|
|
421
|
-
initQueue() {
|
|
422
|
-
this.addAction({
|
|
423
|
-
__register: x => {
|
|
424
|
-
x(Action.apiUrlForJobStatus, false, () => true, async (data, req, res) => {
|
|
425
|
-
let job = await this.bridge.queue.getJobInfo(data.queuedJobId);
|
|
426
|
-
let userId = undefined;
|
|
427
|
-
if (req?.user)
|
|
428
|
-
userId = req.user.id;
|
|
429
|
-
if (job.userId == '')
|
|
430
|
-
job.userId = undefined;
|
|
431
|
-
if (userId != job.userId)
|
|
432
|
-
res.forbidden();
|
|
433
|
-
else
|
|
434
|
-
res.success(job.info);
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
});
|
|
438
|
-
this.initQueue = () => { };
|
|
439
|
-
}
|
|
440
|
-
addAction(action) {
|
|
441
|
-
action.__register((url, queue, allowed, what) => {
|
|
442
|
-
let myUrl = this.rootUrl + '/' + url;
|
|
443
|
-
let tag = (() => {
|
|
444
|
-
let split = url.split('/');
|
|
445
|
-
if (split.length == 1)
|
|
446
|
-
return 'Static Backend Methods';
|
|
447
|
-
else
|
|
448
|
-
return split[0];
|
|
449
|
-
})();
|
|
450
|
-
this.bridge.backendMethodsOpenApi.push({ path: myUrl, allowed, tag });
|
|
451
|
-
if (this.logApiEndpoints)
|
|
452
|
-
console.log(myUrl);
|
|
453
|
-
if (queue) {
|
|
454
|
-
this.initQueue();
|
|
455
|
-
this.bridge.queue.mapQueuedAction(myUrl, what);
|
|
456
|
-
}
|
|
457
|
-
this.app.route(myUrl).post(this.process(async (remult, req, res, orig) => {
|
|
458
|
-
if (queue) {
|
|
459
|
-
let r = {
|
|
460
|
-
queuedJobId: await this.bridge.queue.submitJob(myUrl, remult, orig.body)
|
|
461
|
-
};
|
|
462
|
-
res.success(r);
|
|
463
|
-
}
|
|
464
|
-
else
|
|
465
|
-
return what(orig.body, remult, res);
|
|
466
|
-
}));
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
export class ExpressRequestBridgeToDataApiRequest {
|
|
477
|
+
class ExpressRequestBridgeToDataApiRequest {
|
|
471
478
|
constructor(r) {
|
|
472
479
|
this.r = r;
|
|
473
480
|
}
|
|
@@ -484,8 +491,6 @@ class ExpressResponseBridgeToDataApiResponse {
|
|
|
484
491
|
this.setStatus(403).end();
|
|
485
492
|
}
|
|
486
493
|
setStatus(status) {
|
|
487
|
-
if (this.r.setStatus)
|
|
488
|
-
return this.r.setStatus(status);
|
|
489
494
|
return this.r.status(status);
|
|
490
495
|
}
|
|
491
496
|
progress(progress) {
|
|
@@ -629,6 +634,114 @@ export class EntityQueueStorage {
|
|
|
629
634
|
return q.id;
|
|
630
635
|
}
|
|
631
636
|
}
|
|
637
|
+
class RouteImplementation {
|
|
638
|
+
constructor() {
|
|
639
|
+
this.map = new Map();
|
|
640
|
+
}
|
|
641
|
+
route(path) {
|
|
642
|
+
//consider using:
|
|
643
|
+
//* https://raw.githubusercontent.com/cmorten/opine/main/src/utils/pathToRegex.ts
|
|
644
|
+
//* https://github.com/pillarjs/path-to-regexp
|
|
645
|
+
let r = path.toLowerCase();
|
|
646
|
+
let m = new Map();
|
|
647
|
+
this.map.set(r, m);
|
|
648
|
+
const route = {
|
|
649
|
+
get: (h) => {
|
|
650
|
+
m.set("get", h);
|
|
651
|
+
return route;
|
|
652
|
+
},
|
|
653
|
+
put: (h) => {
|
|
654
|
+
m.set("put", h);
|
|
655
|
+
return route;
|
|
656
|
+
},
|
|
657
|
+
post: (h) => {
|
|
658
|
+
m.set("post", h);
|
|
659
|
+
return route;
|
|
660
|
+
},
|
|
661
|
+
delete: (h) => {
|
|
662
|
+
m.set("delete", h);
|
|
663
|
+
return route;
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
return route;
|
|
667
|
+
}
|
|
668
|
+
async handle(req, gRes) {
|
|
669
|
+
return new Promise(res => {
|
|
670
|
+
const response = new class {
|
|
671
|
+
constructor() {
|
|
672
|
+
this.statusCode = 200;
|
|
673
|
+
}
|
|
674
|
+
json(data) {
|
|
675
|
+
if (gRes !== undefined)
|
|
676
|
+
gRes.json(data);
|
|
677
|
+
res({ statusCode: this.statusCode, data });
|
|
678
|
+
}
|
|
679
|
+
status(statusCode) {
|
|
680
|
+
if (gRes !== undefined)
|
|
681
|
+
gRes.status(statusCode);
|
|
682
|
+
this.statusCode = statusCode;
|
|
683
|
+
return this;
|
|
684
|
+
}
|
|
685
|
+
end() {
|
|
686
|
+
if (gRes !== undefined)
|
|
687
|
+
gRes.end();
|
|
688
|
+
res({
|
|
689
|
+
statusCode: this.statusCode
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
this.middleware(req, response, () => res(undefined));
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
middleware(req, res, next) {
|
|
697
|
+
let theUrl = req.url;
|
|
698
|
+
if (theUrl.startsWith('/')) //next sends a partial url '/api/tasks' and not the full url
|
|
699
|
+
theUrl = 'http://stam' + theUrl;
|
|
700
|
+
const url = new URL(theUrl);
|
|
701
|
+
const path = url.pathname;
|
|
702
|
+
if (!req.query) {
|
|
703
|
+
let query = {};
|
|
704
|
+
url.searchParams.forEach((val, key) => {
|
|
705
|
+
let current = query[key];
|
|
706
|
+
if (!current) {
|
|
707
|
+
query[key] = val;
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (Array.isArray(current)) {
|
|
711
|
+
current.push(val);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
query[key] = [current, val];
|
|
715
|
+
});
|
|
716
|
+
req.query = query;
|
|
717
|
+
}
|
|
718
|
+
let lowerPath = path.toLowerCase();
|
|
719
|
+
let m = this.map.get(lowerPath);
|
|
720
|
+
if (m) {
|
|
721
|
+
let h = m.get(req.method.toLowerCase());
|
|
722
|
+
if (h) {
|
|
723
|
+
h(req, res, next);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
let idPosition = path.lastIndexOf('/');
|
|
728
|
+
if (idPosition >= 0) {
|
|
729
|
+
lowerPath = path.substring(0, idPosition) + '/:id';
|
|
730
|
+
m = this.map.get(lowerPath);
|
|
731
|
+
if (m) {
|
|
732
|
+
let h = m.get(req.method.toLowerCase());
|
|
733
|
+
if (h) {
|
|
734
|
+
if (!req.params)
|
|
735
|
+
req.params = {};
|
|
736
|
+
req.params.id = path.substring(idPosition + 1);
|
|
737
|
+
h(req, res, next);
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
next();
|
|
743
|
+
}
|
|
744
|
+
}
|
|
632
745
|
let JobsInQueueEntity = class JobsInQueueEntity extends IdEntity {
|
|
633
746
|
};
|
|
634
747
|
__decorate([
|
package/esm/server/index.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export { registerEntitiesOnServer } from './register-entities-on-server';
|
|
4
|
-
export { registerActionsOnServer } from './register-actions-on-server';
|
|
1
|
+
export { queuedJobInfo, QueueStorage, GenericRequest, GenericRequestHandler, GenericResponse, GenericRouter, buildRemultServer, RemultServerOptions, SpecificRoute, RemultServer } from './expressBridge';
|
|
2
|
+
export { JsonEntityFileStorage, JsonFileDataProvider } from './JsonEntityFileStorage';
|
package/esm/server/index.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export { registerEntitiesOnServer } from './register-entities-on-server';
|
|
4
|
-
export { registerActionsOnServer } from './register-actions-on-server';
|
|
1
|
+
export { buildRemultServer } from './expressBridge';
|
|
2
|
+
export { JsonEntityFileStorage, JsonFileDataProvider } from './JsonEntityFileStorage';
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
2
|
import axios from 'axios';
|
|
3
|
+
import { remultFresh } from '../../remult-fresh';
|
|
3
4
|
import { HttpProviderBridgeToRestDataProviderHttpProvider, Remult } from '../context';
|
|
5
|
+
import { InMemoryDataProvider } from '../data-providers/in-memory-database';
|
|
4
6
|
import { Entity, Fields } from '../remult3';
|
|
5
7
|
import { Action, BackendMethod } from '../server-action';
|
|
8
|
+
import { Categories } from '../tests/remult-3-entities';
|
|
6
9
|
Remult.apiBaseUrl = 'http://localhost:3003/api';
|
|
7
10
|
let path = Remult.apiBaseUrl + '/tasks';
|
|
8
11
|
const environments = [
|
|
@@ -11,9 +14,9 @@ const environments = [
|
|
|
11
14
|
// ["koa", 3002],
|
|
12
15
|
// ["fastify", 3003],
|
|
13
16
|
// ["express", 3004],
|
|
14
|
-
// ["
|
|
17
|
+
// ["generic server", 3005],
|
|
15
18
|
// ["optine", 3006],
|
|
16
|
-
// ["fresh", 8000]
|
|
19
|
+
// ["fresh", 8000]
|
|
17
20
|
];
|
|
18
21
|
function test(name, test) {
|
|
19
22
|
for (const [env, port] of environments) {
|
|
@@ -93,6 +96,32 @@ test("test regular api call", async () => {
|
|
|
93
96
|
let result = await axios.get(Remult.apiBaseUrl + "/test");
|
|
94
97
|
expect(result.data.result).toBe(3);
|
|
95
98
|
});
|
|
99
|
+
class FreshResponseTest {
|
|
100
|
+
constructor(body, init) {
|
|
101
|
+
this.body = body;
|
|
102
|
+
this.init = init;
|
|
103
|
+
}
|
|
104
|
+
static json(data, init) {
|
|
105
|
+
return new this(data, init);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
fit("test fresh", async () => {
|
|
109
|
+
const api = remultFresh({ entities: [Categories],
|
|
110
|
+
dataProvider: new InMemoryDataProvider(),
|
|
111
|
+
rootPath: '/api' }, FreshResponseTest);
|
|
112
|
+
const r = await api.freshHandler({
|
|
113
|
+
url: '/api/Categories',
|
|
114
|
+
json() {
|
|
115
|
+
return undefined;
|
|
116
|
+
},
|
|
117
|
+
method: "get"
|
|
118
|
+
}, {
|
|
119
|
+
next() {
|
|
120
|
+
return undefined;
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
expect(r.body).toEqual([]);
|
|
124
|
+
});
|
|
96
125
|
let Task = class Task {
|
|
97
126
|
constructor() {
|
|
98
127
|
this.title = '';
|
package/graphql.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function remultGraphql(api:
|
|
1
|
+
import { RemultServer } from "./server/expressBridge";
|
|
2
|
+
export declare function remultGraphql(api: RemultServer): {
|
|
3
3
|
rootValue: {};
|
|
4
4
|
schema: string;
|
|
5
5
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.34",
|
|
4
4
|
"description": "A CRUD framework for full-stack TypeScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"require": "./remult-express.js",
|
|
29
29
|
"import": "./esm/remult-express.js"
|
|
30
30
|
},
|
|
31
|
-
"./
|
|
32
|
-
"require": "./
|
|
33
|
-
"import": "./esm/
|
|
31
|
+
"./server": {
|
|
32
|
+
"require": "./server/index.js",
|
|
33
|
+
"import": "./esm/server/index.js"
|
|
34
34
|
},
|
|
35
35
|
"./remult-fastify": {
|
|
36
36
|
"require": "./remult-fastify.js",
|
package/remult-express.d.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as express from 'express';
|
|
2
|
+
import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
2
3
|
export declare function remultExpress(options?: RemultServerOptions & {
|
|
3
4
|
bodyParser?: boolean;
|
|
4
5
|
bodySizeLimit?: string;
|
|
5
|
-
}):
|
|
6
|
-
getRemult: (req: any) => Promise<import(".").Remult>;
|
|
7
|
-
openApiDoc: (options: {
|
|
8
|
-
title: string;
|
|
9
|
-
}) => any;
|
|
10
|
-
addArea: (x: any) => void;
|
|
11
|
-
};
|
|
6
|
+
}): express.RequestHandler & RemultServer;
|
package/remult-express.js
CHANGED
|
@@ -15,11 +15,12 @@ function remultExpress(options) {
|
|
|
15
15
|
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
16
16
|
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
17
17
|
}
|
|
18
|
-
var server = expressBridge_1.buildRemultServer(
|
|
18
|
+
var server = expressBridge_1.buildRemultServer(options);
|
|
19
|
+
server.registerRouter(app);
|
|
19
20
|
return Object.assign(app, {
|
|
20
21
|
getRemult: function (req) { return server.getRemult(req); },
|
|
21
22
|
openApiDoc: function (options) { return server.openApiDoc(options); },
|
|
22
|
-
|
|
23
|
+
registerRouter: function (x) { return server.registerRouter(x); }
|
|
23
24
|
});
|
|
24
25
|
}
|
|
25
26
|
exports.remultExpress = remultExpress;
|
package/remult-fastify.js
CHANGED
|
@@ -23,7 +23,7 @@ function remultFastify(options) {
|
|
|
23
23
|
};
|
|
24
24
|
return response;
|
|
25
25
|
}
|
|
26
|
-
var api;
|
|
26
|
+
var api = expressBridge_1.buildRemultServer(options);
|
|
27
27
|
var pluginFunction = function (instance, op) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
28
28
|
var fastifyRouter;
|
|
29
29
|
return tslib_1.__generator(this, function (_a) {
|
|
@@ -48,19 +48,14 @@ function remultFastify(options) {
|
|
|
48
48
|
return r;
|
|
49
49
|
},
|
|
50
50
|
};
|
|
51
|
-
api
|
|
51
|
+
api.registerRouter(fastifyRouter);
|
|
52
52
|
return [2 /*return*/];
|
|
53
53
|
});
|
|
54
54
|
}); };
|
|
55
|
-
var getApi = function () {
|
|
56
|
-
if (!api)
|
|
57
|
-
throw "Please call fastify's register before using this method";
|
|
58
|
-
return api;
|
|
59
|
-
};
|
|
60
55
|
return Object.assign(pluginFunction, {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
getRemult: function (x) { return api.getRemult(x); },
|
|
57
|
+
openApiDoc: function (x) { return api.openApiDoc(x); },
|
|
58
|
+
handle: function (req, res) { return api.handle(req, res); }
|
|
64
59
|
});
|
|
65
60
|
}
|
|
66
61
|
exports.remultFastify = remultFastify;
|
package/remult-fresh.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { RemultServerOptions, RemultServer } from "./server/expressBridge";
|
|
2
|
-
import { Remult } from "./src/context";
|
|
3
2
|
export declare function remultFresh(options: RemultServerOptions, response: FreshResponse): RemultFresh;
|
|
4
3
|
export interface RemultFresh extends RemultServer {
|
|
5
|
-
|
|
4
|
+
freshHandler(req: FreshRequest, ctx: FreshContext): Promise<any>;
|
|
6
5
|
}
|
|
7
6
|
export interface FreshRequest {
|
|
8
7
|
url: string;
|
|
@@ -11,12 +10,8 @@ export interface FreshRequest {
|
|
|
11
10
|
}
|
|
12
11
|
export interface FreshContext {
|
|
13
12
|
next: () => Promise<any>;
|
|
14
|
-
state: FreshRemultState;
|
|
15
13
|
}
|
|
16
14
|
export interface FreshResponse {
|
|
17
15
|
new (body?: any | undefined, init?: ResponseInit): any;
|
|
18
16
|
json(data: unknown, init?: ResponseInit): any;
|
|
19
17
|
}
|
|
20
|
-
export interface FreshRemultState {
|
|
21
|
-
remult: Remult;
|
|
22
|
-
}
|