@ruiapp/rapid-core 0.1.54 → 0.1.55
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/dist/core/server.d.ts +2 -2
- package/dist/dataAccess/entityManager.d.ts +3 -3
- package/dist/index.js +213 -92
- package/dist/server.d.ts +2 -2
- package/dist/types.d.ts +34 -25
- package/package.json +1 -1
- package/src/core/server.ts +2 -2
- package/src/dataAccess/entityManager.ts +121 -68
- package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +1 -1
- package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +3 -2
- package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +1 -1
- package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +1 -1
- package/src/plugins/dataManage/actionHandlers/deleteCollectionEntityById.ts +4 -1
- package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +1 -1
- package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +4 -1
- package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +3 -2
- package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +9 -2
- package/src/plugins/metaManage/MetaManagePlugin.ts +33 -2
- package/src/server.ts +6 -4
- package/src/types.ts +37 -25
package/dist/types.d.ts
CHANGED
|
@@ -56,32 +56,29 @@ export interface GetModelOptions {
|
|
|
56
56
|
singularCode: string;
|
|
57
57
|
}
|
|
58
58
|
export type RpdServerEventTypes = {
|
|
59
|
-
"entity.beforeCreate": [RapidPlugin, RpdEntityBeforeCreateEventPayload];
|
|
60
|
-
"entity.create": [RapidPlugin, RpdEntityCreateEventPayload];
|
|
61
|
-
"entity.beforeUpdate": [RapidPlugin, RpdEntityBeforeUpdateEventPayload];
|
|
62
|
-
"entity.update": [RapidPlugin, RpdEntityUpdateEventPayload];
|
|
63
|
-
"entity.beforeDelete": [RapidPlugin, RpdEntityBeforeDeleteEventPayload];
|
|
64
|
-
"entity.delete": [RapidPlugin, RpdEntityDeleteEventPayload];
|
|
65
|
-
"entity.addRelations": [RapidPlugin, RpdEntityAddRelationsEventPayload];
|
|
66
|
-
"entity.removeRelations": [RapidPlugin, RpdEntityRemoveRelationsEventPayload];
|
|
67
|
-
"entity.beforeResponse": [RapidPlugin, RpdEntityBeforeResponseEventPayload];
|
|
59
|
+
"entity.beforeCreate": [RapidPlugin, RpdEntityBeforeCreateEventPayload, RouteContext?];
|
|
60
|
+
"entity.create": [RapidPlugin, RpdEntityCreateEventPayload, RouteContext?];
|
|
61
|
+
"entity.beforeUpdate": [RapidPlugin, RpdEntityBeforeUpdateEventPayload, RouteContext?];
|
|
62
|
+
"entity.update": [RapidPlugin, RpdEntityUpdateEventPayload, RouteContext?];
|
|
63
|
+
"entity.beforeDelete": [RapidPlugin, RpdEntityBeforeDeleteEventPayload, RouteContext?];
|
|
64
|
+
"entity.delete": [RapidPlugin, RpdEntityDeleteEventPayload, RouteContext?];
|
|
65
|
+
"entity.addRelations": [RapidPlugin, RpdEntityAddRelationsEventPayload, RouteContext?];
|
|
66
|
+
"entity.removeRelations": [RapidPlugin, RpdEntityRemoveRelationsEventPayload, RouteContext?];
|
|
67
|
+
"entity.beforeResponse": [RapidPlugin, RpdEntityBeforeResponseEventPayload, RouteContext?];
|
|
68
68
|
};
|
|
69
69
|
export interface RpdEntityBeforeCreateEventPayload {
|
|
70
|
-
routerContext?: RouteContext;
|
|
71
70
|
namespace: string;
|
|
72
71
|
modelSingularCode: string;
|
|
73
72
|
baseModelSingularCode?: string;
|
|
74
73
|
before: any;
|
|
75
74
|
}
|
|
76
75
|
export interface RpdEntityCreateEventPayload {
|
|
77
|
-
routerContext?: RouteContext;
|
|
78
76
|
namespace: string;
|
|
79
77
|
modelSingularCode: string;
|
|
80
78
|
baseModelSingularCode?: string;
|
|
81
79
|
after: any;
|
|
82
80
|
}
|
|
83
81
|
export interface RpdEntityBeforeUpdateEventPayload {
|
|
84
|
-
routerContext?: RouteContext;
|
|
85
82
|
namespace: string;
|
|
86
83
|
modelSingularCode: string;
|
|
87
84
|
baseModelSingularCode?: string;
|
|
@@ -89,7 +86,6 @@ export interface RpdEntityBeforeUpdateEventPayload {
|
|
|
89
86
|
changes: any;
|
|
90
87
|
}
|
|
91
88
|
export interface RpdEntityUpdateEventPayload {
|
|
92
|
-
routerContext?: RouteContext;
|
|
93
89
|
namespace: string;
|
|
94
90
|
modelSingularCode: string;
|
|
95
91
|
baseModelSingularCode?: string;
|
|
@@ -98,21 +94,18 @@ export interface RpdEntityUpdateEventPayload {
|
|
|
98
94
|
changes: any;
|
|
99
95
|
}
|
|
100
96
|
export interface RpdEntityBeforeDeleteEventPayload {
|
|
101
|
-
routerContext?: RouteContext;
|
|
102
97
|
namespace: string;
|
|
103
98
|
modelSingularCode: string;
|
|
104
99
|
baseModelSingularCode?: string;
|
|
105
100
|
before: any;
|
|
106
101
|
}
|
|
107
102
|
export interface RpdEntityDeleteEventPayload {
|
|
108
|
-
routerContext?: RouteContext;
|
|
109
103
|
namespace: string;
|
|
110
104
|
modelSingularCode: string;
|
|
111
105
|
baseModelSingularCode?: string;
|
|
112
106
|
before: any;
|
|
113
107
|
}
|
|
114
108
|
export interface RpdEntityAddRelationsEventPayload {
|
|
115
|
-
routerContext?: RouteContext;
|
|
116
109
|
namespace: string;
|
|
117
110
|
modelSingularCode: string;
|
|
118
111
|
baseModelSingularCode?: string;
|
|
@@ -121,7 +114,6 @@ export interface RpdEntityAddRelationsEventPayload {
|
|
|
121
114
|
relations: any[];
|
|
122
115
|
}
|
|
123
116
|
export interface RpdEntityRemoveRelationsEventPayload {
|
|
124
|
-
routerContext?: RouteContext;
|
|
125
117
|
namespace: string;
|
|
126
118
|
modelSingularCode: string;
|
|
127
119
|
baseModelSingularCode?: string;
|
|
@@ -130,12 +122,17 @@ export interface RpdEntityRemoveRelationsEventPayload {
|
|
|
130
122
|
relations: any[];
|
|
131
123
|
}
|
|
132
124
|
export interface RpdEntityBeforeResponseEventPayload {
|
|
133
|
-
routerContext?: RouteContext;
|
|
134
125
|
namespace: string;
|
|
135
126
|
modelSingularCode: string;
|
|
136
127
|
baseModelSingularCode?: string;
|
|
137
128
|
entities: any[];
|
|
138
129
|
}
|
|
130
|
+
export type EmitServerEventOptions<TEventName extends keyof RpdServerEventTypes> = {
|
|
131
|
+
eventName: TEventName;
|
|
132
|
+
payload: RpdServerEventTypes[TEventName][1];
|
|
133
|
+
sender?: RapidPlugin;
|
|
134
|
+
routeContext?: RouteContext;
|
|
135
|
+
};
|
|
139
136
|
export interface QuoteTableOptions {
|
|
140
137
|
schema?: string;
|
|
141
138
|
tableName: string;
|
|
@@ -345,13 +342,19 @@ export type EntityFilterOperators = EntityFilterRelationalOperators | EntityFilt
|
|
|
345
342
|
export type EntityFilterOptions = FindEntityRelationalFilterOptions | FindEntitySetFilterOptions | FindEntityLogicalFilterOptions | FindEntityUnaryFilterOptions | FindEntityExistenceFilterOptions;
|
|
346
343
|
export type EntityNonRelationPropertyFilterOptions = FindEntityRelationalFilterOptions | FindEntitySetFilterOptions | FindEntityUnaryFilterOptions;
|
|
347
344
|
export interface FindEntityOptions {
|
|
348
|
-
|
|
345
|
+
routeContext?: RouteContext;
|
|
349
346
|
filters?: EntityFilterOptions[];
|
|
350
347
|
orderBy?: FindEntityOrderByOptions[];
|
|
351
348
|
pagination?: FindEntityPaginationOptions;
|
|
352
349
|
properties?: string[];
|
|
353
350
|
keepNonPropertyFields?: boolean;
|
|
354
351
|
}
|
|
352
|
+
export interface FindEntityByIdOptions {
|
|
353
|
+
routeContext?: RouteContext;
|
|
354
|
+
id: any;
|
|
355
|
+
properties?: string[];
|
|
356
|
+
keepNonPropertyFields?: boolean;
|
|
357
|
+
}
|
|
355
358
|
export interface FindEntityRelationalFilterOptions {
|
|
356
359
|
field: string;
|
|
357
360
|
operator: EntityFilterRelationalOperators;
|
|
@@ -386,33 +389,38 @@ export interface FindEntityOrderByOptions {
|
|
|
386
389
|
desc?: boolean;
|
|
387
390
|
}
|
|
388
391
|
export interface CountEntityOptions {
|
|
392
|
+
routeContext?: RouteContext;
|
|
389
393
|
filters?: EntityFilterOptions[];
|
|
390
394
|
}
|
|
391
395
|
export interface CountEntityResult {
|
|
392
396
|
count: number;
|
|
393
397
|
}
|
|
398
|
+
export interface DeleteEntityByIdOptions {
|
|
399
|
+
routeContext?: RouteContext;
|
|
400
|
+
id: any;
|
|
401
|
+
}
|
|
394
402
|
export interface CreateEntityOptions {
|
|
395
|
-
|
|
403
|
+
routeContext?: RouteContext;
|
|
396
404
|
entity: any;
|
|
397
405
|
}
|
|
398
406
|
export interface UpdateEntityOptions {
|
|
399
|
-
|
|
407
|
+
routeContext?: RouteContext;
|
|
400
408
|
filters?: EntityFilterOptions[];
|
|
401
409
|
entity: any;
|
|
402
410
|
}
|
|
403
411
|
export interface UpdateEntityByIdOptions {
|
|
404
|
-
|
|
412
|
+
routeContext?: RouteContext;
|
|
405
413
|
id: any;
|
|
406
414
|
entityToSave: any;
|
|
407
415
|
operation?: any;
|
|
408
416
|
stateProperties?: string[];
|
|
409
417
|
}
|
|
410
418
|
export interface DeleteEntityOptions {
|
|
411
|
-
|
|
419
|
+
routeContext?: RouteContext;
|
|
412
420
|
filters?: EntityFilterOptions[];
|
|
413
421
|
}
|
|
414
422
|
export interface AddEntityRelationsOptions {
|
|
415
|
-
|
|
423
|
+
routeContext?: RouteContext;
|
|
416
424
|
id: number;
|
|
417
425
|
property: string;
|
|
418
426
|
relations: {
|
|
@@ -421,7 +429,7 @@ export interface AddEntityRelationsOptions {
|
|
|
421
429
|
}[];
|
|
422
430
|
}
|
|
423
431
|
export interface RemoveEntityRelationsOptions {
|
|
424
|
-
|
|
432
|
+
routeContext?: RouteContext;
|
|
425
433
|
id: number;
|
|
426
434
|
property: string;
|
|
427
435
|
relations: {
|
|
@@ -439,6 +447,7 @@ export type EntityWatchHandler<TEventName extends keyof RpdServerEventTypes> = (
|
|
|
439
447
|
export type EntityWatchHandlerContext<TEventName extends keyof RpdServerEventTypes> = {
|
|
440
448
|
server: IRpdServer;
|
|
441
449
|
payload: RpdServerEventTypes[TEventName][1];
|
|
450
|
+
routerContext?: RouteContext;
|
|
442
451
|
};
|
|
443
452
|
export interface EntityWatchPluginInitOptions {
|
|
444
453
|
watchers: EntityWatcherType[];
|
package/package.json
CHANGED
package/src/core/server.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateEntityOptions, EntityWatcherType, GetDataAccessorOptions, GetModelOptions, IDatabaseConfig, IQueryBuilder, IRpdDataAccessor, RapidServerConfig, RpdApplicationConfig, RpdDataModel, RpdDataModelProperty, RpdServerEventTypes, UpdateEntityByIdOptions } from "~/types";
|
|
1
|
+
import { CreateEntityOptions, EmitServerEventOptions, EntityWatcherType, GetDataAccessorOptions, GetModelOptions, IDatabaseConfig, IQueryBuilder, IRpdDataAccessor, RapidServerConfig, RpdApplicationConfig, RpdDataModel, RpdDataModelProperty, RpdServerEventTypes, UpdateEntityByIdOptions } from "~/types";
|
|
2
2
|
import { IPluginActionHandler, ActionHandler, ActionHandlerContext } from "./actionHandler";
|
|
3
3
|
import { Next, RouteContext } from "./routeContext";
|
|
4
4
|
import EntityManager from "~/dataAccess/entityManager";
|
|
@@ -30,7 +30,7 @@ export interface IRpdServer {
|
|
|
30
30
|
getModel(options: GetModelOptions): RpdDataModel | undefined;
|
|
31
31
|
registerEventHandler<K extends keyof RpdServerEventTypes>(eventName: K, listener: (...args: RpdServerEventTypes[K]) => void);
|
|
32
32
|
registerEntityWatcher(entityWatcher: EntityWatcherType);
|
|
33
|
-
emitEvent<
|
|
33
|
+
emitEvent<TEventName extends keyof RpdServerEventTypes>(event: EmitServerEventOptions<TEventName>): void;
|
|
34
34
|
handleRequest(request: Request, next: Next): Promise<Response>;
|
|
35
35
|
beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
|
|
36
36
|
beforeCreateEntity(model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
|
|
@@ -3,9 +3,11 @@ import {
|
|
|
3
3
|
CountEntityOptions,
|
|
4
4
|
CountEntityResult,
|
|
5
5
|
CreateEntityOptions,
|
|
6
|
+
DeleteEntityByIdOptions,
|
|
6
7
|
EntityFilterOperators,
|
|
7
8
|
EntityFilterOptions,
|
|
8
9
|
EntityNonRelationPropertyFilterOptions,
|
|
10
|
+
FindEntityByIdOptions,
|
|
9
11
|
FindEntityOptions,
|
|
10
12
|
FindEntityOrderByOptions,
|
|
11
13
|
IRpdDataAccessor,
|
|
@@ -24,6 +26,7 @@ import { filter, find, first, forEach, isArray, isObject, keys, map, reject, uni
|
|
|
24
26
|
import { getEntityPropertiesIncludingBase, getEntityProperty, getEntityPropertyByCode } from "./metaHelper";
|
|
25
27
|
import { ColumnQueryOptions, CountRowOptions, FindRowOptions, FindRowOrderByOptions, RowFilterOptions } from "./dataAccessTypes";
|
|
26
28
|
import { newEntityOperationError } from "~/utilities/errorUtility";
|
|
29
|
+
import { RouteContext } from "~/core/routeContext";
|
|
27
30
|
|
|
28
31
|
function convertEntityOrderByToRowOrderBy(server: IRpdServer, model: RpdDataModel, baseModel?: RpdDataModel, orderByList?: FindEntityOrderByOptions[]) {
|
|
29
32
|
if (!orderByList) {
|
|
@@ -151,7 +154,7 @@ async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
151
154
|
forEach(rows, (row: any) => {
|
|
152
155
|
row[relationProperty.code] = filter(relationLinks, (link: any) => {
|
|
153
156
|
return link[relationProperty.selfIdColumnName!] == row["id"];
|
|
154
|
-
}).map((link) => mapDbRowToEntity(server, targetModel, link.targetEntity,
|
|
157
|
+
}).map((link) => mapDbRowToEntity(server, targetModel, link.targetEntity, options.keepNonPropertyFields));
|
|
155
158
|
});
|
|
156
159
|
}
|
|
157
160
|
} else {
|
|
@@ -175,7 +178,7 @@ async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
175
178
|
if (isManyRelation) {
|
|
176
179
|
row[relationProperty.code] = filter(relatedEntities, (relatedEntity: any) => {
|
|
177
180
|
return relatedEntity[relationProperty.selfIdColumnName!] == row.id;
|
|
178
|
-
}).map((item) => mapDbRowToEntity(server, targetModel!, item,
|
|
181
|
+
}).map((item) => mapDbRowToEntity(server, targetModel!, item, options.keepNonPropertyFields));
|
|
179
182
|
} else {
|
|
180
183
|
row[relationProperty.code] = mapDbRowToEntity(
|
|
181
184
|
server,
|
|
@@ -184,7 +187,7 @@ async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
184
187
|
// TODO: id property code should be configurable.
|
|
185
188
|
return relatedEntity["id"] == row[relationProperty.targetIdColumnName!];
|
|
186
189
|
}),
|
|
187
|
-
|
|
190
|
+
options.keepNonPropertyFields,
|
|
188
191
|
);
|
|
189
192
|
}
|
|
190
193
|
});
|
|
@@ -193,17 +196,17 @@ async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
193
196
|
}
|
|
194
197
|
const entities = rows.map((item) => mapDbRowToEntity(server, model, item, options.keepNonPropertyFields));
|
|
195
198
|
|
|
196
|
-
await server.emitEvent(
|
|
197
|
-
"entity.beforeResponse",
|
|
198
|
-
{
|
|
199
|
-
routerContext: options.routerContext,
|
|
199
|
+
await server.emitEvent({
|
|
200
|
+
eventName: "entity.beforeResponse",
|
|
201
|
+
payload: {
|
|
200
202
|
namespace: model.namespace,
|
|
201
203
|
modelSingularCode: model.singularCode,
|
|
202
204
|
baseModelSingularCode: model.base,
|
|
203
205
|
entities,
|
|
204
206
|
},
|
|
205
|
-
null,
|
|
206
|
-
|
|
207
|
+
sender: null,
|
|
208
|
+
routeContext: options.routeContext,
|
|
209
|
+
});
|
|
207
210
|
|
|
208
211
|
return entities;
|
|
209
212
|
}
|
|
@@ -213,7 +216,8 @@ async function findEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor, op
|
|
|
213
216
|
return first(entities);
|
|
214
217
|
}
|
|
215
218
|
|
|
216
|
-
async function findById(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
219
|
+
async function findById(server: IRpdServer, dataAccessor: IRpdDataAccessor, options: FindEntityByIdOptions): Promise<any> {
|
|
220
|
+
const { id, properties, keepNonPropertyFields, routeContext } = options;
|
|
217
221
|
return await findEntity(server, dataAccessor, {
|
|
218
222
|
filters: [
|
|
219
223
|
{
|
|
@@ -222,7 +226,9 @@ async function findById(server: IRpdServer, dataAccessor: IRpdDataAccessor, id:
|
|
|
222
226
|
value: id,
|
|
223
227
|
},
|
|
224
228
|
],
|
|
229
|
+
properties,
|
|
225
230
|
keepNonPropertyFields,
|
|
231
|
+
routeContext,
|
|
226
232
|
});
|
|
227
233
|
}
|
|
228
234
|
|
|
@@ -506,21 +512,21 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
506
512
|
throw newEntityOperationError("Create base entity directly is not allowed.");
|
|
507
513
|
}
|
|
508
514
|
|
|
509
|
-
const { entity } = options;
|
|
515
|
+
const { entity, routeContext } = options;
|
|
510
516
|
|
|
511
517
|
await server.beforeCreateEntity(model, options);
|
|
512
518
|
|
|
513
|
-
await server.emitEvent(
|
|
514
|
-
"entity.beforeCreate",
|
|
515
|
-
{
|
|
516
|
-
routerContext: options.routerContext,
|
|
519
|
+
await server.emitEvent({
|
|
520
|
+
eventName: "entity.beforeCreate",
|
|
521
|
+
payload: {
|
|
517
522
|
namespace: model.namespace,
|
|
518
523
|
modelSingularCode: model.singularCode,
|
|
519
524
|
baseModelSingularCode: model.base,
|
|
520
525
|
before: entity,
|
|
521
526
|
},
|
|
522
|
-
plugin,
|
|
523
|
-
|
|
527
|
+
sender: plugin,
|
|
528
|
+
routeContext,
|
|
529
|
+
});
|
|
524
530
|
|
|
525
531
|
const oneRelationPropertiesToCreate: RpdDataModelProperty[] = [];
|
|
526
532
|
const manyRelationPropertiesToCreate: RpdDataModelProperty[] = [];
|
|
@@ -560,7 +566,10 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
560
566
|
newEntityOneRelationProps[property.code] = newTargetEntity;
|
|
561
567
|
targetRow[property.targetIdColumnName!] = newTargetEntity["id"];
|
|
562
568
|
} else {
|
|
563
|
-
const targetEntity = await findById(server, targetDataAccessor,
|
|
569
|
+
const targetEntity = await findById(server, targetDataAccessor, {
|
|
570
|
+
id: targetEntityId,
|
|
571
|
+
routeContext,
|
|
572
|
+
});
|
|
564
573
|
if (!targetEntity) {
|
|
565
574
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
566
575
|
}
|
|
@@ -570,7 +579,10 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
570
579
|
} else {
|
|
571
580
|
// fieldValue is id;
|
|
572
581
|
const targetEntityId = fieldValue;
|
|
573
|
-
const targetEntity = await findById(server, targetDataAccessor,
|
|
582
|
+
const targetEntity = await findById(server, targetDataAccessor, {
|
|
583
|
+
id: targetEntityId,
|
|
584
|
+
routeContext,
|
|
585
|
+
});
|
|
574
586
|
if (!targetEntity) {
|
|
575
587
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
576
588
|
}
|
|
@@ -664,29 +676,32 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
664
676
|
}
|
|
665
677
|
}
|
|
666
678
|
|
|
667
|
-
await server.emitEvent(
|
|
668
|
-
"entity.create",
|
|
669
|
-
{
|
|
670
|
-
routerContext: options.routerContext,
|
|
679
|
+
await server.emitEvent({
|
|
680
|
+
eventName: "entity.create",
|
|
681
|
+
payload: {
|
|
671
682
|
namespace: model.namespace,
|
|
672
683
|
modelSingularCode: model.singularCode,
|
|
673
684
|
baseModelSingularCode: model.base,
|
|
674
685
|
after: newEntity,
|
|
675
686
|
},
|
|
676
|
-
plugin,
|
|
677
|
-
|
|
687
|
+
sender: plugin,
|
|
688
|
+
routeContext,
|
|
689
|
+
});
|
|
678
690
|
|
|
679
691
|
return newEntity;
|
|
680
692
|
}
|
|
681
693
|
|
|
682
694
|
async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccessor, options: UpdateEntityByIdOptions, plugin?: RapidPlugin) {
|
|
683
695
|
const model = dataAccessor.getModel();
|
|
684
|
-
const { id, entityToSave } = options;
|
|
696
|
+
const { id, entityToSave, routeContext } = options;
|
|
685
697
|
if (!id) {
|
|
686
698
|
throw new Error("Id is required when updating an entity.");
|
|
687
699
|
}
|
|
688
700
|
|
|
689
|
-
const entity = await findById(server, dataAccessor,
|
|
701
|
+
const entity = await findById(server, dataAccessor, {
|
|
702
|
+
id,
|
|
703
|
+
routeContext,
|
|
704
|
+
});
|
|
690
705
|
if (!entity) {
|
|
691
706
|
throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
|
|
692
707
|
}
|
|
@@ -699,16 +714,17 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
699
714
|
options.entityToSave = changes || {};
|
|
700
715
|
await server.beforeUpdateEntity(model, options, entity);
|
|
701
716
|
|
|
702
|
-
await server.emitEvent(
|
|
703
|
-
"entity.beforeUpdate",
|
|
704
|
-
{
|
|
717
|
+
await server.emitEvent({
|
|
718
|
+
eventName: "entity.beforeUpdate",
|
|
719
|
+
payload: {
|
|
705
720
|
namespace: model.namespace,
|
|
706
721
|
modelSingularCode: model.singularCode,
|
|
707
722
|
before: entity,
|
|
708
723
|
changes: options.entityToSave,
|
|
709
724
|
},
|
|
710
|
-
plugin,
|
|
711
|
-
|
|
725
|
+
sender: plugin,
|
|
726
|
+
routeContext: options.routeContext,
|
|
727
|
+
});
|
|
712
728
|
|
|
713
729
|
changes = getEntityPartChanges(entity, options.entityToSave);
|
|
714
730
|
|
|
@@ -750,7 +766,10 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
750
766
|
updatedEntityOneRelationProps[property.code] = newTargetEntity;
|
|
751
767
|
targetRow[property.targetIdColumnName!] = newTargetEntity["id"];
|
|
752
768
|
} else {
|
|
753
|
-
const targetEntity = await findById(server, targetDataAccessor,
|
|
769
|
+
const targetEntity = await findById(server, targetDataAccessor, {
|
|
770
|
+
id: targetEntityId,
|
|
771
|
+
routeContext,
|
|
772
|
+
});
|
|
754
773
|
if (!targetEntity) {
|
|
755
774
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
756
775
|
}
|
|
@@ -760,7 +779,10 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
760
779
|
} else {
|
|
761
780
|
// fieldValue is id;
|
|
762
781
|
const targetEntityId = fieldValue;
|
|
763
|
-
const targetEntity = await findById(server, targetDataAccessor,
|
|
782
|
+
const targetEntity = await findById(server, targetDataAccessor, {
|
|
783
|
+
id: targetEntityId,
|
|
784
|
+
routeContext,
|
|
785
|
+
});
|
|
764
786
|
if (!targetEntity) {
|
|
765
787
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
766
788
|
}
|
|
@@ -862,9 +884,9 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
862
884
|
updatedEntity[property.code] = relatedEntities;
|
|
863
885
|
}
|
|
864
886
|
|
|
865
|
-
await server.emitEvent(
|
|
866
|
-
"entity.update",
|
|
867
|
-
{
|
|
887
|
+
await server.emitEvent({
|
|
888
|
+
eventName: "entity.update",
|
|
889
|
+
payload: {
|
|
868
890
|
namespace: model.namespace,
|
|
869
891
|
modelSingularCode: model.singularCode,
|
|
870
892
|
// TODO: should not emit event on base model if it's not effected.
|
|
@@ -873,8 +895,10 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
873
895
|
after: updatedEntity,
|
|
874
896
|
changes: changes,
|
|
875
897
|
},
|
|
876
|
-
plugin,
|
|
877
|
-
|
|
898
|
+
sender: plugin,
|
|
899
|
+
routeContext: options.routeContext,
|
|
900
|
+
});
|
|
901
|
+
|
|
878
902
|
return updatedEntity;
|
|
879
903
|
}
|
|
880
904
|
|
|
@@ -899,8 +923,14 @@ export default class EntityManager<TEntity = any> {
|
|
|
899
923
|
return await findEntity(this.#server, this.#dataAccessor, options);
|
|
900
924
|
}
|
|
901
925
|
|
|
902
|
-
async findById(
|
|
903
|
-
|
|
926
|
+
async findById(options: FindEntityByIdOptions): Promise<TEntity | null> {
|
|
927
|
+
// options is id
|
|
928
|
+
if (!isObject(options)) {
|
|
929
|
+
options = {
|
|
930
|
+
id: options,
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
return await findById(this.#server, this.#dataAccessor, options);
|
|
904
934
|
}
|
|
905
935
|
|
|
906
936
|
async createEntity(options: CreateEntityOptions, plugin?: RapidPlugin): Promise<TEntity> {
|
|
@@ -925,26 +955,41 @@ export default class EntityManager<TEntity = any> {
|
|
|
925
955
|
return await this.#dataAccessor.count(countRowOptions);
|
|
926
956
|
}
|
|
927
957
|
|
|
928
|
-
async deleteById(
|
|
958
|
+
async deleteById(options: DeleteEntityByIdOptions, plugin?: RapidPlugin): Promise<void> {
|
|
959
|
+
// options is id
|
|
960
|
+
if (!isObject(options)) {
|
|
961
|
+
options = {
|
|
962
|
+
id: options,
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
|
|
929
966
|
const model = this.getModel();
|
|
930
967
|
if (model.derivedTypePropertyCode) {
|
|
931
968
|
throw newEntityOperationError("Delete base entity directly is not allowed.");
|
|
932
969
|
}
|
|
933
970
|
|
|
934
|
-
const
|
|
971
|
+
const { id, routeContext } = options;
|
|
972
|
+
|
|
973
|
+
const entity = await this.findById({
|
|
974
|
+
id,
|
|
975
|
+
keepNonPropertyFields: true,
|
|
976
|
+
routeContext,
|
|
977
|
+
});
|
|
978
|
+
|
|
935
979
|
if (!entity) {
|
|
936
980
|
return;
|
|
937
981
|
}
|
|
938
982
|
|
|
939
|
-
await this.#server.emitEvent(
|
|
940
|
-
"entity.beforeDelete",
|
|
941
|
-
{
|
|
983
|
+
await this.#server.emitEvent({
|
|
984
|
+
eventName: "entity.beforeDelete",
|
|
985
|
+
payload: {
|
|
942
986
|
namespace: model.namespace,
|
|
943
987
|
modelSingularCode: model.singularCode,
|
|
944
988
|
before: entity,
|
|
945
989
|
},
|
|
946
|
-
plugin,
|
|
947
|
-
|
|
990
|
+
sender: plugin,
|
|
991
|
+
routeContext,
|
|
992
|
+
});
|
|
948
993
|
|
|
949
994
|
await this.#dataAccessor.deleteById(id);
|
|
950
995
|
if (model.base) {
|
|
@@ -954,23 +999,26 @@ export default class EntityManager<TEntity = any> {
|
|
|
954
999
|
await baseDataAccessor.deleteById(id);
|
|
955
1000
|
}
|
|
956
1001
|
|
|
957
|
-
await this.#server.emitEvent(
|
|
958
|
-
"entity.delete",
|
|
959
|
-
{
|
|
1002
|
+
await this.#server.emitEvent({
|
|
1003
|
+
eventName: "entity.delete",
|
|
1004
|
+
payload: {
|
|
960
1005
|
namespace: model.namespace,
|
|
961
1006
|
modelSingularCode: model.singularCode,
|
|
962
|
-
baseModelSingularCode: model.base,
|
|
963
1007
|
before: entity,
|
|
964
1008
|
},
|
|
965
|
-
plugin,
|
|
966
|
-
|
|
1009
|
+
sender: plugin,
|
|
1010
|
+
routeContext,
|
|
1011
|
+
});
|
|
967
1012
|
}
|
|
968
1013
|
|
|
969
1014
|
async addRelations(options: AddEntityRelationsOptions, plugin?: RapidPlugin): Promise<void> {
|
|
970
1015
|
const server = this.#server;
|
|
971
1016
|
const model = this.getModel();
|
|
972
|
-
const { id, property, relations } = options;
|
|
973
|
-
const entity = await this.findById(
|
|
1017
|
+
const { id, property, relations, routeContext } = options;
|
|
1018
|
+
const entity = await this.findById({
|
|
1019
|
+
id,
|
|
1020
|
+
routeContext,
|
|
1021
|
+
});
|
|
974
1022
|
if (!entity) {
|
|
975
1023
|
throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
|
|
976
1024
|
}
|
|
@@ -998,24 +1046,28 @@ export default class EntityManager<TEntity = any> {
|
|
|
998
1046
|
}
|
|
999
1047
|
}
|
|
1000
1048
|
|
|
1001
|
-
await server.emitEvent(
|
|
1002
|
-
"entity.addRelations",
|
|
1003
|
-
{
|
|
1049
|
+
await server.emitEvent({
|
|
1050
|
+
eventName: "entity.addRelations",
|
|
1051
|
+
payload: {
|
|
1004
1052
|
namespace: model.namespace,
|
|
1005
1053
|
modelSingularCode: model.singularCode,
|
|
1006
1054
|
entity,
|
|
1007
1055
|
property,
|
|
1008
1056
|
relations,
|
|
1009
1057
|
},
|
|
1010
|
-
plugin,
|
|
1011
|
-
|
|
1058
|
+
sender: plugin,
|
|
1059
|
+
routeContext: options.routeContext,
|
|
1060
|
+
});
|
|
1012
1061
|
}
|
|
1013
1062
|
|
|
1014
1063
|
async removeRelations(options: RemoveEntityRelationsOptions, plugin?: RapidPlugin): Promise<void> {
|
|
1015
1064
|
const server = this.#server;
|
|
1016
1065
|
const model = this.getModel();
|
|
1017
|
-
const { id, property, relations } = options;
|
|
1018
|
-
const entity = await this.findById(
|
|
1066
|
+
const { id, property, relations, routeContext } = options;
|
|
1067
|
+
const entity = await this.findById({
|
|
1068
|
+
id,
|
|
1069
|
+
routeContext,
|
|
1070
|
+
});
|
|
1019
1071
|
if (!entity) {
|
|
1020
1072
|
throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
|
|
1021
1073
|
}
|
|
@@ -1039,16 +1091,17 @@ export default class EntityManager<TEntity = any> {
|
|
|
1039
1091
|
}
|
|
1040
1092
|
}
|
|
1041
1093
|
|
|
1042
|
-
await server.emitEvent(
|
|
1043
|
-
"entity.removeRelations",
|
|
1044
|
-
{
|
|
1094
|
+
await server.emitEvent({
|
|
1095
|
+
eventName: "entity.removeRelations",
|
|
1096
|
+
payload: {
|
|
1045
1097
|
namespace: model.namespace,
|
|
1046
1098
|
modelSingularCode: model.singularCode,
|
|
1047
1099
|
entity,
|
|
1048
1100
|
property,
|
|
1049
1101
|
relations,
|
|
1050
1102
|
},
|
|
1051
|
-
plugin,
|
|
1052
|
-
|
|
1103
|
+
sender: plugin,
|
|
1104
|
+
routeContext: options.routeContext,
|
|
1105
|
+
});
|
|
1053
1106
|
}
|
|
1054
1107
|
}
|
|
@@ -13,7 +13,7 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
|
|
|
13
13
|
logger.debug(`Running ${code} handler...`, { defaultInput, fixedInput, mergedInput });
|
|
14
14
|
|
|
15
15
|
const entityManager = server.getEntityManager(options.singularCode);
|
|
16
|
-
mergedInput.
|
|
16
|
+
mergedInput.routeContext = ctx.routerContext;
|
|
17
17
|
await entityManager.addRelations(mergedInput, plugin);
|
|
18
18
|
|
|
19
19
|
ctx.output = {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RunEntityActionHandlerOptions } from "~/types";
|
|
1
|
+
import { CountEntityOptions, RunEntityActionHandlerOptions } from "~/types";
|
|
2
2
|
import runCollectionEntityActionHandler from "~/helpers/runCollectionEntityActionHandler";
|
|
3
3
|
import { removeFiltersWithNullValue } from "~/dataAccess/filterHelper";
|
|
4
4
|
import { ActionHandlerContext } from "~/core/actionHandler";
|
|
@@ -7,8 +7,9 @@ import { RapidPlugin } from "~/core/server";
|
|
|
7
7
|
export const code = "countCollectionEntities";
|
|
8
8
|
|
|
9
9
|
export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions) {
|
|
10
|
-
await runCollectionEntityActionHandler(ctx, options, code, (entityManager, input) => {
|
|
10
|
+
await runCollectionEntityActionHandler(ctx, options, code, (entityManager, input: CountEntityOptions) => {
|
|
11
11
|
input.filters = removeFiltersWithNullValue(input.filters);
|
|
12
|
+
input.routeContext = ctx.routerContext;
|
|
12
13
|
return entityManager.count(input);
|
|
13
14
|
});
|
|
14
15
|
}
|
|
@@ -30,7 +30,7 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
|
|
|
30
30
|
const newEntity = await entityManager.createEntity(
|
|
31
31
|
{
|
|
32
32
|
entity: mergedEntity,
|
|
33
|
-
|
|
33
|
+
routeContext: ctx.routerContext,
|
|
34
34
|
},
|
|
35
35
|
plugin,
|
|
36
36
|
);
|
|
@@ -9,7 +9,10 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
|
|
|
9
9
|
logger.debug(`Running ${code} handler...`);
|
|
10
10
|
|
|
11
11
|
const entityManager = server.getEntityManager(options.singularCode);
|
|
12
|
-
await entityManager.deleteById(
|
|
12
|
+
await entityManager.deleteById({
|
|
13
|
+
id: input.id,
|
|
14
|
+
routeContext: ctx.routerContext,
|
|
15
|
+
}, plugin);
|
|
13
16
|
|
|
14
17
|
ctx.status = 200;
|
|
15
18
|
ctx.output = {};
|