remult 3.0.5 → 3.0.6-next.1

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/remult-nuxt.js CHANGED
@@ -8,8 +8,8 @@ var index_js_1 = require("./server/index.js");
8
8
  function remultApi(options) {
9
9
  var _this = this;
10
10
  var result = (0, index_js_1.createRemultServer)(options, {
11
- buildGenericRequestInfo: function (event) {
12
- return {
11
+ buildGenericRequestInfo: function (event) { return ({
12
+ internal: {
13
13
  method: event.node.req.method,
14
14
  url: event.node.req.url,
15
15
  on: function (a, b) {
@@ -17,8 +17,11 @@ function remultApi(options) {
17
17
  b();
18
18
  });
19
19
  },
20
- };
21
- },
20
+ },
21
+ public: {
22
+ headers: new Headers(event.node.req.headers),
23
+ },
24
+ }); },
22
25
  getRequestBody: function (event) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
23
26
  switch (_a.label) {
24
27
  case 0: return [4 /*yield*/, (0, h3_1.readBody)(event)];
@@ -9,13 +9,16 @@ function remultApi(options) {
9
9
  var _this = this;
10
10
  var result = (0, index_js_1.createRemultServer)(options, {
11
11
  buildGenericRequestInfo: function (event) { return ({
12
- url: event.request.url,
13
- method: event.request.method,
14
- on: function (e, do1) {
15
- if (e === 'close') {
16
- event.locals['_tempOnClose'] = do1;
17
- }
12
+ internal: {
13
+ url: event.request.url,
14
+ method: event.request.method,
15
+ on: function (e, do1) {
16
+ if (e === 'close') {
17
+ event.locals['_tempOnClose'] = do1;
18
+ }
19
+ },
18
20
  },
21
+ public: { headers: new Headers(event.request.headers) },
19
22
  }); },
20
23
  getRequestBody: function (event) { return event.request.json(); },
21
24
  });
@@ -8,14 +8,17 @@ function remultApi(options) {
8
8
  var _this = this;
9
9
  var result = (0, index_js_1.createRemultServer)(options, {
10
10
  buildGenericRequestInfo: function (event) { return ({
11
- url: event.request.url,
12
- method: event.request.method,
13
- on: function (e, do1) {
14
- if (e === 'close') {
15
- ;
16
- event.locals['_tempOnClose'] = do1;
17
- }
11
+ internal: {
12
+ url: event.request.url,
13
+ method: event.request.method,
14
+ on: function (e, do1) {
15
+ if (e === 'close') {
16
+ ;
17
+ event.locals['_tempOnClose'] = do1;
18
+ }
19
+ },
18
20
  },
21
+ public: { headers: event.request.headers },
19
22
  }); },
20
23
  getRequestBody: function (event) { return event.request.json(); },
21
24
  });
@@ -88,7 +91,7 @@ function remultApi(options) {
88
91
  status: responseFromRemultHandler.statusCode,
89
92
  headers: {
90
93
  'Content-Type': 'application/json',
91
- }
94
+ },
92
95
  });
93
96
  return [2 /*return*/, res];
94
97
  }
package/server/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { queuedJobInfo, QueueStorage, GenericRequestInfo, GenericRequestHandler, GenericResponse, GenericRouter, createRemultServerCore, RemultServerOptions, SpecificRoute, RemultServer, } from './remult-api-server.js';
1
+ export { type queuedJobInfo, type QueueStorage, type GenericRequestInfo, type GenericRequestHandler, type GenericResponse, type GenericRouter, createRemultServerCore, type RemultServerOptions, type SpecificRoute, type RemultServer, } from './remult-api-server.js';
2
2
  export { JsonEntityFileStorage, JsonFileDataProvider, } from './JsonEntityFileStorage.js';
3
3
  export { SseSubscriptionServer } from '../SseSubscriptionServer.js';
4
4
  export { DataProviderLiveQueryStorage } from '../live-query/data-provider-live-query-storage.js';
package/server/index.d.ts CHANGED
@@ -4,4 +4,6 @@ export { DataProviderLiveQueryStorage } from '../live-query/data-provider-live-q
4
4
  export { JsonEntityFileStorage, JsonFileDataProvider, } from './JsonEntityFileStorage.js';
5
5
  export { TestApiDataProvider } from './test-api-data-provider.js';
6
6
  export { GenericRequestHandler, GenericRequestInfo, GenericResponse, GenericRouter, InitRequestOptions, QueueStorage, RemultServer, RemultServerCore, RemultServerOptions, SpecificRoute, queuedJobInfo, } from './remult-api-server.js';
7
+ export { Module } from './module.js';
8
+ export type { ModuleInput } from './module.js';
7
9
  export declare function createRemultServer<RequestType>(options: RemultServerOptions<RequestType>, serverCoreOptions?: ServerCoreOptions<RequestType>): RemultServer<RequestType>;
package/server/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TestApiDataProvider = exports.JsonFileDataProvider = exports.JsonEntityFileStorage = exports.DataProviderLiveQueryStorage = exports.SseSubscriptionServer = void 0;
3
+ exports.Module = exports.TestApiDataProvider = exports.JsonFileDataProvider = exports.JsonEntityFileStorage = exports.DataProviderLiveQueryStorage = exports.SseSubscriptionServer = void 0;
4
4
  exports.createRemultServer = createRemultServer;
5
5
  var tslib_1 = require("tslib");
6
6
  var remult_api_server_js_1 = require("./remult-api-server.js");
@@ -15,11 +15,16 @@ Object.defineProperty(exports, "JsonEntityFileStorage", { enumerable: true, get:
15
15
  Object.defineProperty(exports, "JsonFileDataProvider", { enumerable: true, get: function () { return JsonEntityFileStorage_js_1.JsonFileDataProvider; } });
16
16
  var test_api_data_provider_js_1 = require("./test-api-data-provider.js");
17
17
  Object.defineProperty(exports, "TestApiDataProvider", { enumerable: true, get: function () { return test_api_data_provider_js_1.TestApiDataProvider; } });
18
+ var module_js_1 = require("./module.js");
19
+ Object.defineProperty(exports, "Module", { enumerable: true, get: function () { return module_js_1.Module; } });
18
20
  function createRemultServer(options, serverCoreOptions) {
19
21
  var _this = this;
20
22
  (0, initAsyncHooks_js_1.initAsyncHooks)();
21
23
  return (0, remult_api_server_js_1.createRemultServerCore)(options, serverCoreOptions || {
22
- buildGenericRequestInfo: function (req) { return (0, isOfType_js_1.cast)(req, 'method'); },
24
+ buildGenericRequestInfo: function (req) { return ({
25
+ internal: (0, isOfType_js_1.cast)(req, 'method'),
26
+ public: { headers: new Headers(req.headers) },
27
+ }); },
23
28
  getRequestBody: function (req) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
24
29
  return [2 /*return*/, req.body];
25
30
  }); }); },
@@ -0,0 +1,26 @@
1
+ import type { ClassType } from '../classType.js';
2
+ import type { RemultServerOptions } from './remult-api-server.js';
3
+ export interface ModuleInput<RequestType> {
4
+ key: string;
5
+ /** @default 0 */
6
+ priority?: number;
7
+ entities?: ClassType<unknown>[];
8
+ controllers?: ClassType<unknown>[];
9
+ initApi?: RemultServerOptions<RequestType>['initApi'];
10
+ initRequest?: RemultServerOptions<RequestType>['initRequest'];
11
+ modules?: Module<RequestType>[];
12
+ }
13
+ export declare class Module<RequestType> {
14
+ key: string;
15
+ priority: number;
16
+ entities?: ClassType<unknown>[];
17
+ controllers?: ClassType<unknown>[];
18
+ initApi?: RemultServerOptions<RequestType>['initApi'];
19
+ initRequest?: RemultServerOptions<RequestType>['initRequest'];
20
+ modules?: Module<RequestType>[];
21
+ constructor(options: ModuleInput<RequestType>);
22
+ }
23
+ /**
24
+ * Full flat and ordered list by index and concatenaining the modules name
25
+ */
26
+ export declare const modulesFlatAndOrdered: <RequestType>(modules: Module<RequestType>[]) => Module<RequestType>[];
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.modulesFlatAndOrdered = exports.Module = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var Module = /** @class */ (function () {
6
+ function Module(options) {
7
+ var _a;
8
+ this.key = options.key;
9
+ this.priority = (_a = options.priority) !== null && _a !== void 0 ? _a : 0;
10
+ this.entities = options.entities;
11
+ this.controllers = options.controllers;
12
+ this.initApi = options.initApi;
13
+ this.initRequest = options.initRequest;
14
+ this.modules = options.modules;
15
+ }
16
+ return Module;
17
+ }());
18
+ exports.Module = Module;
19
+ /**
20
+ * Full flat and ordered list by index and concatenaining the modules name
21
+ */
22
+ var modulesFlatAndOrdered = function (modules) {
23
+ var flattenModules = function (modules, parentName) {
24
+ if (parentName === void 0) { parentName = ''; }
25
+ return modules.reduce(function (acc, module) {
26
+ var fullKey = parentName ? "".concat(parentName, "-").concat(module.key) : module.key;
27
+ // Create a new module object without the 'modules' property
28
+ var _ = module.modules, flatModule = tslib_1.__rest(module, ["modules"]);
29
+ var newModule = tslib_1.__assign(tslib_1.__assign({}, flatModule), { key: fullKey });
30
+ var subModules = module.modules
31
+ ? flattenModules(module.modules, fullKey)
32
+ : [];
33
+ return tslib_1.__spreadArray(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(acc), false), [newModule], false), tslib_1.__read(subModules), false);
34
+ }, []);
35
+ };
36
+ var flatModules = flattenModules(modules);
37
+ flatModules.sort(function (a, b) { return a.priority - b.priority; });
38
+ return flatModules;
39
+ };
40
+ exports.modulesFlatAndOrdered = modulesFlatAndOrdered;
@@ -6,6 +6,7 @@ import type { LiveQueryStorage, SubscriptionServer } from '../src/live-query/Sub
6
6
  import { IdEntity } from '../src/remult3/IdEntity.js';
7
7
  import type { EntityMetadata, Repository } from '../src/remult3/remult3.js';
8
8
  import type { queuedJobInfoResponse } from '../src/server-action.js';
9
+ import { type Module } from './module.js';
9
10
  export interface RemultServerOptions<RequestType> {
10
11
  /**Entities to use for the api */
11
12
  entities?: ClassType<any>[];
@@ -92,6 +93,31 @@ export interface RemultServerOptions<RequestType> {
92
93
  responseBody: any;
93
94
  sendError: (httpStatusCode: number, body: any) => void;
94
95
  }) => Promise<void> | undefined;
96
+ /**
97
+ * Modules are here to group code by feature.
98
+ *
99
+ * @example
100
+ * import { Module } from 'remult/server'
101
+ *
102
+ * // create an analytics module
103
+ * const analytics = () => new Module({
104
+ * key: 'analytics',
105
+ * priority: 11, // Default: 0, Prioritized by ascending order.
106
+ * entities: [AnalyticsEvent],
107
+ * controllers: [AnalyticsController],
108
+ * initApi: () => console.log('analytics module initialized'),
109
+ * initRequest: () => {},
110
+ * modules: [] // You can nest modules
111
+ * })
112
+ *
113
+ * // use the module in the remultApi
114
+ * remultApi({
115
+ * modules: [
116
+ * analytics(),
117
+ * ]
118
+ * })
119
+ */
120
+ modules?: Module<RequestType>[];
95
121
  }
96
122
  export interface InitRequestOptions {
97
123
  liveQueryStorage: LiveQueryStorage;
@@ -126,6 +152,9 @@ export type SpecificRoute<RequestType> = {
126
152
  post(handler: GenericRequestHandler<RequestType>): SpecificRoute<RequestType>;
127
153
  delete(handler: GenericRequestHandler<RequestType>): SpecificRoute<RequestType>;
128
154
  };
155
+ export interface GenericRequest {
156
+ headers: Headers;
157
+ }
129
158
  export interface GenericRequestInfo {
130
159
  url?: string;
131
160
  method?: any;
@@ -180,7 +209,10 @@ export declare class JobsInQueueEntity extends IdEntity {
180
209
  progress: number;
181
210
  }
182
211
  export interface ServerCoreOptions<RequestType> {
183
- buildGenericRequestInfo(req: RequestType): GenericRequestInfo;
212
+ buildGenericRequestInfo(req: RequestType): {
213
+ internal: GenericRequestInfo;
214
+ public: GenericRequest;
215
+ };
184
216
  getRequestBody(req: RequestType): Promise<any>;
185
217
  ignoreAsyncStorage?: boolean;
186
218
  }
@@ -18,6 +18,7 @@ var remult_static_js_1 = require("../src/remult-static.js");
18
18
  var remult_admin_js_1 = tslib_1.__importStar(require("./remult-admin.js"));
19
19
  var isOfType_js_1 = require("../src/isOfType.js");
20
20
  var initDataProviderOrJson_js_1 = require("./initDataProviderOrJson.js");
21
+ var module_js_1 = require("./module.js");
21
22
  function createRemultServerCore(options, serverCoreOptions) {
22
23
  var safeOptions = options !== null && options !== void 0 ? options : {};
23
24
  if (!safeOptions.entities)
@@ -58,11 +59,15 @@ function createRemultServerCore(options, serverCoreOptions) {
58
59
  var RemultServerImplementation = /** @class */ (function () {
59
60
  function RemultServerImplementation(queue, options, dataProvider, coreOptions) {
60
61
  var _this = this;
62
+ var _a, _b, _c;
61
63
  this.queue = queue;
62
64
  this.options = options;
63
65
  this.dataProvider = dataProvider;
64
66
  this.coreOptions = coreOptions;
65
67
  this.liveQueryStorage = new SubscriptionServer_js_1.InMemoryLiveQueryStorage();
68
+ this.modulesSorted = [];
69
+ this.entities = [];
70
+ this.controllers = [];
66
71
  this.runWithSerializedJsonContextData = function (jsonContextData, entityKey, what) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
67
72
  var _loop_1, this_1, _a, _b, e, state_1, e_1_1;
68
73
  var e_1, _c;
@@ -113,7 +118,7 @@ var RemultServerImplementation = /** @class */ (function () {
113
118
  _d.label = 1;
114
119
  case 1:
115
120
  _d.trys.push([1, 6, 7, 8]);
116
- _a = tslib_1.__values(this.options.entities), _b = _a.next();
121
+ _a = tslib_1.__values(this.entities), _b = _a.next();
117
122
  _d.label = 2;
118
123
  case 2:
119
124
  if (!!_b.done) return [3 /*break*/, 5];
@@ -171,12 +176,25 @@ var RemultServerImplementation = /** @class */ (function () {
171
176
  if (options.subscriptionServer)
172
177
  this.subscriptionServer = options.subscriptionServer;
173
178
  var entitiesMetaData = [];
179
+ var modules = (_a = options.modules) !== null && _a !== void 0 ? _a : [];
180
+ modules.push({
181
+ key: 'default',
182
+ priority: 0,
183
+ entities: (_b = options.entities) !== null && _b !== void 0 ? _b : [],
184
+ controllers: (_c = options.controllers) !== null && _c !== void 0 ? _c : [],
185
+ initApi: options.initApi,
186
+ initRequest: options.initRequest,
187
+ modules: [],
188
+ });
189
+ this.modulesSorted = (0, module_js_1.modulesFlatAndOrdered)(modules);
190
+ this.entities = this.modulesSorted.flatMap(function (m) { var _a; return (_a = m.entities) !== null && _a !== void 0 ? _a : []; });
191
+ this.controllers = this.modulesSorted.flatMap(function (m) { var _a; return (_a = m.controllers) !== null && _a !== void 0 ? _a : []; });
174
192
  this.dataProvider = dataProvider.then(function (dp) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
175
193
  var _this = this;
176
194
  return tslib_1.__generator(this, function (_a) {
177
195
  switch (_a.label) {
178
196
  case 0: return [4 /*yield*/, this.runWithRemult(function (remult) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
179
- var started_1, startConsoleLog, _a, _b, item, e_2_1;
197
+ var started_1, startConsoleLog, _a, _b, item, e_2_1, i, _initApi;
180
198
  var e_2, _c;
181
199
  return tslib_1.__generator(this, function (_d) {
182
200
  switch (_d.label) {
@@ -190,8 +208,8 @@ var RemultServerImplementation = /** @class */ (function () {
190
208
  started_1 = true;
191
209
  console.time('Schema ensured');
192
210
  };
193
- if (options.entities)
194
- entitiesMetaData.push.apply(entitiesMetaData, tslib_1.__spreadArray([], tslib_1.__read(options.entities.map(function (e) { return remult.repo(e).metadata; })), false));
211
+ if (this.entities)
212
+ entitiesMetaData.push.apply(entitiesMetaData, tslib_1.__spreadArray([], tslib_1.__read(this.entities.map(function (e) { return remult.repo(e).metadata; })), false));
195
213
  if (!dp.ensureSchema) return [3 /*break*/, 2];
196
214
  startConsoleLog();
197
215
  return [4 /*yield*/, dp.ensureSchema(entitiesMetaData)];
@@ -233,12 +251,20 @@ var RemultServerImplementation = /** @class */ (function () {
233
251
  console.timeEnd('Schema ensured');
234
252
  _d.label = 10;
235
253
  case 10:
236
- if (!options.initApi) return [3 /*break*/, 12];
237
- return [4 /*yield*/, options.initApi(remult)];
254
+ i = 0;
255
+ _d.label = 11;
238
256
  case 11:
257
+ if (!(i < this.modulesSorted.length)) return [3 /*break*/, 14];
258
+ _initApi = this.modulesSorted[i].initApi;
259
+ if (!_initApi) return [3 /*break*/, 13];
260
+ return [4 /*yield*/, _initApi(remult)];
261
+ case 12:
239
262
  _d.sent();
240
- _d.label = 12;
241
- case 12: return [2 /*return*/];
263
+ _d.label = 13;
264
+ case 13:
265
+ i++;
266
+ return [3 /*break*/, 11];
267
+ case 14: return [2 /*return*/];
242
268
  }
243
269
  });
244
270
  }); }, { skipDataProvider: true })];
@@ -284,7 +310,7 @@ var RemultServerImplementation = /** @class */ (function () {
284
310
  RemultServerImplementation.prototype.getEntities = function () {
285
311
  //TODO V2 - consider using entitiesMetaData - but it may require making it all awaitable
286
312
  var r = new context_js_1.Remult();
287
- return this.options.entities.map(function (x) { return r.repo(x).metadata; });
313
+ return this.entities.map(function (x) { return r.repo(x).metadata; });
288
314
  };
289
315
  RemultServerImplementation.prototype.getRouteImpl = function () {
290
316
  if (!this.routeImpl) {
@@ -299,14 +325,13 @@ var RemultServerImplementation = /** @class */ (function () {
299
325
  RemultServerImplementation.prototype.registerRouter = function (r) {
300
326
  var e_3, _a, e_4, _b;
301
327
  var _this = this;
302
- var _c;
303
328
  if (this.registeredRouter)
304
329
  throw 'Router already registered';
305
330
  this.registeredRouter = true;
306
331
  {
307
332
  try {
308
- for (var _d = tslib_1.__values(this.options.controllers), _e = _d.next(); !_e.done; _e = _d.next()) {
309
- var c = _e.value;
333
+ for (var _c = tslib_1.__values(this.controllers), _d = _c.next(); !_d.done; _d = _c.next()) {
334
+ var c = _d.value;
310
335
  var z = c[server_action_js_1.classBackendMethodsArray];
311
336
  if (z)
312
337
  try {
@@ -331,7 +356,7 @@ var RemultServerImplementation = /** @class */ (function () {
331
356
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
332
357
  finally {
333
358
  try {
334
- if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
359
+ if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
335
360
  }
336
361
  finally { if (e_3) throw e_3.error; }
337
362
  }
@@ -365,8 +390,8 @@ var RemultServerImplementation = /** @class */ (function () {
365
390
  var admin = function () {
366
391
  return _this.process(function (remult, req, res, orig, origResponse) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
367
392
  var allowed, head, requireAuthToken, disableLiveQuery;
368
- var _a, _b, _c, _d, _e, _f, _g, _h;
369
- return tslib_1.__generator(this, function (_j) {
393
+ var _a, _b, _c, _d, _e, _f, _g;
394
+ return tslib_1.__generator(this, function (_h) {
370
395
  allowed = (0, isOfType_js_1.isOfType)(this.options.admin, 'allow')
371
396
  ? this.options.admin.allow
372
397
  : this.options.admin;
@@ -374,7 +399,7 @@ var RemultServerImplementation = /** @class */ (function () {
374
399
  if (((_a = orig === null || orig === void 0 ? void 0 : orig.params) === null || _a === void 0 ? void 0 : _a.id) === '__entities-metadata') {
375
400
  res.success((0, remult_admin_js_1.buildEntityInfo)({
376
401
  remult: remult,
377
- entities: (_b = this.options.entities) !== null && _b !== void 0 ? _b : [],
402
+ entities: this.entities,
378
403
  }));
379
404
  }
380
405
  else {
@@ -382,14 +407,14 @@ var RemultServerImplementation = /** @class */ (function () {
382
407
  requireAuthToken = false;
383
408
  disableLiveQuery = false;
384
409
  if ((0, isOfType_js_1.isOfType)(this.options.admin, 'allow')) {
385
- head = (_e = (_d = (_c = this.options.admin).customHtmlHead) === null || _d === void 0 ? void 0 : _d.call(_c, remult)) !== null && _e !== void 0 ? _e : head;
410
+ head = (_d = (_c = (_b = this.options.admin).customHtmlHead) === null || _c === void 0 ? void 0 : _c.call(_b, remult)) !== null && _d !== void 0 ? _d : head;
386
411
  requireAuthToken =
387
- (_f = this.options.admin.requireAuthToken) !== null && _f !== void 0 ? _f : requireAuthToken;
412
+ (_e = this.options.admin.requireAuthToken) !== null && _e !== void 0 ? _e : requireAuthToken;
388
413
  disableLiveQuery =
389
- (_g = this.options.admin.disableLiveQuery) !== null && _g !== void 0 ? _g : disableLiveQuery;
414
+ (_f = this.options.admin.disableLiveQuery) !== null && _f !== void 0 ? _f : disableLiveQuery;
390
415
  }
391
416
  origResponse.send((0, remult_admin_js_1.default)({
392
- rootPath: (_h = this.options.rootPath) !== null && _h !== void 0 ? _h : '/api',
417
+ rootPath: (_g = this.options.rootPath) !== null && _g !== void 0 ? _g : '/api',
393
418
  head: head,
394
419
  requireAuthToken: requireAuthToken,
395
420
  disableLiveQuery: disableLiveQuery,
@@ -465,7 +490,7 @@ var RemultServerImplementation = /** @class */ (function () {
465
490
  });
466
491
  }); }));
467
492
  }
468
- (_c = this.options.entities) === null || _c === void 0 ? void 0 : _c.forEach(function (e) {
493
+ this.entities.forEach(function (e) {
469
494
  _this.addEntity(e, (0, getEntityRef_js_1.getEntityKey)(e), r);
470
495
  });
471
496
  };
@@ -604,12 +629,14 @@ var RemultServerImplementation = /** @class */ (function () {
604
629
  RemultServerImplementation.prototype.process = function (what, doNotReuseInitRequest) {
605
630
  var _this = this;
606
631
  return function (req, origRes) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
607
- var genReq, myReq, myRes, err_2;
632
+ var _a, genReq, genReqPublic, myReq, myRes, err_2;
608
633
  var _this = this;
609
- return tslib_1.__generator(this, function (_a) {
610
- switch (_a.label) {
634
+ return tslib_1.__generator(this, function (_b) {
635
+ switch (_b.label) {
611
636
  case 0:
612
- genReq = req ? this.coreOptions.buildGenericRequestInfo(req) : {};
637
+ _a = req
638
+ ? this.coreOptions.buildGenericRequestInfo(req)
639
+ : { internal: {}, public: { headers: new Headers() } }, genReq = _a.internal, genReqPublic = _a.public;
613
640
  if (req) {
614
641
  if (!genReq.query) {
615
642
  genReq.query = req['_tempQuery'];
@@ -619,25 +646,35 @@ var RemultServerImplementation = /** @class */ (function () {
619
646
  }
620
647
  myReq = new RequestBridgeToDataApiRequest(genReq);
621
648
  myRes = new ResponseBridgeToDataApiResponse(origRes, req, genReq, this.options.error);
622
- _a.label = 1;
649
+ _b.label = 1;
623
650
  case 1:
624
- _a.trys.push([1, 6, , 7]);
651
+ _b.trys.push([1, 6, , 7]);
625
652
  if (!(remult_static_js_1.remultStatic.asyncContext.isInInitRequest() &&
626
653
  !doNotReuseInitRequest)) return [3 /*break*/, 3];
627
654
  return [4 /*yield*/, what(remult_static_js_1.remultStatic.asyncContext.getStore().remult, myReq, myRes, genReq, origRes, req)];
628
- case 2: return [2 /*return*/, _a.sent()];
655
+ case 2: return [2 /*return*/, _b.sent()];
629
656
  case 3: return [4 /*yield*/, this.runWithRemult(function (remult) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
630
- var user;
657
+ var user, i, _initRequest;
631
658
  return tslib_1.__generator(this, function (_a) {
632
659
  switch (_a.label) {
633
660
  case 0:
634
- if (!req) return [3 /*break*/, 9];
661
+ if (!req) return [3 /*break*/, 11];
635
662
  ;
636
663
  remult.context.request = req;
664
+ remult.context.headers = {
665
+ get: function (key) { var _a; return (_a = genReqPublic.headers.get(key)) !== null && _a !== void 0 ? _a : undefined; },
666
+ getAll: function () {
667
+ var result = {};
668
+ genReqPublic.headers.forEach(function (value, key) {
669
+ result[key] = value;
670
+ });
671
+ return result;
672
+ },
673
+ };
637
674
  remult_static_js_1.remultStatic.asyncContext.setInInitRequest(true);
638
675
  _a.label = 1;
639
676
  case 1:
640
- _a.trys.push([1, , 8, 9]);
677
+ _a.trys.push([1, , 10, 11]);
641
678
  user = void 0;
642
679
  if (!this.options.getUser) return [3 /*break*/, 3];
643
680
  return [4 /*yield*/, this.options.getUser(req)];
@@ -654,8 +691,13 @@ var RemultServerImplementation = /** @class */ (function () {
654
691
  case 4:
655
692
  if (user)
656
693
  remult.user = user;
657
- if (!this.options.initRequest) return [3 /*break*/, 6];
658
- return [4 /*yield*/, this.options.initRequest(req, {
694
+ i = 0;
695
+ _a.label = 5;
696
+ case 5:
697
+ if (!(i < this.modulesSorted.length)) return [3 /*break*/, 8];
698
+ _initRequest = this.modulesSorted[i].initRequest;
699
+ if (!_initRequest) return [3 /*break*/, 7];
700
+ return [4 /*yield*/, _initRequest(req, {
659
701
  remult: remult,
660
702
  get liveQueryStorage() {
661
703
  return remult.liveQueryStorage;
@@ -664,26 +706,29 @@ var RemultServerImplementation = /** @class */ (function () {
664
706
  remult.liveQueryStorage = value;
665
707
  },
666
708
  })];
667
- case 5:
709
+ case 6:
668
710
  _a.sent();
669
- _a.label = 6;
670
- case 6: return [4 /*yield*/, what(remult, myReq, myRes, genReq, origRes, req)];
711
+ _a.label = 7;
671
712
  case 7:
713
+ i++;
714
+ return [3 /*break*/, 5];
715
+ case 8: return [4 /*yield*/, what(remult, myReq, myRes, genReq, origRes, req)];
716
+ case 9:
672
717
  _a.sent();
673
- return [3 /*break*/, 9];
674
- case 8:
718
+ return [3 /*break*/, 11];
719
+ case 10:
675
720
  remult_static_js_1.remultStatic.asyncContext.setInInitRequest(false);
676
721
  return [7 /*endfinally*/];
677
- case 9: return [2 /*return*/];
722
+ case 11: return [2 /*return*/];
678
723
  }
679
724
  });
680
725
  }); })];
681
726
  case 4:
682
- _a.sent();
683
- _a.label = 5;
727
+ _b.sent();
728
+ _b.label = 5;
684
729
  case 5: return [3 /*break*/, 7];
685
730
  case 6:
686
- err_2 = _a.sent();
731
+ err_2 = _b.sent();
687
732
  if (origRes)
688
733
  myRes.error(err_2, undefined);
689
734
  else
@@ -1548,7 +1593,7 @@ var RouteImplementation = /** @class */ (function () {
1548
1593
  RouteImplementation.prototype.middleware = function (origReq, res, next) {
1549
1594
  var e_8, _a;
1550
1595
  var _b;
1551
- var req = this.coreOptions.buildGenericRequestInfo(origReq);
1596
+ var req = this.coreOptions.buildGenericRequestInfo(origReq).internal;
1552
1597
  var theUrl = ((_b = req.url) === null || _b === void 0 ? void 0 : _b.toString()) || '';
1553
1598
  if (theUrl.startsWith('/'))
1554
1599
  //next sends a partial url '/api/tasks' and not the full url
@@ -21,7 +21,10 @@ function TestApiDataProvider(options) {
21
21
  getRequestBody: function (req) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
22
22
  return [2 /*return*/, req.body];
23
23
  }); }); },
24
- buildGenericRequestInfo: function (req) { return req; },
24
+ buildGenericRequestInfo: function (req) { return ({
25
+ internal: req,
26
+ public: { headers: new Headers() },
27
+ }); },
25
28
  ignoreAsyncStorage: true,
26
29
  });
27
30
  var lock = new AsyncLock();
package/src/context.d.ts CHANGED
@@ -90,7 +90,15 @@ export declare class Remult {
90
90
  clearAllCache(): any;
91
91
  /** A helper callback that is called whenever an entity is created. */
92
92
  static entityRefInit?: (ref: EntityRef<any>, row: any) => void;
93
- /** context information that can be used to store custom information that will be disposed as part of the `remult` object */
93
+ /**
94
+ * context that can be used to store custom information that will be disposed as part of the `remult` object.
95
+ *
96
+ * `remult.context` is pre-filled in a framework-agnostic way with:
97
+ * - `headers.get(key: string)` _of request_
98
+ * - `headers.getAll()` _of request_
99
+ *
100
+ * Check out the [extensibility section](/docs/custom-options#enhancing-field-and-entity-definitions-with-custom-options) for more custom options.
101
+ */
94
102
  readonly context: RemultContext;
95
103
  /** The api client that will be used by `remult` to perform calls to the `api` */
96
104
  apiClient: ApiClient;
@@ -102,13 +110,18 @@ export type GetArguments<T> = T extends (...args: infer FirstArgument) => any ?
102
110
  * To type it correctly, you can extend it with your own properties.
103
111
  * @example
104
112
  * import type express from 'express'
113
+ *
105
114
  * declare module 'remult' {
106
115
  * export interface RemultContext {
107
116
  * request?: express.Request
108
117
  * }
109
118
  * }
110
- * */
119
+ */
111
120
  export interface RemultContext {
121
+ headers?: {
122
+ get: (key: string) => string | undefined;
123
+ getAll: () => Record<string, string>;
124
+ };
112
125
  }
113
126
  /**
114
127
  * Interface for configuring the API client used by Remult to perform HTTP calls to the backend.
package/src/context.js CHANGED
@@ -121,7 +121,15 @@ var Remult = /** @class */ (function () {
121
121
  };
122
122
  /* @internal*/
123
123
  this.liveQuerySubscriber = new LiveQueryClient_js_1.LiveQueryClient(function () { return _this.apiClient; }, function () { var _a; return (_a = _this.user) === null || _a === void 0 ? void 0 : _a.id; });
124
- /** context information that can be used to store custom information that will be disposed as part of the `remult` object */
124
+ /**
125
+ * context that can be used to store custom information that will be disposed as part of the `remult` object.
126
+ *
127
+ * `remult.context` is pre-filled in a framework-agnostic way with:
128
+ * - `headers.get(key: string)` _of request_
129
+ * - `headers.getAll()` _of request_
130
+ *
131
+ * Check out the [extensibility section](/docs/custom-options#enhancing-field-and-entity-definitions-with-custom-options) for more custom options.
132
+ */
125
133
  this.context = {};
126
134
  /** The api client that will be used by `remult` to perform calls to the `api` */
127
135
  this.apiClient = {