@ruiapp/rapid-core 0.2.8 → 0.2.9

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/index.js CHANGED
@@ -3252,15 +3252,15 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3252
3252
  const updatedEntityOneRelationProps = {};
3253
3253
  for (const property of oneRelationPropertiesToUpdate) {
3254
3254
  const rowToBeSaved = property.isBaseProperty ? baseRow : row;
3255
- const fieldValue = changes[property.code];
3255
+ const relatedEntityToBeSaved = changes[property.code];
3256
3256
  const targetDataAccessor = server.getDataAccessor({
3257
3257
  singularCode: property.targetSingularCode,
3258
3258
  });
3259
- if (lodash.isObject(fieldValue)) {
3260
- const targetEntityId = fieldValue["id"];
3261
- if (!targetEntityId) {
3259
+ if (lodash.isObject(relatedEntityToBeSaved)) {
3260
+ const relatedEntityId = relatedEntityToBeSaved["id"];
3261
+ if (!relatedEntityId) {
3262
3262
  if (!property.selfIdColumnName) {
3263
- const targetEntity = fieldValue;
3263
+ const targetEntity = relatedEntityToBeSaved;
3264
3264
  const newTargetEntity = await createEntity(server, targetDataAccessor, {
3265
3265
  routeContext,
3266
3266
  entity: targetEntity,
@@ -3270,20 +3270,44 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3270
3270
  }
3271
3271
  }
3272
3272
  else {
3273
- const targetEntity = await findById(server, targetDataAccessor, {
3274
- id: targetEntityId,
3273
+ let targetEntity = await findById(server, targetDataAccessor, {
3274
+ id: relatedEntityId,
3275
3275
  routeContext,
3276
3276
  });
3277
3277
  if (!targetEntity) {
3278
- throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
3278
+ throw newEntityOperationError(`Update ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${relatedEntityId}' was not found.`);
3279
+ }
3280
+ // update relation entity if options.relationPropertiesToUpdate is specified.
3281
+ const updateRelationPropertiesOptions = lodash.get(options.relationPropertiesToUpdate, property.code);
3282
+ let subRelationPropertiesToUpdate = undefined;
3283
+ let relationEntityToUpdate = null;
3284
+ if (updateRelationPropertiesOptions === true) {
3285
+ relationEntityToUpdate = targetEntity;
3286
+ }
3287
+ else if (updateRelationPropertiesOptions) {
3288
+ let propertiesToUpdate = lodash.uniq([
3289
+ "id",
3290
+ ...(updateRelationPropertiesOptions.propertiesToUpdate || []),
3291
+ ...Object.keys(updateRelationPropertiesOptions.relationPropertiesToUpdate || []),
3292
+ ]);
3293
+ relationEntityToUpdate = lodash.pick(relatedEntityToBeSaved, propertiesToUpdate);
3294
+ subRelationPropertiesToUpdate = updateRelationPropertiesOptions.relationPropertiesToUpdate;
3295
+ }
3296
+ if (relationEntityToUpdate) {
3297
+ targetEntity = await updateEntityById(server, targetDataAccessor, {
3298
+ routeContext: routeContext,
3299
+ id: relatedEntityId,
3300
+ entityToSave: relationEntityToUpdate,
3301
+ relationPropertiesToUpdate: subRelationPropertiesToUpdate,
3302
+ });
3279
3303
  }
3280
3304
  updatedEntityOneRelationProps[property.code] = targetEntity;
3281
- rowToBeSaved[property.targetIdColumnName] = targetEntityId;
3305
+ rowToBeSaved[property.targetIdColumnName] = relatedEntityId;
3282
3306
  }
3283
3307
  }
3284
- else if (lodash.isNumber(fieldValue) || lodash.isString(fieldValue)) {
3308
+ else if (lodash.isNumber(relatedEntityToBeSaved) || lodash.isString(relatedEntityToBeSaved)) {
3285
3309
  // fieldValue is id;
3286
- const targetEntityId = fieldValue;
3310
+ const targetEntityId = relatedEntityToBeSaved;
3287
3311
  const targetEntity = await findById(server, targetDataAccessor, {
3288
3312
  id: targetEntityId,
3289
3313
  routeContext,
@@ -3417,9 +3441,33 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3417
3441
  }
3418
3442
  else {
3419
3443
  // related entity is existed
3420
- const targetEntity = await targetDataAccessor.findById(relatedEntityId);
3444
+ let targetEntity = await targetDataAccessor.findById(relatedEntityId);
3421
3445
  if (!targetEntity) {
3422
- throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
3446
+ throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' does not exist.`);
3447
+ }
3448
+ // update relation entity if options.relationPropertiesToUpdate is specified.
3449
+ const updateRelationPropertiesOptions = lodash.get(options.relationPropertiesToUpdate, property.code);
3450
+ let subRelationPropertiesToUpdate = undefined;
3451
+ let relationEntityToUpdate = null;
3452
+ if (updateRelationPropertiesOptions === true) {
3453
+ relationEntityToUpdate = targetEntity;
3454
+ }
3455
+ else if (updateRelationPropertiesOptions) {
3456
+ let propertiesToUpdate = lodash.uniq([
3457
+ "id",
3458
+ ...(updateRelationPropertiesOptions.propertiesToUpdate || []),
3459
+ ...Object.keys(updateRelationPropertiesOptions.relationPropertiesToUpdate || []),
3460
+ ]);
3461
+ relationEntityToUpdate = lodash.pick(relatedEntityToBeSaved, propertiesToUpdate);
3462
+ subRelationPropertiesToUpdate = updateRelationPropertiesOptions.relationPropertiesToUpdate;
3463
+ }
3464
+ if (relationEntityToUpdate) {
3465
+ targetEntity = await updateEntityById(server, targetDataAccessor, {
3466
+ routeContext: routeContext,
3467
+ id: relatedEntityId,
3468
+ entityToSave: relationEntityToUpdate,
3469
+ relationPropertiesToUpdate: subRelationPropertiesToUpdate,
3470
+ });
3423
3471
  }
3424
3472
  if (!currentTargetIds.includes(relatedEntityId)) {
3425
3473
  if (property.linkTableName) {
@@ -4905,11 +4953,16 @@ async function handler$l(plugin, ctx, options) {
4905
4953
  if (stateProperties) {
4906
4954
  delete mergedInput.$stateProperties;
4907
4955
  }
4956
+ const relationPropertiesToUpdate = mergedInput.$relationPropertiesToUpdate;
4957
+ if (relationPropertiesToUpdate) {
4958
+ delete mergedInput.$relationPropertiesToUpdate;
4959
+ }
4908
4960
  const updateEntityByIdOptions = {
4909
4961
  id: mergedInput.id,
4910
4962
  entityToSave: mergedInput,
4911
4963
  operation,
4912
4964
  stateProperties,
4965
+ relationPropertiesToUpdate,
4913
4966
  routeContext: ctx.routerContext,
4914
4967
  };
4915
4968
  const entityManager = server.getEntityManager(options.singularCode);
package/dist/types.d.ts CHANGED
@@ -487,9 +487,20 @@ export interface UpdateEntityByIdOptions {
487
487
  operation?: {
488
488
  type: string;
489
489
  };
490
+ /**
491
+ * 指定需要更新那几个状态属性(配置了`config.stateMachine`的属性)。当不指定时默认更新全部状态属性。
492
+ */
490
493
  stateProperties?: string[];
491
494
  postponeUniquenessCheck?: boolean;
495
+ /**
496
+ * 指定需要更新关联对象的哪些属性。更新实体时,会创建关联对象,但是默认不更新关联对象的属性。
497
+ */
498
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
492
499
  }
500
+ export type UpdateRelationPropertiesOptions = true | {
501
+ propertiesToUpdate?: string[];
502
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
503
+ };
493
504
  export interface DeleteEntityOptions {
494
505
  routeContext?: RouteContext;
495
506
  filters?: EntityFilterOptions[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -24,7 +24,26 @@ import { mapDbRowToEntity, mapEntityToDbRow } from "./entityMapper";
24
24
  import { mapPropertyNameToColumnName } from "./propertyMapper";
25
25
  import { IRpdServer, RapidPlugin } from "~/core/server";
26
26
  import { getEntityPartChanges } from "~/helpers/entityHelpers";
27
- import { cloneDeep, filter, find, first, forEach, isArray, isNumber, isObject, isPlainObject, isString, isUndefined, keys, map, reject, uniq } from "lodash";
27
+ import {
28
+ cloneDeep,
29
+ concat,
30
+ filter,
31
+ find,
32
+ first,
33
+ forEach,
34
+ get,
35
+ isArray,
36
+ isNumber,
37
+ isObject,
38
+ isPlainObject,
39
+ isString,
40
+ isUndefined,
41
+ keys,
42
+ map,
43
+ pick,
44
+ reject,
45
+ uniq,
46
+ } from "lodash";
28
47
  import {
29
48
  getEntityPropertiesIncludingBase,
30
49
  getEntityProperty,
@@ -1103,16 +1122,16 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1103
1122
  const updatedEntityOneRelationProps = {};
1104
1123
  for (const property of oneRelationPropertiesToUpdate) {
1105
1124
  const rowToBeSaved = property.isBaseProperty ? baseRow : row;
1106
- const fieldValue = changes[property.code];
1125
+ const relatedEntityToBeSaved = changes[property.code];
1107
1126
  const targetDataAccessor = server.getDataAccessor({
1108
1127
  singularCode: property.targetSingularCode!,
1109
1128
  });
1110
1129
 
1111
- if (isObject(fieldValue)) {
1112
- const targetEntityId = fieldValue["id"];
1113
- if (!targetEntityId) {
1130
+ if (isObject(relatedEntityToBeSaved)) {
1131
+ const relatedEntityId = relatedEntityToBeSaved["id"];
1132
+ if (!relatedEntityId) {
1114
1133
  if (!property.selfIdColumnName) {
1115
- const targetEntity = fieldValue;
1134
+ const targetEntity = relatedEntityToBeSaved;
1116
1135
  const newTargetEntity = await createEntity(server, targetDataAccessor, {
1117
1136
  routeContext,
1118
1137
  entity: targetEntity,
@@ -1121,21 +1140,46 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1121
1140
  rowToBeSaved[property.targetIdColumnName!] = newTargetEntity["id"];
1122
1141
  }
1123
1142
  } else {
1124
- const targetEntity = await findById(server, targetDataAccessor, {
1125
- id: targetEntityId,
1143
+ let targetEntity = await findById(server, targetDataAccessor, {
1144
+ id: relatedEntityId,
1126
1145
  routeContext,
1127
1146
  });
1128
1147
  if (!targetEntity) {
1129
1148
  throw newEntityOperationError(
1130
- `Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`,
1149
+ `Update ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${relatedEntityId}' was not found.`,
1131
1150
  );
1132
1151
  }
1152
+
1153
+ // update relation entity if options.relationPropertiesToUpdate is specified.
1154
+ const updateRelationPropertiesOptions = get(options.relationPropertiesToUpdate, property.code);
1155
+ let subRelationPropertiesToUpdate = undefined;
1156
+ let relationEntityToUpdate = null;
1157
+ if (updateRelationPropertiesOptions === true) {
1158
+ relationEntityToUpdate = targetEntity;
1159
+ } else if (updateRelationPropertiesOptions) {
1160
+ let propertiesToUpdate = uniq([
1161
+ "id",
1162
+ ...(updateRelationPropertiesOptions.propertiesToUpdate || []),
1163
+ ...Object.keys(updateRelationPropertiesOptions.relationPropertiesToUpdate || []),
1164
+ ]);
1165
+ relationEntityToUpdate = pick(relatedEntityToBeSaved, propertiesToUpdate);
1166
+ subRelationPropertiesToUpdate = updateRelationPropertiesOptions.relationPropertiesToUpdate;
1167
+ }
1168
+ if (relationEntityToUpdate) {
1169
+ targetEntity = await updateEntityById(server, targetDataAccessor, {
1170
+ routeContext: routeContext,
1171
+ id: relatedEntityId,
1172
+ entityToSave: relationEntityToUpdate,
1173
+ relationPropertiesToUpdate: subRelationPropertiesToUpdate,
1174
+ });
1175
+ }
1176
+
1133
1177
  updatedEntityOneRelationProps[property.code] = targetEntity;
1134
- rowToBeSaved[property.targetIdColumnName!] = targetEntityId;
1178
+ rowToBeSaved[property.targetIdColumnName!] = relatedEntityId;
1135
1179
  }
1136
- } else if (isNumber(fieldValue) || isString(fieldValue)) {
1180
+ } else if (isNumber(relatedEntityToBeSaved) || isString(relatedEntityToBeSaved)) {
1137
1181
  // fieldValue is id;
1138
- const targetEntityId = fieldValue;
1182
+ const targetEntityId = relatedEntityToBeSaved;
1139
1183
  const targetEntity = await findById(server, targetDataAccessor, {
1140
1184
  id: targetEntityId,
1141
1185
  routeContext,
@@ -1289,9 +1333,33 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1289
1333
  relatedEntities.push(newTargetEntity);
1290
1334
  } else {
1291
1335
  // related entity is existed
1292
- const targetEntity = await targetDataAccessor.findById(relatedEntityId);
1336
+ let targetEntity = await targetDataAccessor.findById(relatedEntityId);
1293
1337
  if (!targetEntity) {
1294
- throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
1338
+ throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' does not exist.`);
1339
+ }
1340
+
1341
+ // update relation entity if options.relationPropertiesToUpdate is specified.
1342
+ const updateRelationPropertiesOptions = get(options.relationPropertiesToUpdate, property.code);
1343
+ let subRelationPropertiesToUpdate = undefined;
1344
+ let relationEntityToUpdate = null;
1345
+ if (updateRelationPropertiesOptions === true) {
1346
+ relationEntityToUpdate = targetEntity;
1347
+ } else if (updateRelationPropertiesOptions) {
1348
+ let propertiesToUpdate = uniq([
1349
+ "id",
1350
+ ...(updateRelationPropertiesOptions.propertiesToUpdate || []),
1351
+ ...Object.keys(updateRelationPropertiesOptions.relationPropertiesToUpdate || []),
1352
+ ]);
1353
+ relationEntityToUpdate = pick(relatedEntityToBeSaved, propertiesToUpdate);
1354
+ subRelationPropertiesToUpdate = updateRelationPropertiesOptions.relationPropertiesToUpdate;
1355
+ }
1356
+ if (relationEntityToUpdate) {
1357
+ targetEntity = await updateEntityById(server, targetDataAccessor, {
1358
+ routeContext: routeContext,
1359
+ id: relatedEntityId,
1360
+ entityToSave: relationEntityToUpdate,
1361
+ relationPropertiesToUpdate: subRelationPropertiesToUpdate,
1362
+ });
1295
1363
  }
1296
1364
 
1297
1365
  if (!currentTargetIds.includes(relatedEntityId)) {
@@ -22,11 +22,17 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
22
22
  delete mergedInput.$stateProperties;
23
23
  }
24
24
 
25
+ const relationPropertiesToUpdate = mergedInput.$relationPropertiesToUpdate;
26
+ if (relationPropertiesToUpdate) {
27
+ delete mergedInput.$relationPropertiesToUpdate;
28
+ }
29
+
25
30
  const updateEntityByIdOptions: UpdateEntityByIdOptions = {
26
31
  id: mergedInput.id,
27
32
  entityToSave: mergedInput,
28
33
  operation,
29
34
  stateProperties,
35
+ relationPropertiesToUpdate,
30
36
  routeContext: ctx.routerContext,
31
37
  };
32
38
  const entityManager = server.getEntityManager(options.singularCode);
package/src/types.ts CHANGED
@@ -628,10 +628,24 @@ export interface UpdateEntityByIdOptions {
628
628
  operation?: {
629
629
  type: string;
630
630
  };
631
+ /**
632
+ * 指定需要更新那几个状态属性(配置了`config.stateMachine`的属性)。当不指定时默认更新全部状态属性。
633
+ */
631
634
  stateProperties?: string[];
632
635
  postponeUniquenessCheck?: boolean;
636
+ /**
637
+ * 指定需要更新关联对象的哪些属性。更新实体时,会创建关联对象,但是默认不更新关联对象的属性。
638
+ */
639
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
633
640
  }
634
641
 
642
+ export type UpdateRelationPropertiesOptions =
643
+ | true
644
+ | {
645
+ propertiesToUpdate?: string[];
646
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
647
+ };
648
+
635
649
  export interface DeleteEntityOptions {
636
650
  routeContext?: RouteContext;
637
651
  filters?: EntityFilterOptions[];