remult 0.19.3 → 0.20.0-exp.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/graphql.d.ts +1 -1
- package/esm/remult-express.d.ts +1 -1
- package/esm/remult-express.js +3 -1
- package/esm/remult-fastify.d.ts +1 -1
- package/esm/remult-fastify.js +3 -1
- package/esm/remult-fresh.d.ts +3 -3
- package/esm/remult-fresh.js +4 -2
- package/esm/remult-next.d.ts +1 -1
- package/esm/remult-next.js +4 -2
- package/esm/remult-sveltekit.d.ts +3 -0
- package/esm/remult-sveltekit.js +83 -0
- package/esm/remult-svletekit.d.ts +3 -0
- package/esm/remult-svletekit.js +83 -0
- package/esm/server/expressBridge.d.ts +13 -10
- package/esm/server/expressBridge.js +70 -56
- package/esm/server/index.d.ts +2 -2
- package/esm/server/index.js +2 -2
- package/esm/src/data-api.d.ts +3 -3
- package/esm/src/data-api.js +1 -1
- package/esm/src/live-query/SubscriptionServer.js +3 -3
- package/esm/src/remult3/RepositoryImplementation.js +1 -1
- package/esm/src/tests/testHelper.spec.js +2 -2
- package/graphql.d.ts +1 -1
- package/package.json +9 -1
- package/remult-express.d.ts +1 -1
- package/remult-express.js +3 -1
- package/remult-fastify.d.ts +1 -1
- package/remult-fastify.js +3 -1
- package/remult-fresh.d.ts +3 -3
- package/remult-fresh.js +4 -2
- package/remult-next.d.ts +1 -1
- package/remult-next.js +4 -2
- package/remult-sveltekit.d.ts +3 -0
- package/remult-sveltekit.js +136 -0
- package/remult-svletekit.d.ts +3 -0
- package/remult-svletekit.js +136 -0
- package/server/expressBridge.d.ts +13 -10
- package/server/expressBridge.js +157 -116
- package/server/index.d.ts +2 -2
- package/server/index.js +2 -2
- package/src/data-api.d.ts +3 -3
- package/src/data-api.js +20 -17
- package/src/live-query/SubscriptionServer.js +3 -3
- package/src/remult3/RepositoryImplementation.js +1 -1
- package/src/tests/testHelper.spec.js +8 -2
package/esm/graphql.d.ts
CHANGED
package/esm/remult-express.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
|
3
3
|
export declare function remultExpress(options?: RemultServerOptions<express.Request> & {
|
|
4
4
|
bodyParser?: boolean;
|
|
5
5
|
bodySizeLimit?: string;
|
|
6
|
-
}): express.RequestHandler & RemultServer
|
|
6
|
+
}): express.RequestHandler & RemultServer<express.Request>;
|
package/esm/remult-express.js
CHANGED
|
@@ -12,7 +12,9 @@ export function remultExpress(options) {
|
|
|
12
12
|
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
13
13
|
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
14
14
|
}
|
|
15
|
-
const server = createRemultServer(options
|
|
15
|
+
const server = createRemultServer(options, {
|
|
16
|
+
buildGenericRequest: req => req
|
|
17
|
+
});
|
|
16
18
|
server.registerRouter(app);
|
|
17
19
|
return Object.assign(app, {
|
|
18
20
|
getRemult: (req) => server.getRemult(req),
|
package/esm/remult-fastify.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { FastifyPluginCallback, FastifyRequest } from 'fastify';
|
|
2
2
|
import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
3
|
-
export declare function remultFastify(options: RemultServerOptions<FastifyRequest>): FastifyPluginCallback & RemultServer
|
|
3
|
+
export declare function remultFastify(options: RemultServerOptions<FastifyRequest>): FastifyPluginCallback & RemultServer<FastifyRequest>;
|
package/esm/remult-fastify.js
CHANGED
|
@@ -29,7 +29,9 @@ export function remultFastify(options) {
|
|
|
29
29
|
};
|
|
30
30
|
return response;
|
|
31
31
|
}
|
|
32
|
-
const api = createRemultServer(options
|
|
32
|
+
const api = createRemultServer(options, {
|
|
33
|
+
buildGenericRequest: req => req
|
|
34
|
+
});
|
|
33
35
|
const pluginFunction = async (instance, op) => {
|
|
34
36
|
//@ts-ignore
|
|
35
37
|
let fastifyRouter = {
|
package/esm/remult-fresh.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { RemultServerOptions
|
|
1
|
+
import { RemultServerOptions } from "./server/expressBridge";
|
|
2
2
|
import { Remult } from "./src/context";
|
|
3
|
-
export declare function remultFresh
|
|
3
|
+
export declare function remultFresh(options: RemultServerOptions<FreshRequest>, response: FreshResponse): RemultFresh;
|
|
4
4
|
export interface RemultFresh {
|
|
5
|
-
getRemult(req:
|
|
5
|
+
getRemult(req: FreshRequest): Promise<Remult>;
|
|
6
6
|
openApiDoc(options: {
|
|
7
7
|
title: string;
|
|
8
8
|
}): any;
|
package/esm/remult-fresh.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createRemultServerCore } from "./server/expressBridge";
|
|
2
2
|
export function remultFresh(options, response) {
|
|
3
|
-
const server = createRemultServerCore(options
|
|
3
|
+
const server = createRemultServerCore(options, {
|
|
4
|
+
buildGenericRequest: r => r
|
|
5
|
+
});
|
|
4
6
|
return {
|
|
5
7
|
getRemult: r => server.getRemult(r),
|
|
6
8
|
openApiDoc: x => server.openApiDoc(x),
|
|
@@ -17,7 +19,7 @@ export function remultFresh(options, response) {
|
|
|
17
19
|
break;
|
|
18
20
|
}
|
|
19
21
|
let init = {};
|
|
20
|
-
const res = await server.handle(
|
|
22
|
+
const res = await server.handle(req);
|
|
21
23
|
if (res) {
|
|
22
24
|
init.status = res.statusCode;
|
|
23
25
|
if (res.data) {
|
package/esm/remult-next.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { GetServerSideProps, NextApiRequest, PreviewData, NextApiHandler } from "next";
|
|
3
3
|
import type { ParsedUrlQuery } from "querystring";
|
|
4
4
|
import { RemultServer, RemultServerOptions } from "./server";
|
|
5
|
-
export declare function remultNext(options?: RemultServerOptions<NextApiRequest>): RemultServer & NextApiHandler & {
|
|
5
|
+
export declare function remultNext(options?: RemultServerOptions<NextApiRequest>): RemultServer<NextApiRequest> & NextApiHandler & {
|
|
6
6
|
getServerSideProps<P extends {
|
|
7
7
|
[key: string]: any;
|
|
8
8
|
} = {
|
package/esm/remult-next.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createRemultServer } from "./server";
|
|
2
2
|
export function remultNext(options) {
|
|
3
|
-
let result = createRemultServer(options
|
|
4
|
-
|
|
3
|
+
let result = createRemultServer(options, {
|
|
4
|
+
buildGenericRequest: req => req
|
|
5
|
+
});
|
|
6
|
+
return Object.assign((req, res) => result.handle(req, res).then(() => { }), result, {
|
|
5
7
|
getRemult: (...args) => result.getRemult(...args),
|
|
6
8
|
handle: (...args) => result.handle(...args),
|
|
7
9
|
openApiDoc: (...args) => result.openApiDoc(...args),
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createRemultServer } from './server';
|
|
2
|
+
export function remultSveltekit(options) {
|
|
3
|
+
let result = createRemultServer(options, {
|
|
4
|
+
buildGenericRequest: event => ({
|
|
5
|
+
url: event.request.url,
|
|
6
|
+
method: event.request.method,
|
|
7
|
+
body: event.locals["_tempJson"],
|
|
8
|
+
on: (e, do1) => {
|
|
9
|
+
if (e === 'close') {
|
|
10
|
+
event.locals["_tempOnClose"] = do1;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
});
|
|
15
|
+
const handler = async ({ event, resolve }) => {
|
|
16
|
+
if (event.url.pathname.startsWith(options.rootPath)) {
|
|
17
|
+
let json = {};
|
|
18
|
+
try {
|
|
19
|
+
if (event.request.method == 'POST' || event.request.method == 'PUT') {
|
|
20
|
+
json = await event.request.json();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.log(error);
|
|
25
|
+
}
|
|
26
|
+
let sseResponse = undefined;
|
|
27
|
+
event.locals["_tempOnClose"] = () => { };
|
|
28
|
+
const response = {
|
|
29
|
+
end: () => { },
|
|
30
|
+
json: () => { },
|
|
31
|
+
status: () => {
|
|
32
|
+
return response;
|
|
33
|
+
},
|
|
34
|
+
write: () => { },
|
|
35
|
+
writeHead: (status, headers) => {
|
|
36
|
+
if (status === 200 && headers) {
|
|
37
|
+
const contentType = headers['Content-Type'];
|
|
38
|
+
if (contentType === 'text/event-stream') {
|
|
39
|
+
const messages = [];
|
|
40
|
+
response.write = (x) => messages.push(x);
|
|
41
|
+
const stream = new ReadableStream({
|
|
42
|
+
start: (controller) => {
|
|
43
|
+
for (const message of messages) {
|
|
44
|
+
controller.enqueue(message);
|
|
45
|
+
}
|
|
46
|
+
response.write = (data) => {
|
|
47
|
+
controller.enqueue(data);
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
cancel: () => {
|
|
51
|
+
response.write = () => { };
|
|
52
|
+
event.locals["_tempOnClose"]();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
sseResponse = new Response(stream, { headers });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
event.locals["_tempJson"] = json;
|
|
61
|
+
const responseFromRemultHandler = await result.handle(event, response);
|
|
62
|
+
if (sseResponse !== undefined) {
|
|
63
|
+
return sseResponse;
|
|
64
|
+
}
|
|
65
|
+
if (responseFromRemultHandler) {
|
|
66
|
+
return new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
67
|
+
status: responseFromRemultHandler.statusCode
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return new Promise((res) => {
|
|
72
|
+
result.withRemult(event, undefined, async () => {
|
|
73
|
+
res(await resolve(event));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
return Object.assign(handler, {
|
|
78
|
+
getRemult: (req) => result.getRemult(req),
|
|
79
|
+
openApiDoc: (options) => result.openApiDoc(options),
|
|
80
|
+
registerRouter: x => result.registerRouter(x),
|
|
81
|
+
withRemult: (...args) => result.withRemult(...args)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createRemultServer } from './server';
|
|
2
|
+
export function remultSveltekit(options) {
|
|
3
|
+
let result = createRemultServer(options, {
|
|
4
|
+
buildGenericRequest: event => ({
|
|
5
|
+
url: event.request.url,
|
|
6
|
+
method: event.request.method,
|
|
7
|
+
body: event.locals["_tempJson"],
|
|
8
|
+
on: (e, do1) => {
|
|
9
|
+
if (e === 'close') {
|
|
10
|
+
event.locals["_tempOnClose"] = do1;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
});
|
|
15
|
+
const handler = async ({ event, resolve }) => {
|
|
16
|
+
if (event.url.pathname.startsWith(options.rootPath)) {
|
|
17
|
+
let json = {};
|
|
18
|
+
try {
|
|
19
|
+
if (event.request.method == 'POST' || event.request.method == 'PUT') {
|
|
20
|
+
json = await event.request.json();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.log(error);
|
|
25
|
+
}
|
|
26
|
+
let sseResponse = undefined;
|
|
27
|
+
event.locals["_tempOnClose"] = () => { };
|
|
28
|
+
const response = {
|
|
29
|
+
end: () => { },
|
|
30
|
+
json: () => { },
|
|
31
|
+
status: () => {
|
|
32
|
+
return response;
|
|
33
|
+
},
|
|
34
|
+
write: () => { },
|
|
35
|
+
writeHead: (status, headers) => {
|
|
36
|
+
if (status === 200 && headers) {
|
|
37
|
+
const contentType = headers['Content-Type'];
|
|
38
|
+
if (contentType === 'text/event-stream') {
|
|
39
|
+
const messages = [];
|
|
40
|
+
response.write = (x) => messages.push(x);
|
|
41
|
+
const stream = new ReadableStream({
|
|
42
|
+
start: (controller) => {
|
|
43
|
+
for (const message of messages) {
|
|
44
|
+
controller.enqueue(message);
|
|
45
|
+
}
|
|
46
|
+
response.write = (data) => {
|
|
47
|
+
controller.enqueue(data);
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
cancel: () => {
|
|
51
|
+
response.write = () => { };
|
|
52
|
+
event.locals["_tempOnClose"]();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
sseResponse = new Response(stream, { headers });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
event.locals["_tempJson"] = json;
|
|
61
|
+
const responseFromRemultHandler = await result.handle(event, response);
|
|
62
|
+
if (sseResponse !== undefined) {
|
|
63
|
+
return sseResponse;
|
|
64
|
+
}
|
|
65
|
+
if (responseFromRemultHandler) {
|
|
66
|
+
return new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
67
|
+
status: responseFromRemultHandler.statusCode
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return new Promise((res) => {
|
|
72
|
+
result.withRemult(event, undefined, async () => {
|
|
73
|
+
res(await resolve(event));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
return Object.assign(handler, {
|
|
78
|
+
getRemult: (req) => result.getRemult(req),
|
|
79
|
+
openApiDoc: (options) => result.openApiDoc(options),
|
|
80
|
+
registerRouter: x => result.registerRouter(x),
|
|
81
|
+
withRemult: (...args) => result.withRemult(...args)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -5,7 +5,7 @@ import { ClassType } from '../classType';
|
|
|
5
5
|
import { Repository } from '../src/remult3';
|
|
6
6
|
import { IdEntity } from '../src/id-entity';
|
|
7
7
|
import { LiveQueryStorage, SubscriptionServer } from '../src/live-query/SubscriptionServer';
|
|
8
|
-
export interface RemultServerOptions<RequestType
|
|
8
|
+
export interface RemultServerOptions<RequestType> {
|
|
9
9
|
/**Entities to use for the api */
|
|
10
10
|
entities?: ClassType<any>[];
|
|
11
11
|
/**Controller to use for the api */
|
|
@@ -41,10 +41,10 @@ export interface RemultServerOptions<RequestType extends GenericRequest> {
|
|
|
41
41
|
subscriptionServer?: SubscriptionServer;
|
|
42
42
|
/** A storage to use to store live queries, relevant mostly for serverless scenarios or larger scales */
|
|
43
43
|
liveQueryStorage?: LiveQueryStorage;
|
|
44
|
-
/** Used to store the
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
/** Used to store the context relevant info for re running a live query */
|
|
45
|
+
contextSerializer?: {
|
|
46
|
+
serialize(remult: Remult): Promise<any>;
|
|
47
|
+
deserialize(json: any, remult: Remult): Promise<void>;
|
|
48
48
|
};
|
|
49
49
|
/** Storage to use for backend methods that use queue */
|
|
50
50
|
queueStorage?: QueueStorage;
|
|
@@ -53,21 +53,21 @@ export interface InitRequestOptions {
|
|
|
53
53
|
liveQueryStorage: LiveQueryStorage;
|
|
54
54
|
readonly remult: Remult;
|
|
55
55
|
}
|
|
56
|
-
export declare function createRemultServerCore<RequestType
|
|
56
|
+
export declare function createRemultServerCore<RequestType>(options: RemultServerOptions<RequestType>, serverCoreOptions: ServerCoreOptions<RequestType>): RemultServer<RequestType>;
|
|
57
57
|
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
58
58
|
export interface ServerHandleResponse {
|
|
59
59
|
data?: any;
|
|
60
60
|
statusCode: number;
|
|
61
61
|
}
|
|
62
|
-
export interface RemultServer {
|
|
63
|
-
getRemult(req:
|
|
62
|
+
export interface RemultServer<RequestType> {
|
|
63
|
+
getRemult(req: RequestType): Promise<Remult>;
|
|
64
64
|
openApiDoc(options: {
|
|
65
65
|
title: string;
|
|
66
66
|
version?: string;
|
|
67
67
|
}): any;
|
|
68
68
|
registerRouter(r: GenericRouter): void;
|
|
69
|
-
handle(req:
|
|
70
|
-
withRemult(req:
|
|
69
|
+
handle(req: RequestType, gRes?: GenericResponse): Promise<ServerHandleResponse | undefined>;
|
|
70
|
+
withRemult(req: RequestType, res: GenericResponse, next: VoidFunction): any;
|
|
71
71
|
}
|
|
72
72
|
export declare type GenericRouter = {
|
|
73
73
|
route(path: string): SpecificRoute;
|
|
@@ -128,3 +128,6 @@ export declare class JobsInQueueEntity extends IdEntity {
|
|
|
128
128
|
error: boolean;
|
|
129
129
|
progress: number;
|
|
130
130
|
}
|
|
131
|
+
export interface ServerCoreOptions<RequestType> {
|
|
132
|
+
buildGenericRequest(req: RequestType): GenericRequest;
|
|
133
|
+
}
|
|
@@ -10,7 +10,7 @@ import { liveQueryKeepAliveRoute, streamUrl } from '../src/live-query/Subscripti
|
|
|
10
10
|
import { initDataProvider } from './initDataProvider';
|
|
11
11
|
import { SseSubscriptionServer } from "../SseSubscriptionServer";
|
|
12
12
|
;
|
|
13
|
-
export function createRemultServerCore(options) {
|
|
13
|
+
export function createRemultServerCore(options, serverCoreOptions) {
|
|
14
14
|
if (!options) {
|
|
15
15
|
options = {};
|
|
16
16
|
}
|
|
@@ -63,23 +63,6 @@ export function createRemultServerCore(options) {
|
|
|
63
63
|
});
|
|
64
64
|
return dp;
|
|
65
65
|
});
|
|
66
|
-
if (!options.requestSerializer) {
|
|
67
|
-
options.requestSerializer = {
|
|
68
|
-
toJson: x => {
|
|
69
|
-
const r = {
|
|
70
|
-
url: x.url
|
|
71
|
-
};
|
|
72
|
-
for (const key of ['session', 'auth', 'user']) {
|
|
73
|
-
if (x[key])
|
|
74
|
-
r[key] = x[key];
|
|
75
|
-
}
|
|
76
|
-
return r;
|
|
77
|
-
},
|
|
78
|
-
fromJson: x => {
|
|
79
|
-
return x;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
66
|
{
|
|
84
67
|
let allControllers = [];
|
|
85
68
|
if (!options.entities)
|
|
@@ -93,7 +76,7 @@ export function createRemultServerCore(options) {
|
|
|
93
76
|
if (options.rootPath === undefined)
|
|
94
77
|
options.rootPath = '/api';
|
|
95
78
|
actionInfo.runningOnServer = true;
|
|
96
|
-
let bridge = new RemultServerImplementation(new inProcessQueueHandler(options.queueStorage), options, dataProvider);
|
|
79
|
+
let bridge = new RemultServerImplementation(new inProcessQueueHandler(options.queueStorage), options, dataProvider, serverCoreOptions);
|
|
97
80
|
return bridge;
|
|
98
81
|
}
|
|
99
82
|
;
|
|
@@ -129,20 +112,22 @@ export class RemultAsyncLocalStorage {
|
|
|
129
112
|
RemultAsyncLocalStorage.instance = new RemultAsyncLocalStorage(undefined);
|
|
130
113
|
/* @internal*/
|
|
131
114
|
export class RemultServerImplementation {
|
|
132
|
-
constructor(queue, options, dataProvider) {
|
|
115
|
+
constructor(queue, options, dataProvider, coreOptions) {
|
|
133
116
|
this.queue = queue;
|
|
134
117
|
this.options = options;
|
|
135
118
|
this.dataProvider = dataProvider;
|
|
119
|
+
this.coreOptions = coreOptions;
|
|
136
120
|
this.liveQueryStorage = new InMemoryLiveQueryStorage();
|
|
137
|
-
this.
|
|
121
|
+
this.runWithSerializedJsonContextData = async (jsonContextData, entityKey, what) => {
|
|
138
122
|
for (const e of this.options.entities) {
|
|
139
123
|
let key = getEntityKey(e);
|
|
140
124
|
if (key === entityKey) {
|
|
141
|
-
await
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
125
|
+
await this.runWithRemult(async (remult) => {
|
|
126
|
+
remult.user = jsonContextData.user;
|
|
127
|
+
if (this.options.contextSerializer) {
|
|
128
|
+
await this.options.contextSerializer.deserialize(jsonContextData, remult);
|
|
129
|
+
}
|
|
130
|
+
await what(remult.repo(e));
|
|
146
131
|
});
|
|
147
132
|
return;
|
|
148
133
|
}
|
|
@@ -164,7 +149,7 @@ export class RemultServerImplementation {
|
|
|
164
149
|
}
|
|
165
150
|
getRouteImpl() {
|
|
166
151
|
if (!this.routeImpl) {
|
|
167
|
-
this.routeImpl = new RouteImplementation();
|
|
152
|
+
this.routeImpl = new RouteImplementation(this.coreOptions);
|
|
168
153
|
this.registerRouter(this.routeImpl);
|
|
169
154
|
}
|
|
170
155
|
return this.routeImpl;
|
|
@@ -230,14 +215,24 @@ export class RemultServerImplementation {
|
|
|
230
215
|
}, r);
|
|
231
216
|
});
|
|
232
217
|
}
|
|
218
|
+
async serializeContext(remult) {
|
|
219
|
+
let result = {
|
|
220
|
+
user: remult.user,
|
|
221
|
+
context: undefined
|
|
222
|
+
};
|
|
223
|
+
if (this.options.contextSerializer) {
|
|
224
|
+
result.context = await this.options.contextSerializer.serialize(remult);
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
233
228
|
add(key, dataApiFactory, r) {
|
|
234
229
|
let myRoute = this.options.rootPath + '/' + key;
|
|
235
230
|
if (this.options.logApiEndPoints)
|
|
236
231
|
console.info("[remult] " + myRoute);
|
|
237
232
|
r.route(myRoute)
|
|
238
|
-
.get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.
|
|
233
|
+
.get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.serializeContext(c)))).put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, '', orig.body)))
|
|
239
234
|
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
|
|
240
|
-
.post(this.process(async (c, req, res, orig) => dataApiFactory(c).httpPost(res, req, orig.body, () => this.
|
|
235
|
+
.post(this.process(async (c, req, res, orig) => dataApiFactory(c).httpPost(res, req, orig.body, () => this.serializeContext(c))));
|
|
241
236
|
r.route(myRoute + '/:id')
|
|
242
237
|
//@ts-ignore
|
|
243
238
|
.get(this.process(async (c, req, res, orig) => dataApiFactory(c).get(res, orig.params.id)))
|
|
@@ -246,29 +241,44 @@ export class RemultServerImplementation {
|
|
|
246
241
|
//@ts-ignore
|
|
247
242
|
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, orig.params.id)));
|
|
248
243
|
}
|
|
244
|
+
async runWithRemult(what) {
|
|
245
|
+
let remult = new Remult();
|
|
246
|
+
remult.liveQueryPublisher = new LiveQueryPublisher(() => remult.subscriptionServer, () => remult.liveQueryStorage, this.runWithSerializedJsonContextData);
|
|
247
|
+
remult.dataProvider = (await this.dataProvider);
|
|
248
|
+
remult.subscriptionServer = this.subscriptionServer;
|
|
249
|
+
remult.liveQueryStorage = this.liveQueryStorage;
|
|
250
|
+
await new Promise(res => {
|
|
251
|
+
RemultAsyncLocalStorage.instance.run(remult, async () => {
|
|
252
|
+
res(await what(remult));
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
249
256
|
process(what) {
|
|
250
257
|
return async (req, origRes) => {
|
|
251
|
-
|
|
258
|
+
const genReq = this.coreOptions.buildGenericRequest(req);
|
|
259
|
+
if (!genReq.query) {
|
|
260
|
+
genReq.query = req["_tempQuery"];
|
|
261
|
+
}
|
|
262
|
+
if (!genReq.params)
|
|
263
|
+
genReq.params = req["_tempParams"];
|
|
264
|
+
let myReq = new ExpressRequestBridgeToDataApiRequest(genReq);
|
|
252
265
|
let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
user = req['
|
|
266
|
-
if (!user)
|
|
267
|
-
user = req['auth'];
|
|
268
|
-
}
|
|
269
|
-
if (user)
|
|
270
|
-
remult.user = (user);
|
|
266
|
+
await this.runWithRemult(async (remult) => {
|
|
267
|
+
remult.liveQueryPublisher = new LiveQueryPublisher(() => remult.subscriptionServer, () => remult.liveQueryStorage, this.runWithSerializedJsonContextData);
|
|
268
|
+
remult.dataProvider = (await this.dataProvider);
|
|
269
|
+
remult.subscriptionServer = this.subscriptionServer;
|
|
270
|
+
remult.liveQueryStorage = this.liveQueryStorage;
|
|
271
|
+
if (req) {
|
|
272
|
+
let user;
|
|
273
|
+
if (this.options.getUser)
|
|
274
|
+
user = await this.options.getUser(req);
|
|
275
|
+
else {
|
|
276
|
+
user = req['user'];
|
|
277
|
+
if (!user)
|
|
278
|
+
user = req['auth'];
|
|
271
279
|
}
|
|
280
|
+
if (user)
|
|
281
|
+
remult.user = (user);
|
|
272
282
|
if (this.options.initRequest) {
|
|
273
283
|
await this.options.initRequest(req, {
|
|
274
284
|
remult,
|
|
@@ -280,9 +290,8 @@ export class RemultServerImplementation {
|
|
|
280
290
|
}
|
|
281
291
|
});
|
|
282
292
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
});
|
|
293
|
+
}
|
|
294
|
+
await what(remult, myReq, myRes, genReq, origRes);
|
|
286
295
|
});
|
|
287
296
|
};
|
|
288
297
|
}
|
|
@@ -776,7 +785,8 @@ export class EntityQueueStorage {
|
|
|
776
785
|
}
|
|
777
786
|
}
|
|
778
787
|
class RouteImplementation {
|
|
779
|
-
constructor() {
|
|
788
|
+
constructor(coreOptions) {
|
|
789
|
+
this.coreOptions = coreOptions;
|
|
780
790
|
this.map = new Map();
|
|
781
791
|
}
|
|
782
792
|
route(path) {
|
|
@@ -846,7 +856,8 @@ class RouteImplementation {
|
|
|
846
856
|
this.middleware(req, response, () => res(undefined));
|
|
847
857
|
});
|
|
848
858
|
}
|
|
849
|
-
middleware(
|
|
859
|
+
middleware(origReq, res, next) {
|
|
860
|
+
const req = this.coreOptions.buildGenericRequest(origReq);
|
|
850
861
|
let theUrl = req.url;
|
|
851
862
|
if (theUrl.startsWith('/')) //next sends a partial url '/api/tasks' and not the full url
|
|
852
863
|
theUrl = 'http://stam' + theUrl;
|
|
@@ -866,6 +877,7 @@ class RouteImplementation {
|
|
|
866
877
|
}
|
|
867
878
|
query[key] = [current, val];
|
|
868
879
|
});
|
|
880
|
+
origReq["_tempQuery"] = query;
|
|
869
881
|
req.query = query;
|
|
870
882
|
}
|
|
871
883
|
let lowerPath = path.toLowerCase();
|
|
@@ -873,7 +885,7 @@ class RouteImplementation {
|
|
|
873
885
|
if (m) {
|
|
874
886
|
let h = m.get(req.method.toLowerCase());
|
|
875
887
|
if (h) {
|
|
876
|
-
h(
|
|
888
|
+
h(origReq, res, next);
|
|
877
889
|
return;
|
|
878
890
|
}
|
|
879
891
|
}
|
|
@@ -884,10 +896,12 @@ class RouteImplementation {
|
|
|
884
896
|
if (m) {
|
|
885
897
|
let h = m.get(req.method.toLowerCase());
|
|
886
898
|
if (h) {
|
|
887
|
-
if (!req.params)
|
|
899
|
+
if (!req.params) {
|
|
888
900
|
req.params = {};
|
|
901
|
+
origReq["_tempParams"] = req.params;
|
|
902
|
+
}
|
|
889
903
|
req.params.id = path.substring(idPosition + 1);
|
|
890
|
-
h(
|
|
904
|
+
h(origReq, res, next);
|
|
891
905
|
return;
|
|
892
906
|
}
|
|
893
907
|
}
|
package/esm/server/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RemultServer, RemultServerOptions, ServerCoreOptions } from './expressBridge';
|
|
2
2
|
export { queuedJobInfo, QueueStorage, GenericRequest, GenericRequestHandler, GenericResponse, GenericRouter, RemultServerOptions, SpecificRoute, RemultServer, InitRequestOptions } from './expressBridge';
|
|
3
3
|
export { JsonEntityFileStorage, JsonFileDataProvider } from './JsonEntityFileStorage';
|
|
4
4
|
export { DataProviderLiveQueryStorage } from '../live-query/data-provider-live-query-storage';
|
|
5
5
|
export { SseSubscriptionServer } from '../SseSubscriptionServer';
|
|
6
|
-
export declare function createRemultServer<RequestType
|
|
6
|
+
export declare function createRemultServer<RequestType>(options: RemultServerOptions<RequestType>, serverCoreOptions?: ServerCoreOptions<RequestType>): RemultServer<RequestType>;
|
package/esm/server/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { initAsyncHooks } from './initAsyncHooks';
|
|
|
3
3
|
export { JsonEntityFileStorage, JsonFileDataProvider } from './JsonEntityFileStorage';
|
|
4
4
|
export { DataProviderLiveQueryStorage } from '../live-query/data-provider-live-query-storage';
|
|
5
5
|
export { SseSubscriptionServer } from '../SseSubscriptionServer';
|
|
6
|
-
export function createRemultServer(options) {
|
|
6
|
+
export function createRemultServer(options, serverCoreOptions) {
|
|
7
7
|
initAsyncHooks();
|
|
8
|
-
return createRemultServerCore(options);
|
|
8
|
+
return createRemultServerCore(options, serverCoreOptions || { buildGenericRequest: req => req });
|
|
9
9
|
}
|
package/esm/src/data-api.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ export declare class DataApi<T = any> {
|
|
|
5
5
|
private repository;
|
|
6
6
|
private remult;
|
|
7
7
|
constructor(repository: Repository<T>, remult: Remult);
|
|
8
|
-
httpGet(res: DataApiResponse, req: DataApiRequest, serializeRequest: () => any): Promise<void>;
|
|
9
|
-
httpPost(res: DataApiResponse, req: DataApiRequest, body: any, serializeRequest: () => any): Promise<void>;
|
|
8
|
+
httpGet(res: DataApiResponse, req: DataApiRequest, serializeRequest: () => Promise<any>): Promise<void>;
|
|
9
|
+
httpPost(res: DataApiResponse, req: DataApiRequest, body: any, serializeRequest: () => Promise<any>): Promise<void>;
|
|
10
10
|
static defaultGetLimit: number;
|
|
11
11
|
get(response: DataApiResponse, id: any): Promise<void>;
|
|
12
12
|
count(response: DataApiResponse, request: DataApiRequest, filterBody?: any): Promise<void>;
|
|
@@ -15,7 +15,7 @@ export declare class DataApi<T = any> {
|
|
|
15
15
|
findOptions: FindOptions<T>;
|
|
16
16
|
}>;
|
|
17
17
|
getArray(response: DataApiResponse, request: DataApiRequest, filterBody?: any): Promise<void>;
|
|
18
|
-
liveQuery(response: DataApiResponse, request: DataApiRequest, filterBody: any, serializeRequest: () => any
|
|
18
|
+
liveQuery(response: DataApiResponse, request: DataApiRequest, filterBody: any, serializeRequest: () => Promise<any>, queryChannel: string): Promise<void>;
|
|
19
19
|
private buildWhere;
|
|
20
20
|
private doOnId;
|
|
21
21
|
put(response: DataApiResponse, id: any, body: any): Promise<void>;
|
package/esm/src/data-api.js
CHANGED
|
@@ -128,7 +128,7 @@ export class DataApi {
|
|
|
128
128
|
try {
|
|
129
129
|
const r = await this.getArrayImpl(response, request, filterBody);
|
|
130
130
|
const data = {
|
|
131
|
-
requestJson: serializeRequest(),
|
|
131
|
+
requestJson: await serializeRequest(),
|
|
132
132
|
findOptionsJson: findOptionsToJson(r.findOptions, this.repository.metadata),
|
|
133
133
|
lastIds: r.r.map(y => this.repository.metadata.idMetadata.getId(y))
|
|
134
134
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { findOptionsFromJson } from '../data-providers/rest-data-provider';
|
|
2
2
|
/* @internal*/
|
|
3
3
|
export class LiveQueryPublisher {
|
|
4
|
-
constructor(subscriptionServer, liveQueryStorage,
|
|
4
|
+
constructor(subscriptionServer, liveQueryStorage, performWithContext) {
|
|
5
5
|
this.subscriptionServer = subscriptionServer;
|
|
6
6
|
this.liveQueryStorage = liveQueryStorage;
|
|
7
|
-
this.
|
|
7
|
+
this.performWithContext = performWithContext;
|
|
8
8
|
this.debugFileSaver = (x) => { };
|
|
9
9
|
}
|
|
10
10
|
runPromise(p) { }
|
|
@@ -12,7 +12,7 @@ export class LiveQueryPublisher {
|
|
|
12
12
|
//TODO 2 - optimize so that the user will get their messages first. Based on user id
|
|
13
13
|
await (this.liveQueryStorage().forEach(entityKey, async ({ query: q, setData }) => {
|
|
14
14
|
let query = { ...q.data };
|
|
15
|
-
await this.
|
|
15
|
+
await this.performWithContext(query.requestJson, entityKey, async (repo) => {
|
|
16
16
|
const messages = [];
|
|
17
17
|
const currentItems = await repo.find(findOptionsFromJson(query.findOptionsJson, repo.metadata));
|
|
18
18
|
const currentIds = currentItems.map(x => repo.getEntityRef(x).getId());
|