complexqa_frontend_core 1.15.1 → 1.16.1

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 (50) hide show
  1. package/package.json +1 -1
  2. package/publish/api/api_abstract_class.js +326 -0
  3. package/publish/api/api_abstract_element_class.js +5 -298
  4. package/publish/api/api_abstract_reference_class.js +56 -0
  5. package/publish/api/context/context_browser_api.js +17 -0
  6. package/publish/api/context/context_deployment_target_api.js +17 -0
  7. package/publish/api/context/context_devices_api.js +17 -0
  8. package/publish/api/context/context_execution_general_api.js +17 -0
  9. package/publish/api/context/context_locale_api.js +17 -0
  10. package/publish/api/context/context_os_api.js +17 -0
  11. package/publish/api/context/context_screen_resolution_api.js +17 -0
  12. package/publish/api/index.js +43 -15
  13. package/publish/index.js +9 -0
  14. package/publish/types/core/0_familyGeneralElement.js +632 -0
  15. package/publish/types/core/1_familyContext.js +144 -0
  16. package/publish/types/core/1_familyTestAutomation.js +20 -0
  17. package/publish/types/core/1_familyTestDocumentation.js +21 -0
  18. package/publish/types/family_context/0_familyContext.js +144 -0
  19. package/publish/types/family_context/typeBrowserContext.js +59 -0
  20. package/publish/types/family_context/typeDeploymentTargetContext.js +98 -0
  21. package/publish/types/family_context/typeDeviceContext.js +86 -0
  22. package/publish/types/family_context/typeExecutionContext.js +148 -0
  23. package/publish/types/family_context/typeLocaleContext.js +75 -0
  24. package/publish/types/family_context/typeOsContext.js +86 -0
  25. package/publish/types/family_context/typeScreenResolutionContext.js +99 -0
  26. package/publish/types/family_elements/typeAutomationTestEnvironment.js +1 -1
  27. package/publish/types/family_elements/typeAutomationTestPlan.js +1 -1
  28. package/publish/types/family_elements/typeAutomationTestStep.js +1 -1
  29. package/publish/types/family_elements/typeAutomationTestStepTarget.js +1 -1
  30. package/publish/types/family_elements/typeBug.js +4 -4
  31. package/publish/types/family_elements/typeFunctional.js +2 -2
  32. package/publish/types/family_elements/typeFunctionalGroup.js +2 -2
  33. package/publish/types/family_elements/typeMilestone.js +1 -1
  34. package/publish/types/family_elements/typePrice.js +1 -1
  35. package/publish/types/family_elements/typeProject.js +1 -1
  36. package/publish/types/family_elements/typeProjectDocument.js +1 -1
  37. package/publish/types/family_elements/typeProjectTestData.js +1 -1
  38. package/publish/types/family_elements/typeProjectUserRole.js +1 -1
  39. package/publish/types/family_elements/typeTask.js +1 -1
  40. package/publish/types/family_elements/typeTeam.js +1 -1
  41. package/publish/types/family_elements/typeTeamMember.js +1 -1
  42. package/publish/types/family_elements/typeTeamUserRole.js +1 -1
  43. package/publish/types/family_elements/typeTestAccount.js +1 -1
  44. package/publish/types/family_elements/typeTestCase.js +1 -1
  45. package/publish/types/family_elements/typeTestCaseStep.js +1 -1
  46. package/publish/types/family_elements/typeTestPlan.js +2 -2
  47. package/publish/types/family_elements/typeTestRun.js +1 -1
  48. package/publish/types/family_elements/typeTestRunResult.js +1 -1
  49. package/publish/types/family_elements/typeTestSuite.js +1 -1
  50. package/publish/types/family_elements/typeUser.js +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "complexqa_frontend_core",
3
- "version": "1.15.1",
3
+ "version": "1.16.1",
4
4
  "description": "core of web ",
5
5
  "type": "module",
6
6
  "exports": {
@@ -0,0 +1,326 @@
1
+ import { ApiException } from "../exceptions/ApiException.js";
2
+ import { clone_object, echo, is_array } from "../utils/utils.js";
3
+
4
+ /**
5
+ *
6
+ * @version v.1.0 (03/06/2026)
7
+ */
8
+ export class ApiAbstractClass
9
+ {
10
+ init_options;
11
+ element_class_instance;
12
+ dev_stage_config;
13
+ parent_app;
14
+ host_api;
15
+ stage = 'production';
16
+ module_prefix = false;
17
+ api_prefix = '';
18
+ method;
19
+ headers;
20
+
21
+
22
+ /**
23
+ *
24
+ * @version v.1.0 (03/06/2026)
25
+ * @param options
26
+ */
27
+ constructor(options)
28
+ {
29
+ if (options?.init_options)
30
+ {
31
+ this.init_options = options?.init_options;
32
+ }
33
+ if (options?.stage)
34
+ {
35
+ this.stage = options?.stage;
36
+ }
37
+ if (options?.dev_stage_config)
38
+ {
39
+ this.dev_stage_config = options?.dev_stage_config;
40
+ }
41
+ if (options?.parent_app)
42
+ {
43
+ this.parent_app = options?.parent_app;
44
+ }
45
+ if (options?.host_api)
46
+ {
47
+ this.host_api = options?.host_api;
48
+ }
49
+ }
50
+
51
+
52
+ set_element_class_instance(element_class_instance)
53
+ {
54
+ this.element_class_instance = element_class_instance;
55
+ }
56
+
57
+
58
+
59
+ /**
60
+ *
61
+ * @version v.0.1 (26/05/2024)
62
+ * @param {object|typeFOR} payload
63
+ * @param {array} payload.filter
64
+ * @param {?object|undefined} payload.object
65
+ * @param {?object|undefined} payload.response
66
+ */
67
+ async search(payload)
68
+ {
69
+ if (!this.module_prefix)
70
+ {
71
+ throw new Error('Error #10-1152 in ApiAbstractClass');
72
+ }
73
+
74
+ if (this.stage === 'development')
75
+ {
76
+ let response = await this.mock_search(payload);
77
+ return {
78
+ response: response,
79
+ payload : payload
80
+ };
81
+ }
82
+
83
+ let url = `/${ this.api_prefix }/${ this.module_prefix }/search`;
84
+
85
+ payload = this.handle_request_payload(payload);
86
+ let response = this.api_request(url, payload);
87
+ response = this.handle_response(response);
88
+
89
+ return {
90
+ response: response,
91
+ payload : payload
92
+ };
93
+ }
94
+
95
+
96
+ /**
97
+ *
98
+ * @version v.0.1 (27/06/2024)
99
+ * @param payload
100
+ * @returns {Promise<array>}
101
+ */
102
+ async mock_search(payload)
103
+ {
104
+ // @todo - дописать
105
+ if (this.dev_stage_config.api_response_search_element_count > 0 && this.dev_stage_config.api_response_search_element_count < 999)
106
+ {
107
+
108
+ }
109
+ else
110
+ {
111
+ throw new Error('Error #100-154');
112
+ }
113
+
114
+ let model = new this.element_class_instance();
115
+ let response = model.get_random_demo_data(this.dev_stage_config.api_response_search_element_count)
116
+
117
+ return response;
118
+
119
+ }
120
+
121
+
122
+
123
+
124
+ /******************************************************************************************/
125
+ /******************************************************************************************/
126
+
127
+ /******************************************************************************************/
128
+
129
+ /**
130
+ *
131
+ * @param payload
132
+ * @returns {*}
133
+ */
134
+ handle_request_payload(payload)
135
+ {
136
+ return this.object_replace_null_recursively(payload);
137
+ }
138
+
139
+
140
+ /**
141
+ *
142
+ * @param object
143
+ * @returns {*}
144
+ */
145
+ object_replace_null_recursively(object)
146
+ {
147
+ let result = clone_object(object);
148
+ for (let key in result)
149
+ {
150
+ if (result[ key ] === null)
151
+ {
152
+ result[ key ] = 'NULL';
153
+ }
154
+ else if (( result[ key ]?.constructor === Object ) || ( result[ key ]?.constructor === Array ))
155
+ {
156
+ result[ key ] = this.object_replace_null_recursively(result[ key ]);
157
+ }
158
+ }
159
+
160
+ return result;
161
+ }
162
+
163
+
164
+ /**
165
+ *
166
+ * @param url
167
+ * @param payload
168
+ * @param method
169
+ * @returns {Promise<Promise<axios.AxiosResponse<any>> | *>}
170
+ * @version v.0.2 (26/01/2025)
171
+ * @todo - валидация входящих параметров
172
+ */
173
+ async api_request(url, payload, method = 'POST')
174
+ {
175
+ let request_params;
176
+ if (!payload)
177
+ {
178
+ request_params = {};
179
+ }
180
+ else
181
+ {
182
+ request_params = clone_object(payload)
183
+ }
184
+
185
+ request_params = this.mixin_service_params(request_params);
186
+
187
+ //console.log({payload, request_params});
188
+
189
+
190
+ if (this.host_api)
191
+ {
192
+ url = 'https://' + this.host_api + url;
193
+ }
194
+
195
+ let request_options = {
196
+ method : method,
197
+ headers: this.headers,
198
+ url : url
199
+ };
200
+
201
+ if (this.method === 'get')
202
+ {
203
+ request_options.paramsSerializer = this.object_to_string;
204
+ request_options.params = request_params;
205
+ }
206
+ else
207
+ {
208
+ request_options.data = (request_params);
209
+ }
210
+
211
+ let config = {};
212
+
213
+ return axios(request_options, config);
214
+ }
215
+
216
+
217
+ /**
218
+ *
219
+ * @param object
220
+ * @returns {string}
221
+ * @todo - валидация входящих параметров
222
+ */
223
+ object_to_string(object)
224
+ {
225
+ let result = qs.stringify(object, { array_format: 'indices' });
226
+
227
+ return result;
228
+ }
229
+
230
+
231
+ mixin_service_params(params)
232
+ {
233
+ params.client = 'webapp';
234
+ return params;
235
+ }
236
+
237
+
238
+ /**
239
+ *
240
+ * @param {object} response
241
+ * @param {object} init_class_instance
242
+ * @returns {Promise<any>}
243
+ * @version v.0.1 (04/03/2026)
244
+ */
245
+ handle_response(response, init_class_instance = true)
246
+ {
247
+ response = response.then((api_response) =>
248
+ {
249
+ let error_payload = {
250
+ api_response: api_response?.data?.api_response,
251
+ api_code : api_response?.data?.api_code,
252
+ api_result : api_response?.data?.api_result,
253
+ api_error : api_response?.data?.api_error
254
+ };
255
+
256
+ if (api_response?.data?.api_error?.adapted_message)
257
+ {
258
+ error_payload.message = api_response.data.api_error.adapted_message
259
+ throw new ApiException(error_payload);
260
+ }
261
+ else if (api_response?.data?.api_code)
262
+ {
263
+ let api_code = api_response.data.api_code;
264
+
265
+ if (( api_code >= 200 ) && ( api_code <= 299 ))
266
+ {
267
+ if (is_array(api_response?.data?.api_result) && this.element_class_instance)
268
+ {
269
+ let result = api_response?.data.api_result.map((row) =>
270
+ {
271
+ if (init_class_instance)
272
+ {
273
+ return new this.element_class_instance(row);
274
+ }
275
+ else
276
+ {
277
+ return row;
278
+ }
279
+ });
280
+
281
+ return result;
282
+ }
283
+ else if (is_object(api_response?.data?.api_result))
284
+ {
285
+ return api_response?.data?.api_result;
286
+ }
287
+ else if (api_response?.data?.api_result === false)
288
+ {
289
+ return api_response?.data?.api_result;
290
+ }
291
+ else
292
+ {
293
+ return api_response?.data;
294
+ }
295
+ }
296
+ else if (api_response?.data?.api_result === false)
297
+ {
298
+ throw new ApiException(error_payload);
299
+ }
300
+ else
301
+ {
302
+ throw new ApiException(error_payload);
303
+ }
304
+ }
305
+ else
306
+ {
307
+ return api_response?.data;
308
+ }
309
+ })
310
+ .catch((error) =>
311
+ {
312
+
313
+ echo({ app: this });
314
+ console.error(error);
315
+ if (error instanceof ApiException)
316
+ {
317
+ throw error;
318
+ }
319
+
320
+
321
+ throw new ApiException({ error: error });
322
+ });
323
+
324
+ return response;
325
+ }
326
+ }
@@ -1,124 +1,24 @@
1
- import { clone_object, echo, is_array, is_object } from "../utils/utils";
2
- import axios from "axios";
3
- import * as qs from "query-string";
4
- import { ApiException } from "../exceptions/ApiException";
1
+ import { ApiAbstractClass } from "./api_abstract_class.js";
5
2
 
6
3
  /**
7
4
  * Общие методы для всех типизированных элементов
8
5
  *
9
- * @version v.2.0 (24/11/2024)
6
+ * @version v.3.0 (03/06/2026)
10
7
  */
11
- export class ApiAbstractElementClass
8
+ export class ApiAbstractElementClass extends ApiAbstractClass
12
9
  {
13
10
 
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
11
  api_prefix = 'web_api';
22
- method;
23
- headers;
24
12
 
25
13
 
26
14
  /**
27
15
  *
28
- * @version v.0.1 (27/06/2024)
16
+ * @version v.1.0 (03/06/2026)
29
17
  * @param options
30
18
  */
31
19
  constructor(options)
32
20
  {
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
-
21
+ super();
122
22
  }
123
23
 
124
24
 
@@ -314,197 +214,4 @@ export class ApiAbstractElementClass
314
214
  payload : payload
315
215
  };
316
216
  }
317
-
318
-
319
- /******************************************************************************************/
320
- /******************************************************************************************/
321
-
322
- /******************************************************************************************/
323
-
324
- handle_request_payload(payload)
325
- {
326
- return this.object_replace_null_recursively(payload);
327
- }
328
-
329
- object_replace_null_recursively(object)
330
- {
331
- let result = clone_object(object);
332
- for (let key in result)
333
- {
334
- if (result[ key ] === null)
335
- {
336
- result[ key ] = 'NULL';
337
- }
338
- else if (( result[ key ]?.constructor === Object ) || ( result[ key ]?.constructor === Array ))
339
- {
340
- result[ key ] = this.object_replace_null_recursively(result[ key ]);
341
- }
342
- }
343
-
344
- return result;
345
- }
346
-
347
-
348
- /**
349
- *
350
- * @param url
351
- * @param payload
352
- * @param method
353
- * @returns {Promise<Promise<axios.AxiosResponse<any>> | *>}
354
- * @version v.0.2 (26/01/2025)
355
- * @todo - валидация входящих параметров
356
- */
357
- async api_request(url, payload, method = 'POST')
358
- {
359
- let request_params;
360
- if (!payload)
361
- {
362
- request_params = {};
363
- }
364
- else
365
- {
366
- request_params = clone_object(payload)
367
- }
368
-
369
- request_params = this.mixin_service_params(request_params);
370
-
371
- //console.log({payload, request_params});
372
-
373
-
374
- if (this.host_api)
375
- {
376
- url = 'https://' + this.host_api + url;
377
- }
378
-
379
- let request_options = {
380
- method : method,
381
- headers: this.headers,
382
- url : url
383
- };
384
-
385
- if (this.method === 'get')
386
- {
387
- request_options.paramsSerializer = this.object_to_string;
388
- request_options.params = request_params;
389
- }
390
- else
391
- {
392
- request_options.data = (request_params);
393
- }
394
-
395
- let config = {};
396
-
397
- return axios(request_options, config);
398
- }
399
-
400
-
401
- /**
402
- *
403
- * @param object
404
- * @returns {string}
405
- * @todo - валидация входящих параметров
406
- */
407
- object_to_string(object)
408
- {
409
- let result = qs.stringify(object, { array_format: 'indices' });
410
-
411
- return result;
412
- }
413
-
414
-
415
- mixin_service_params(params)
416
- {
417
- params.client = 'webapp';
418
- return params;
419
- }
420
-
421
-
422
- /**
423
- *
424
- * @param {} response
425
- * @param {} init_class_instance
426
- * @returns {Promise<any>}
427
- * @version v.0.1 (04/03/2026)
428
- */
429
- handle_response(response, init_class_instance = true)
430
- {
431
- response = response.then((api_response) =>
432
- {
433
- let error_payload = {
434
- api_response: api_response?.data?.api_response,
435
- api_code : api_response?.data?.api_code,
436
- api_result : api_response?.data?.api_result,
437
- api_error : api_response?.data?.api_error
438
- };
439
-
440
- if (api_response?.data?.api_error?.adapted_message)
441
- {
442
- error_payload.message = api_response.data.api_error.adapted_message
443
- throw new ApiException(error_payload);
444
- }
445
- else if (api_response?.data?.api_code)
446
- {
447
- let api_code = api_response.data.api_code;
448
-
449
- if (( api_code >= 200 ) && ( api_code <= 299 ))
450
- {
451
- if (is_array(api_response?.data?.api_result) && this.element_class_instance)
452
- {
453
- let result = api_response?.data.api_result.map((row) =>
454
- {
455
- if (init_class_instance)
456
- {
457
- return new this.element_class_instance(row);
458
- }
459
- else
460
- {
461
- return row;
462
- }
463
- });
464
-
465
- return result;
466
- }
467
- else if (is_object(api_response?.data?.api_result))
468
- {
469
- return api_response?.data?.api_result;
470
- }
471
- else if (api_response?.data?.api_result === false)
472
- {
473
- return api_response?.data?.api_result;
474
- }
475
- else
476
- {
477
- return api_response?.data;
478
- }
479
- }
480
- else if (api_response?.data?.api_result === false)
481
- {
482
- throw new ApiException(error_payload);
483
- }
484
- else
485
- {
486
- throw new ApiException(error_payload);
487
- }
488
- }
489
- else
490
- {
491
- return api_response?.data;
492
- }
493
- })
494
- .catch((error) =>
495
- {
496
-
497
- echo({ app: this });
498
- console.error(error);
499
- if (error instanceof ApiException)
500
- {
501
- throw error;
502
- }
503
-
504
-
505
- throw new ApiException({ error: error });
506
- });
507
-
508
- return response;
509
- }
510
217
  }
@@ -0,0 +1,56 @@
1
+ import { ApiAbstractClass } from "./api_abstract_class.js";
2
+
3
+ /**
4
+ *
5
+ * @version v.1.0 (03/06/2026)
6
+ */
7
+ export class ApiAbstractReferenceClass extends ApiAbstractClass
8
+ {
9
+
10
+ api_prefix = 'api';
11
+
12
+ /**
13
+ *
14
+ * @version v.1.0 (03/06/2026)
15
+ * @param options
16
+ */
17
+ constructor(options)
18
+ {
19
+ super();
20
+ }
21
+
22
+
23
+ /**
24
+ * Немного другой роутинг
25
+ *
26
+ * @version v.0.1 (04/06/2026)
27
+ *
28
+ * @param {object|typeFOR} payload
29
+ * @param {array} payload.filter
30
+ * @param {?object|undefined} payload.object
31
+ * @param {?object|undefined} payload.response
32
+ */
33
+ async search(payload = {})
34
+ {
35
+ if (!this.module_prefix)
36
+ {
37
+ throw new Error('Error #34-1152 in ApiAbstractClass');
38
+ }
39
+
40
+ if (!payload?.filter)
41
+ {
42
+ payload.filter = [];
43
+ }
44
+
45
+ let url = `/${ this.api_prefix }/reference/${ this.module_prefix }/search`;
46
+
47
+ payload = this.handle_request_payload(payload);
48
+ let response = this.api_request(url, payload);
49
+ response = this.handle_response(response);
50
+
51
+ return {
52
+ response: response,
53
+ payload : payload
54
+ };
55
+ }
56
+ }