@futdevpro/nts-dynamo 1.10.1 → 1.10.3

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 (83) hide show
  1. package/.eslintrc.json +1 -0
  2. package/build/_collections/global-settings.const.d.ts.map +1 -1
  3. package/build/_collections/global-settings.const.js +2 -0
  4. package/build/_collections/global-settings.const.js.map +1 -1
  5. package/build/_models/control-models/endpoint-params.control-model.js +1 -1
  6. package/build/_models/control-models/endpoint-params.control-model.js.map +1 -1
  7. package/build/_models/interfaces/global-log-settings.interface.d.ts +4 -0
  8. package/build/_models/interfaces/global-log-settings.interface.d.ts.map +1 -1
  9. package/build/_models/interfaces/global-settings.interface.d.ts +4 -0
  10. package/build/_models/interfaces/global-settings.interface.d.ts.map +1 -1
  11. package/build/_modules/mock/app-extended-server.mock.d.ts +3 -3
  12. package/build/_modules/mock/app-extended-server.mock.d.ts.map +1 -1
  13. package/build/_modules/mock/app-extended-server.mock.js +8 -8
  14. package/build/_modules/mock/app-extended-server.mock.js.map +1 -1
  15. package/build/_modules/mock/app-server.mock.d.ts +2 -2
  16. package/build/_modules/mock/app-server.mock.d.ts.map +1 -1
  17. package/build/_modules/mock/app-server.mock.js +6 -6
  18. package/build/_modules/mock/app-server.mock.js.map +1 -1
  19. package/build/_modules/socket/{_services/app-extended.server.d.ts → app-extended.server.d.ts} +2 -2
  20. package/build/_modules/socket/app-extended.server.d.ts.map +1 -0
  21. package/build/_modules/socket/{_services/app-extended.server.js → app-extended.server.js} +6 -6
  22. package/build/_modules/socket/app-extended.server.js.map +1 -0
  23. package/build/_modules/socket/app-extended.server.spec.d.ts.map +1 -0
  24. package/build/_modules/socket/{_services/app-extended.server.spec.js → app-extended.server.spec.js} +5 -5
  25. package/build/_modules/socket/app-extended.server.spec.js.map +1 -0
  26. package/build/_modules/socket/index.d.ts +1 -1
  27. package/build/_modules/socket/index.d.ts.map +1 -1
  28. package/build/_modules/socket/index.js +1 -1
  29. package/build/_modules/socket/index.js.map +1 -1
  30. package/build/_services/base/data.service.d.ts +9 -3
  31. package/build/_services/base/data.service.d.ts.map +1 -1
  32. package/build/_services/base/data.service.js +162 -24
  33. package/build/_services/base/data.service.js.map +1 -1
  34. package/build/_services/base/db.service.d.ts +8 -2
  35. package/build/_services/base/db.service.d.ts.map +1 -1
  36. package/build/_services/base/db.service.js +82 -24
  37. package/build/_services/base/db.service.js.map +1 -1
  38. package/build/_services/core/api.service.d.ts.map +1 -1
  39. package/build/_services/core/api.service.js +8 -9
  40. package/build/_services/core/api.service.js.map +1 -1
  41. package/build/_services/core/api.service.spec.js +3 -3
  42. package/build/_services/core/api.service.spec.js.map +1 -1
  43. package/build/_services/core/global.service.d.ts.map +1 -1
  44. package/build/_services/core/global.service.js +3 -0
  45. package/build/_services/core/global.service.js.map +1 -1
  46. package/build/_services/server/app.server.d.ts +25 -0
  47. package/build/_services/server/app.server.d.ts.map +1 -1
  48. package/build/_services/server/app.server.js +1 -4
  49. package/build/_services/server/app.server.js.map +1 -1
  50. package/build/_services/server/app.server.spec.js +4 -1
  51. package/build/_services/server/app.server.spec.js.map +1 -1
  52. package/build/_services/server/env-set.d.ts +2 -0
  53. package/build/_services/server/env-set.d.ts.map +1 -0
  54. package/build/_services/server/env-set.js +20 -0
  55. package/build/_services/server/env-set.js.map +1 -0
  56. package/build/index.d.ts +1 -0
  57. package/build/index.d.ts.map +1 -1
  58. package/build/index.js +1 -0
  59. package/build/index.js.map +1 -1
  60. package/package.json +13 -17
  61. package/src/_collections/global-settings.const.ts +2 -0
  62. package/src/_models/control-models/endpoint-params.control-model.ts +1 -1
  63. package/src/_models/interfaces/global-log-settings.interface.ts +5 -0
  64. package/src/_models/interfaces/global-settings.interface.ts +5 -0
  65. package/src/_modules/mock/app-extended-server.mock.ts +13 -13
  66. package/src/_modules/mock/app-server.mock.ts +10 -10
  67. package/src/_modules/socket/{_services/app-extended.server.spec.ts → app-extended.server.spec.ts} +7 -7
  68. package/src/_modules/socket/{_services/app-extended.server.ts → app-extended.server.ts} +18 -13
  69. package/src/_modules/socket/index.ts +1 -1
  70. package/src/_services/base/data.service.ts +265 -31
  71. package/src/_services/base/db.service.ts +91 -15
  72. package/src/_services/core/api.service.spec.ts +11 -4
  73. package/src/_services/core/api.service.ts +5 -6
  74. package/src/_services/core/global.service.ts +3 -0
  75. package/src/_services/server/app.server.spec.ts +7 -2
  76. package/src/_services/server/app.server.ts +2 -2
  77. package/src/_services/server/env-set.ts +21 -0
  78. package/src/index.ts +1 -0
  79. package/build/_modules/socket/_services/app-extended.server.d.ts.map +0 -1
  80. package/build/_modules/socket/_services/app-extended.server.js.map +0 -1
  81. package/build/_modules/socket/_services/app-extended.server.spec.d.ts.map +0 -1
  82. package/build/_modules/socket/_services/app-extended.server.spec.js.map +0 -1
  83. /package/build/_modules/socket/{_services/app-extended.server.spec.d.ts → app-extended.server.spec.d.ts} +0 -0
package/package.json CHANGED
@@ -1,19 +1,17 @@
1
1
  {
2
2
  "name": "@futdevpro/nts-dynamo",
3
- "version": "01.10.01",
3
+ "version": "01.10.03",
4
4
  "description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
5
5
  "scripts": {
6
6
  "prep": "npm i rimraf nodemon -g",
7
7
  "first-start": "npm run prep && nodemon",
8
8
  "start": "nodemon",
9
-
10
9
  "deploy": "npm run build",
11
10
  "clean-deploy": "npm run clean && npm run build-all",
12
11
  "build": "npm run build-base && jasmine && npm publish",
13
12
  "build-tgz": "npm run build-base && jasmine && npm pack && move ./*.tgz ../tgz-collection/dynamo-nts",
14
13
  "build-all": "npm run build-tgz && npm run build",
15
14
  "build-base": "npm i && rimraf ./build && npx tsc",
16
-
17
15
  "clean-build": "npm run clean && npm run build-base",
18
16
  "clean": "rimraf ./build && rimraf package-lock.json && rimraf ./node_modules",
19
17
  "test": "npm run build-base && jasmine",
@@ -90,38 +88,36 @@
90
88
  },
91
89
  "homepage": "https:/futdevpro.hu/projects/dynamo",
92
90
  "DISABLED": {
93
- "@futdevpro/fsm-dynamo": "file:../tgz-collection/dynamo-fsm/futdevpro-fsm-dynamo-01.10.02.tgz",
91
+ "@futdevpro/fsm-dynamo": "file:../tgz-collection/dynamo-fsm/futdevpro-fsm-dynamo-01.10.04.tgz",
94
92
  "empty": ""
95
93
  },
96
94
  "peerDependencies": {
97
- "@futdevpro/fsm-dynamo": "1.10.2",
95
+ "@futdevpro/fsm-dynamo": "1.10.5",
98
96
 
99
97
  "@types/express": "~4.17.17",
100
98
  "@types/geoip-lite": "~1.4.1",
101
99
  "@types/node": "~20.5.7",
102
100
  "@types/nodemailer": "~6.4.9",
103
- "axios": "~1.5.0",
104
- "express": "~4.18.2",
101
+ "axios": "~1.7.9",
102
+ "express": "~4.21.2",
105
103
  "geoip-lite": "~1.4.7",
106
- "mongoose": "~5.13.20",
104
+ "mongoose": "~8.10.1",
107
105
  "nodemailer": "~6.9.4",
108
106
  "rxjs": "~7.8.1",
109
107
  "ts-node": "~10.9.2",
110
108
  "body-parser": "~1.20.2"
111
109
  },
112
- "peerDevDependencies": {
113
- },
114
110
  "devDependencies": {
115
111
  "@types/jasmine": "~4.3.5",
116
- "@typescript-eslint/eslint-plugin": "^8.18.2",
117
- "@typescript-eslint/parser": "^8.18.2",
118
- "eslint": "~8.57.0",
119
- "eslint-plugin-max-params-no-constructor": "~0.0.4",
120
- "eslint-plugin-unused-imports": "~4.1.4",
112
+ "@typescript-eslint/eslint-plugin": "^8.24.1",
113
+ "@typescript-eslint/parser": "^8.24.1",
114
+ "eslint": "^9.21.0",
115
+ "eslint-plugin-max-params-no-constructor": "^0.0.4",
116
+ "eslint-plugin-unused-imports": "^4.1.4",
121
117
  "jasmine": "~5.0.2",
122
118
  "jasmine-ts": "~0.4.0",
123
- "socket.io": "~4.7.2",
124
- "socket.io-client": "~4.7.2",
119
+ "socket.io": "~4.8.1",
120
+ "socket.io-client": "~4.8.1",
125
121
  "tslib": "~2.6.2",
126
122
  "typescript": "~5.3.3"
127
123
  }
@@ -9,6 +9,7 @@ export const DyNTS_global_settings: DyNTS_Global_Settings = {
9
9
  defaultSocketSecurity: DyNTS_SocketSecurity.open,
10
10
  defaultPageSize: 10,
11
11
  autoResolveEndpointCirculationErrors: true,
12
+ archiveListAfter: 100,
12
13
 
13
14
  log_settings: {
14
15
  highDetailedLogs: false,
@@ -28,6 +29,7 @@ export const DyNTS_global_settings: DyNTS_Global_Settings = {
28
29
  api_requestContents: false,
29
30
  api_requestSettings: false,
30
31
  api_responseContents: false,
32
+ api_errors: true,
31
33
 
32
34
  detailedErrors: false,
33
35
 
@@ -260,7 +260,7 @@ export class DyNTS_Endpoint_Params {
260
260
  `Endpoint "${this.endpoint}" caught an error. (${this.name})`,
261
261
  '\n ERROR:', error
262
262
  );
263
- } else {
263
+ } else if (DyNTS_global_settings.log_settings.api_errors) {
264
264
  error.logSimple(`Endpoint "${this.endpoint}" caught an error. (${this.name})`);
265
265
  }
266
266
 
@@ -74,6 +74,11 @@ export interface DyNTS_GlobalLog_Settings {
74
74
  */
75
75
  api_responseContents?: boolean;
76
76
 
77
+ /**
78
+ * this is an application wide default setting for api debug logs
79
+ */
80
+ api_errors?: boolean;
81
+
77
82
 
78
83
  /**
79
84
  * this is an application wide default setting for detailed error logs
@@ -44,4 +44,9 @@ export interface DyNTS_Global_Settings {
44
44
  * this is the default page size for pagination
45
45
  */
46
46
  defaultPageSize: number;
47
+
48
+ /**
49
+ * this is the number of items to archive in the list, this will be used to archive the list
50
+ */
51
+ archiveListAfter: number;
47
52
  }
@@ -1,28 +1,28 @@
1
1
 
2
2
 
3
3
  import { DyFM_error_defaults } from '@futdevpro/fsm-dynamo';
4
- import { DyFM_usageSession_dataParams } from '@futdevpro/fsm-dynamo/usage';
5
4
  import { DyFM_customData_dataParams } from '@futdevpro/fsm-dynamo/custom-data';
5
+ import { DyFM_usageSession_dataParams } from '@futdevpro/fsm-dynamo/usage';
6
6
 
7
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
7
8
  import { DyNTS_App_Params } from '../../_models/control-models/app-params.control-model';
8
- import {
9
- DyNTS_GlobalService_Settings
10
- } from '../../_models/interfaces/global-service-settings.interface';
11
9
  import { DyNTS_Http_Settings } from '../../_models/control-models/http-settings.control-model';
10
+ import {
11
+ DyNTS_GlobalService_Settings
12
+ } from '../../_models/interfaces/global-service-settings.interface';
13
+ import { DyNTS_SingletonService } from '../../_services/base/singleton.service';
14
+ import { DyNTS_RoutingModule } from '../../_services/route/routing-module.service';
15
+ import { DyNTS_getCustomDataRoutingModule } from '../custom-data';
16
+ import { DyNTS_SocketServerService } from '../socket/_services/socket-server.service';
17
+ import { DyNTS_AppExtended } from '../socket/app-extended.server';
12
18
  import { DyNTS_getTestRoutingModule } from '../test';
13
19
  import { DyNTS_getUsageRoutingModule } from '../usage';
14
- import { DyNTS_RoutingModule } from '../../_services/route/routing-module.service';
15
- import { DyNTS_Controller_Mock } from './controller.mock';
16
20
  import { AuthService_Mock } from './auth-service.mock';
21
+ import { DyNTS_Controller_Mock } from './controller.mock';
17
22
  import { dependency_mock_DataParams, dependent_mock_DataParams } from './data-model.mock';
18
23
  import { EmailServiceCollection_Mock } from './email-service-collection.mock';
19
- import { DyNTS_getCustomDataRoutingModule } from '../custom-data';
20
- import { DyNTS_SingletonService } from '../../_services/base/singleton.service';
21
- import { DyNTS_AppExtended } from '../socket/_services/app-extended.server';
22
- import { DyNTS_SocketServerService } from '../socket/_services/socket-server.service';
23
- import { DyNTS_SocketServer_Mock } from './socket-server.mock';
24
24
  import { SocketClient_Mock } from './socket-client.mock';
25
- import { DyNTS_global_settings } from '../../_collections/global-settings.const';
25
+ import { DyNTS_SocketServer_Mock } from './socket-server.mock';
26
26
 
27
27
  /**
28
28
  *
@@ -94,7 +94,7 @@ export class DyNTS_AppExtendedFull_Mock extends DyNTS_AppExtended {
94
94
 
95
95
  getPortSettings(): DyNTS_Http_Settings {
96
96
  return {
97
- httpPort: 53535,
97
+ httpPort: 53534,
98
98
  };
99
99
  }
100
100
 
@@ -1,22 +1,22 @@
1
1
 
2
2
 
3
- import { DyFM_usageSession_dataParams } from '@futdevpro/fsm-dynamo/usage';
4
3
  import { DyFM_customData_dataParams } from '@futdevpro/fsm-dynamo/custom-data';
4
+ import { DyFM_usageSession_dataParams } from '@futdevpro/fsm-dynamo/usage';
5
5
 
6
6
  import { DyNTS_App_Params } from '../../_models/control-models/app-params.control-model';
7
- import {
8
- DyNTS_GlobalService_Settings
9
- } from '../../_models/interfaces/global-service-settings.interface';
10
7
  import { DyNTS_Http_Settings } from '../../_models/control-models/http-settings.control-model';
11
- import { DyNTS_getTestRoutingModule } from '../test';
12
- import { DyNTS_getUsageRoutingModule } from '../usage';
8
+ import {
9
+ DyNTS_GlobalService_Settings
10
+ } from '../../_models/interfaces/global-service-settings.interface';
11
+ import { DyNTS_SingletonService } from '../../_services/base/singleton.service';
13
12
  import { DyNTS_RoutingModule } from '../../_services/route/routing-module.service';
14
13
  import { DyNTS_App } from '../../_services/server/app.server';
15
- import { DyNTS_Controller_Mock } from './controller.mock';
14
+ import { DyNTS_getCustomDataRoutingModule } from '../custom-data';
15
+ import { DyNTS_getTestRoutingModule } from '../test';
16
+ import { DyNTS_getUsageRoutingModule } from '../usage';
16
17
  import { AuthService_Mock } from './auth-service.mock';
18
+ import { DyNTS_Controller_Mock } from './controller.mock';
17
19
  import { dependency_mock_DataParams, dependent_mock_DataParams } from './data-model.mock';
18
- import { DyNTS_getCustomDataRoutingModule } from '../custom-data';
19
- import { DyNTS_SingletonService } from '../../_services/base/singleton.service';
20
20
 
21
21
  /**
22
22
  *
@@ -83,7 +83,7 @@ export class DyNTS_AppFull_Mock extends DyNTS_App {
83
83
 
84
84
  getPortSettings(): DyNTS_Http_Settings {
85
85
  return {
86
- httpPort: 10101,
86
+ httpPort: 20101,
87
87
  };
88
88
  }
89
89
 
@@ -1,7 +1,7 @@
1
1
  import { DyFM_delay, DyFM_Error, DyFM_Log } from '@futdevpro/fsm-dynamo';
2
- import {
3
- DyNTS_AppExtendedBase_Mock, DyNTS_AppExtendedFull_Mock, DyNTS_AppWbMock_Mock
4
- } from '../../mock/app-extended-server.mock';
2
+ import {
3
+ DyNTS_AppExtendedBase_Mock, DyNTS_AppExtendedFull_Mock, DyNTS_AppWbMock_Mock
4
+ } from '../mock/app-extended-server.mock';
5
5
 
6
6
  describe('DyNTS_AppExtended;', (): void => {
7
7
  describe('a extended-base instance;', (): void => {
@@ -71,11 +71,11 @@ describe('DyNTS_AppExtended;', (): void => {
71
71
  }
72
72
  });
73
73
 
74
- it('should be created', (): void => {
74
+ it('should be created', async (): Promise<void> => {
75
75
  expect(app).toBeDefined();
76
76
  });
77
77
 
78
- it('should be started', (): void => {
78
+ it('should be started', async (): Promise<void> => {
79
79
  expect(app.started).toBeTrue();
80
80
  });
81
81
  });
@@ -109,11 +109,11 @@ describe('DyNTS_AppExtended;', (): void => {
109
109
  }
110
110
  });
111
111
 
112
- it('should be created', (): void => {
112
+ it('should be created', async (): Promise<void> => {
113
113
  expect(app).toBeDefined();
114
114
  });
115
115
 
116
- it('should be started', (): void => {
116
+ it('should be started', async (): Promise<void> => {
117
117
  expect(app.started).toBeTrue();
118
118
  });
119
119
  });
@@ -1,21 +1,26 @@
1
1
 
2
- import * as SocketIO from 'socket.io';
3
2
  import * as Http from 'http';
3
+ import * as SocketIO from 'socket.io';
4
4
 
5
- import {
6
- DyFM_Array, DyFM_Error, DyFM_Log, second, DyFM_wait, DyFM_AnyError, DyFM_Error_Settings,
7
- DyFM_ErrorLevel,
8
- DyFM_delay
5
+ import {
6
+ DyFM_AnyError,
7
+ DyFM_Array,
8
+ DyFM_delay,
9
+ DyFM_Error,
10
+ DyFM_Error_Settings,
11
+ DyFM_ErrorLevel,
12
+ DyFM_Log,
13
+ DyFM_wait
9
14
  } from '@futdevpro/fsm-dynamo';
10
15
 
11
- import { DyNTS_App } from '../../../_services/server/app.server';
12
- import { DyNTS_RouteSecurity } from '../../../_enums/route-security.enum';
13
- import { DyNTS_SocketServerService } from './socket-server.service';
14
- import { DyNTS_SocketSecurity } from '../_enums/socket-security.enum';
15
- import {
16
- DyNTS_AppExtSysControls
17
- } from '../../../_models/control-models/app-ext-system-controls.control-model';
18
- import { DyNTS_global_settings } from '../../../_collections/global-settings.const';
16
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
17
+ import { DyNTS_RouteSecurity } from '../../_enums/route-security.enum';
18
+ import {
19
+ DyNTS_AppExtSysControls
20
+ } from '../../_models/control-models/app-ext-system-controls.control-model';
21
+ import { DyNTS_App } from '../../_services/server/app.server';
22
+ import { DyNTS_SocketSecurity } from './_enums/socket-security.enum';
23
+ import { DyNTS_SocketServerService } from './_services/socket-server.service';
19
24
 
20
25
  /**
21
26
  * This will be the MAIN service of our server project,
@@ -12,8 +12,8 @@ export * from './_models/socket-server-service-params.control-model';
12
12
 
13
13
 
14
14
  // SERVICES
15
- export * from './_services/app-extended.server';
16
15
  export * from './_services/socket-client.service';
17
16
  export * from './_services/socket-server.service';
17
+ export * from './app-extended.server';
18
18
 
19
19
 
@@ -6,11 +6,13 @@ import {
6
6
  DyFM_DataModel_Params,
7
7
  DyFM_DataProperty_Params,
8
8
  DyFM_DBFilter,
9
+ DyFM_DBĐSort,
9
10
  DyFM_Error,
10
11
  DyFM_Error_Settings,
11
12
  DyFM_ErrorLevel,
12
13
  DyFM_Log,
13
14
  DyFM_Metadata,
15
+ DyFM_RangeValue,
14
16
  DyFM_SearchQuery,
15
17
  DyFM_SearchResult
16
18
  } from '@futdevpro/fsm-dynamo';
@@ -161,6 +163,9 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
161
163
  * also if dontSetToService is false or not setted,
162
164
  * the data will be saved to the service, even if its not found
163
165
  *
166
+ * if the data is not found, it will try to find it from the archive
167
+ * unless skipArchiveLoad is set to true
168
+ *
164
169
  * @remarks
165
170
  * If you need to get-save a data, if possible,
166
171
  * use db-service update instead.
@@ -171,9 +176,15 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
171
176
  *
172
177
  * @return {T} data: T
173
178
  */
174
- async getDataById(id?: string, dontSetToService?: boolean): Promise<T> {
179
+ async getDataById(
180
+ id?: string,
181
+ dontSetToService?: boolean,
182
+ skipArchiveLoad?: boolean
183
+ ): Promise<T> {
175
184
  try {
176
- if (!id && !this.data._id) {
185
+ id = id ?? this.data?._id;
186
+
187
+ if (!id) {
177
188
  throw new DyFM_Error({
178
189
  ...this._getDefaultErrorSettings(
179
190
  'getDataById',
@@ -188,7 +199,13 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
188
199
  });
189
200
  }
190
201
 
191
- const dataExists: T = await this.dataDBService.getDataById(id ?? this.data._id);
202
+ let dataExists: T = await this.dataDBService.getDataById(id);
203
+
204
+ if (this.haveArchiveDataService && !skipArchiveLoad) {
205
+ const archiveDataService: DyNTS_ArchiveDataService<T> = this.getArchiveDataService();
206
+
207
+ dataExists = await archiveDataService.getDataByOriginalId(id, true);
208
+ }
192
209
 
193
210
  if (!dontSetToService) {
194
211
  this.data = dataExists;
@@ -1086,54 +1103,79 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
1086
1103
  }
1087
1104
  }
1088
1105
 
1089
- async searchData(query?: DyFM_SearchQuery<T>): Promise<DyFM_SearchResult<T>> {
1106
+ async searchData(query?: DyFM_SearchQuery<T>, dataList?: T[]): Promise<DyFM_SearchResult<T>> {
1090
1107
  try {
1091
- if (!query || Object.keys(query).length === 0) {
1092
- const allData: T[] = await this.getAll();
1108
+ const searchResult = await this.sortAndFilterDataList(query, dataList);
1093
1109
 
1094
- return {
1095
- results: allData,
1096
- total: allData.length,
1097
- };
1110
+ if (query.page !== undefined && query.pageSize !== undefined) {
1111
+ const start = query.page * query.pageSize;
1112
+ const end = start + query.pageSize;
1113
+
1114
+ searchResult.results = searchResult.results.slice(start, end);
1098
1115
  }
1099
1116
 
1117
+ return searchResult;
1118
+ } catch (error) {
1119
+ throw new DyFM_Error({
1120
+ ...this._getDefaultErrorSettings('searchData', error),
1121
+
1122
+ errorCode: 'NTS-DS0-SD0',
1123
+ });
1124
+ }
1125
+ }
1126
+
1127
+ async sortAndFilterDataList(
1128
+ query: DyFM_SearchQuery<T>,
1129
+ dataList?: T[]
1130
+ ): Promise<DyFM_SearchResult<T>> {
1131
+ try {
1100
1132
  if (!query.filterBy) {
1101
1133
  query.filterBy = {};
1102
1134
  }
1103
-
1104
- if (!query.page && !query.pageSize && !query.sortBy) {
1105
- const dataFindResult: T[] = await this.dataDBService.find(query.filterBy);
1106
-
1107
- return {
1108
- results: dataFindResult,
1109
- total: dataFindResult.length,
1110
- };
1111
- }
1112
1135
 
1113
1136
  if (!query.page) {
1114
- query.page = 1;
1137
+ query.page = 0;
1115
1138
  }
1116
1139
 
1117
1140
  if (!query.pageSize) {
1118
- DyFM_Log.warn('searchData pageSize is not setted, setting to 10.');
1141
+ DyFM_Log.warn(
1142
+ `searchData pageSize is not setted, setting to ${DyNTS_global_settings.defaultPageSize}.`
1143
+ );
1119
1144
  query.pageSize = DyNTS_global_settings.defaultPageSize;
1120
1145
  }
1121
1146
 
1122
- if (!query.sortBy) {
1123
- query.sortBy = { __lastModified: -1 };
1147
+ if (!query.sortBy?.length) {
1148
+ query.sortBy = [{ key: '__lastModified', order: -1 }];
1149
+ }
1150
+
1151
+ query.sortBy.reverse();
1152
+
1153
+ if (!dataList) {
1154
+ dataList = await this.getAll();
1124
1155
  }
1125
1156
 
1126
- const dataFindWithPagingResult: T[] =
1127
- await this.dataDBService.findWithPaging(
1128
- query.filterBy,
1129
- query.page,
1130
- query.pageSize,
1131
- query.sortBy
1157
+ const filterKeys = Object.keys(query.filterBy);
1158
+ const filterFunctionsByKey: { [key: string]: (dataProperty) => boolean } = {};
1159
+
1160
+ filterKeys.forEach((key: string): void => {
1161
+ filterFunctionsByKey[key] = this.getFilterFunctionForKey(
1162
+ key, query.filterBy[key]
1132
1163
  );
1164
+ });
1165
+
1166
+ query.sortBy.forEach((sort: DyFM_DBĐSort): void => {
1167
+ dataList.sort(this.getSortFunctionForKey(sort.key, sort.order));
1168
+ });
1169
+
1170
+ dataList = dataList.filter(
1171
+ (data: T): boolean => filterKeys.every(
1172
+ (key: string): boolean => filterFunctionsByKey[key](data[key])
1173
+ )
1174
+ );
1133
1175
 
1134
1176
  return {
1135
- results: dataFindWithPagingResult,
1136
- total: dataFindWithPagingResult.length,
1177
+ results: dataList,
1178
+ totalItems: dataList.length,
1137
1179
  };
1138
1180
  } catch (error) {
1139
1181
  throw new DyFM_Error({
@@ -1144,6 +1186,198 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
1144
1186
  }
1145
1187
  }
1146
1188
 
1189
+ protected getFilterFunctionForKey<T>(
1190
+ key: string,
1191
+ searchValue: T | T[] | DyFM_RangeValue<T>,
1192
+ ): (dataProperty) => boolean {
1193
+ if (!this.dataParams.properties[key]) {
1194
+ throw new DyFM_Error({
1195
+ ...this._getDefaultErrorSettings(
1196
+ 'getFilterFunctionForKey',
1197
+ new Error(
1198
+ `getFilterFunctionForKey failed, key not found in dataParams ` +
1199
+ `(${this.dataParams.dataName})`
1200
+ )
1201
+ ),
1202
+
1203
+ errorCode: 'NTS-DS0-GFF1',
1204
+ });
1205
+ }
1206
+
1207
+ if (searchValue === undefined) {
1208
+ throw new DyFM_Error({
1209
+ ...this._getDefaultErrorSettings(
1210
+ 'getFilterFunctionForKey',
1211
+ new Error(
1212
+ `getFilterFunctionForKey failed, searchValue is missing! ` +
1213
+ `(${this.dataParams.dataName})`
1214
+ )
1215
+ ),
1216
+
1217
+ errorCode: 'NTS-DS0-GFF2',
1218
+ });
1219
+ }
1220
+
1221
+
1222
+ switch (this.dataParams.properties[key].type) {
1223
+ case 'String':
1224
+ if (typeof searchValue !== 'string') {
1225
+ throw new DyFM_Error({
1226
+ ...this._getDefaultErrorSettings(
1227
+ 'getFilterFunctionForKey',
1228
+ new Error(
1229
+ `getFilterFunctionForKey failed, searchValue is not a string! ` +
1230
+ `(${this.dataParams.dataName})`
1231
+ )
1232
+ ),
1233
+
1234
+ errorCode: 'NTS-DS0-GFF3',
1235
+ });
1236
+ }
1237
+
1238
+ const lowerCaseSearchValue: string = (searchValue as string).toLowerCase();
1239
+
1240
+ return (dataProperty): boolean =>
1241
+ (dataProperty as string).toLowerCase().includes(lowerCaseSearchValue);
1242
+
1243
+ case 'Date':
1244
+ if ((searchValue as DyFM_RangeValue).isRange) {
1245
+ const rangeAsNumber = new DyFM_RangeValue<number>(
1246
+ +new Date((searchValue as DyFM_RangeValue).from),
1247
+ +new Date((searchValue as DyFM_RangeValue).to)
1248
+ );
1249
+
1250
+ return (dataProperty): boolean => DyFM_RangeValue.isInRange(
1251
+ +new Date(dataProperty), rangeAsNumber
1252
+ );
1253
+ }
1254
+
1255
+ if (Array.isArray(searchValue)) {
1256
+ const searchValueAsDateArray = (searchValue as Date[]).map(
1257
+ (date: Date): Date => new Date(date)
1258
+ );
1259
+
1260
+ return (dataProperty): boolean => searchValueAsDateArray.includes(new Date(dataProperty));
1261
+ }
1262
+
1263
+ const searchValueAsDate: Date = new Date(searchValue as Date);
1264
+
1265
+ return (dataProperty): boolean => new Date(dataProperty) === searchValueAsDate;
1266
+
1267
+ case 'Number':
1268
+ if ((searchValue as DyFM_RangeValue).isRange) {
1269
+ return (dataProperty): boolean => DyFM_RangeValue.isInRange(
1270
+ dataProperty, searchValue as DyFM_RangeValue<number>
1271
+ );
1272
+ }
1273
+
1274
+ if (Array.isArray(searchValue)) {
1275
+ return (dataProperty): boolean => (searchValue as number[]).includes(dataProperty);
1276
+ }
1277
+
1278
+ return (dataProperty): boolean => dataProperty === searchValue;
1279
+
1280
+ case 'Boolean':
1281
+ return (dataProperty): boolean => dataProperty === searchValue;
1282
+
1283
+ default:
1284
+ if ((searchValue as DyFM_RangeValue).isRange) {
1285
+ throw new DyFM_Error({
1286
+ ...this._getDefaultErrorSettings(
1287
+ 'getFilterFunctionForKey',
1288
+ new Error(
1289
+ `getFilterFunctionForKey failed, range search not implemented for this type ` +
1290
+ `(${this.dataParams.dataName})`
1291
+ )
1292
+ ),
1293
+
1294
+ errorCode: 'NTS-DS0-GFF3',
1295
+ });
1296
+ }
1297
+
1298
+ if (Array.isArray(searchValue)) {
1299
+ return (dataProperty): boolean => (searchValue as number[]).includes(dataProperty);
1300
+ }
1301
+
1302
+ return (dataProperty): boolean => dataProperty === searchValue;
1303
+ }
1304
+ }
1305
+
1306
+ protected getSortFunctionForKey<T>(
1307
+ key: string,
1308
+ sortDirection: 1 | -1 | 'asc' | 'desc' | 'ascending' | 'descending'
1309
+ ): (a: T, b: T) => number {
1310
+ if (!this.dataParams.properties[key]) {
1311
+ throw new DyFM_Error({
1312
+ ...this._getDefaultErrorSettings(
1313
+ 'getSortFunctionForKey',
1314
+ new Error(
1315
+ `getSortFunctionForKey failed, key not found in dataParams ` +
1316
+ `(${this.dataParams.dataName})`
1317
+ )
1318
+ ),
1319
+
1320
+ errorCode: 'NTS-DS0-GSF1',
1321
+ });
1322
+ }
1323
+
1324
+ const sortValue: 1 | -1 = (
1325
+ sortDirection === 1 || sortDirection === 'asc' || sortDirection === 'ascending'
1326
+ ) ? 1 : -1;
1327
+
1328
+ switch (this.dataParams.properties[key].type) {
1329
+ case 'String':
1330
+ return (a: T, b: T): number => (a as string).localeCompare(b as string) * sortValue;
1331
+
1332
+ case 'Date':
1333
+ return (a: T, b: T): number => {
1334
+ if (+new Date(a[key]) < +new Date(b[key])) {
1335
+ return -sortValue;
1336
+ } else if (+new Date(a[key]) > +new Date(b[key])) {
1337
+ return sortValue;
1338
+ } else {
1339
+ return 0;
1340
+ }
1341
+ };
1342
+
1343
+ case 'Number':
1344
+ return (a: T, b: T): number => {
1345
+ if (a[key] < b[key]) {
1346
+ return -sortValue;
1347
+ } else if (a[key] > b[key]) {
1348
+ return sortValue;
1349
+ } else {
1350
+ return 0;
1351
+ }
1352
+ };
1353
+
1354
+ case 'Boolean':
1355
+ return (a: T, b: T): number => {
1356
+ if (a[key] === b[key]) {
1357
+ return 0;
1358
+ }
1359
+
1360
+ if (a[key]) {
1361
+ return sortValue;
1362
+ }
1363
+
1364
+ return -sortValue;
1365
+ };
1366
+
1367
+ default:
1368
+ throw new DyFM_Error({
1369
+ ...this._getDefaultErrorSettings(
1370
+ 'getSortFunctionForKey',
1371
+ new Error(
1372
+ `getSortFunctionForKey failed, sorting not implemented for this type ` +
1373
+ `(${this.dataParams.dataName}, ${this.dataParams.properties[key].type})`
1374
+ )
1375
+ ),
1376
+
1377
+ errorCode: 'NTS-DS0-GSF2',
1378
+ });
1379
+ }
1380
+ }
1147
1381
 
1148
1382
  /**
1149
1383
  * setting up dependency dataHook by DynamoBEDataModelParams