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.
Files changed (45) hide show
  1. package/esm/graphql.d.ts +1 -1
  2. package/esm/remult-express.d.ts +1 -1
  3. package/esm/remult-express.js +3 -1
  4. package/esm/remult-fastify.d.ts +1 -1
  5. package/esm/remult-fastify.js +3 -1
  6. package/esm/remult-fresh.d.ts +3 -3
  7. package/esm/remult-fresh.js +4 -2
  8. package/esm/remult-next.d.ts +1 -1
  9. package/esm/remult-next.js +4 -2
  10. package/esm/remult-sveltekit.d.ts +3 -0
  11. package/esm/remult-sveltekit.js +83 -0
  12. package/esm/remult-svletekit.d.ts +3 -0
  13. package/esm/remult-svletekit.js +83 -0
  14. package/esm/server/expressBridge.d.ts +13 -10
  15. package/esm/server/expressBridge.js +70 -56
  16. package/esm/server/index.d.ts +2 -2
  17. package/esm/server/index.js +2 -2
  18. package/esm/src/data-api.d.ts +3 -3
  19. package/esm/src/data-api.js +1 -1
  20. package/esm/src/live-query/SubscriptionServer.js +3 -3
  21. package/esm/src/remult3/RepositoryImplementation.js +1 -1
  22. package/esm/src/tests/testHelper.spec.js +2 -2
  23. package/graphql.d.ts +1 -1
  24. package/package.json +9 -1
  25. package/remult-express.d.ts +1 -1
  26. package/remult-express.js +3 -1
  27. package/remult-fastify.d.ts +1 -1
  28. package/remult-fastify.js +3 -1
  29. package/remult-fresh.d.ts +3 -3
  30. package/remult-fresh.js +4 -2
  31. package/remult-next.d.ts +1 -1
  32. package/remult-next.js +4 -2
  33. package/remult-sveltekit.d.ts +3 -0
  34. package/remult-sveltekit.js +136 -0
  35. package/remult-svletekit.d.ts +3 -0
  36. package/remult-svletekit.js +136 -0
  37. package/server/expressBridge.d.ts +13 -10
  38. package/server/expressBridge.js +157 -116
  39. package/server/index.d.ts +2 -2
  40. package/server/index.js +2 -2
  41. package/src/data-api.d.ts +3 -3
  42. package/src/data-api.js +20 -17
  43. package/src/live-query/SubscriptionServer.js +3 -3
  44. package/src/remult3/RepositoryImplementation.js +1 -1
  45. package/src/tests/testHelper.spec.js +8 -2
package/esm/graphql.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { RemultServer } from "./server/expressBridge";
2
- export declare function remultGraphql(api: RemultServer): {
2
+ export declare function remultGraphql(api: RemultServer<any>): {
3
3
  rootValue: {};
4
4
  schema: string;
5
5
  };
@@ -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>;
@@ -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),
@@ -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>;
@@ -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 = {
@@ -1,8 +1,8 @@
1
- import { RemultServerOptions, GenericRequest } from "./server/expressBridge";
1
+ import { RemultServerOptions } from "./server/expressBridge";
2
2
  import { Remult } from "./src/context";
3
- export declare function remultFresh<RequestType extends GenericRequest>(options: RemultServerOptions<RequestType>, response: FreshResponse): RemultFresh;
3
+ export declare function remultFresh(options: RemultServerOptions<FreshRequest>, response: FreshResponse): RemultFresh;
4
4
  export interface RemultFresh {
5
- getRemult(req: GenericRequest): Promise<Remult>;
5
+ getRemult(req: FreshRequest): Promise<Remult>;
6
6
  openApiDoc(options: {
7
7
  title: string;
8
8
  }): any;
@@ -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(theReq);
22
+ const res = await server.handle(req);
21
23
  if (res) {
22
24
  init.status = res.statusCode;
23
25
  if (res.data) {
@@ -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
  } = {
@@ -1,7 +1,9 @@
1
1
  import { createRemultServer } from "./server";
2
2
  export function remultNext(options) {
3
- let result = createRemultServer(options);
4
- return Object.assign((req, res) => result.handle(req, res), result, {
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,3 @@
1
+ import type { RequestEvent, Handle } from '@sveltejs/kit';
2
+ import { RemultServer, RemultServerOptions } from './server';
3
+ export declare function remultSveltekit(options?: RemultServerOptions<RequestEvent>): RemultServer<RequestEvent> & Handle;
@@ -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,3 @@
1
+ import type { RequestEvent, Handle } from '@sveltejs/kit';
2
+ import { RemultServer, RemultServerOptions } from './server';
3
+ export declare function remultSveltekit(options?: RemultServerOptions<RequestEvent>): RemultServer<RequestEvent> & Handle;
@@ -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 extends GenericRequest> {
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 relevent request info for re running a live query */
45
- requestSerializer?: {
46
- toJson: (request: RequestType) => any;
47
- fromJson: (request: any) => RequestType;
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 extends GenericRequest = GenericRequest>(options?: RemultServerOptions<RequestType>): RemultServer;
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: GenericRequest): Promise<Remult>;
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: GenericRequest, gRes?: GenericResponse): Promise<ServerHandleResponse | undefined>;
70
- withRemult(req: GenericRequest, res: GenericResponse, next: VoidFunction): any;
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.runWithRequest = async (req, entityKey, what) => {
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 new Promise((result) => {
142
- this.withRemult(this.options.requestSerializer.fromJson(req), undefined, async () => {
143
- await what(remult.repo(e));
144
- result({});
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.options.requestSerializer.toJson(orig)))).put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, '', orig.body)))
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.options.requestSerializer.toJson(orig))));
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
- let myReq = new ExpressRequestBridgeToDataApiRequest(req);
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
- let remult = new Remult();
254
- remult.liveQueryPublisher = new LiveQueryPublisher(() => remult.subscriptionServer, () => remult.liveQueryStorage, this.runWithRequest);
255
- remult.dataProvider = (await this.dataProvider);
256
- remult.subscriptionServer = this.subscriptionServer;
257
- remult.liveQueryStorage = this.liveQueryStorage;
258
- await new Promise(res => {
259
- RemultAsyncLocalStorage.instance.run(remult, async () => {
260
- if (req) {
261
- let user;
262
- if (this.options.getUser)
263
- user = await this.options.getUser(req);
264
- else {
265
- user = req['user'];
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
- await what(remult, myReq, myRes, req, origRes);
284
- res({});
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(req, res, next) {
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(req, res, next);
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(req, res, next);
904
+ h(origReq, res, next);
891
905
  return;
892
906
  }
893
907
  }
@@ -1,6 +1,6 @@
1
- import { GenericRequest, RemultServer, RemultServerOptions } from './expressBridge';
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 extends GenericRequest = GenericRequest>(options?: RemultServerOptions<RequestType>): RemultServer;
6
+ export declare function createRemultServer<RequestType>(options: RemultServerOptions<RequestType>, serverCoreOptions?: ServerCoreOptions<RequestType>): RemultServer<RequestType>;
@@ -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
  }
@@ -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, queryChannel: string): Promise<void>;
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>;
@@ -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, performWithRequest) {
4
+ constructor(subscriptionServer, liveQueryStorage, performWithContext) {
5
5
  this.subscriptionServer = subscriptionServer;
6
6
  this.liveQueryStorage = liveQueryStorage;
7
- this.performWithRequest = performWithRequest;
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.performWithRequest(query.requestJson, entityKey, async (repo) => {
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());