@futdevpro/nts-dynamo 1.10.5 → 1.10.7

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 (79) hide show
  1. package/.github/workflows/main.yml +1 -2
  2. package/build/_collections/archive.util.d.ts +1 -1
  3. package/build/_collections/archive.util.js +2 -2
  4. package/build/_collections/archive.util.js.map +1 -1
  5. package/build/_collections/archive.util.spec.js +3 -3
  6. package/build/_collections/archive.util.spec.js.map +1 -1
  7. package/build/_models/control-models/api-call-params.control-model.d.ts +3 -30
  8. package/build/_models/control-models/api-call-params.control-model.d.ts.map +1 -1
  9. package/build/_models/control-models/api-call-params.control-model.js +26 -13
  10. package/build/_models/control-models/api-call-params.control-model.js.map +1 -1
  11. package/build/_models/control-models/api-call-params.control-model.spec.js +6 -6
  12. package/build/_models/control-models/app-params.control-model.d.ts +1 -1
  13. package/build/_models/control-models/app-params.control-model.d.ts.map +1 -1
  14. package/build/_models/control-models/app-params.control-model.js.map +1 -1
  15. package/build/_models/control-models/endpoint-params.control-model.d.ts +2 -5
  16. package/build/_models/control-models/endpoint-params.control-model.d.ts.map +1 -1
  17. package/build/_models/control-models/endpoint-params.control-model.js +13 -12
  18. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  19. package/build/_modules/socket/_models/socket-presence.control-model.d.ts.map +1 -1
  20. package/build/_modules/socket/_models/socket-presence.control-model.js +3 -1
  21. package/build/_modules/socket/_models/socket-presence.control-model.js.map +1 -1
  22. package/build/_modules/socket/_services/socket-server.service.d.ts.map +1 -1
  23. package/build/_modules/socket/_services/socket-server.service.js +3 -1
  24. package/build/_modules/socket/_services/socket-server.service.js.map +1 -1
  25. package/build/_modules/socket/app-extended.server.d.ts.map +1 -1
  26. package/build/_modules/socket/app-extended.server.js +3 -1
  27. package/build/_modules/socket/app-extended.server.js.map +1 -1
  28. package/build/_services/base/data.service.d.ts +4 -3
  29. package/build/_services/base/data.service.d.ts.map +1 -1
  30. package/build/_services/base/data.service.js +374 -76
  31. package/build/_services/base/data.service.js.map +1 -1
  32. package/build/_services/base/db.service.d.ts.map +1 -1
  33. package/build/_services/base/db.service.js +3 -1
  34. package/build/_services/base/db.service.js.map +1 -1
  35. package/build/_services/base/singleton.service.d.ts.map +1 -1
  36. package/build/_services/base/singleton.service.js +1 -0
  37. package/build/_services/base/singleton.service.js.map +1 -1
  38. package/build/_services/core/api.service.d.ts +1 -1
  39. package/build/_services/core/api.service.d.ts.map +1 -1
  40. package/build/_services/core/api.service.js +19 -7
  41. package/build/_services/core/api.service.js.map +1 -1
  42. package/build/_services/core/api.service.spec.js +4 -3
  43. package/build/_services/core/api.service.spec.js.map +1 -1
  44. package/build/_services/core/auth.service.d.ts +1 -0
  45. package/build/_services/core/auth.service.d.ts.map +1 -1
  46. package/build/_services/core/auth.service.js.map +1 -1
  47. package/build/_services/core/email.service.d.ts.map +1 -1
  48. package/build/_services/core/email.service.js +4 -1
  49. package/build/_services/core/email.service.js.map +1 -1
  50. package/build/_services/core/global.service.d.ts.map +1 -1
  51. package/build/_services/core/global.service.js +1 -0
  52. package/build/_services/core/global.service.js.map +1 -1
  53. package/build/_services/route/routing-module.service.d.ts.map +1 -1
  54. package/build/_services/route/routing-module.service.js +3 -1
  55. package/build/_services/route/routing-module.service.js.map +1 -1
  56. package/build/_services/server/app.server.d.ts.map +1 -1
  57. package/build/_services/server/app.server.js +3 -1
  58. package/build/_services/server/app.server.js.map +1 -1
  59. package/nodemon.json +1 -1
  60. package/package.json +5 -4
  61. package/src/_collections/archive.util.spec.ts +3 -4
  62. package/src/_collections/archive.util.ts +2 -2
  63. package/src/_models/control-models/api-call-params.control-model.spec.ts +6 -6
  64. package/src/_models/control-models/api-call-params.control-model.ts +30 -43
  65. package/src/_models/control-models/app-params.control-model.ts +1 -1
  66. package/src/_models/control-models/endpoint-params.control-model.ts +19 -13
  67. package/src/_modules/socket/_models/socket-presence.control-model.ts +5 -3
  68. package/src/_modules/socket/_services/socket-server.service.ts +3 -1
  69. package/src/_modules/socket/app-extended.server.ts +3 -1
  70. package/src/_services/base/data.service.ts +512 -119
  71. package/src/_services/base/db.service.ts +3 -1
  72. package/src/_services/base/singleton.service.ts +1 -0
  73. package/src/_services/core/api.service.spec.ts +3 -3
  74. package/src/_services/core/api.service.ts +24 -8
  75. package/src/_services/core/auth.service.ts +1 -0
  76. package/src/_services/core/email.service.ts +4 -1
  77. package/src/_services/core/global.service.ts +1 -0
  78. package/src/_services/route/routing-module.service.ts +3 -1
  79. package/src/_services/server/app.server.ts +3 -1
@@ -148,7 +148,7 @@ class DyNTS_DataService {
148
148
  });
149
149
  }
150
150
  let dataExists = await this.dataDBService.getDataById(id);
151
- if (this.haveArchiveDataService && !skipArchiveLoad) {
151
+ if (!dataExists && this.haveArchiveDataService && !skipArchiveLoad) {
152
152
  const archiveDataService = this.getArchiveDataService();
153
153
  dataExists = await archiveDataService.getDataByOriginalId(id, true);
154
154
  }
@@ -558,7 +558,17 @@ class DyNTS_DataService {
558
558
  try {
559
559
  data = this.ensureData(data);
560
560
  await this.validateForSave(data);
561
- if (!data._id && (!this.depKey || !data[this.depKey])) {
561
+ if (!data._id) {
562
+ if (this.depKey && !data[this.depKey]) {
563
+ throw new fsm_dynamo_1.DyFM_Error({
564
+ ...this._getDefaultErrorSettings('saveData', new Error(`saveData was unsuccessful: dependency data id missing from data ` +
565
+ `(key: ${this.depKey}, ${this.dataParams.dataName})`)),
566
+ errorCode: 'NTS-DS0-SD1',
567
+ additionalContent: {
568
+ data: data,
569
+ },
570
+ });
571
+ }
562
572
  // if ID of dependencyID is not present, data not exists, create new data
563
573
  data = await this.dataDBService.createData(data, this.issuer);
564
574
  if (!dontSetToService) {
@@ -574,7 +584,7 @@ class DyNTS_DataService {
574
584
  throw new fsm_dynamo_1.DyFM_Error({
575
585
  ...this._getDefaultErrorSettings('saveData', new Error(`saveData was unsuccessful: provided ID not exists ` +
576
586
  `(id: "${data._id}", ${this.dataParams.dataName})`)),
577
- errorCode: 'NTS-DS0-SD1',
587
+ errorCode: 'NTS-DS0-SD2',
578
588
  additionalContent: {
579
589
  data: data,
580
590
  },
@@ -592,7 +602,7 @@ class DyNTS_DataService {
592
602
  throw new fsm_dynamo_1.DyFM_Error({
593
603
  ...this._getDefaultErrorSettings('saveData', new Error(`saveData was unsuccessful: dependency data id missing from data ` +
594
604
  `(key: ${this.depKey}, ${this.dataParams.dataName})`)),
595
- errorCode: 'NTS-DS0-SD2',
605
+ errorCode: 'NTS-DS0-SD3',
596
606
  additionalContent: {
597
607
  data: data,
598
608
  },
@@ -618,7 +628,7 @@ class DyNTS_DataService {
618
628
  ...this._getDefaultErrorSettings('saveData', new Error(`saveData was unsuccessful: dependency data not exists ` +
619
629
  `(key: ${this.depKey}, id: "${data[this.depKey]}", ` +
620
630
  `${this.dataParams.dataName})`)),
621
- errorCode: 'NTS-DS0-SD3',
631
+ errorCode: 'NTS-DS0-SD4',
622
632
  });
623
633
  }
624
634
  }
@@ -630,7 +640,7 @@ class DyNTS_DataService {
630
640
  throw new fsm_dynamo_1.DyFM_Error({
631
641
  ...this._getDefaultErrorSettings('saveData', new Error(`saveData was unsuccessful: data creation failed ` +
632
642
  `(${this.dataParams.dataName})`)),
633
- errorCode: 'NTS-DS0-SD4',
643
+ errorCode: 'NTS-DS0-SD5',
634
644
  additionalContent: {
635
645
  data: data,
636
646
  },
@@ -647,6 +657,7 @@ class DyNTS_DataService {
647
657
  'NTS-DS0-SD2',
648
658
  'NTS-DS0-SD3',
649
659
  'NTS-DS0-SD4',
660
+ 'NTS-DS0-SD5',
650
661
  ].includes(error?.errorCode)) {
651
662
  throw error;
652
663
  }
@@ -827,7 +838,10 @@ class DyNTS_DataService {
827
838
  });
828
839
  }
829
840
  catch (error) {
830
- if (['NTS-DS0-VD1', 'NTS-DS0-VD2'].includes(error?.errorCode)) {
841
+ if ([
842
+ 'NTS-DS0-VD1',
843
+ 'NTS-DS0-VD2'
844
+ ].includes(error?.errorCode)) {
831
845
  throw error;
832
846
  }
833
847
  else {
@@ -877,13 +891,61 @@ class DyNTS_DataService {
877
891
  }
878
892
  const filterKeys = Object.keys(query.filterBy);
879
893
  const filterFunctionsByKey = {};
894
+ const addFilterKeys = [];
895
+ const removeFilterKeys = [];
880
896
  filterKeys.forEach((key) => {
881
- filterFunctionsByKey[key] = this.getFilterFunctionForKey(key, query.filterBy[key]);
897
+ const filterBy = query.filterBy[key];
898
+ if (filterBy.isSpecialNestSearch) {
899
+ filterBy.nestedPropertySearches.forEach((nestSearch) => {
900
+ const nestKey = nestSearch.nestKeys.join('.');
901
+ filterFunctionsByKey[nestKey] = this.getFilterFunctionForKey(nestKey, nestSearch.search, nestSearch.valueType);
902
+ query.filterBy[nestKey] = nestSearch;
903
+ addFilterKeys.push(nestKey);
904
+ });
905
+ removeFilterKeys.push(key);
906
+ }
907
+ else {
908
+ filterFunctionsByKey[key] = this.getFilterFunctionForKey(key, filterBy);
909
+ }
910
+ });
911
+ addFilterKeys.forEach((key) => {
912
+ filterKeys.push(key);
913
+ });
914
+ removeFilterKeys.forEach((key) => {
915
+ filterKeys.splice(filterKeys.indexOf(key), 1);
882
916
  });
883
917
  query.sortBy.forEach((sort) => {
884
- dataList.sort(this.getSortFunctionForKey(sort.key, sort.order));
918
+ dataList.sort(this.getSortFunctionForKey(sort));
885
919
  });
886
- dataList = dataList.filter((data) => filterKeys.every((key) => filterFunctionsByKey[key](data[key])));
920
+ if (filterKeys.some((key) => key.includes('.'))) {
921
+ const keyResolvers = {};
922
+ filterKeys.forEach((key) => {
923
+ if (key.includes('.')) {
924
+ if (!query.filterBy[key].nestKeys) {
925
+ throw new fsm_dynamo_1.DyFM_Error({
926
+ ...this._getDefaultErrorSettings('searchData', new Error(`searchData failed, nestKeys missing from nestedPropertySearch! ` +
927
+ `(${this.dataParams.dataName})`)),
928
+ errorCode: 'NTS-DS0-SD1',
929
+ });
930
+ }
931
+ keyResolvers[key] = this.getKeyResolver(query.filterBy[key].nestKeys);
932
+ }
933
+ else {
934
+ keyResolvers[key] = (data) => data[key];
935
+ }
936
+ });
937
+ if (filterKeys.some((key) => query.filterBy[key].isSpecialNestSearch)) {
938
+ dataList = dataList.filter((data) => filterKeys.every((key) => query.filterBy[key].isSpecialNestSearch ?
939
+ keyResolvers[key](data).some((dataProperty) => filterFunctionsByKey[key](dataProperty)) :
940
+ filterFunctionsByKey[key](keyResolvers[key](data))));
941
+ }
942
+ else {
943
+ dataList = dataList.filter((data) => filterKeys.every((key) => filterFunctionsByKey[key](keyResolvers[key](data))));
944
+ }
945
+ }
946
+ else {
947
+ dataList = dataList.filter((data) => filterKeys.every((key) => filterFunctionsByKey[key](data[key])));
948
+ }
887
949
  return {
888
950
  results: dataList,
889
951
  totalItems: dataList.length,
@@ -896,109 +958,265 @@ class DyNTS_DataService {
896
958
  });
897
959
  }
898
960
  }
899
- getFilterFunctionForKey(key, searchValue) {
900
- if (!this.dataParams.properties[key]) {
901
- throw new fsm_dynamo_1.DyFM_Error({
902
- ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, key not found in dataParams ` +
903
- `(${this.dataParams.dataName})`)),
904
- errorCode: 'NTS-DS0-GFF1',
905
- });
906
- }
907
- if (searchValue === undefined) {
908
- throw new fsm_dynamo_1.DyFM_Error({
909
- ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, searchValue is missing! ` +
910
- `(${this.dataParams.dataName})`)),
911
- errorCode: 'NTS-DS0-GFF2',
912
- });
913
- }
914
- switch (this.dataParams.properties[key].type) {
915
- case 'String':
916
- if (typeof searchValue !== 'string') {
961
+ getFilterFunctionForKey(key, searchValue, propertyType) {
962
+ try {
963
+ if (searchValue === undefined) {
964
+ throw new fsm_dynamo_1.DyFM_Error({
965
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, searchValue is missing for key: "${key}" ` +
966
+ `(${this.dataParams.dataName})`)),
967
+ errorCode: 'NTS-DS0-GFF1',
968
+ });
969
+ }
970
+ if (!key.includes('.')) {
971
+ if (!this.dataParams.properties[key]) {
917
972
  throw new fsm_dynamo_1.DyFM_Error({
918
- ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, searchValue is not a string! ` +
973
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, key not found in dataParams: "${key}" ` +
919
974
  `(${this.dataParams.dataName})`)),
920
- errorCode: 'NTS-DS0-GFF3',
975
+ errorCode: 'NTS-DS0-GFF2',
921
976
  });
922
977
  }
923
- const lowerCaseSearchValue = searchValue.toLowerCase();
924
- return (dataProperty) => dataProperty.toLowerCase().includes(lowerCaseSearchValue);
925
- case 'Date':
926
- if (searchValue.isRange) {
927
- const rangeAsNumber = new fsm_dynamo_1.DyFM_RangeValue(+new Date(searchValue.from), +new Date(searchValue.to));
928
- return (dataProperty) => fsm_dynamo_1.DyFM_RangeValue.isInRange(+new Date(dataProperty), rangeAsNumber);
929
- }
930
- if (Array.isArray(searchValue)) {
931
- const searchValueAsDateArray = searchValue.map((date) => new Date(date));
932
- return (dataProperty) => searchValueAsDateArray.includes(new Date(dataProperty));
933
- }
934
- const searchValueAsDate = new Date(searchValue);
935
- return (dataProperty) => new Date(dataProperty) === searchValueAsDate;
936
- case 'Number':
937
- if (searchValue.isRange) {
938
- return (dataProperty) => fsm_dynamo_1.DyFM_RangeValue.isInRange(dataProperty, searchValue);
939
- }
940
- if (Array.isArray(searchValue)) {
941
- return (dataProperty) => searchValue.includes(dataProperty);
942
- }
943
- return (dataProperty) => dataProperty === searchValue;
944
- case 'Boolean':
945
- return (dataProperty) => dataProperty === searchValue;
946
- default:
947
- if (searchValue.isRange) {
978
+ propertyType = this.dataParams.properties[key].type;
979
+ }
980
+ else {
981
+ if (!propertyType) {
948
982
  throw new fsm_dynamo_1.DyFM_Error({
949
- ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, range search not implemented for this type ` +
983
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, propertyType is missing for key: "${key}" ` +
950
984
  `(${this.dataParams.dataName})`)),
951
985
  errorCode: 'NTS-DS0-GFF3',
952
986
  });
953
987
  }
954
- if (Array.isArray(searchValue)) {
955
- return (dataProperty) => searchValue.includes(dataProperty);
956
- }
957
- return (dataProperty) => dataProperty === searchValue;
988
+ }
989
+ switch (propertyType) {
990
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.string:
991
+ if (typeof searchValue !== 'string') {
992
+ throw new fsm_dynamo_1.DyFM_Error({
993
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, searchValue is not a string! ` +
994
+ `(${this.dataParams.dataName})`)),
995
+ errorCode: 'NTS-DS0-GFF4',
996
+ });
997
+ }
998
+ if (Array.isArray(searchValue)) {
999
+ const lowerCaseSearchValueArray = searchValue.filter((searchString) => Boolean(searchString)).map((searchString) => searchString.toLowerCase());
1000
+ return (dataProperty) => lowerCaseSearchValueArray.some((searchString) => dataProperty?.toLowerCase().includes(searchString));
1001
+ }
1002
+ else {
1003
+ const lowerCaseSearchValue = searchValue?.toLowerCase();
1004
+ if (!lowerCaseSearchValue) {
1005
+ return (dataProperty) => !dataProperty;
1006
+ }
1007
+ return (dataProperty) => dataProperty?.toLowerCase().includes(lowerCaseSearchValue);
1008
+ }
1009
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.date:
1010
+ if (searchValue.isRange) {
1011
+ if (searchValue.from === undefined ||
1012
+ searchValue.from === null) {
1013
+ const toAsNumber = +new Date(searchValue.to);
1014
+ return (dataProperty) => +new Date(dataProperty) <= toAsNumber;
1015
+ }
1016
+ else if (searchValue.to === undefined ||
1017
+ searchValue.to === null) {
1018
+ const fromAsNumber = +new Date(searchValue.from);
1019
+ return (dataProperty) => +new Date(dataProperty) >= fromAsNumber;
1020
+ }
1021
+ const rangeAsNumber = new fsm_dynamo_1.DyFM_RangeValue(+new Date(searchValue.from), +new Date(searchValue.to));
1022
+ return (dataProperty) => fsm_dynamo_1.DyFM_RangeValue.isInRange(+new Date(dataProperty), rangeAsNumber);
1023
+ }
1024
+ if (Array.isArray(searchValue)) {
1025
+ const searchValueAsNumberArray = searchValue.map((date) => +new Date(date));
1026
+ return (dataProperty) => searchValueAsNumberArray.includes(+new Date(dataProperty));
1027
+ }
1028
+ const searchValueAsNumber = +new Date(searchValue);
1029
+ return (dataProperty) => +new Date(dataProperty) === searchValueAsNumber;
1030
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.number:
1031
+ if (searchValue.isRange) {
1032
+ if (searchValue.from === undefined ||
1033
+ searchValue.from === null) {
1034
+ return (dataProperty) => dataProperty <= searchValue.to;
1035
+ }
1036
+ else if (searchValue.to === undefined ||
1037
+ searchValue.to === null) {
1038
+ return (dataProperty) => dataProperty >= searchValue.from;
1039
+ }
1040
+ return (dataProperty) => fsm_dynamo_1.DyFM_RangeValue.isInRange(dataProperty, searchValue);
1041
+ }
1042
+ if (Array.isArray(searchValue)) {
1043
+ return (dataProperty) => searchValue.includes(dataProperty);
1044
+ }
1045
+ return (dataProperty) => dataProperty === searchValue;
1046
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.boolean:
1047
+ return (dataProperty) => dataProperty === searchValue;
1048
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.object:
1049
+ if (Array.isArray(searchValue)) {
1050
+ throw new fsm_dynamo_1.DyFM_Error({
1051
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, array search not implemented for this type ` +
1052
+ `(${this.dataParams.dataName})`)),
1053
+ errorCode: 'NTS-DS0-GFF5',
1054
+ });
1055
+ }
1056
+ return (dataProperty) => {
1057
+ const searchValueKeys = Object.keys(searchValue);
1058
+ const stringifiedSearchValue = {};
1059
+ try {
1060
+ searchValueKeys.forEach((key) => {
1061
+ stringifiedSearchValue[key] = JSON.stringify(searchValue[key]);
1062
+ });
1063
+ }
1064
+ catch (error) {
1065
+ throw new fsm_dynamo_1.DyFM_Error({
1066
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, object search failed! ` +
1067
+ `(${this.dataParams.dataName})`)),
1068
+ errorCode: 'NTS-DS0-GFF6',
1069
+ additionalContent: {
1070
+ searchValue: searchValue,
1071
+ },
1072
+ });
1073
+ }
1074
+ return searchValueKeys.every((key) => {
1075
+ try {
1076
+ return stringifiedSearchValue[key] === JSON.stringify(dataProperty[key]);
1077
+ }
1078
+ catch (error) {
1079
+ console.error('object filter returning false, bc of an error', 'searchValue:', searchValue, 'dataProperty:', dataProperty, 'key:', key, 'error:', error);
1080
+ return false;
1081
+ }
1082
+ });
1083
+ };
1084
+ default:
1085
+ if (searchValue.isRange) {
1086
+ throw new fsm_dynamo_1.DyFM_Error({
1087
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', new Error(`getFilterFunctionForKey failed, range search not implemented for this type ` +
1088
+ `(${this.dataParams.dataName})`)),
1089
+ errorCode: 'NTS-DS0-GFF7',
1090
+ });
1091
+ }
1092
+ if (Array.isArray(searchValue)) {
1093
+ return (dataProperty) => searchValue.includes(dataProperty);
1094
+ }
1095
+ return (dataProperty) => dataProperty === searchValue;
1096
+ }
1097
+ }
1098
+ catch (error) {
1099
+ throw new fsm_dynamo_1.DyFM_Error({
1100
+ ...this._getDefaultErrorSettings('getFilterFunctionForKey', error),
1101
+ errorCode: 'NTS-DS0-GFF0',
1102
+ additionalContent: {
1103
+ key: key,
1104
+ searchValue: searchValue,
1105
+ propertyType: propertyType,
1106
+ },
1107
+ });
958
1108
  }
959
1109
  }
960
- getSortFunctionForKey(key, sortDirection) {
961
- if (!this.dataParams.properties[key]) {
1110
+ getKeyResolver(nestKeys) {
1111
+ return (data) => {
1112
+ let value = data;
1113
+ nestKeys.forEach((nestKey) => {
1114
+ if (!value) {
1115
+ return;
1116
+ }
1117
+ if (nestKey === '*') {
1118
+ if (Array.isArray(value[nestKey])) {
1119
+ if (Array.isArray(value)) {
1120
+ value = value[nestKey].map((element) => element[nestKey]).flat();
1121
+ }
1122
+ else {
1123
+ value = value[nestKey].map((element) => element[nestKey]);
1124
+ }
1125
+ }
1126
+ else if (value[nestKey] && typeof value[nestKey] === 'object') {
1127
+ value = Object.values(value[nestKey]);
1128
+ }
1129
+ else {
1130
+ value = value[nestKey];
1131
+ }
1132
+ }
1133
+ else if (Array.isArray(value)) {
1134
+ if (!isNaN(+nestKey)) {
1135
+ value = value[+nestKey];
1136
+ }
1137
+ else {
1138
+ value = value.map((element) => element ? element[nestKey] : element);
1139
+ }
1140
+ }
1141
+ else {
1142
+ value = value[nestKey];
1143
+ }
1144
+ });
1145
+ return value;
1146
+ };
1147
+ }
1148
+ getSortFunctionForKey(sortSettings) {
1149
+ let keyResolver;
1150
+ let valueType;
1151
+ if (!this.dataParams.properties[sortSettings.key] &&
1152
+ !sortSettings.isNestedPropertySort) {
962
1153
  throw new fsm_dynamo_1.DyFM_Error({
963
1154
  ...this._getDefaultErrorSettings('getSortFunctionForKey', new Error(`getSortFunctionForKey failed, key not found in dataParams ` +
964
1155
  `(${this.dataParams.dataName})`)),
965
1156
  errorCode: 'NTS-DS0-GSF1',
966
1157
  });
967
1158
  }
968
- const sortValue = (sortDirection === 1 || sortDirection === 'asc' || sortDirection === 'ascending') ? 1 : -1;
969
- switch (this.dataParams.properties[key].type) {
970
- case 'String':
971
- return (a, b) => a.localeCompare(b) * sortValue;
972
- case 'Date':
1159
+ if (sortSettings.isNestedPropertySort) {
1160
+ keyResolver = this.getKeyResolver(sortSettings.nestKeys);
1161
+ valueType = sortSettings.valueType;
1162
+ }
1163
+ else {
1164
+ keyResolver = (data) => data[sortSettings.key];
1165
+ valueType = this.dataParams.properties[sortSettings.key].type;
1166
+ }
1167
+ if (!valueType) {
1168
+ throw new fsm_dynamo_1.DyFM_Error({
1169
+ ...this._getDefaultErrorSettings('getSortFunctionForKey', new Error(`getSortFunctionForKey failed, valueType is missing! ` +
1170
+ `(${this.dataParams.dataName})`)),
1171
+ errorCode: 'NTS-DS0-GSF1',
1172
+ });
1173
+ }
1174
+ const sortValue = (sortSettings.order === 1 ||
1175
+ sortSettings.order === 'asc' ||
1176
+ sortSettings.order === 'ascending') ? 1 : -1;
1177
+ switch (valueType) {
1178
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.string:
1179
+ return (a, b) => {
1180
+ a = keyResolver(a);
1181
+ b = keyResolver(b);
1182
+ return a.localeCompare(b) * sortValue;
1183
+ };
1184
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.date:
973
1185
  return (a, b) => {
974
- if (+new Date(a[key]) < +new Date(b[key])) {
1186
+ const aNum = +new Date(keyResolver(a));
1187
+ const bNum = +new Date(keyResolver(b));
1188
+ if (aNum < bNum) {
975
1189
  return -sortValue;
976
1190
  }
977
- else if (+new Date(a[key]) > +new Date(b[key])) {
1191
+ else if (aNum > bNum) {
978
1192
  return sortValue;
979
1193
  }
980
1194
  else {
981
1195
  return 0;
982
1196
  }
983
1197
  };
984
- case 'Number':
1198
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.number:
985
1199
  return (a, b) => {
986
- if (a[key] < b[key]) {
1200
+ a = keyResolver(a);
1201
+ b = keyResolver(b);
1202
+ if (a < b) {
987
1203
  return -sortValue;
988
1204
  }
989
- else if (a[key] > b[key]) {
1205
+ else if (a > b) {
990
1206
  return sortValue;
991
1207
  }
992
1208
  else {
993
1209
  return 0;
994
1210
  }
995
1211
  };
996
- case 'Boolean':
1212
+ case fsm_dynamo_1.DyFM_BasicProperty_Type.boolean:
997
1213
  return (a, b) => {
998
- if (a[key] === b[key]) {
1214
+ a = keyResolver(a);
1215
+ b = keyResolver(b);
1216
+ if (a === b) {
999
1217
  return 0;
1000
1218
  }
1001
- if (a[key]) {
1219
+ if (a) {
1002
1220
  return sortValue;
1003
1221
  }
1004
1222
  return -sortValue;
@@ -1006,11 +1224,89 @@ class DyNTS_DataService {
1006
1224
  default:
1007
1225
  throw new fsm_dynamo_1.DyFM_Error({
1008
1226
  ...this._getDefaultErrorSettings('getSortFunctionForKey', new Error(`getSortFunctionForKey failed, sorting not implemented for this type ` +
1009
- `(${this.dataParams.dataName}, ${this.dataParams.properties[key].type})`)),
1227
+ `(${this.dataParams.dataName}, ${valueType})`)),
1010
1228
  errorCode: 'NTS-DS0-GSF2',
1011
1229
  });
1012
1230
  }
1013
1231
  }
1232
+ /* private getSortFunctionForNestedKeys<T>(
1233
+ sortSettings: DyFM_DBĐNestedPropertySort
1234
+ ): (a: T, b: T) => number {
1235
+ const nestedPropertyResolver: (data) => any = this.getKeyResolver(sortSettings.nestKeys);
1236
+
1237
+ const sortValue: 1 | -1 = (
1238
+ sortSettings.order === 1 ||
1239
+ sortSettings.order === 'asc' ||
1240
+ sortSettings.order === 'ascending'
1241
+ ) ? 1 : -1;
1242
+
1243
+ switch (sortSettings.valueType) {
1244
+ case DyFM_BasicProperty_Type.string:
1245
+ return (a: T, b: T): number => {
1246
+ a = nestedPropertyResolver(a);
1247
+ b = nestedPropertyResolver(b);
1248
+
1249
+ return (a as string).localeCompare(b as string) * sortValue
1250
+ };
1251
+
1252
+ case DyFM_BasicProperty_Type.date:
1253
+ return (a: T, b: T): number => {
1254
+ a = nestedPropertyResolver(a);
1255
+ b = nestedPropertyResolver(b);
1256
+
1257
+ if (+new Date(a) < +new Date(b)) {
1258
+ return -sortValue;
1259
+ } else if (+new Date(a) > +new Date(b)) {
1260
+ return sortValue;
1261
+ } else {
1262
+ return 0;
1263
+ }
1264
+ };
1265
+
1266
+ case DyFM_BasicProperty_Type.number:
1267
+ return (a: T, b: T): number => {
1268
+ a = nestedPropertyResolver(a);
1269
+ b = nestedPropertyResolver(b);
1270
+
1271
+ if (a < b) {
1272
+ return -sortValue;
1273
+ } else if (a > b) {
1274
+ return sortValue;
1275
+ } else {
1276
+ return 0;
1277
+ }
1278
+ };
1279
+
1280
+ case DyFM_BasicProperty_Type.boolean:
1281
+ return (a: T, b: T): number => {
1282
+ a = nestedPropertyResolver(a);
1283
+ b = nestedPropertyResolver(b);
1284
+
1285
+ if (a === b) {
1286
+ return 0;
1287
+ }
1288
+
1289
+ if (a) {
1290
+ return sortValue;
1291
+ }
1292
+
1293
+ return -sortValue;
1294
+ };
1295
+
1296
+ default:
1297
+ throw new DyFM_Error({
1298
+ ...this._getDefaultErrorSettings(
1299
+ 'getSortFunctionForKey',
1300
+ new Error(
1301
+ `getSortFunctionForKey failed, sorting not implemented for this type ` +
1302
+ `(${this.dataParams.dataName}, ${this.dataParams.properties[key].type})`
1303
+ )
1304
+ ),
1305
+
1306
+ errorCode: 'NTS-DS0-GSF2',
1307
+ });
1308
+ }
1309
+ } */
1014
1310
  /**
1015
1311
  * setting up dependency dataHook by DynamoBEDataModelParams
1016
1312
  */
@@ -1054,6 +1350,7 @@ class DyNTS_DataService {
1054
1350
  return {
1055
1351
  status: error?.___status ?? 500,
1056
1352
  message: error?.message ??
1353
+ error?._message ??
1057
1354
  `${fnName} was UNSUCCESSFUL (NTS; ${this.dataParams.dataName})`,
1058
1355
  addECToUserMsg: !error?.__userMessage,
1059
1356
  userMessage: error?.__userMessage ?? this.defaultErrorUserMsg,
@@ -1066,6 +1363,7 @@ class DyNTS_DataService {
1066
1363
  return {
1067
1364
  status: error?.___status ?? 500,
1068
1365
  message: error?.message ??
1366
+ error?._message ??
1069
1367
  `${fnName} was UNSUCCESSFUL (${global_settings_const_1.DyNTS_global_settings.systemShortCodeName})`,
1070
1368
  addECToUserMsg: !error?.__userMessage,
1071
1369
  userMessage: error?.__userMessage ?? this.defaultErrorUserMsg,