@ruiapp/rapid-core 0.10.12 → 0.11.0

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
@@ -2988,7 +2988,11 @@ async function findEntities(server, dataAccessor, options) {
2988
2988
  }
2989
2989
  });
2990
2990
  }
2991
- const rowFilters = await convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, options.filters);
2991
+ let entityFilters = options.filters;
2992
+ if (!options.includingSoftDeleted) {
2993
+ entityFilters = tryAddUndeletedEntityFilter(model, baseModel, entityFilters);
2994
+ }
2995
+ const rowFilters = await convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, entityFilters);
2992
2996
  const findRowOptions = {
2993
2997
  filters: rowFilters,
2994
2998
  orderBy: convertEntityOrderByToRowOrderBy(server, model, baseModel, options.orderBy),
@@ -3121,6 +3125,33 @@ async function findById(server, dataAccessor, options) {
3121
3125
  routeContext,
3122
3126
  });
3123
3127
  }
3128
+ const UNDELETED_ENTITY_FILTER_OPTIONS = {
3129
+ operator: "null",
3130
+ field: "deletedAt",
3131
+ };
3132
+ function tryAddUndeletedEntityFilter(model, baseModel, filters) {
3133
+ let isEntitySoftDeleteEnabled = baseModel ? baseModel.softDelete : model.softDelete;
3134
+ if (!isEntitySoftDeleteEnabled) {
3135
+ return filters;
3136
+ }
3137
+ if (!filters || !filters.length) {
3138
+ filters = [UNDELETED_ENTITY_FILTER_OPTIONS];
3139
+ }
3140
+ else if (filters.length === 1 && filters[0].operator === "and") {
3141
+ let andFilters = filters[0].filters;
3142
+ if (!andFilters || !andFilters.length) {
3143
+ andFilters = [UNDELETED_ENTITY_FILTER_OPTIONS];
3144
+ }
3145
+ else {
3146
+ andFilters = [UNDELETED_ENTITY_FILTER_OPTIONS, ...andFilters];
3147
+ }
3148
+ filters[0].filters = andFilters;
3149
+ }
3150
+ else {
3151
+ filters = [UNDELETED_ENTITY_FILTER_OPTIONS, ...filters];
3152
+ }
3153
+ return filters;
3154
+ }
3124
3155
  async function convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, filters) {
3125
3156
  if (!filters || !filters.length) {
3126
3157
  return [];
@@ -3142,10 +3173,23 @@ async function convertEntityFiltersToRowFilters(routeContext, server, model, bas
3142
3173
  if (!isRelationProperty(relationProperty)) {
3143
3174
  throw new Error(`Invalid filters. Filter with 'existence' operator on property '${filter.field}' is not allowed. You can only use it on an relation property.`);
3144
3175
  }
3145
- const relatedEntityFilters = filter.filters;
3176
+ let relatedEntityFilters = filter.filters;
3146
3177
  if (!relatedEntityFilters || !relatedEntityFilters.length) {
3147
3178
  throw new Error(`Invalid filters. 'filters' must be provided on filter with 'existence' operator.`);
3148
3179
  }
3180
+ const relatedEntityDataAccessor = server.getDataAccessor({
3181
+ singularCode: relationProperty.targetSingularCode,
3182
+ });
3183
+ const relatedModel = relatedEntityDataAccessor.getModel();
3184
+ let relatedBaseModel;
3185
+ if (relatedModel.base) {
3186
+ relatedBaseModel = server.getModel({
3187
+ singularCode: relatedModel.base,
3188
+ });
3189
+ }
3190
+ if (!filter.includingSoftDeleted) {
3191
+ relatedEntityFilters = tryAddUndeletedEntityFilter(relatedModel, relatedBaseModel, relatedEntityFilters);
3192
+ }
3149
3193
  if (relationProperty.relation === "one") {
3150
3194
  // Optimize when filtering by id of related entity
3151
3195
  if (relatedEntityFilters.length === 1) {
@@ -3174,18 +3218,8 @@ async function convertEntityFiltersToRowFilters(routeContext, server, model, bas
3174
3218
  continue;
3175
3219
  }
3176
3220
  }
3177
- const dataAccessor = server.getDataAccessor({
3178
- singularCode: relationProperty.targetSingularCode,
3179
- });
3180
- const relatedModel = dataAccessor.getModel();
3181
- let relatedBaseModel;
3182
- if (relatedModel.base) {
3183
- relatedBaseModel = server.getModel({
3184
- singularCode: relatedModel.base,
3185
- });
3186
- }
3187
- const rows = await dataAccessor.find({
3188
- filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
3221
+ const rows = await relatedEntityDataAccessor.find({
3222
+ filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, relatedEntityFilters),
3189
3223
  fields: [
3190
3224
  {
3191
3225
  name: "id",
@@ -3208,18 +3242,8 @@ async function convertEntityFiltersToRowFilters(routeContext, server, model, bas
3208
3242
  if (!relationProperty.selfIdColumnName) {
3209
3243
  throw new Error(`Invalid filters. 'selfIdColumnName' of property '${relationProperty.code}' was not configured`);
3210
3244
  }
3211
- const targetEntityDataAccessor = server.getDataAccessor({
3212
- singularCode: relationProperty.targetSingularCode,
3213
- });
3214
- const relatedModel = targetEntityDataAccessor.getModel();
3215
- let relatedBaseModel;
3216
- if (relatedModel.base) {
3217
- relatedBaseModel = server.getModel({
3218
- singularCode: relatedModel.base,
3219
- });
3220
- }
3221
- const targetEntities = await targetEntityDataAccessor.find({
3222
- filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
3245
+ const targetEntities = await relatedEntityDataAccessor.find({
3246
+ filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, relatedEntityFilters),
3223
3247
  fields: [
3224
3248
  {
3225
3249
  name: relationProperty.selfIdColumnName,
@@ -3248,18 +3272,8 @@ async function convertEntityFiltersToRowFilters(routeContext, server, model, bas
3248
3272
  // 1. find target entities
3249
3273
  // 2. find links
3250
3274
  // 3. convert to 'in' filter
3251
- const targetEntityDataAccessor = server.getDataAccessor({
3252
- singularCode: relationProperty.targetSingularCode,
3253
- });
3254
- const relatedModel = targetEntityDataAccessor.getModel();
3255
- let relatedBaseModel;
3256
- if (relatedModel.base) {
3257
- relatedBaseModel = server.getModel({
3258
- singularCode: relatedModel.base,
3259
- });
3260
- }
3261
- const targetEntities = await targetEntityDataAccessor.find({
3262
- filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
3275
+ const targetEntities = await relatedEntityDataAccessor.find({
3276
+ filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, relatedEntityFilters),
3263
3277
  fields: [
3264
3278
  {
3265
3279
  name: "id",
@@ -3389,6 +3403,9 @@ async function findManyRelationLinksViaLinkTable(options) {
3389
3403
  if (!lodash.isUndefined(selectRelationOptions.keepNonPropertyFields)) {
3390
3404
  findEntityOptions.keepNonPropertyFields = selectRelationOptions.keepNonPropertyFields;
3391
3405
  }
3406
+ if (!lodash.isUndefined(selectRelationOptions.includingSoftDeleted)) {
3407
+ findEntityOptions.includingSoftDeleted = selectRelationOptions.includingSoftDeleted;
3408
+ }
3392
3409
  }
3393
3410
  }
3394
3411
  const targetEntities = await findEntities(server, dataAccessor, findEntityOptions);
@@ -3439,6 +3456,9 @@ async function findManyRelatedEntitiesViaIdPropertyCode(options) {
3439
3456
  if (!lodash.isUndefined(selectRelationOptions.keepNonPropertyFields)) {
3440
3457
  findEntityOptions.keepNonPropertyFields = selectRelationOptions.keepNonPropertyFields;
3441
3458
  }
3459
+ if (!lodash.isUndefined(selectRelationOptions.includingSoftDeleted)) {
3460
+ findEntityOptions.includingSoftDeleted = selectRelationOptions.includingSoftDeleted;
3461
+ }
3442
3462
  }
3443
3463
  }
3444
3464
  return await findEntities(server, dataAccessor, findEntityOptions);
@@ -3467,6 +3487,12 @@ async function findOneRelatedEntitiesViaIdPropertyCode(options) {
3467
3487
  if (selectRelationOptions.relations) {
3468
3488
  findEntityOptions.relations = selectRelationOptions.relations;
3469
3489
  }
3490
+ if (!lodash.isUndefined(selectRelationOptions.keepNonPropertyFields)) {
3491
+ findEntityOptions.keepNonPropertyFields = selectRelationOptions.keepNonPropertyFields;
3492
+ }
3493
+ if (!lodash.isUndefined(selectRelationOptions.includingSoftDeleted)) {
3494
+ findEntityOptions.includingSoftDeleted = selectRelationOptions.includingSoftDeleted;
3495
+ }
3470
3496
  }
3471
3497
  }
3472
3498
  return await findEntities(server, dataAccessor, findEntityOptions);
package/dist/types.d.ts CHANGED
@@ -530,6 +530,10 @@ export interface FindEntityOptions {
530
530
  relations?: Record<string, FindEntityFindRelationEntitiesOptions>;
531
531
  extraColumnsToSelect?: ColumnSelectOptions[];
532
532
  keepNonPropertyFields?: boolean;
533
+ /**
534
+ * 是否包含已经软删除的实体
535
+ */
536
+ includingSoftDeleted?: boolean;
533
537
  }
534
538
  export interface FindEntityByIdOptions {
535
539
  routeContext?: RouteContext;
@@ -567,6 +571,7 @@ export interface FindEntityExistenceFilterOptions {
567
571
  field: string;
568
572
  operator: EntityFilterExistenceOperators;
569
573
  filters: EntityFilterOptions[];
574
+ includingSoftDeleted?: boolean;
570
575
  }
571
576
  export interface FindEntityPaginationOptions {
572
577
  offset: number;
@@ -578,6 +583,7 @@ export type FindEntityFindOneRelationEntitiesOptions = true | {
578
583
  properties?: string[];
579
584
  relations?: Record<string, FindEntityFindRelationEntitiesOptions>;
580
585
  keepNonPropertyFields?: boolean;
586
+ includingSoftDeleted?: boolean;
581
587
  };
582
588
  export type FindEntityFindManyRelationEntitiesOptions = true | {
583
589
  properties?: string[];
@@ -586,6 +592,7 @@ export type FindEntityFindManyRelationEntitiesOptions = true | {
586
592
  orderBy?: FindEntityOrderByOptions[];
587
593
  pagination?: FindEntityPaginationOptions;
588
594
  keepNonPropertyFields?: boolean;
595
+ includingSoftDeleted?: boolean;
589
596
  };
590
597
  export interface FindEntityOrderByOptions {
591
598
  field: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.10.12",
3
+ "version": "0.11.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -248,7 +248,11 @@ async function findEntities(server: IRpdServer, dataAccessor: IRpdDataAccessor,
248
248
  });
249
249
  }
250
250
 
251
- const rowFilters = await convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, options.filters);
251
+ let entityFilters = options.filters;
252
+ if (!options.includingSoftDeleted) {
253
+ entityFilters = tryAddUndeletedEntityFilter(model, baseModel, entityFilters);
254
+ }
255
+ const rowFilters = await convertEntityFiltersToRowFilters(routeContext, server, model, baseModel, entityFilters);
252
256
  const findRowOptions: FindRowOptions = {
253
257
  filters: rowFilters,
254
258
  orderBy: convertEntityOrderByToRowOrderBy(server, model, baseModel, options.orderBy),
@@ -391,6 +395,34 @@ async function findById(server: IRpdServer, dataAccessor: IRpdDataAccessor, opti
391
395
  });
392
396
  }
393
397
 
398
+ const UNDELETED_ENTITY_FILTER_OPTIONS: EntityFilterOptions = {
399
+ operator: "null",
400
+ field: "deletedAt",
401
+ };
402
+
403
+ function tryAddUndeletedEntityFilter(model: RpdDataModel, baseModel: RpdDataModel, filters: EntityFilterOptions[] | undefined) {
404
+ let isEntitySoftDeleteEnabled = baseModel ? baseModel.softDelete : model.softDelete;
405
+ if (!isEntitySoftDeleteEnabled) {
406
+ return filters;
407
+ }
408
+
409
+ if (!filters || !filters.length) {
410
+ filters = [UNDELETED_ENTITY_FILTER_OPTIONS];
411
+ } else if (filters.length === 1 && filters[0].operator === "and") {
412
+ let andFilters = filters[0].filters;
413
+ if (!andFilters || !andFilters.length) {
414
+ andFilters = [UNDELETED_ENTITY_FILTER_OPTIONS];
415
+ } else {
416
+ andFilters = [UNDELETED_ENTITY_FILTER_OPTIONS, ...andFilters];
417
+ }
418
+ filters[0].filters = andFilters;
419
+ } else {
420
+ filters = [UNDELETED_ENTITY_FILTER_OPTIONS, ...filters];
421
+ }
422
+
423
+ return filters;
424
+ }
425
+
394
426
  async function convertEntityFiltersToRowFilters(
395
427
  routeContext: RouteContext,
396
428
  server: IRpdServer,
@@ -421,11 +453,26 @@ async function convertEntityFiltersToRowFilters(
421
453
  );
422
454
  }
423
455
 
424
- const relatedEntityFilters = filter.filters;
456
+ let relatedEntityFilters = filter.filters;
425
457
  if (!relatedEntityFilters || !relatedEntityFilters.length) {
426
458
  throw new Error(`Invalid filters. 'filters' must be provided on filter with 'existence' operator.`);
427
459
  }
428
460
 
461
+ const relatedEntityDataAccessor = server.getDataAccessor({
462
+ singularCode: relationProperty.targetSingularCode as string,
463
+ });
464
+ const relatedModel = relatedEntityDataAccessor.getModel();
465
+ let relatedBaseModel: RpdDataModel;
466
+ if (relatedModel.base) {
467
+ relatedBaseModel = server.getModel({
468
+ singularCode: relatedModel.base,
469
+ });
470
+ }
471
+
472
+ if (!filter.includingSoftDeleted) {
473
+ relatedEntityFilters = tryAddUndeletedEntityFilter(relatedModel, relatedBaseModel, relatedEntityFilters);
474
+ }
475
+
429
476
  if (relationProperty.relation === "one") {
430
477
  // Optimize when filtering by id of related entity
431
478
  if (relatedEntityFilters.length === 1) {
@@ -453,19 +500,9 @@ async function convertEntityFiltersToRowFilters(
453
500
  }
454
501
  }
455
502
 
456
- const dataAccessor = server.getDataAccessor({
457
- singularCode: relationProperty.targetSingularCode as string,
458
- });
459
- const relatedModel = dataAccessor.getModel();
460
- let relatedBaseModel: RpdDataModel;
461
- if (relatedModel.base) {
462
- relatedBaseModel = server.getModel({
463
- singularCode: relatedModel.base,
464
- });
465
- }
466
- const rows = await dataAccessor.find(
503
+ const rows = await relatedEntityDataAccessor.find(
467
504
  {
468
- filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
505
+ filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, relatedEntityFilters),
469
506
  fields: [
470
507
  {
471
508
  name: "id",
@@ -490,19 +527,9 @@ async function convertEntityFiltersToRowFilters(
490
527
  throw new Error(`Invalid filters. 'selfIdColumnName' of property '${relationProperty.code}' was not configured`);
491
528
  }
492
529
 
493
- const targetEntityDataAccessor = server.getDataAccessor({
494
- singularCode: relationProperty.targetSingularCode as string,
495
- });
496
- const relatedModel = targetEntityDataAccessor.getModel();
497
- let relatedBaseModel: RpdDataModel;
498
- if (relatedModel.base) {
499
- relatedBaseModel = server.getModel({
500
- singularCode: relatedModel.base,
501
- });
502
- }
503
- const targetEntities = await targetEntityDataAccessor.find(
530
+ const targetEntities = await relatedEntityDataAccessor.find(
504
531
  {
505
- filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
532
+ filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, relatedEntityFilters),
506
533
  fields: [
507
534
  {
508
535
  name: relationProperty.selfIdColumnName,
@@ -534,19 +561,9 @@ async function convertEntityFiltersToRowFilters(
534
561
  // 1. find target entities
535
562
  // 2. find links
536
563
  // 3. convert to 'in' filter
537
- const targetEntityDataAccessor = server.getDataAccessor({
538
- singularCode: relationProperty.targetSingularCode as string,
539
- });
540
- const relatedModel = targetEntityDataAccessor.getModel();
541
- let relatedBaseModel: RpdDataModel;
542
- if (relatedModel.base) {
543
- relatedBaseModel = server.getModel({
544
- singularCode: relatedModel.base,
545
- });
546
- }
547
- const targetEntities = await targetEntityDataAccessor.find(
564
+ const targetEntities = await relatedEntityDataAccessor.find(
548
565
  {
549
- filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, filter.filters),
566
+ filters: await convertEntityFiltersToRowFilters(routeContext, server, relatedModel, relatedBaseModel, relatedEntityFilters),
550
567
  fields: [
551
568
  {
552
569
  name: "id",
@@ -683,6 +700,9 @@ async function findManyRelationLinksViaLinkTable(options: FindManyRelationEntiti
683
700
  if (!isUndefined(selectRelationOptions.keepNonPropertyFields)) {
684
701
  findEntityOptions.keepNonPropertyFields = selectRelationOptions.keepNonPropertyFields;
685
702
  }
703
+ if (!isUndefined(selectRelationOptions.includingSoftDeleted)) {
704
+ findEntityOptions.includingSoftDeleted = selectRelationOptions.includingSoftDeleted;
705
+ }
686
706
  }
687
707
  }
688
708
 
@@ -739,6 +759,9 @@ async function findManyRelatedEntitiesViaIdPropertyCode(options: FindManyRelatio
739
759
  if (!isUndefined(selectRelationOptions.keepNonPropertyFields)) {
740
760
  findEntityOptions.keepNonPropertyFields = selectRelationOptions.keepNonPropertyFields;
741
761
  }
762
+ if (!isUndefined(selectRelationOptions.includingSoftDeleted)) {
763
+ findEntityOptions.includingSoftDeleted = selectRelationOptions.includingSoftDeleted;
764
+ }
742
765
  }
743
766
  }
744
767
 
@@ -772,6 +795,12 @@ async function findOneRelatedEntitiesViaIdPropertyCode(options: FindOneRelationE
772
795
  if (selectRelationOptions.relations) {
773
796
  findEntityOptions.relations = selectRelationOptions.relations;
774
797
  }
798
+ if (!isUndefined(selectRelationOptions.keepNonPropertyFields)) {
799
+ findEntityOptions.keepNonPropertyFields = selectRelationOptions.keepNonPropertyFields;
800
+ }
801
+ if (!isUndefined(selectRelationOptions.includingSoftDeleted)) {
802
+ findEntityOptions.includingSoftDeleted = selectRelationOptions.includingSoftDeleted;
803
+ }
775
804
  }
776
805
  }
777
806
 
package/src/types.ts CHANGED
@@ -681,6 +681,10 @@ export interface FindEntityOptions {
681
681
  relations?: Record<string, FindEntityFindRelationEntitiesOptions>;
682
682
  extraColumnsToSelect?: ColumnSelectOptions[];
683
683
  keepNonPropertyFields?: boolean;
684
+ /**
685
+ * 是否包含已经软删除的实体
686
+ */
687
+ includingSoftDeleted?: boolean;
684
688
  }
685
689
 
686
690
  export interface FindEntityByIdOptions {
@@ -725,6 +729,7 @@ export interface FindEntityExistenceFilterOptions {
725
729
  field: string;
726
730
  operator: EntityFilterExistenceOperators;
727
731
  filters: EntityFilterOptions[];
732
+ includingSoftDeleted?: boolean;
728
733
  }
729
734
 
730
735
  export interface FindEntityPaginationOptions {
@@ -741,6 +746,7 @@ export type FindEntityFindOneRelationEntitiesOptions =
741
746
  properties?: string[];
742
747
  relations?: Record<string, FindEntityFindRelationEntitiesOptions>;
743
748
  keepNonPropertyFields?: boolean;
749
+ includingSoftDeleted?: boolean;
744
750
  };
745
751
 
746
752
  export type FindEntityFindManyRelationEntitiesOptions =
@@ -752,6 +758,7 @@ export type FindEntityFindManyRelationEntitiesOptions =
752
758
  orderBy?: FindEntityOrderByOptions[];
753
759
  pagination?: FindEntityPaginationOptions;
754
760
  keepNonPropertyFields?: boolean;
761
+ includingSoftDeleted?: boolean;
755
762
  };
756
763
 
757
764
  export interface FindEntityOrderByOptions {