@ruiapp/rapid-core 0.1.12 → 0.1.13

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 (29) hide show
  1. package/dist/core/eventManager.d.ts +1 -2
  2. package/dist/dataAccess/entityManager.d.ts +8 -6
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.js +402 -233
  5. package/dist/plugins/entityWatch/EntityWatchPlugin.d.ts +15 -0
  6. package/dist/plugins/entityWatch/EntityWatchPluginTypes.d.ts +15 -0
  7. package/dist/plugins/serverOperation/ServerOperationPlugin.d.ts +25 -0
  8. package/dist/plugins/serverOperation/ServerOperationPluginTypes.d.ts +11 -0
  9. package/dist/plugins/serverOperation/actionHandlers/index.d.ts +3 -0
  10. package/dist/plugins/serverOperation/actionHandlers/runServerOperation.d.ts +6 -0
  11. package/dist/types.d.ts +17 -2
  12. package/package.json +1 -1
  13. package/src/core/eventManager.ts +3 -4
  14. package/src/dataAccess/entityManager.ts +153 -10
  15. package/src/index.ts +5 -1
  16. package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +2 -50
  17. package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +1 -12
  18. package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +1 -11
  19. package/src/plugins/dataManage/actionHandlers/deleteCollectionEntityById.ts +1 -20
  20. package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +2 -48
  21. package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +1 -25
  22. package/src/plugins/entityWatch/EntityWatchPlugin.ts +96 -0
  23. package/src/plugins/entityWatch/EntityWatchPluginTypes.ts +19 -0
  24. package/src/plugins/serverOperation/ServerOperationPlugin.ts +94 -0
  25. package/src/plugins/serverOperation/ServerOperationPluginTypes.ts +13 -0
  26. package/src/plugins/serverOperation/actionHandlers/index.ts +6 -0
  27. package/src/plugins/serverOperation/actionHandlers/runServerOperation.ts +15 -0
  28. package/src/server.ts +1 -1
  29. package/src/types.ts +13 -2
@@ -0,0 +1,15 @@
1
+ import type { RpdEntityCreateEventPayload, RpdServerEventTypes } from "../../types";
2
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
3
+ import { EntityWatchPluginInitOptions } from "./EntityWatchPluginTypes";
4
+ declare class EntityWatchPlugin implements RapidPlugin {
5
+ #private;
6
+ constructor(options: EntityWatchPluginInitOptions);
7
+ get code(): string;
8
+ get description(): string;
9
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[];
10
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[];
11
+ get configurations(): RpdConfigurationItemOptions[];
12
+ registerEventHandlers(server: IRpdServer): Promise<any>;
13
+ handleEntityEvent(server: IRpdServer, eventName: keyof RpdServerEventTypes, sender: RapidPlugin, payload: RpdEntityCreateEventPayload): void;
14
+ }
15
+ export default EntityWatchPlugin;
@@ -0,0 +1,15 @@
1
+ import { IRpdServer } from "../../core/server";
2
+ import { RpdServerEventTypes } from "../../types";
3
+ export interface EntityWatcher<TEventName extends keyof RpdServerEventTypes> {
4
+ eventName: TEventName;
5
+ modelSingularCode: string;
6
+ handler: EntityWatchHandler<TEventName>;
7
+ }
8
+ export type EntityWatchHandler<TEventName extends keyof RpdServerEventTypes> = (ctx: EntityWatchHandlerContext<TEventName>) => Promise<void>;
9
+ export type EntityWatchHandlerContext<TEventName extends keyof RpdServerEventTypes> = {
10
+ server: IRpdServer;
11
+ payload: RpdServerEventTypes[TEventName][1];
12
+ };
13
+ export interface EntityWatchPluginInitOptions {
14
+ watchers: EntityWatcher<keyof RpdServerEventTypes>[];
15
+ }
@@ -0,0 +1,25 @@
1
+ import type { RpdApplicationConfig } from "../../types";
2
+ import { ServerOperationPluginInitOptions } from "./ServerOperationPluginTypes";
3
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
4
+ declare class ServerOperationPlugin implements RapidPlugin {
5
+ #private;
6
+ constructor(options: ServerOperationPluginInitOptions);
7
+ get code(): string;
8
+ get description(): string;
9
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[];
10
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[];
11
+ get configurations(): RpdConfigurationItemOptions[];
12
+ initPlugin(server: IRpdServer): Promise<any>;
13
+ registerMiddlewares(server: IRpdServer): Promise<any>;
14
+ registerActionHandlers(server: IRpdServer): Promise<any>;
15
+ registerEventHandlers(server: IRpdServer): Promise<any>;
16
+ registerMessageHandlers(server: IRpdServer): Promise<any>;
17
+ registerTaskProcessors(server: IRpdServer): Promise<any>;
18
+ onLoadingApplication(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
19
+ configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
20
+ configureModelProperties(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
21
+ configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
22
+ onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
23
+ onApplicationReady(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
24
+ }
25
+ export default ServerOperationPlugin;
@@ -0,0 +1,11 @@
1
+ import { ActionHandlerContext } from "../../core/actionHandler";
2
+ import { RpdHttpMethod } from "../../types";
3
+ export interface ServerOperation {
4
+ code: string;
5
+ description?: string;
6
+ method: RpdHttpMethod;
7
+ handler: (ctx: ActionHandlerContext) => Promise<void>;
8
+ }
9
+ export interface ServerOperationPluginInitOptions {
10
+ operations: ServerOperation[];
11
+ }
@@ -0,0 +1,3 @@
1
+ import * as runServerOperation from "./runServerOperation";
2
+ declare const _default: (typeof runServerOperation)[];
3
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import { ActionHandlerContext } from "../../../core/actionHandler";
2
+ import { RapidPlugin } from "../../../core/server";
3
+ export declare const code = "runServerOperation";
4
+ export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: {
5
+ operation: (ctx: ActionHandlerContext) => Promise<void>;
6
+ }): Promise<void>;
package/dist/types.d.ts CHANGED
@@ -321,9 +321,24 @@ export interface UpdateEntityOptions {
321
321
  }
322
322
  export interface UpdateEntityByIdOptions {
323
323
  id: any;
324
- entity: any;
325
- changes: any;
324
+ entityToSave: any;
326
325
  }
327
326
  export interface DeleteEntityOptions {
328
327
  filters?: EntityFilterOptions[];
329
328
  }
329
+ export interface AddEntityRelationsOptions {
330
+ id: number;
331
+ property: string;
332
+ relations: {
333
+ id?: number;
334
+ [k: string]: any;
335
+ }[];
336
+ }
337
+ export interface RemoveEntityRelationsOptions {
338
+ id: number;
339
+ property: string;
340
+ relations: {
341
+ id?: number;
342
+ [k: string]: any;
343
+ }[];
344
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "keywords": [],
@@ -1,7 +1,6 @@
1
1
  import { EventEmitter } from "events";
2
- import { RpdServerEventTypes as EventTypes } from "~/types";
3
2
 
4
- export default class EventManager {
3
+ export default class EventManager<EventTypes extends Record<string, any[]>> {
5
4
  #eventEmitter: EventEmitter;
6
5
 
7
6
  constructor() {
@@ -12,10 +11,10 @@ export default class EventManager {
12
11
  eventName: K,
13
12
  listener: (...args: EventTypes[K]) => void,
14
13
  ) {
15
- this.#eventEmitter.on(eventName, listener);
14
+ this.#eventEmitter.on(eventName as string, listener);
16
15
  }
17
16
 
18
17
  emit<K extends keyof EventTypes>(eventName: K, ...args: EventTypes[K]) {
19
- return this.#eventEmitter.emit(eventName, ...args);
18
+ return this.#eventEmitter.emit(eventName as string, ...args);
20
19
  }
21
20
  }
@@ -1,5 +1,6 @@
1
1
  import * as _ from "lodash";
2
2
  import {
3
+ AddEntityRelationsOptions,
3
4
  CountEntityOptions,
4
5
  CountEntityResult,
5
6
  CreateEntityOptions,
@@ -8,6 +9,7 @@ import {
8
9
  FindEntityOptions,
9
10
  FindEntityOrderByOptions,
10
11
  IRpdDataAccessor,
12
+ RemoveEntityRelationsOptions,
11
13
  RpdDataModel,
12
14
  RpdDataModelProperty,
13
15
  UpdateEntityByIdOptions,
@@ -16,7 +18,8 @@ import { isNullOrUndefined } from "~/utilities/typeUtility";
16
18
  import { mapDbRowToEntity, mapEntityToDbRow } from "./entityMapper";
17
19
  import { mapPropertyNameToColumnName } from "./propertyMapper";
18
20
  import { isRelationProperty } from "~/utilities/rapidUtility";
19
- import { IRpdServer } from "~/core/server";
21
+ import { IRpdServer, RapidPlugin } from "~/core/server";
22
+ import { getEntityPartChanges } from "~/helpers/entityHelpers";
20
23
 
21
24
  function convertToDataAccessOrderBy(model: RpdDataModel, orderByList?: FindEntityOrderByOptions[]) {
22
25
  if (!orderByList) {
@@ -533,9 +536,23 @@ async function updateEntityById(
533
536
  server: IRpdServer,
534
537
  dataAccessor: IRpdDataAccessor,
535
538
  options: UpdateEntityByIdOptions,
539
+ plugin: RapidPlugin
536
540
  ) {
537
541
  const model = dataAccessor.getModel();
538
- const { id, entity, changes } = options;
542
+ const { id, entityToSave } = options;
543
+ if (!id) {
544
+ throw new Error("Id is required when updating an entity.")
545
+ }
546
+
547
+ const entity = await this.findById(id);
548
+ if (!entity) {
549
+ throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
550
+ }
551
+
552
+ const changes = getEntityPartChanges(entity, entityToSave);
553
+ if (!changes) {
554
+ return entity;
555
+ }
539
556
 
540
557
  const oneRelationPropertiesToUpdate: RpdDataModelProperty[] = [];
541
558
  const manyRelationPropertiesToUpdate: RpdDataModelProperty[] = [];
@@ -648,6 +665,18 @@ async function updateEntityById(
648
665
  updatedEntity[property.code] = relatedEntities;
649
666
  }
650
667
 
668
+
669
+ server.emitEvent(
670
+ "entity.update",
671
+ plugin,
672
+ {
673
+ namespace: model.namespace,
674
+ modelSingularCode: model.singularCode,
675
+ before: entity,
676
+ after: updatedEntity,
677
+ changes: changes,
678
+ },
679
+ );
651
680
  return updatedEntity;
652
681
  }
653
682
 
@@ -660,6 +689,10 @@ export default class EntityManager<TEntity=any> {
660
689
  this.#dataAccessor = dataAccessor;
661
690
  }
662
691
 
692
+ getModel(): RpdDataModel {
693
+ return this.#dataAccessor.getModel();
694
+ }
695
+
663
696
  async findEntities(options: FindEntityOptions): Promise<TEntity[]> {
664
697
  return await findEntities(this.#server, this.#dataAccessor, options);
665
698
  }
@@ -680,23 +713,133 @@ export default class EntityManager<TEntity=any> {
680
713
  });
681
714
  }
682
715
 
683
- async createEntity(options: CreateEntityOptions): Promise<TEntity> {
684
- return await createEntity(this.#server, this.#dataAccessor, options);
716
+ async createEntity(options: CreateEntityOptions, plugin: RapidPlugin): Promise<TEntity> {
717
+ const model = this.getModel();
718
+ const newEntity = await createEntity(this.#server, this.#dataAccessor, options);
719
+
720
+ this.#server.emitEvent(
721
+ "entity.create",
722
+ plugin,
723
+ {
724
+ namespace: model.namespace,
725
+ modelSingularCode: model.singularCode,
726
+ after: newEntity,
727
+ },
728
+ );
729
+
730
+ return newEntity;
685
731
  }
686
732
 
687
- async updateEntityById(options: UpdateEntityByIdOptions): Promise<TEntity> {
688
- return await updateEntityById(this.#server, this.#dataAccessor, options);
733
+ async updateEntityById(options: UpdateEntityByIdOptions, plugin: RapidPlugin): Promise<TEntity> {
734
+ return await updateEntityById(this.#server, this.#dataAccessor, options, plugin);
689
735
  }
690
736
 
691
737
  async count(options: CountEntityOptions): Promise<CountEntityResult> {
692
738
  return await this.#dataAccessor.count(options);
693
739
  }
694
740
 
695
- async deleteById(id: any): Promise<void> {
696
- return await this.#dataAccessor.deleteById(id);
741
+ async deleteById(id: any, plugin: RapidPlugin): Promise<void> {
742
+ const model = this.getModel();
743
+ const entity = await this.findById(id);
744
+ if (!entity) {
745
+ return;
746
+ }
747
+
748
+ await this.#dataAccessor.deleteById(id);
749
+ this.#server.emitEvent(
750
+ "entity.delete",
751
+ plugin,
752
+ {
753
+ namespace: model.namespace,
754
+ modelSingularCode: model.singularCode,
755
+ before: entity,
756
+ },
757
+ );
697
758
  }
698
759
 
699
- getModel(): RpdDataModel {
700
- return this.#dataAccessor.getModel();
760
+ async addRelations(options: AddEntityRelationsOptions, plugin: RapidPlugin): Promise<void> {
761
+ const model = this.getModel();
762
+ const {id, property, relations} = options;
763
+ const entity = await this.findById(id);
764
+ if (!entity) {
765
+ throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
766
+ }
767
+
768
+ const relationProperty = model.properties.find(e => e.code === property);
769
+ if (!relationProperty) {
770
+ throw new Error(`Property '${property}' was not found in ${model.namespace}.${model.singularCode}`);
771
+ }
772
+
773
+ if (!(isRelationProperty(relationProperty) && relationProperty.relation === "many")) {
774
+ throw new Error(`Operation 'addRelations' is only supported on property of 'many' relation`);
775
+ }
776
+
777
+ const server = this.#server;
778
+ const { queryBuilder } = server;
779
+ if (relationProperty.linkTableName) {
780
+ for (const relation of relations) {
781
+ const command = `INSERT INTO ${queryBuilder.quoteTable({schema:relationProperty.linkSchema, tableName: relationProperty.linkTableName})} (${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)})
782
+ SELECT $1, $2 WHERE NOT EXISTS (
783
+ SELECT ${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)}
784
+ FROM ${queryBuilder.quoteTable({schema:relationProperty.linkSchema, tableName: relationProperty.linkTableName})}
785
+ WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)}=$2
786
+ )`;
787
+ const params = [id, relation.id];
788
+ await server.queryDatabaseObject(command, params);
789
+ }
790
+ }
791
+
792
+ server.emitEvent(
793
+ "entity.addRelations",
794
+ plugin,
795
+ {
796
+ namespace: model.namespace,
797
+ modelSingularCode: model.singularCode,
798
+ entity,
799
+ property,
800
+ relations,
801
+ },
802
+ );
803
+ }
804
+
805
+ async removeRelations(options: RemoveEntityRelationsOptions, plugin: RapidPlugin): Promise<void> {
806
+ const model = this.getModel();
807
+ const {id, property, relations} = options;
808
+ const entity = await this.findById(id);
809
+ if (!entity) {
810
+ throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
811
+ }
812
+
813
+ const relationProperty = model.properties.find(e => e.code === property);
814
+ if (!relationProperty) {
815
+ throw new Error(`Property '${property}' was not found in ${model.namespace}.${model.singularCode}`);
816
+ }
817
+
818
+ if (!(isRelationProperty(relationProperty) && relationProperty.relation === "many")) {
819
+ throw new Error(`Operation 'removeRelations' is only supported on property of 'many' relation`);
820
+ }
821
+
822
+ const server = this.#server;
823
+ const { queryBuilder } = server;
824
+ if (relationProperty.linkTableName) {
825
+ for (const relation of relations) {
826
+ const command = `DELETE FROM ${queryBuilder.quoteTable({schema:relationProperty.linkSchema, tableName: relationProperty.linkTableName})}
827
+ WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)}=$2;`;
828
+ const params = [id, relation.id];
829
+ await server.queryDatabaseObject(command, params);
830
+ }
831
+ }
832
+
833
+ server.emitEvent(
834
+ "entity.removeRelations",
835
+ plugin,
836
+ {
837
+ namespace: model.namespace,
838
+ modelSingularCode: model.singularCode,
839
+ entity,
840
+ property,
841
+ relations,
842
+ },
843
+ );
701
844
  }
702
845
  }
package/src/index.ts CHANGED
@@ -19,4 +19,8 @@ export { default as DataManagePlugin } from "./plugins/dataManage/DataManagePlug
19
19
  export { default as RouteManagePlugin } from "./plugins/routeManage/RouteManagePlugin";
20
20
  export { default as WebhooksPlugin } from "./plugins/webhooks/WebhooksPlugin";
21
21
  export { default as AuthPlugin } from "./plugins/auth/AuthPlugin";
22
- export { default as FileManagePlugin } from "./plugins/fileManage/FileManagePlugin";
22
+ export { default as FileManagePlugin } from "./plugins/fileManage/FileManagePlugin";
23
+ export { default as ServerOperationPlugin } from "./plugins/serverOperation/ServerOperationPlugin";
24
+ export * from "./plugins/serverOperation/ServerOperationPluginTypes";
25
+ export { default as EntityWatchPlugin } from "./plugins/entityWatch/EntityWatchPlugin";
26
+ export * from "./plugins/entityWatch/EntityWatchPluginTypes";
@@ -1,24 +1,16 @@
1
1
  import { RunEntityActionHandlerOptions } from "~/types";
2
2
  import { mergeInput } from "~/helpers/inputHelper";
3
- import { isRelationProperty } from "~/utilities/rapidUtility";
4
3
  import { ActionHandlerContext } from "~/core/actionHandler";
5
4
  import { RapidPlugin } from "~/core/server";
6
5
 
7
6
  export const code = "addEntityRelations";
8
7
 
9
- interface AddEntityRelationsInput {
10
- id: number;
11
- property: string;
12
- relations: {id?: number, [k: string]: any}[];
13
- }
14
-
15
8
  export async function handler(
16
9
  plugin: RapidPlugin,
17
10
  ctx: ActionHandlerContext,
18
11
  options: RunEntityActionHandlerOptions,
19
12
  ) {
20
13
  const { server, input } = ctx;
21
- const { queryBuilder } = server;
22
14
  const { defaultInput, fixedInput } = options;
23
15
 
24
16
  console.debug(`Running ${code} handler...`);
@@ -28,48 +20,8 @@ export async function handler(
28
20
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
29
21
  console.debug(`mergedInput: ${JSON.stringify(mergedInput)}`);
30
22
 
31
- const dataAccessor = server.getDataAccessor(options);
32
- const model = dataAccessor.getModel();
33
-
34
- const {id, property, relations} = mergedInput as AddEntityRelationsInput;
35
- const row = await dataAccessor.findById(id);
36
- if (!row) {
37
- throw new Error(`${options.namespace}.${options.singularCode} with id "${id}" was not found.`);
38
- }
39
-
40
- const relationProperty = model.properties.find(e => e.code === property);
41
- if (!relationProperty) {
42
- throw new Error(`Property '${property}' was not found in ${options.namespace}.${options.singularCode}`);
43
- }
44
-
45
- if (!(isRelationProperty(relationProperty) && relationProperty.relation === "many")) {
46
- throw new Error(`Operation 'createEntityRelations' is only supported on property of 'many' relation`);
47
- }
48
-
49
- if (relationProperty.linkTableName) {
50
- for (const relation of relations) {
51
- const command = `INSERT INTO ${queryBuilder.quoteTable({schema:relationProperty.linkSchema, tableName: relationProperty.linkTableName})} (${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)})
52
- SELECT $1, $2 WHERE NOT EXISTS (
53
- SELECT ${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)}
54
- FROM ${queryBuilder.quoteTable({schema:relationProperty.linkSchema, tableName: relationProperty.linkTableName})}
55
- WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)}=$2
56
- )`;
57
- const params = [id, relation.id];
58
- await server.queryDatabaseObject(command, params);
59
- }
60
- }
23
+ const entityManager = server.getEntityManager(options.singularCode);
24
+ await entityManager.addRelations(mergedInput, plugin);
61
25
 
62
26
  ctx.output = {};
63
-
64
- server.emitEvent(
65
- "entity.addRelations",
66
- plugin,
67
- {
68
- namespace: options.namespace,
69
- modelSingularCode: options.singularCode,
70
- entity: row,
71
- property,
72
- relations: relations,
73
- },
74
- );
75
27
  }
@@ -37,21 +37,10 @@ export async function handler(
37
37
  const entityManager = server.getEntityManager(options.singularCode);
38
38
  const newEntity = await entityManager.createEntity({
39
39
  entity: mergedEntity,
40
- });
41
-
42
- server.emitEvent(
43
- "entity.create",
44
- plugin,
45
- {
46
- namespace: options.namespace,
47
- modelSingularCode: options.singularCode,
48
- after: newEntity,
49
- },
50
- );
40
+ }, plugin);
51
41
 
52
42
  output.push(newEntity);
53
43
  }
54
44
 
55
45
  ctx.output = output;
56
-
57
46
  }
@@ -28,16 +28,6 @@ export async function handler(
28
28
  const entityManager = server.getEntityManager(options.singularCode);
29
29
  const output = await entityManager.createEntity({
30
30
  entity: input,
31
- });
31
+ }, plugin);
32
32
  ctx.output = output;
33
-
34
- server.emitEvent(
35
- "entity.create",
36
- plugin,
37
- {
38
- namespace: options.namespace,
39
- modelSingularCode: options.singularCode,
40
- after: output,
41
- },
42
- );
43
33
  }
@@ -14,26 +14,7 @@ export async function handler(
14
14
  const { server, input } = ctx;
15
15
 
16
16
  const entityManager = server.getEntityManager(options.singularCode);
17
- const id = input.id;
18
- const row = await entityManager.findById(id);
19
- if (!row) {
20
- ctx.status = 200;
21
- return;
22
- }
23
-
24
- await entityManager.deleteById(id);
25
-
26
- const entity = mapDbRowToEntity(entityManager.getModel(), row);
27
-
28
- server.emitEvent(
29
- "entity.delete",
30
- plugin,
31
- {
32
- namespace: options.namespace,
33
- modelSingularCode: options.singularCode,
34
- before: entity,
35
- },
36
- );
17
+ await entityManager.deleteById(input.id, plugin);
37
18
 
38
19
  ctx.status = 200;
39
20
  }
@@ -1,24 +1,16 @@
1
1
  import { RunEntityActionHandlerOptions } from "~/types";
2
2
  import { mergeInput } from "~/helpers/inputHelper";
3
- import { isRelationProperty } from "~/utilities/rapidUtility";
4
3
  import { ActionHandlerContext } from "~/core/actionHandler";
5
4
  import { RapidPlugin } from "~/core/server";
6
5
 
7
6
  export const code = "removeEntityRelations";
8
7
 
9
- interface RemoveEntityRelationsInput {
10
- id: number;
11
- property: string;
12
- relations: {id?: number, [k: string]: any}[];
13
- }
14
-
15
8
  export async function handler(
16
9
  plugin: RapidPlugin,
17
10
  ctx: ActionHandlerContext,
18
11
  options: RunEntityActionHandlerOptions,
19
12
  ) {
20
13
  const { server, input } = ctx;
21
- const { queryBuilder } = server;
22
14
  const { defaultInput, fixedInput } = options;
23
15
 
24
16
  console.debug(`Running ${code} handler...`);
@@ -28,46 +20,8 @@ export async function handler(
28
20
  console.debug(`fixedInput: ${JSON.stringify(fixedInput)}`);
29
21
  console.debug(`mergedInput: ${JSON.stringify(mergedInput)}`);
30
22
 
31
- const dataAccessor = server.getDataAccessor(options);
32
- const model = dataAccessor.getModel();
33
-
34
- const {id, property, relations} = mergedInput as RemoveEntityRelationsInput;
35
- const row = await dataAccessor.findById(id);
36
- if (!row) {
37
- throw new Error(`${options.namespace}.${options.singularCode} with id "${id}" was not found.`);
38
- }
39
-
40
- console.log(mergedInput);
41
-
42
- const relationProperty = model.properties.find(e => e.code === property);
43
- if (!relationProperty) {
44
- throw new Error(`Property '${property}' was not found in ${options.namespace}.${options.singularCode}`);
45
- }
46
-
47
- if (!(isRelationProperty(relationProperty) && relationProperty.relation === "many")) {
48
- throw new Error(`Operation 'createEntityRelations' is only supported on property of 'many' relation`);
49
- }
50
-
51
- if (relationProperty.linkTableName) {
52
- for (const relation of relations) {
53
- const command = `DELETE FROM ${queryBuilder.quoteTable({schema:relationProperty.linkSchema, tableName: relationProperty.linkTableName})}
54
- WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName!)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName!)}=$2;`;
55
- const params = [id, relation.id];
56
- await server.queryDatabaseObject(command, params);
57
- }
58
- }
23
+ const entityManager = server.getEntityManager(options.singularCode);
24
+ await entityManager.removeRelations(mergedInput, plugin);
59
25
 
60
26
  ctx.output = {};
61
-
62
- server.emitEvent(
63
- "entity.removeRelations",
64
- plugin,
65
- {
66
- namespace: options.namespace,
67
- modelSingularCode: options.singularCode,
68
- entity: row,
69
- property,
70
- relations: relations,
71
- },
72
- );
73
27
  }
@@ -23,31 +23,7 @@ export async function handler(
23
23
  console.debug(`mergedInput: ${JSON.stringify(mergedInput)}`);
24
24
 
25
25
  const entityManager = server.getEntityManager(options.singularCode);
26
- const id = mergedInput.id;
27
- const row = await entityManager.findById(id);
28
- if (!row) {
29
- throw new Error(`${options.namespace}.${options.singularCode} with id "${id}" was not found.`);
30
- }
31
26
 
32
- const entity = mapDbRowToEntity(entityManager.getModel(), row);
33
- const changes = getEntityPartChanges(entity, mergedInput);
34
- if (!changes) {
35
- ctx.output = entity;
36
- return;
37
- }
38
-
39
- const output = await entityManager.updateEntityById({ id, entity, changes });
27
+ const output = await entityManager.updateEntityById({ id: mergedInput.id, entityToSave: mergedInput }, plugin);
40
28
  ctx.output = output;
41
-
42
- server.emitEvent(
43
- "entity.update",
44
- plugin,
45
- {
46
- namespace: options.namespace,
47
- modelSingularCode: options.singularCode,
48
- before: entity,
49
- after: output,
50
- changes: changes,
51
- },
52
- );
53
29
  }