complexqa_frontend_core 1.0.9 → 1.0.12

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 (51) hide show
  1. package/package.json +6 -4
  2. package/publish/api/api_abstract_element_class.js +426 -0
  3. package/publish/api/functional_api.js +18 -0
  4. package/publish/api/index.js +114 -0
  5. package/publish/api/project_api.js +17 -0
  6. package/publish/api/service_api.js +20 -0
  7. package/publish/api/team_member_api.js +18 -0
  8. package/publish/api/test_case_api.js +18 -0
  9. package/publish/api/test_case_step_api.js +18 -0
  10. package/publish/api/test_plan_api.js +18 -0
  11. package/publish/api/test_run_api.js +13 -0
  12. package/publish/api/test_run_result_api.js +18 -0
  13. package/publish/api/test_suite_api.js +18 -0
  14. package/publish/exceptions/ApiException.js +69 -0
  15. package/publish/index.js +51 -0
  16. package/publish/services/UserService.js +129 -0
  17. package/publish/services/abstractService.js +36 -0
  18. package/publish/services/mock_data/MockUserService.js +30 -0
  19. package/publish/services/serviceTranslate.js +98 -0
  20. package/publish/types/family_elements/0_familyGeneralElement.js +439 -0
  21. package/publish/types/family_elements/mock_data/abstract_mock_data.js +13 -0
  22. package/publish/types/family_elements/mock_data/mock_data_typeProject.js +88 -0
  23. package/publish/types/family_elements/typeActionLog.js +9 -0
  24. package/publish/types/family_elements/typeFunctional.js +96 -0
  25. package/publish/types/family_elements/typeFunctionalGroup.js +95 -0
  26. package/publish/types/family_elements/typeMilestone.js +93 -0
  27. package/publish/types/family_elements/typeProject.js +114 -0
  28. package/publish/types/family_elements/typeProjectDocument.js +80 -0
  29. package/publish/types/family_elements/typeProjectTestAccount.js +59 -0
  30. package/publish/types/family_elements/typeProjectTestData.js +43 -0
  31. package/publish/types/family_elements/typeProjectUserRole.js +55 -0
  32. package/publish/types/family_elements/typeTask.js +78 -0
  33. package/publish/types/family_elements/typeTeam.js +105 -0
  34. package/publish/types/family_elements/typeTeamMember.js +58 -0
  35. package/publish/types/family_elements/typeTeamUserRole.js +56 -0
  36. package/publish/types/family_elements/typeTestCase.js +98 -0
  37. package/publish/types/family_elements/typeTestCaseStep.js +87 -0
  38. package/publish/types/family_elements/typeTestPlan.js +35 -0
  39. package/publish/types/family_elements/typeTestRun.js +56 -0
  40. package/publish/types/family_elements/typeTestRunResult.js +72 -0
  41. package/publish/types/family_elements/typeTestSuite.js +75 -0
  42. package/publish/types/family_elements/typeUser.js +56 -0
  43. package/publish/types/family_service/familyService.js +8 -0
  44. package/publish/types/family_service/typeAppConfiguration.js +39 -0
  45. package/publish/types/family_service/typeFOR.js +36 -0
  46. package/publish/types/family_service/typeFilter.js +38 -0
  47. package/publish/types/family_service/typeFunctionCallback.js +40 -0
  48. package/publish/types/family_service/typeNotification.js +36 -0
  49. package/publish/types/family_service/typeTableColumn.js +37 -0
  50. package/publish/types/family_service/typeTableConfiguration.js +56 -0
  51. package/publish/utils/utils.js +190 -0
package/package.json CHANGED
@@ -1,15 +1,14 @@
1
1
  {
2
2
  "name": "complexqa_frontend_core",
3
- "version": "1.0.9",
3
+ "version": "1.0.12",
4
4
  "description": "core of web ",
5
5
  "type": "module",
6
6
  "exports": {
7
- ".": "./publish_module/index.js"
7
+ ".": "./publish/index.js"
8
8
  },
9
9
  "files": [
10
- "publish_module/"
10
+ "publish/"
11
11
  ],
12
-
13
12
  "scripts": {
14
13
  "test": "echo \"Error: no test specified\" && exit 1"
15
14
  },
@@ -27,6 +26,7 @@
27
26
  "@babel/plugin-proposal-class-properties": "^7.18.6",
28
27
  "@babel/plugin-proposal-optional-chaining": "^7.21.0",
29
28
  "@babel/plugin-transform-modules-commonjs": "^7.24.7",
29
+ "@babel/plugin-transform-runtime": "^7.27.4",
30
30
  "@babel/preset-env": "^7.24.7",
31
31
  "axios": "^1.7.2",
32
32
  "gulp": "^5.0.0",
@@ -40,11 +40,13 @@
40
40
  "gulp-uncomment": "^0.3.0",
41
41
  "i18next": "^23.11.5",
42
42
  "query-string": "^9.0.0",
43
+ "uglify-js": "^3.19.3",
43
44
  "underscore": "^1.13.6"
44
45
  },
45
46
  "devDependencies": {
46
47
  "babel": "^6.23.0",
47
48
  "babel-plugin-module-resolver-standalone": "^0.0.2",
49
+ "gulp-uglify": "^3.0.2",
48
50
  "requirejs-babel": "^0.0.9"
49
51
  }
50
52
  }
@@ -0,0 +1,426 @@
1
+ import { clone_object, echo, is_array } from "../utils/utils";
2
+ import axios from "axios";
3
+ import * as qs from "query-string";
4
+ import { ApiException } from "../exceptions/ApiException";
5
+
6
+ /**
7
+ * Общие методы для всех типизированных элементов
8
+ *
9
+ * @version v.2.0 (24/11/2024)
10
+ */
11
+ export class ApiAbstractElementClass
12
+ {
13
+
14
+ init_options;
15
+ element_class_instance;
16
+ dev_stage_config;
17
+ parent_app;
18
+ host_api;
19
+ stage = 'production';
20
+ module_prefix = false;
21
+ api_prefix = 'web_api';
22
+ method;
23
+ headers;
24
+
25
+
26
+ /**
27
+ *
28
+ * @version v.0.1 (27/06/2024)
29
+ * @param options
30
+ */
31
+ constructor(options)
32
+ {
33
+ if (options?.init_options)
34
+ {
35
+ this.init_options = options?.init_options;
36
+ }
37
+ if (options?.stage)
38
+ {
39
+ this.stage = options?.stage;
40
+ }
41
+ if (options?.dev_stage_config)
42
+ {
43
+ this.dev_stage_config = options?.dev_stage_config;
44
+ }
45
+ if (options?.parent_app)
46
+ {
47
+ this.parent_app = options?.parent_app;
48
+ }
49
+ if (options?.host_api)
50
+ {
51
+ this.host_api = options?.host_api;
52
+ }
53
+ }
54
+
55
+
56
+ set_element_class_instance(element_class_instance)
57
+ {
58
+ this.element_class_instance = element_class_instance;
59
+ }
60
+
61
+
62
+ /**
63
+ *
64
+ * @version v.0.1 (26/05/2024)
65
+ * @param {object|typeFOR} payload
66
+ * @param {array} payload.filter
67
+ * @param {?object|undefined} payload.object
68
+ * @param {?object|undefined} payload.response
69
+ */
70
+ async search(payload)
71
+ {
72
+ if (!this.module_prefix)
73
+ {
74
+ throw new Error('Error #10-1152 in ApiAbstractClass');
75
+ }
76
+
77
+ if (this.stage === 'development')
78
+ {
79
+ let response = await this.#mock_search(payload);
80
+ return {
81
+ response: response,
82
+ payload : payload
83
+ };
84
+ }
85
+
86
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/search`;
87
+
88
+ payload = this.#handle_request_payload(payload);
89
+ let response = this.#api_request(url, payload);
90
+ response = this.#handle_response(response);
91
+
92
+ return {
93
+ response: response,
94
+ payload : payload
95
+ };
96
+ }
97
+
98
+
99
+ /**
100
+ *
101
+ * @version v.0.1 (27/06/2024)
102
+ * @param payload
103
+ * @returns {Promise<array>}
104
+ */
105
+ async #mock_search(payload)
106
+ {
107
+ // @todo - дописать
108
+ if (this.dev_stage_config.api_response_search_element_count > 0 && this.dev_stage_config.api_response_search_element_count < 999)
109
+ {
110
+
111
+ }
112
+ else
113
+ {
114
+ throw new Error('Error #100-154');
115
+ }
116
+
117
+ let model = new this.element_class_instance();
118
+ let response = model.get_random_demo_data(this.dev_stage_config.api_response_search_element_count)
119
+
120
+ return response;
121
+
122
+ }
123
+
124
+
125
+ /**
126
+ *
127
+ * @version v.0.1 (26/05/2024)
128
+ * @param payload
129
+ */
130
+ async find(payload)
131
+ {
132
+ if (!this.module_prefix)
133
+ {
134
+ throw new Error('Error #10-1152 in ApiAbstractClass');
135
+ }
136
+ }
137
+
138
+
139
+ /**
140
+ *
141
+ * @version v.0.1 (26/05/2024)
142
+ * @param payload
143
+ */
144
+ async create(payload)
145
+ {
146
+ if (!this.module_prefix)
147
+ {
148
+ throw new Error('Error #10-1152 in ApiAbstractClass');
149
+ }
150
+
151
+ if (this.stage === 'development')
152
+ {
153
+ return {
154
+ response: payload,
155
+ payload : payload
156
+ };
157
+ }
158
+
159
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/create`;
160
+
161
+ payload = this.#handle_request_payload(payload);
162
+ let response = this.#api_request(url, payload);
163
+ response = this.#handle_response(response);
164
+
165
+ return {
166
+ response: response,
167
+ payload : payload
168
+ };
169
+ }
170
+
171
+
172
+ /**
173
+ *
174
+ * @version v.0.1 (26/05/2024)
175
+ * @param payload
176
+ */
177
+ async update(payload)
178
+ {
179
+ if (!this.module_prefix)
180
+ {
181
+ throw new Error('Error #10-1152 in ApiAbstractClass');
182
+ }
183
+
184
+ }
185
+
186
+
187
+ /**
188
+ *
189
+ * @version v.0.1 (26/05/2024)
190
+ * @param payload
191
+ */
192
+ async update_property(payload)
193
+ {
194
+ if (!this.module_prefix)
195
+ {
196
+ throw new Error('Error #10-1152 in ApiAbstractClass');
197
+ }
198
+
199
+ if (this.stage === 'development')
200
+ {
201
+ return {
202
+ response: payload,
203
+ payload : payload
204
+ };
205
+ }
206
+
207
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/update_property`;
208
+
209
+ payload = this.#handle_request_payload(payload);
210
+ let response = this.#api_request(url, payload);
211
+ response = this.#handle_response(response);
212
+
213
+ return {
214
+ response: response,
215
+ payload : payload
216
+ };
217
+ }
218
+
219
+
220
+ /**
221
+ *
222
+ * @version v.0.1 (26/05/2024)
223
+ * @param payload
224
+ */
225
+ async delete(payload)
226
+ {
227
+ if (!this.module_prefix)
228
+ {
229
+ throw new Error('Error #10-1152 in ApiAbstractClass');
230
+ }
231
+
232
+ if (this.stage === 'development')
233
+ {
234
+ return {
235
+ response: payload,
236
+ payload : payload
237
+ };
238
+ }
239
+
240
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/delete`;
241
+
242
+ payload = this.#handle_request_payload(payload);
243
+ let response = this.#api_request(url, payload);
244
+ response = this.#handle_response(response);
245
+
246
+ return {
247
+ response: response,
248
+ payload : payload
249
+ };
250
+ }
251
+
252
+
253
+ /******************************************************************************************/
254
+ /******************************************************************************************/
255
+
256
+ /******************************************************************************************/
257
+
258
+ #handle_request_payload(payload)
259
+ {
260
+ return this.#object_replace_null_recursively(payload);
261
+ }
262
+
263
+ #object_replace_null_recursively(object)
264
+ {
265
+ let result = clone_object(object);
266
+ for (let key in result)
267
+ {
268
+ if (result[ key ] === null)
269
+ {
270
+ result[ key ] = 'NULL';
271
+ }
272
+ else if (( result[ key ]?.constructor === Object ) || ( result[ key ]?.constructor === Array ))
273
+ {
274
+ result[ key ] = this.#object_replace_null_recursively(result[ key ]);
275
+ }
276
+ }
277
+
278
+ return result;
279
+ }
280
+
281
+
282
+ /**
283
+ *
284
+ * @param url
285
+ * @param payload
286
+ * @param method
287
+ * @returns {Promise<Promise<axios.AxiosResponse<any>> | *>}
288
+ * @version v.0.2 (26/01/2025)
289
+ */
290
+ async #api_request(url, payload, method = 'POST')
291
+ {
292
+ let request_params;
293
+ if (!payload)
294
+ {
295
+ request_params = {};
296
+ }
297
+ else
298
+ {
299
+ request_params = clone_object(payload)
300
+ }
301
+
302
+ request_params = this.#mixin_service_params(request_params);
303
+
304
+ console.log({payload, request_params});
305
+
306
+
307
+ if (this.host_api)
308
+ {
309
+ url = 'https://' + this.host_api + url;
310
+ }
311
+
312
+ let request_options = {
313
+ method : method,
314
+ headers: this.headers,
315
+ url : url
316
+ };
317
+
318
+ if (this.method === 'get')
319
+ {
320
+ request_options.paramsSerializer = this.object_to_string;
321
+ request_options.params = request_params;
322
+ }
323
+ else
324
+ {
325
+ request_options.data = (request_params);
326
+ }
327
+
328
+ let config = {};
329
+
330
+ return axios(request_options, config);
331
+ }
332
+
333
+
334
+ /**
335
+ *
336
+ * @param object
337
+ * @returns {string}
338
+ */
339
+ object_to_string(object)
340
+ {
341
+ let result = qs.stringify(object, { array_format: 'indices' });
342
+
343
+ return result;
344
+ }
345
+
346
+
347
+ #mixin_service_params(params)
348
+ {
349
+ params.client = 'webapp';
350
+ return params;
351
+ }
352
+
353
+
354
+ /**
355
+ *
356
+ * @param {} response
357
+ * @returns {Promise<any>}
358
+ * @version v.0.1 (01/06/2024)
359
+ */
360
+ #handle_response(response)
361
+ {
362
+ response = response.then((api_response) =>
363
+ {
364
+ let error_payload = {
365
+ api_response: api_response?.data?.api_response,
366
+ api_code : api_response?.data?.api_code,
367
+ api_result : api_response?.data?.api_result,
368
+ api_error : api_response?.data?.api_error
369
+ };
370
+
371
+ if (api_response?.data?.api_error?.adapted_message)
372
+ {
373
+ error_payload.message = api_response.data.api_error.adapted_message
374
+ throw new ApiException(error_payload);
375
+ }
376
+ else if (api_response?.data?.api_code)
377
+ {
378
+ let api_code = api_response.data.api_code;
379
+
380
+ if (( api_code >= 200 ) && ( api_code <= 299 ))
381
+ {
382
+ if (is_array(api_response?.data) && this.element_class_instance)
383
+ {
384
+ let result = api_response?.data.map((row) =>
385
+ {
386
+ return new this.element_class_instance(row);
387
+ });
388
+
389
+ return result;
390
+ }
391
+ else
392
+ {
393
+ return api_response?.data;
394
+ }
395
+ }
396
+ else if (api_response?.data?.api_result === false)
397
+ {
398
+ throw new ApiException(error_payload);
399
+ }
400
+ else
401
+ {
402
+ throw new ApiException(error_payload);
403
+ }
404
+ }
405
+ else
406
+ {
407
+ return api_response?.data;
408
+ }
409
+ })
410
+ .catch((error) =>
411
+ {
412
+
413
+ echo({ app: this });
414
+ console.error(error);
415
+ if (error instanceof ApiException)
416
+ {
417
+ throw error;
418
+ }
419
+
420
+
421
+ throw new ApiException({ error: error });
422
+ });
423
+
424
+ return response;
425
+ }
426
+ }
@@ -0,0 +1,18 @@
1
+ import { ApiAbstractElementClass } from "./api_abstract_element_class";
2
+ import { typeFunctional } from "../types/family_elements/typeFunctional";
3
+
4
+
5
+ /**
6
+ *
7
+ * @version v.0.1 (24/11/2024)
8
+ */
9
+ export class FunctionalApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'functional';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeFunctional);
17
+ }
18
+ }
@@ -0,0 +1,114 @@
1
+ import { TestPlanApi } from "./test_plan_api";
2
+ import { ProjectApi } from "./project_api";
3
+ import { ServiceApi } from "./service_api";
4
+ import { TestCaseApi } from "./test_case_api";
5
+ import { TestSuiteApi } from "./test_suite_api";
6
+
7
+ /**
8
+ * Обертка над axios
9
+ * @version v.0.3 (26/01/2025)
10
+ */
11
+ export class Api
12
+ {
13
+ /**
14
+ * Режим работы
15
+ *
16
+ * @type {string} development || production || tests
17
+ */
18
+ stage = 'development';
19
+ dev_stage_config = {
20
+ generate_error : false,
21
+ api_response_delay : 3500,
22
+ api_response_search_element_count: 8,
23
+ };
24
+
25
+ init_options;
26
+
27
+ test_plan;
28
+ /**
29
+ * {ProjectApi} project
30
+ */
31
+ project;
32
+ service;
33
+
34
+ host_api = false;
35
+
36
+
37
+ /**
38
+ *
39
+ * @version v.0.3 (26/01/2025)
40
+ */
41
+ constructor(init_options)
42
+ {
43
+
44
+ if (this.constructor._instance)
45
+ {
46
+ return this.constructor._instance;
47
+ }
48
+
49
+
50
+ if (init_options.host_api)
51
+ {
52
+ // @todo validate
53
+ this.host_api = init_options.host_api;
54
+ }
55
+ else
56
+ {
57
+ // подумать
58
+ this.host_api = 'complexqa.localhost';
59
+ }
60
+
61
+ if (init_options.stage)
62
+ {
63
+ // @todo validate
64
+ this.stage = init_options.stage;
65
+ }
66
+
67
+ if (init_options.dev_stage_config)
68
+ {
69
+ // @todo validate
70
+ this.dev_stage_config = init_options.dev_stage_config;
71
+ }
72
+
73
+ this.init_options = init_options;
74
+ this.constructor._instance = this;
75
+
76
+
77
+ this.#bootstrap();
78
+ return this.constructor._instance;
79
+ }
80
+
81
+
82
+ /**
83
+ *
84
+ * @param stage
85
+ */
86
+ set_stage(stage)
87
+ {
88
+ this.stage = stage;
89
+ }
90
+
91
+
92
+ /**
93
+ *
94
+ * @version v.0.1 (25/06/2024)
95
+ */
96
+ #bootstrap()
97
+ {
98
+ let payload = {
99
+ init_options : this.init_options,
100
+ stage : this.stage,
101
+ dev_stage_config: this.dev_stage_config,
102
+ host_api: this.host_api,
103
+ parent_app : this
104
+ };
105
+
106
+ //echo({payload});
107
+
108
+ this.test_plan = new TestPlanApi(payload);
109
+ this.project = new ProjectApi(payload);
110
+ this.service = new ServiceApi(payload);
111
+ this.test_case = new TestCaseApi(payload);
112
+ this.test_suite = new TestSuiteApi(payload);
113
+ }
114
+ }
@@ -0,0 +1,17 @@
1
+ import { ApiAbstractElementClass } from "./api_abstract_element_class";
2
+ import { typeProject } from "../types/family_elements/typeProject";
3
+
4
+ /**
5
+ *
6
+ * @version v.0.1 (15/06/2024)
7
+ */
8
+ export class ProjectApi extends ApiAbstractElementClass
9
+ {
10
+ module_prefix = 'project';
11
+
12
+ constructor(options)
13
+ {
14
+ super(options);
15
+ this.set_element_class_instance(typeProject);
16
+ }
17
+ }
@@ -0,0 +1,20 @@
1
+
2
+ // тут нужен свой класс, не для типов
3
+ export class ServiceApi
4
+ {
5
+ module_prefix = '--';
6
+
7
+ constructor(options)
8
+ {
9
+ }
10
+
11
+
12
+ /**
13
+ *
14
+ * @returns {Promise<*[]>}
15
+ */
16
+ async translate_get_dictionaries()
17
+ {
18
+ return [];
19
+ }
20
+ }
@@ -0,0 +1,18 @@
1
+ import { ApiAbstractElementClass } from "./api_abstract_element_class";
2
+ import { typeTeamMember } from "../types/family_elements/typeTeamMember";
3
+
4
+
5
+ /**
6
+ *
7
+ * @version v.0.1 (24/11/2024)
8
+ */
9
+ export class TeamMemberApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'team_member';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeTeamMember);
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ import { ApiAbstractElementClass } from "./api_abstract_element_class";
2
+ import { typeTestCase } from "../types/family_elements/typeTestCase";
3
+
4
+
5
+ /**
6
+ *
7
+ * @version v.0.1 (24/11/2024)
8
+ */
9
+ export class TestCaseApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'test_case';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeTestCase);
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ import { typeTestCaseStep } from "../types/family_elements/typeTestCaseStep";
2
+ import { ApiAbstractElementClass } from "./api_abstract_element_class";
3
+
4
+
5
+ /**
6
+ *
7
+ * @version v.0.1 (24/11/2024)
8
+ */
9
+ export class TestCaseStepApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'test_case_step';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeTestCaseStep);
17
+ }
18
+ }
@@ -0,0 +1,18 @@
1
+ import { ApiAbstractElementClass } from "./api_abstract_element_class";
2
+ import { typeTestPlan } from "../types/family_elements/typeTestPlan";
3
+
4
+
5
+ /**
6
+ *
7
+ * @version v.0.1 (26/05/2024)
8
+ */
9
+ export class TestPlanApi extends ApiAbstractElementClass
10
+ {
11
+ module_prefix = 'test_plan';
12
+
13
+ constructor(options)
14
+ {
15
+ super(options);
16
+ this.set_element_class_instance(typeTestPlan);
17
+ }
18
+ }