@ruiapp/rapid-core 0.1.21 → 0.1.23

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.
@@ -0,0 +1,5 @@
1
+ import { IRpdServer } from "./server";
2
+ export interface FacilityFactory {
3
+ name: string;
4
+ createFacility: (server: IRpdServer, options?: any) => Promise<any>;
5
+ }
@@ -3,11 +3,14 @@ import { IPluginActionHandler, ActionHandler, ActionHandlerContext } from "./act
3
3
  import { Next, RouteContext } from "./routeContext";
4
4
  import EntityManager from "../dataAccess/entityManager";
5
5
  import { Logger } from "../facilities/log/LogFacility";
6
+ import { FacilityFactory } from "./facility";
6
7
  export interface IRpdServer {
7
8
  config: RapidServerConfig;
8
9
  databaseConfig: IDatabaseConfig;
9
10
  queryBuilder: IQueryBuilder;
10
11
  getLogger(): Logger;
12
+ registerFacilityFactory(factory: FacilityFactory): any;
13
+ getFacility<TFacility = any>(name: string, options?: any): Promise<TFacility>;
11
14
  queryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
12
15
  tryQueryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
13
16
  registerMiddleware(middleware: any): void;
@@ -20,7 +23,7 @@ export interface IRpdServer {
20
23
  appendModelProperties(modelSingularCode: string, properties: RpdDataModelProperty[]): any;
21
24
  getModel(options: GetModelOptions): RpdDataModel | undefined;
22
25
  registerEventHandler<K extends keyof RpdServerEventTypes>(eventName: K, listener: (...args: RpdServerEventTypes[K]) => void): this;
23
- emitEvent<K extends keyof RpdServerEventTypes>(eventName: K, sender: RapidPlugin, payload: RpdServerEventTypes[K][1]): void;
26
+ emitEvent<K extends keyof RpdServerEventTypes>(eventName: K, payload: RpdServerEventTypes[K][1], sender?: RapidPlugin): void;
24
27
  handleRequest(request: Request, next: Next): Promise<Response>;
25
28
  beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
26
29
  }
@@ -7,10 +7,10 @@ export default class EntityManager<TEntity = any> {
7
7
  findEntities(options: FindEntityOptions): Promise<TEntity[]>;
8
8
  findEntity(options: FindEntityOptions): Promise<TEntity | null>;
9
9
  findById(id: any, keepNonPropertyFields?: boolean): Promise<TEntity | null>;
10
- createEntity(options: CreateEntityOptions, plugin: RapidPlugin): Promise<TEntity>;
11
- updateEntityById(options: UpdateEntityByIdOptions, plugin: RapidPlugin): Promise<TEntity>;
10
+ createEntity(options: CreateEntityOptions, plugin?: RapidPlugin): Promise<TEntity>;
11
+ updateEntityById(options: UpdateEntityByIdOptions, plugin?: RapidPlugin): Promise<TEntity>;
12
12
  count(options: CountEntityOptions): Promise<CountEntityResult>;
13
- deleteById(id: any, plugin: RapidPlugin): Promise<void>;
14
- addRelations(options: AddEntityRelationsOptions, plugin: RapidPlugin): Promise<void>;
15
- removeRelations(options: RemoveEntityRelationsOptions, plugin: RapidPlugin): Promise<void>;
13
+ deleteById(id: any, plugin?: RapidPlugin): Promise<void>;
14
+ addRelations(options: AddEntityRelationsOptions, plugin?: RapidPlugin): Promise<void>;
15
+ removeRelations(options: RemoveEntityRelationsOptions, plugin?: RapidPlugin): Promise<void>;
16
16
  }
package/dist/index.js CHANGED
@@ -1041,7 +1041,7 @@ class RapidRequest {
1041
1041
  const requestMethod = this.method;
1042
1042
  if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
1043
1043
  const req = this.#raw;
1044
- const contentType = this.#headers.get("Content-Type");
1044
+ const contentType = this.#headers.get("Content-Type") || "application/json";
1045
1045
  if (contentType.includes("json")) {
1046
1046
  this.#body = {
1047
1047
  type: "json",
@@ -2245,13 +2245,13 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
2245
2245
  }
2246
2246
  updatedEntity[property.code] = relatedEntities;
2247
2247
  }
2248
- server.emitEvent("entity.update", plugin, {
2248
+ server.emitEvent("entity.update", {
2249
2249
  namespace: model.namespace,
2250
2250
  modelSingularCode: model.singularCode,
2251
2251
  before: entity,
2252
2252
  after: updatedEntity,
2253
2253
  changes: changes,
2254
- });
2254
+ }, plugin);
2255
2255
  return updatedEntity;
2256
2256
  }
2257
2257
  class EntityManager {
@@ -2276,11 +2276,11 @@ class EntityManager {
2276
2276
  async createEntity(options, plugin) {
2277
2277
  const model = this.getModel();
2278
2278
  const newEntity = await createEntity(this.#server, this.#dataAccessor, options);
2279
- this.#server.emitEvent("entity.create", plugin, {
2279
+ this.#server.emitEvent("entity.create", {
2280
2280
  namespace: model.namespace,
2281
2281
  modelSingularCode: model.singularCode,
2282
2282
  after: newEntity,
2283
- });
2283
+ }, plugin);
2284
2284
  return newEntity;
2285
2285
  }
2286
2286
  async updateEntityById(options, plugin) {
@@ -2296,11 +2296,11 @@ class EntityManager {
2296
2296
  return;
2297
2297
  }
2298
2298
  await this.#dataAccessor.deleteById(id);
2299
- this.#server.emitEvent("entity.delete", plugin, {
2299
+ this.#server.emitEvent("entity.delete", {
2300
2300
  namespace: model.namespace,
2301
2301
  modelSingularCode: model.singularCode,
2302
2302
  before: entity,
2303
- });
2303
+ }, plugin);
2304
2304
  }
2305
2305
  async addRelations(options, plugin) {
2306
2306
  const model = this.getModel();
@@ -2330,13 +2330,13 @@ class EntityManager {
2330
2330
  await server.queryDatabaseObject(command, params);
2331
2331
  }
2332
2332
  }
2333
- server.emitEvent("entity.addRelations", plugin, {
2333
+ server.emitEvent("entity.addRelations", {
2334
2334
  namespace: model.namespace,
2335
2335
  modelSingularCode: model.singularCode,
2336
2336
  entity,
2337
2337
  property,
2338
2338
  relations,
2339
- });
2339
+ }, plugin);
2340
2340
  }
2341
2341
  async removeRelations(options, plugin) {
2342
2342
  const model = this.getModel();
@@ -2362,18 +2362,19 @@ class EntityManager {
2362
2362
  await server.queryDatabaseObject(command, params);
2363
2363
  }
2364
2364
  }
2365
- server.emitEvent("entity.removeRelations", plugin, {
2365
+ server.emitEvent("entity.removeRelations", {
2366
2366
  namespace: model.namespace,
2367
2367
  modelSingularCode: model.singularCode,
2368
2368
  entity,
2369
2369
  property,
2370
2370
  relations,
2371
- });
2371
+ }, plugin);
2372
2372
  }
2373
2373
  }
2374
2374
 
2375
2375
  class RapidServer {
2376
2376
  #logger;
2377
+ #facilityFactories;
2377
2378
  #pluginManager;
2378
2379
  #plugins;
2379
2380
  #eventManager;
@@ -2390,6 +2391,12 @@ class RapidServer {
2390
2391
  #buildedRoutes;
2391
2392
  constructor(options) {
2392
2393
  this.#logger = options.logger;
2394
+ this.#facilityFactories = new Map();
2395
+ if (options.facilityFactories) {
2396
+ lodash.forEach(options.facilityFactories, (factory) => {
2397
+ this.registerFacilityFactory(factory);
2398
+ });
2399
+ }
2393
2400
  this.#pluginManager = new PluginManager(this);
2394
2401
  this.#eventManager = new EventManager();
2395
2402
  this.#middlewares = [];
@@ -2512,7 +2519,7 @@ class RapidServer {
2512
2519
  this.#eventManager.on(eventName, listener);
2513
2520
  return this;
2514
2521
  }
2515
- async emitEvent(eventName, sender, payload) {
2522
+ async emitEvent(eventName, payload, sender) {
2516
2523
  this.#logger.debug(`Emitting '${eventName}' event.`, { eventName, payload });
2517
2524
  await this.#eventManager.emit(eventName, sender, payload);
2518
2525
  // TODO: should move this logic into metaManager
@@ -2549,6 +2556,21 @@ class RapidServer {
2549
2556
  await pluginManager.onApplicationLoaded(this.#applicationConfig);
2550
2557
  this.#buildedRoutes = await buildRoutes(this, this.#applicationConfig);
2551
2558
  }
2559
+ registerFacilityFactory(factory) {
2560
+ this.#facilityFactories.set(factory.name, factory);
2561
+ }
2562
+ async getFacility(name, options, nullIfUnknownFacility) {
2563
+ const factory = this.#facilityFactories.get(name);
2564
+ if (!factory) {
2565
+ if (nullIfUnknownFacility) {
2566
+ return null;
2567
+ }
2568
+ else {
2569
+ throw new Error(`Failed to get facility. Unknown facility name: ${name}`);
2570
+ }
2571
+ }
2572
+ return await factory.createFacility(this, options);
2573
+ }
2552
2574
  async queryDatabaseObject(sql, params) {
2553
2575
  try {
2554
2576
  return await this.#databaseAccessor.queryDatabaseObject(sql, params);
package/dist/server.d.ts CHANGED
@@ -4,12 +4,14 @@ import { IRpdServer, RapidPlugin } from "./core/server";
4
4
  import { Next } from "./core/routeContext";
5
5
  import EntityManager from "./dataAccess/entityManager";
6
6
  import { Logger } from "./facilities/log/LogFacility";
7
+ import { FacilityFactory } from "./core/facility";
7
8
  export interface InitServerOptions {
8
9
  logger: Logger;
9
10
  databaseAccessor: IDatabaseAccessor;
10
11
  databaseConfig: IDatabaseConfig;
11
12
  serverConfig: RapidServerConfig;
12
13
  applicationConfig?: RpdApplicationConfig;
14
+ facilityFactories?: FacilityFactory[];
13
15
  plugins?: RapidPlugin[];
14
16
  }
15
17
  export declare class RapidServer implements IRpdServer {
@@ -29,9 +31,11 @@ export declare class RapidServer implements IRpdServer {
29
31
  getModel(options: GetModelOptions): RpdDataModel | undefined;
30
32
  getEntityManager<TEntity = any>(singularCode: string): EntityManager<TEntity>;
31
33
  registerEventHandler<K extends keyof RpdServerEventTypes>(eventName: K, listener: (...args: RpdServerEventTypes[K]) => void): this;
32
- emitEvent<K extends keyof RpdServerEventTypes>(eventName: K, sender: RapidPlugin, payload: RpdServerEventTypes[K][1]): Promise<void>;
34
+ emitEvent<K extends keyof RpdServerEventTypes>(eventName: K, payload: RpdServerEventTypes[K][1], sender?: RapidPlugin): Promise<void>;
33
35
  start(): Promise<void>;
34
36
  configureApplication(): Promise<void>;
37
+ registerFacilityFactory(factory: FacilityFactory): void;
38
+ getFacility<TFacility = any>(name: string, options?: any, nullIfUnknownFacility?: boolean): Promise<TFacility>;
35
39
  queryDatabaseObject(sql: string, params?: unknown[] | Record<string, unknown>): Promise<any[]>;
36
40
  tryQueryDatabaseObject(sql: string, params?: unknown[] | Record<string, unknown>): Promise<any[]>;
37
41
  get middlewares(): any[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -0,0 +1,7 @@
1
+ import { IRpdServer } from "./server";
2
+
3
+ export interface FacilityFactory {
4
+ name: string;
5
+
6
+ createFacility: (server: IRpdServer, options?: any) => Promise<any>;
7
+ }
@@ -38,7 +38,7 @@ export class RapidRequest {
38
38
  const requestMethod = this.method;
39
39
  if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
40
40
  const req = this.#raw;
41
- const contentType = this.#headers.get("Content-Type");
41
+ const contentType = this.#headers.get("Content-Type") || "application/json";
42
42
  if (contentType.includes("json")) {
43
43
  this.#body = {
44
44
  type: "json",
@@ -3,12 +3,18 @@ import { IPluginActionHandler, ActionHandler, ActionHandlerContext } from "./act
3
3
  import { Next, RouteContext } from "./routeContext";
4
4
  import EntityManager from "~/dataAccess/entityManager";
5
5
  import { Logger } from "~/facilities/log/LogFacility";
6
+ import { FacilityFactory } from "./facility";
6
7
 
7
8
  export interface IRpdServer {
8
9
  config: RapidServerConfig;
9
10
  databaseConfig: IDatabaseConfig;
10
11
  queryBuilder: IQueryBuilder;
11
12
  getLogger(): Logger;
13
+
14
+ registerFacilityFactory(factory: FacilityFactory);
15
+
16
+ getFacility<TFacility=any>(name: string, options?: any): Promise<TFacility>;
17
+
12
18
  queryDatabaseObject: (
13
19
  sql: string,
14
20
  params?: unknown[] | Record<string, unknown>,
@@ -37,8 +43,8 @@ export interface IRpdServer {
37
43
  ): this;
38
44
  emitEvent<K extends keyof RpdServerEventTypes>(
39
45
  eventName: K,
40
- sender: RapidPlugin,
41
46
  payload: RpdServerEventTypes[K][1],
47
+ sender?: RapidPlugin,
42
48
  ): void;
43
49
  handleRequest(request: Request, next: Next): Promise<Response>;
44
50
  beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
@@ -553,7 +553,7 @@ async function updateEntityById(
553
553
  server: IRpdServer,
554
554
  dataAccessor: IRpdDataAccessor,
555
555
  options: UpdateEntityByIdOptions,
556
- plugin: RapidPlugin
556
+ plugin?: RapidPlugin
557
557
  ) {
558
558
  const model = dataAccessor.getModel();
559
559
  const { id, entityToSave } = options;
@@ -685,7 +685,6 @@ async function updateEntityById(
685
685
 
686
686
  server.emitEvent(
687
687
  "entity.update",
688
- plugin,
689
688
  {
690
689
  namespace: model.namespace,
691
690
  modelSingularCode: model.singularCode,
@@ -693,6 +692,7 @@ async function updateEntityById(
693
692
  after: updatedEntity,
694
693
  changes: changes,
695
694
  },
695
+ plugin,
696
696
  );
697
697
  return updatedEntity;
698
698
  }
@@ -722,24 +722,24 @@ export default class EntityManager<TEntity=any> {
722
722
  return await findById(this.#server, this.#dataAccessor, id, keepNonPropertyFields);
723
723
  }
724
724
 
725
- async createEntity(options: CreateEntityOptions, plugin: RapidPlugin): Promise<TEntity> {
725
+ async createEntity(options: CreateEntityOptions, plugin?: RapidPlugin): Promise<TEntity> {
726
726
  const model = this.getModel();
727
727
  const newEntity = await createEntity(this.#server, this.#dataAccessor, options);
728
728
 
729
729
  this.#server.emitEvent(
730
730
  "entity.create",
731
- plugin,
732
731
  {
733
732
  namespace: model.namespace,
734
733
  modelSingularCode: model.singularCode,
735
734
  after: newEntity,
736
735
  },
736
+ plugin,
737
737
  );
738
738
 
739
739
  return newEntity;
740
740
  }
741
741
 
742
- async updateEntityById(options: UpdateEntityByIdOptions, plugin: RapidPlugin): Promise<TEntity> {
742
+ async updateEntityById(options: UpdateEntityByIdOptions, plugin?: RapidPlugin): Promise<TEntity> {
743
743
  return await updateEntityById(this.#server, this.#dataAccessor, options, plugin);
744
744
  }
745
745
 
@@ -747,7 +747,7 @@ export default class EntityManager<TEntity=any> {
747
747
  return await this.#dataAccessor.count(options);
748
748
  }
749
749
 
750
- async deleteById(id: any, plugin: RapidPlugin): Promise<void> {
750
+ async deleteById(id: any, plugin?: RapidPlugin): Promise<void> {
751
751
  const model = this.getModel();
752
752
  const entity = await this.findById(id, true);
753
753
  if (!entity) {
@@ -757,16 +757,16 @@ export default class EntityManager<TEntity=any> {
757
757
  await this.#dataAccessor.deleteById(id);
758
758
  this.#server.emitEvent(
759
759
  "entity.delete",
760
- plugin,
761
760
  {
762
761
  namespace: model.namespace,
763
762
  modelSingularCode: model.singularCode,
764
763
  before: entity,
765
764
  },
765
+ plugin,
766
766
  );
767
767
  }
768
768
 
769
- async addRelations(options: AddEntityRelationsOptions, plugin: RapidPlugin): Promise<void> {
769
+ async addRelations(options: AddEntityRelationsOptions, plugin?: RapidPlugin): Promise<void> {
770
770
  const model = this.getModel();
771
771
  const {id, property, relations} = options;
772
772
  const entity = await this.findById(id);
@@ -800,7 +800,6 @@ export default class EntityManager<TEntity=any> {
800
800
 
801
801
  server.emitEvent(
802
802
  "entity.addRelations",
803
- plugin,
804
803
  {
805
804
  namespace: model.namespace,
806
805
  modelSingularCode: model.singularCode,
@@ -808,10 +807,11 @@ export default class EntityManager<TEntity=any> {
808
807
  property,
809
808
  relations,
810
809
  },
810
+ plugin,
811
811
  );
812
812
  }
813
813
 
814
- async removeRelations(options: RemoveEntityRelationsOptions, plugin: RapidPlugin): Promise<void> {
814
+ async removeRelations(options: RemoveEntityRelationsOptions, plugin?: RapidPlugin): Promise<void> {
815
815
  const model = this.getModel();
816
816
  const {id, property, relations} = options;
817
817
  const entity = await this.findById(id);
@@ -841,7 +841,6 @@ export default class EntityManager<TEntity=any> {
841
841
 
842
842
  server.emitEvent(
843
843
  "entity.removeRelations",
844
- plugin,
845
844
  {
846
845
  namespace: model.namespace,
847
846
  modelSingularCode: model.singularCode,
@@ -849,6 +848,7 @@ export default class EntityManager<TEntity=any> {
849
848
  property,
850
849
  relations,
851
850
  },
851
+ plugin,
852
852
  );
853
853
  }
854
854
  }
package/src/server.ts CHANGED
@@ -23,8 +23,9 @@ import { Next, RouteContext } from "./core/routeContext";
23
23
  import { RapidRequest } from "./core/request";
24
24
  import bootstrapApplicationConfig from "./bootstrapApplicationConfig";
25
25
  import EntityManager from "./dataAccess/entityManager";
26
- import { bind, cloneDeep, find, merge, omit } from "lodash";
26
+ import { bind, cloneDeep, find, forEach, merge, omit } from "lodash";
27
27
  import { Logger } from "./facilities/log/LogFacility";
28
+ import { FacilityFactory } from "./core/facility";
28
29
 
29
30
  export interface InitServerOptions {
30
31
  logger: Logger;
@@ -32,11 +33,13 @@ export interface InitServerOptions {
32
33
  databaseConfig: IDatabaseConfig;
33
34
  serverConfig: RapidServerConfig;
34
35
  applicationConfig?: RpdApplicationConfig;
36
+ facilityFactories?: FacilityFactory[];
35
37
  plugins?: RapidPlugin[];
36
38
  }
37
39
 
38
40
  export class RapidServer implements IRpdServer {
39
41
  #logger: Logger;
42
+ #facilityFactories: Map<string, FacilityFactory>;
40
43
  #pluginManager: PluginManager;
41
44
  #plugins: RapidPlugin[];
42
45
  #eventManager: EventManager<RpdServerEventTypes>;
@@ -55,6 +58,13 @@ export class RapidServer implements IRpdServer {
55
58
  constructor(options: InitServerOptions) {
56
59
  this.#logger = options.logger;
57
60
 
61
+ this.#facilityFactories = new Map();
62
+ if (options.facilityFactories) {
63
+ forEach(options.facilityFactories, (factory) => {
64
+ this.registerFacilityFactory(factory);
65
+ })
66
+ }
67
+
58
68
  this.#pluginManager = new PluginManager(this);
59
69
  this.#eventManager = new EventManager();
60
70
  this.#middlewares = [];
@@ -205,8 +215,8 @@ export class RapidServer implements IRpdServer {
205
215
 
206
216
  async emitEvent<K extends keyof RpdServerEventTypes>(
207
217
  eventName: K,
208
- sender: RapidPlugin,
209
218
  payload: RpdServerEventTypes[K][1],
219
+ sender?: RapidPlugin,
210
220
  ) {
211
221
  this.#logger.debug(`Emitting '${eventName}' event.`, { eventName, payload });
212
222
  await this.#eventManager.emit<K>(eventName, sender, payload as any);
@@ -258,6 +268,23 @@ export class RapidServer implements IRpdServer {
258
268
  this.#buildedRoutes = await buildRoutes(this, this.#applicationConfig);
259
269
  }
260
270
 
271
+ registerFacilityFactory(factory: FacilityFactory) {
272
+ this.#facilityFactories.set(factory.name, factory);
273
+ }
274
+
275
+ async getFacility<TFacility=any>(name: string, options?: any, nullIfUnknownFacility?: boolean): Promise<TFacility> {
276
+ const factory = this.#facilityFactories.get(name);
277
+ if (!factory) {
278
+ if (nullIfUnknownFacility) {
279
+ return null;
280
+ } else {
281
+ throw new Error(`Failed to get facility. Unknown facility name: ${name}`);
282
+ }
283
+ }
284
+
285
+ return await factory.createFacility(this, options);
286
+ }
287
+
261
288
  async queryDatabaseObject(sql: string, params?: unknown[] | Record<string,unknown>) : Promise<any[]> {
262
289
  try {
263
290
  return await this.#databaseAccessor.queryDatabaseObject(sql, params);