@hosterai/types 0.0.30 → 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/decorators/is-e164-validator.spec.d.ts +1 -0
- package/dist/decorators/is-e164-validator.spec.js +64 -0
- package/dist/decorators/is-e164.validator.d.ts +2 -0
- package/dist/decorators/is-e164.validator.js +30 -0
- package/dist/decorators/unique-field-in-array-validator.spec.js +14 -0
- package/dist/decorators/unique-field-in-array.validator.js +18 -4
- package/dist/dtos/addon-field.dto.d.ts +6 -2
- package/dist/dtos/addon-field.dto.js +25 -2
- package/dist/dtos/attribute-field.dto.d.ts +18 -6
- package/dist/dtos/attribute-field.dto.js +18 -2
- package/dist/dtos/base-field.dto.d.ts +45 -0
- package/dist/dtos/base-field.dto.js +133 -0
- package/dist/dtos/field.dto.d.ts +5 -64
- package/dist/dtos/field.dto.js +0 -186
- package/dist/dtos/fields/any-field.dto.d.ts +38 -0
- package/dist/dtos/fields/any-field.dto.js +36 -0
- package/dist/dtos/fields/boolean-field.dto.d.ts +14 -0
- package/dist/dtos/fields/boolean-field.dto.js +48 -0
- package/dist/dtos/fields/countries-field.dto.d.ts +14 -0
- package/dist/dtos/fields/countries-field.dto.js +51 -0
- package/dist/dtos/fields/currency-field.dto.d.ts +14 -0
- package/dist/dtos/fields/currency-field.dto.js +50 -0
- package/dist/dtos/fields/date-field.dto.d.ts +14 -0
- package/dist/dtos/fields/date-field.dto.js +49 -0
- package/dist/dtos/fields/email-field.dto.d.ts +14 -0
- package/dist/dtos/fields/email-field.dto.js +49 -0
- package/dist/dtos/fields/multi-select-field.dto.d.ts +15 -0
- package/dist/dtos/fields/multi-select-field.dto.js +53 -0
- package/dist/dtos/fields/number-field.dto.d.ts +26 -0
- package/dist/dtos/fields/number-field.dto.js +82 -0
- package/dist/dtos/fields/password-field.dto.d.ts +21 -0
- package/dist/dtos/fields/password-field.dto.js +64 -0
- package/dist/dtos/fields/phone-field.dto.d.ts +14 -0
- package/dist/dtos/fields/phone-field.dto.js +50 -0
- package/dist/dtos/fields/select-field.dto.d.ts +15 -0
- package/dist/dtos/fields/select-field.dto.js +51 -0
- package/dist/dtos/fields/text-field.dto.d.ts +31 -0
- package/dist/dtos/fields/text-field.dto.js +102 -0
- package/dist/dtos/fields/textarea-field.dto.d.ts +31 -0
- package/dist/dtos/fields/textarea-field.dto.js +102 -0
- package/dist/dtos/fields/url-field.dto.d.ts +14 -0
- package/dist/dtos/fields/url-field.dto.js +49 -0
- package/dist/dtos/info/info-notification.dto.d.ts +5 -0
- package/dist/dtos/info/info-notification.dto.js +7 -0
- package/dist/dtos/info/info.dto.d.ts +196 -0
- package/dist/dtos/info/info.dto.js +278 -0
- package/dist/dtos/info.dto.d.ts +2 -2
- package/dist/dtos/info.dto.js +2 -5
- package/dist/dtos/notification/notification-request.dto.d.ts +20 -0
- package/dist/dtos/notification/notification-request.dto.js +31 -0
- package/dist/dtos/product/product-info.dto.js +2 -2
- package/dist/dtos/receiver/receiver-email.dto.d.ts +20 -0
- package/dist/dtos/receiver/receiver-email.dto.js +39 -0
- package/dist/dtos/receiver/receiver-push.dto.d.ts +15 -0
- package/dist/dtos/receiver/receiver-push.dto.js +31 -0
- package/dist/dtos/receiver/receiver-sms.dto.d.ts +11 -0
- package/dist/dtos/receiver/receiver-sms.dto.js +26 -0
- package/dist/dtos/request.dto.d.ts +20 -0
- package/dist/dtos/request.dto.js +31 -0
- package/dist/dtos/responses/validate-attributes-response.dto.d.ts +4 -4
- package/dist/dtos/responses/validate-attributes-response.dto.js +2 -6
- package/dist/dtos/sender/sender-email.dto.d.ts +25 -0
- package/dist/dtos/sender/sender-email.dto.js +46 -0
- package/dist/dtos/sender/sender-push.dto.d.ts +31 -0
- package/dist/dtos/sender/sender-push.dto.js +50 -0
- package/dist/dtos/sender/sender-sms.dto.d.ts +15 -0
- package/dist/dtos/sender/sender-sms.dto.js +30 -0
- package/dist/enums/field-type.enum.d.ts +20 -7
- package/dist/enums/field-type.enum.js +19 -7
- package/dist/enums/message-type.enum.d.ts +5 -0
- package/dist/enums/message-type.enum.js +9 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +29 -0
- package/dist/openapi/schemas/components.schemas.d.ts +1168 -235
- package/dist/openapi/schemas/components.schemas.js +1869 -558
- package/dist/validators/addon-field-validator.d.ts +4 -1
- package/dist/validators/addon-field-validator.js +22 -3
- package/dist/validators/addon-field-validator.spec.js +15 -21
- package/dist/validators/any-field-validator.d.ts +10 -0
- package/dist/validators/any-field-validator.js +28 -0
- package/dist/validators/any-field-validator.spec.d.ts +1 -0
- package/dist/validators/any-field-validator.spec.js +37 -0
- package/dist/validators/attribute-field-validator.d.ts +4 -0
- package/dist/validators/attribute-field-validator.js +16 -0
- package/dist/validators/attribute-field-validator.spec.js +30 -20
- package/dist/validators/field-validator.d.ts +2 -4
- package/dist/validators/field-validator.js +4 -10
- package/dist/validators/field-validator.spec.js +16 -79
- package/dist/validators/fields/boolean-field-validator.d.ts +8 -0
- package/dist/validators/fields/boolean-field-validator.js +15 -0
- package/dist/validators/fields/boolean-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/boolean-field-validator.spec.js +43 -0
- package/dist/validators/fields/countries-field-validator.d.ts +8 -0
- package/dist/validators/fields/countries-field-validator.js +15 -0
- package/dist/validators/fields/countries-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/countries-field-validator.spec.js +44 -0
- package/dist/validators/fields/currency-field-validator.d.ts +8 -0
- package/dist/validators/fields/currency-field-validator.js +15 -0
- package/dist/validators/fields/currency-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/currency-field-validator.spec.js +41 -0
- package/dist/validators/fields/date-field-validator.d.ts +8 -0
- package/dist/validators/fields/date-field-validator.js +15 -0
- package/dist/validators/fields/date-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/date-field-validator.spec.js +43 -0
- package/dist/validators/fields/email-field-validator.d.ts +8 -0
- package/dist/validators/fields/email-field-validator.js +15 -0
- package/dist/validators/fields/email-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/email-field-validator.spec.js +43 -0
- package/dist/validators/fields/multi-select-field-validator.d.ts +8 -0
- package/dist/validators/fields/multi-select-field-validator.js +15 -0
- package/dist/validators/fields/multi-select-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/multi-select-field-validator.spec.js +52 -0
- package/dist/validators/fields/number-field-validator.d.ts +8 -0
- package/dist/validators/fields/number-field-validator.js +15 -0
- package/dist/validators/fields/number-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/number-field-validator.spec.js +59 -0
- package/dist/validators/fields/password-field-validator.d.ts +8 -0
- package/dist/validators/fields/password-field-validator.js +15 -0
- package/dist/validators/fields/password-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/password-field-validator.spec.js +44 -0
- package/dist/validators/fields/phone-field-validator.d.ts +8 -0
- package/dist/validators/fields/phone-field-validator.js +15 -0
- package/dist/validators/fields/phone-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/phone-field-validator.spec.js +41 -0
- package/dist/validators/fields/select-field-validator.d.ts +8 -0
- package/dist/validators/fields/select-field-validator.js +15 -0
- package/dist/validators/fields/select-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/select-field-validator.spec.js +46 -0
- package/dist/validators/fields/text-field-validator.d.ts +8 -0
- package/dist/validators/fields/text-field-validator.js +15 -0
- package/dist/validators/fields/text-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/text-field-validator.spec.js +60 -0
- package/dist/validators/fields/textarea-field-validator.d.ts +8 -0
- package/dist/validators/fields/textarea-field-validator.js +15 -0
- package/dist/validators/fields/textarea-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/textarea-field-validator.spec.js +52 -0
- package/dist/validators/fields/url-field-validator.d.ts +8 -0
- package/dist/validators/fields/url-field-validator.js +15 -0
- package/dist/validators/fields/url-field-validator.spec.d.ts +1 -0
- package/dist/validators/fields/url-field-validator.spec.js +43 -0
- package/dist/validators/product-info-validator.spec.js +42 -108
- package/package.json +1 -1
- package/dist/dtos/product/requests/product-downgradeable-request.dto.d.ts +0 -18
- package/dist/dtos/product/requests/product-downgradeable-request.dto.js +0 -37
- package/dist/dtos/product/requests/product-upgradeable-request.dto.d.ts +0 -18
- package/dist/dtos/product/requests/product-upgradeable-request.dto.js +0 -37
- package/dist/dtos/product/responses/product-downgradeable-response.dto.d.ts +0 -22
- package/dist/dtos/product/responses/product-downgradeable-response.dto.js +0 -11
- package/dist/dtos/product/responses/product-upgradeable-response.dto.d.ts +0 -22
- package/dist/dtos/product/responses/product-upgradeable-response.dto.js +0 -11
- package/dist/validators/product-downgradeable-request-validator.d.ts +0 -8
- package/dist/validators/product-downgradeable-request-validator.js +0 -17
- package/dist/validators/product-upgradeable-request-validator.d.ts +0 -8
- package/dist/validators/product-upgradeable-request-validator.js +0 -17
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("reflect-metadata");
|
|
4
|
+
const text_field_validator_1 = require("./text-field-validator");
|
|
5
|
+
const language_enum_1 = require("../../enums/language.enum");
|
|
6
|
+
const baseValidDto = {
|
|
7
|
+
id: 'text-1',
|
|
8
|
+
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'Username' }],
|
|
9
|
+
type: 'TEXT',
|
|
10
|
+
required: true,
|
|
11
|
+
disabled: false,
|
|
12
|
+
};
|
|
13
|
+
describe('TextFieldDto Validator', () => {
|
|
14
|
+
describe('Valid cases', () => {
|
|
15
|
+
it('should return no errors for a valid minimal DTO', () => {
|
|
16
|
+
expect((0, text_field_validator_1.validateTextFieldDto)(baseValidDto)).toHaveLength(0);
|
|
17
|
+
});
|
|
18
|
+
it('should return no errors with optional value, min/max length and regex', () => {
|
|
19
|
+
const dto = {
|
|
20
|
+
...baseValidDto,
|
|
21
|
+
value: 'abc',
|
|
22
|
+
minLength: 1,
|
|
23
|
+
maxLength: 10,
|
|
24
|
+
regexValidation: '^[a-z]+$',
|
|
25
|
+
regexValidationErrorMessage: [
|
|
26
|
+
{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'Lowercase only' },
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
expect((0, text_field_validator_1.validateTextFieldDto)(dto)).toHaveLength(0);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('Missing required fields', () => {
|
|
33
|
+
it('should return errors for all missing required fields', () => {
|
|
34
|
+
const errors = (0, text_field_validator_1.validateTextFieldDto)({});
|
|
35
|
+
for (const prop of ['id', 'label', 'required', 'disabled']) {
|
|
36
|
+
expect(errors.some((e) => e.property === prop)).toBe(true);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('Invalid field values', () => {
|
|
41
|
+
it.each([
|
|
42
|
+
[{ ...baseValidDto, type: 'TEXTAREA' }, 'type'],
|
|
43
|
+
[{ ...baseValidDto, value: 123 }, 'value'],
|
|
44
|
+
[{ ...baseValidDto, minLength: -1 }, 'minLength'],
|
|
45
|
+
[{ ...baseValidDto, maxLength: 'ten' }, 'maxLength'],
|
|
46
|
+
[{ ...baseValidDto, regexValidation: '[' }, 'regexValidation'],
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
...baseValidDto,
|
|
50
|
+
regexValidation: '^x$',
|
|
51
|
+
regexValidationErrorMessage: 'not-an-array',
|
|
52
|
+
},
|
|
53
|
+
'regexValidationErrorMessage',
|
|
54
|
+
],
|
|
55
|
+
])('should return error for invalid %#', (dto, expectedProp) => {
|
|
56
|
+
const errors = (0, text_field_validator_1.validateTextFieldDto)(dto);
|
|
57
|
+
expect(errors.some((e) => e.property === expectedProp)).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ValidationError } from 'class-validator';
|
|
2
|
+
/**
|
|
3
|
+
* Validates a TextareaFieldDto object using class-validator decorators.
|
|
4
|
+
*
|
|
5
|
+
* @param data The object to validate as a TextareaFieldDto.
|
|
6
|
+
* @returns An array of validation errors, empty if validation succeeds.
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateTextareaFieldDto(data: object): ValidationError[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateTextareaFieldDto = validateTextareaFieldDto;
|
|
4
|
+
const class_validator_1 = require("class-validator");
|
|
5
|
+
const class_transformer_1 = require("class-transformer");
|
|
6
|
+
const textarea_field_dto_1 = require("../../dtos/fields/textarea-field.dto");
|
|
7
|
+
/**
|
|
8
|
+
* Validates a TextareaFieldDto object using class-validator decorators.
|
|
9
|
+
*
|
|
10
|
+
* @param data The object to validate as a TextareaFieldDto.
|
|
11
|
+
* @returns An array of validation errors, empty if validation succeeds.
|
|
12
|
+
*/
|
|
13
|
+
function validateTextareaFieldDto(data) {
|
|
14
|
+
return (0, class_validator_1.validateSync)((0, class_transformer_1.plainToInstance)(textarea_field_dto_1.TextareaFieldDto, data));
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("reflect-metadata");
|
|
4
|
+
const textarea_field_validator_1 = require("./textarea-field-validator");
|
|
5
|
+
const language_enum_1 = require("../../enums/language.enum");
|
|
6
|
+
const baseValidDto = {
|
|
7
|
+
id: 'ta-1',
|
|
8
|
+
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'Description' }],
|
|
9
|
+
type: 'TEXTAREA',
|
|
10
|
+
required: true,
|
|
11
|
+
disabled: false,
|
|
12
|
+
};
|
|
13
|
+
describe('TextareaFieldDto Validator', () => {
|
|
14
|
+
describe('Valid cases', () => {
|
|
15
|
+
it('should return no errors for a valid minimal DTO', () => {
|
|
16
|
+
expect((0, textarea_field_validator_1.validateTextareaFieldDto)(baseValidDto)).toHaveLength(0);
|
|
17
|
+
});
|
|
18
|
+
it('should return no errors with optional value and regex', () => {
|
|
19
|
+
expect((0, textarea_field_validator_1.validateTextareaFieldDto)({
|
|
20
|
+
...baseValidDto,
|
|
21
|
+
value: 'Hello world',
|
|
22
|
+
minLength: 1,
|
|
23
|
+
maxLength: 1000,
|
|
24
|
+
regexValidation: '^.+$',
|
|
25
|
+
regexValidationErrorMessage: [
|
|
26
|
+
{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'Must not be empty' },
|
|
27
|
+
],
|
|
28
|
+
})).toHaveLength(0);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe('Missing required fields', () => {
|
|
32
|
+
it('should return errors for all missing required fields', () => {
|
|
33
|
+
const errors = (0, textarea_field_validator_1.validateTextareaFieldDto)({});
|
|
34
|
+
for (const prop of ['id', 'label', 'required', 'disabled']) {
|
|
35
|
+
expect(errors.some((e) => e.property === prop)).toBe(true);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('Invalid field values', () => {
|
|
40
|
+
it('should return error for wrong type literal', () => {
|
|
41
|
+
const errors = (0, textarea_field_validator_1.validateTextareaFieldDto)({
|
|
42
|
+
...baseValidDto,
|
|
43
|
+
type: 'TEXT',
|
|
44
|
+
});
|
|
45
|
+
expect(errors.some((e) => e.property === 'type')).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
it('should return error for non-string value', () => {
|
|
48
|
+
const errors = (0, textarea_field_validator_1.validateTextareaFieldDto)({ ...baseValidDto, value: 42 });
|
|
49
|
+
expect(errors.some((e) => e.property === 'value')).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ValidationError } from 'class-validator';
|
|
2
|
+
/**
|
|
3
|
+
* Validates a UrlFieldDto object using class-validator decorators.
|
|
4
|
+
*
|
|
5
|
+
* @param data The object to validate as a UrlFieldDto.
|
|
6
|
+
* @returns An array of validation errors, empty if validation succeeds.
|
|
7
|
+
*/
|
|
8
|
+
export declare function validateUrlFieldDto(data: object): ValidationError[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateUrlFieldDto = validateUrlFieldDto;
|
|
4
|
+
const class_validator_1 = require("class-validator");
|
|
5
|
+
const class_transformer_1 = require("class-transformer");
|
|
6
|
+
const url_field_dto_1 = require("../../dtos/fields/url-field.dto");
|
|
7
|
+
/**
|
|
8
|
+
* Validates a UrlFieldDto object using class-validator decorators.
|
|
9
|
+
*
|
|
10
|
+
* @param data The object to validate as a UrlFieldDto.
|
|
11
|
+
* @returns An array of validation errors, empty if validation succeeds.
|
|
12
|
+
*/
|
|
13
|
+
function validateUrlFieldDto(data) {
|
|
14
|
+
return (0, class_validator_1.validateSync)((0, class_transformer_1.plainToInstance)(url_field_dto_1.UrlFieldDto, data));
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
require("reflect-metadata");
|
|
4
|
+
const url_field_validator_1 = require("./url-field-validator");
|
|
5
|
+
const language_enum_1 = require("../../enums/language.enum");
|
|
6
|
+
const baseValidDto = {
|
|
7
|
+
id: 'url-1',
|
|
8
|
+
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'Website' }],
|
|
9
|
+
type: 'URL',
|
|
10
|
+
required: true,
|
|
11
|
+
disabled: false,
|
|
12
|
+
};
|
|
13
|
+
describe('UrlFieldDto Validator', () => {
|
|
14
|
+
describe('Valid cases', () => {
|
|
15
|
+
it('should return no errors for a valid minimal DTO', () => {
|
|
16
|
+
expect((0, url_field_validator_1.validateUrlFieldDto)(baseValidDto)).toHaveLength(0);
|
|
17
|
+
});
|
|
18
|
+
it('should return no errors with a valid URL value', () => {
|
|
19
|
+
expect((0, url_field_validator_1.validateUrlFieldDto)({
|
|
20
|
+
...baseValidDto,
|
|
21
|
+
value: 'https://example.com',
|
|
22
|
+
})).toHaveLength(0);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('Missing required fields', () => {
|
|
26
|
+
it('should return errors for all missing required fields', () => {
|
|
27
|
+
const errors = (0, url_field_validator_1.validateUrlFieldDto)({});
|
|
28
|
+
for (const prop of ['id', 'label', 'required', 'disabled']) {
|
|
29
|
+
expect(errors.some((e) => e.property === prop)).toBe(true);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('Invalid field values', () => {
|
|
34
|
+
it.each([
|
|
35
|
+
[{ ...baseValidDto, type: 'TEXT' }, 'type'],
|
|
36
|
+
[{ ...baseValidDto, value: 'not a url' }, 'value'],
|
|
37
|
+
[{ ...baseValidDto, value: 42 }, 'value'],
|
|
38
|
+
])('should return error for invalid %#', (dto, expectedProp) => {
|
|
39
|
+
const errors = (0, url_field_validator_1.validateUrlFieldDto)(dto);
|
|
40
|
+
expect(errors.some((e) => e.property === expectedProp)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
require("reflect-metadata");
|
|
4
|
-
// import { ProductInfoDto } from '../dtos/product/product-info.dto';
|
|
5
4
|
const item_actions_enum_1 = require("../enums/item-actions.enum");
|
|
6
5
|
const language_enum_1 = require("../enums/language.enum");
|
|
7
|
-
const field_type_enum_1 = require("../enums/field-type.enum");
|
|
8
6
|
const product_info_validator_1 = require("./product-info.validator");
|
|
9
7
|
describe('ProductInfoDto Validator', () => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
const validField = {
|
|
9
|
+
field: {
|
|
10
|
+
id: 'field',
|
|
11
|
+
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'label' }],
|
|
12
|
+
type: 'TEXT',
|
|
13
|
+
required: false,
|
|
14
|
+
disabled: false,
|
|
15
|
+
hidden: false,
|
|
16
|
+
upgradable: false,
|
|
17
|
+
value: 'string',
|
|
18
|
+
},
|
|
19
19
|
};
|
|
20
20
|
const invalidField = {
|
|
21
|
-
|
|
22
|
-
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'label' }],
|
|
23
|
-
value: 'string',
|
|
24
|
-
type: field_type_enum_1.FieldTypeEnum.TEXT_BOX,
|
|
25
|
-
disabled: false,
|
|
26
|
-
upgradable: false,
|
|
21
|
+
// missing required field, so `field` is undefined
|
|
27
22
|
};
|
|
28
23
|
const testCases = [
|
|
29
24
|
{
|
|
@@ -32,13 +27,13 @@ describe('ProductInfoDto Validator', () => {
|
|
|
32
27
|
title: 'Test',
|
|
33
28
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
34
29
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
35
|
-
productAttributes: [
|
|
36
|
-
itemAttributes: [
|
|
30
|
+
productAttributes: [validField],
|
|
31
|
+
itemAttributes: [validField],
|
|
37
32
|
},
|
|
38
33
|
expectedErrorsLength: 0,
|
|
39
34
|
},
|
|
40
35
|
{
|
|
41
|
-
description: 'should return error for
|
|
36
|
+
description: 'should return error for missing field in attribute',
|
|
42
37
|
dto: {
|
|
43
38
|
title: 'Test',
|
|
44
39
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
@@ -53,8 +48,8 @@ describe('ProductInfoDto Validator', () => {
|
|
|
53
48
|
title: '',
|
|
54
49
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
55
50
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
56
|
-
productAttributes: [
|
|
57
|
-
itemAttributes: [
|
|
51
|
+
productAttributes: [validField],
|
|
52
|
+
itemAttributes: [validField],
|
|
58
53
|
},
|
|
59
54
|
expectedErrorsLength: 1,
|
|
60
55
|
},
|
|
@@ -64,8 +59,8 @@ describe('ProductInfoDto Validator', () => {
|
|
|
64
59
|
title: 'Test',
|
|
65
60
|
supportedActions: ['update'],
|
|
66
61
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
67
|
-
productAttributes: [
|
|
68
|
-
itemAttributes: [
|
|
62
|
+
productAttributes: [validField],
|
|
63
|
+
itemAttributes: [validField],
|
|
69
64
|
},
|
|
70
65
|
expectedErrorsLength: 1,
|
|
71
66
|
},
|
|
@@ -75,8 +70,8 @@ describe('ProductInfoDto Validator', () => {
|
|
|
75
70
|
title: 'Test',
|
|
76
71
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
77
72
|
supportedLanguages: [],
|
|
78
|
-
productAttributes: [
|
|
79
|
-
itemAttributes: [
|
|
73
|
+
productAttributes: [validField],
|
|
74
|
+
itemAttributes: [validField],
|
|
80
75
|
},
|
|
81
76
|
expectedErrorsLength: 1,
|
|
82
77
|
},
|
|
@@ -86,8 +81,8 @@ describe('ProductInfoDto Validator', () => {
|
|
|
86
81
|
title: 'Test',
|
|
87
82
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
88
83
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
89
|
-
productAttributes: [
|
|
90
|
-
itemAttributes: [
|
|
84
|
+
productAttributes: [validField],
|
|
85
|
+
itemAttributes: [validField],
|
|
91
86
|
adminPanel: {
|
|
92
87
|
tabs: {
|
|
93
88
|
product: [{ label: 'Product', url: 'https://example.com/product' }],
|
|
@@ -105,14 +100,10 @@ describe('ProductInfoDto Validator', () => {
|
|
|
105
100
|
title: '',
|
|
106
101
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
107
102
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
108
|
-
productAttributes: [
|
|
109
|
-
itemAttributes: [
|
|
110
|
-
adminPanel: {
|
|
111
|
-
|
|
112
|
-
},
|
|
113
|
-
clientPanel: {
|
|
114
|
-
/* invalid client panel data */
|
|
115
|
-
},
|
|
103
|
+
productAttributes: [validField],
|
|
104
|
+
itemAttributes: [validField],
|
|
105
|
+
adminPanel: {},
|
|
106
|
+
clientPanel: {},
|
|
116
107
|
},
|
|
117
108
|
expectedErrorsLength: 3,
|
|
118
109
|
},
|
|
@@ -122,8 +113,8 @@ describe('ProductInfoDto Validator', () => {
|
|
|
122
113
|
title: 'Test',
|
|
123
114
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
124
115
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
125
|
-
productAttributes: [
|
|
126
|
-
itemAttributes: [
|
|
116
|
+
productAttributes: [validField],
|
|
117
|
+
itemAttributes: [validField],
|
|
127
118
|
payPerUseUnits: [
|
|
128
119
|
{ id: 'ram', unitDescription: 'MB', intervalDescription: 'month' },
|
|
129
120
|
],
|
|
@@ -136,8 +127,8 @@ describe('ProductInfoDto Validator', () => {
|
|
|
136
127
|
title: 'Test',
|
|
137
128
|
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
138
129
|
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
139
|
-
productAttributes: [
|
|
140
|
-
itemAttributes: [
|
|
130
|
+
productAttributes: [validField],
|
|
131
|
+
itemAttributes: [validField],
|
|
141
132
|
payPerUseUnits: [
|
|
142
133
|
{ id: '', unitDescription: '', intervalDescription: '' },
|
|
143
134
|
],
|
|
@@ -151,49 +142,10 @@ describe('ProductInfoDto Validator', () => {
|
|
|
151
142
|
expect(errors.length).toBe(expectedErrorsLength);
|
|
152
143
|
});
|
|
153
144
|
});
|
|
154
|
-
|
|
155
|
-
{
|
|
156
|
-
description: 'should return ValidationError for missing title',
|
|
157
|
-
dto: {
|
|
158
|
-
supportedActions: [item_actions_enum_1.ProductActionsEnum.CREATE],
|
|
159
|
-
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
160
|
-
productAttributes: [field],
|
|
161
|
-
itemAttributes: [field],
|
|
162
|
-
},
|
|
163
|
-
expectedErrors: ['title'],
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
description: 'should return ValidationError for unsupported action',
|
|
167
|
-
dto: {
|
|
168
|
-
title: 'Test',
|
|
169
|
-
supportedActions: ['update'],
|
|
170
|
-
supportedLanguages: [language_enum_1.LanguageEnum.ENGLISH],
|
|
171
|
-
productAttributes: [field],
|
|
172
|
-
itemAttributes: [field],
|
|
173
|
-
},
|
|
174
|
-
expectedErrors: ['supportedActions'],
|
|
175
|
-
},
|
|
176
|
-
];
|
|
177
|
-
validationErrorTestCases.forEach(({ description, dto, expectedErrors }) => {
|
|
178
|
-
it(description, async () => {
|
|
179
|
-
const errors = await (0, product_info_validator_1.validateProductInfoDto)(dto);
|
|
180
|
-
const errorProperties = errors.map((error) => error.property);
|
|
181
|
-
expectedErrors.forEach((expectedError) => {
|
|
182
|
-
expect(errorProperties).toContain(expectedError);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
describe('FieldDto class-level constraints inside ProductInfoDto', () => {
|
|
187
|
-
it('fails when a FieldDto has only repeatableMin (AllOrNone)', () => {
|
|
145
|
+
describe('AttributeFieldDto class-level constraints inside ProductInfoDto', () => {
|
|
146
|
+
it('fails when an AttributeFieldDto has only repeatableMin (AllOrNone)', () => {
|
|
188
147
|
const fieldWithOnlyMin = {
|
|
189
|
-
|
|
190
|
-
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'label' }],
|
|
191
|
-
value: 'v',
|
|
192
|
-
type: field_type_enum_1.FieldTypeEnum.TEXT_BOX,
|
|
193
|
-
required: false,
|
|
194
|
-
disabled: false,
|
|
195
|
-
hidden: false,
|
|
196
|
-
upgradable: false,
|
|
148
|
+
...validField,
|
|
197
149
|
repeatableMin: 1,
|
|
198
150
|
};
|
|
199
151
|
const dto = {
|
|
@@ -205,16 +157,9 @@ describe('ProductInfoDto Validator', () => {
|
|
|
205
157
|
const errors = (0, product_info_validator_1.validateProductInfoDto)(dto);
|
|
206
158
|
expect(errors.length).toBeGreaterThan(0);
|
|
207
159
|
});
|
|
208
|
-
it('fails when
|
|
160
|
+
it('fails when an AttributeFieldDto has only repeatableMax (AllOrNone)', () => {
|
|
209
161
|
const fieldWithOnlyMax = {
|
|
210
|
-
|
|
211
|
-
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'label' }],
|
|
212
|
-
value: 'v',
|
|
213
|
-
type: field_type_enum_1.FieldTypeEnum.TEXT_BOX,
|
|
214
|
-
required: false,
|
|
215
|
-
disabled: false,
|
|
216
|
-
upgradable: false,
|
|
217
|
-
hidden: false,
|
|
162
|
+
...validField,
|
|
218
163
|
repeatableMax: 5,
|
|
219
164
|
};
|
|
220
165
|
const dto = {
|
|
@@ -226,15 +171,11 @@ describe('ProductInfoDto Validator', () => {
|
|
|
226
171
|
const errors = (0, product_info_validator_1.validateProductInfoDto)(dto);
|
|
227
172
|
expect(errors.length).toBeGreaterThan(0);
|
|
228
173
|
});
|
|
229
|
-
it('passes when
|
|
174
|
+
it('passes when an AttributeFieldDto has both min and max with min <= max', () => {
|
|
230
175
|
const fieldOk = {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
type: field_type_enum_1.FieldTypeEnum.TEXT_BOX,
|
|
235
|
-
required: false,
|
|
236
|
-
disabled: false,
|
|
237
|
-
hidden: false,
|
|
176
|
+
...validField,
|
|
177
|
+
repeatableMin: 1,
|
|
178
|
+
repeatableMax: 3,
|
|
238
179
|
};
|
|
239
180
|
const dto = {
|
|
240
181
|
title: 'Test',
|
|
@@ -244,16 +185,9 @@ describe('ProductInfoDto Validator', () => {
|
|
|
244
185
|
};
|
|
245
186
|
expect((0, product_info_validator_1.validateProductInfoDto)(dto)).toHaveLength(0);
|
|
246
187
|
});
|
|
247
|
-
it('fails when
|
|
188
|
+
it('fails when an AttributeFieldDto has min > max (Min<=Max)', () => {
|
|
248
189
|
const fieldBad = {
|
|
249
|
-
|
|
250
|
-
label: [{ language: language_enum_1.LanguageEnum.ENGLISH, text: 'label' }],
|
|
251
|
-
value: 'v',
|
|
252
|
-
type: field_type_enum_1.FieldTypeEnum.TEXT_BOX,
|
|
253
|
-
required: false,
|
|
254
|
-
disabled: false,
|
|
255
|
-
hidden: false,
|
|
256
|
-
upgradable: false,
|
|
190
|
+
...validField,
|
|
257
191
|
repeatableMin: 5,
|
|
258
192
|
repeatableMax: 2,
|
|
259
193
|
};
|
package/package.json
CHANGED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { ProductItemDataDto } from '../product-item-data.dto';
|
|
2
|
-
import { ClientDataDto } from '../../client-data.dto';
|
|
3
|
-
/**
|
|
4
|
-
* Represents a request to check if a product item is downgradable.
|
|
5
|
-
* This DTO contains all the necessary information for the check.
|
|
6
|
-
*/
|
|
7
|
-
export declare class ProductDowngradableRequestDto {
|
|
8
|
-
/**
|
|
9
|
-
* The client's data.
|
|
10
|
-
* This object holds all the relevant information about the client initiating the request.
|
|
11
|
-
*/
|
|
12
|
-
clientData: ClientDataDto;
|
|
13
|
-
/**
|
|
14
|
-
* The data of the product item to be checked.
|
|
15
|
-
* This object contains the specific details of the product instance being evaluated.
|
|
16
|
-
*/
|
|
17
|
-
itemData: ProductItemDataDto;
|
|
18
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ProductDowngradableRequestDto = void 0;
|
|
13
|
-
const class_validator_1 = require("class-validator");
|
|
14
|
-
const class_transformer_1 = require("class-transformer");
|
|
15
|
-
const product_item_data_dto_1 = require("../product-item-data.dto");
|
|
16
|
-
const client_data_dto_1 = require("../../client-data.dto");
|
|
17
|
-
/**
|
|
18
|
-
* Represents a request to check if a product item is downgradable.
|
|
19
|
-
* This DTO contains all the necessary information for the check.
|
|
20
|
-
*/
|
|
21
|
-
class ProductDowngradableRequestDto {
|
|
22
|
-
}
|
|
23
|
-
exports.ProductDowngradableRequestDto = ProductDowngradableRequestDto;
|
|
24
|
-
__decorate([
|
|
25
|
-
(0, class_validator_1.IsDefined)(),
|
|
26
|
-
(0, class_validator_1.IsObject)(),
|
|
27
|
-
(0, class_validator_1.ValidateNested)(),
|
|
28
|
-
(0, class_transformer_1.Type)(() => client_data_dto_1.ClientDataDto),
|
|
29
|
-
__metadata("design:type", client_data_dto_1.ClientDataDto)
|
|
30
|
-
], ProductDowngradableRequestDto.prototype, "clientData", void 0);
|
|
31
|
-
__decorate([
|
|
32
|
-
(0, class_validator_1.IsDefined)(),
|
|
33
|
-
(0, class_validator_1.IsObject)(),
|
|
34
|
-
(0, class_validator_1.ValidateNested)(),
|
|
35
|
-
(0, class_transformer_1.Type)(() => product_item_data_dto_1.ProductItemDataDto),
|
|
36
|
-
__metadata("design:type", product_item_data_dto_1.ProductItemDataDto)
|
|
37
|
-
], ProductDowngradableRequestDto.prototype, "itemData", void 0);
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { ProductItemDataDto } from '../product-item-data.dto';
|
|
2
|
-
import { ClientDataDto } from '../../client-data.dto';
|
|
3
|
-
/**
|
|
4
|
-
* Represents a request to check if a product item is upgradeable.
|
|
5
|
-
* This DTO contains all the necessary information for the check.
|
|
6
|
-
*/
|
|
7
|
-
export declare class ProductUpgradeableRequestDto {
|
|
8
|
-
/**
|
|
9
|
-
* The client's data.
|
|
10
|
-
* This object holds all the relevant information about the client initiating the request.
|
|
11
|
-
*/
|
|
12
|
-
clientData: ClientDataDto;
|
|
13
|
-
/**
|
|
14
|
-
* The data of the product item to be checked.
|
|
15
|
-
* This object contains the specific details of the product instance being evaluated.
|
|
16
|
-
*/
|
|
17
|
-
itemData: ProductItemDataDto;
|
|
18
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ProductUpgradeableRequestDto = void 0;
|
|
13
|
-
const class_validator_1 = require("class-validator");
|
|
14
|
-
const class_transformer_1 = require("class-transformer");
|
|
15
|
-
const product_item_data_dto_1 = require("../product-item-data.dto");
|
|
16
|
-
const client_data_dto_1 = require("../../client-data.dto");
|
|
17
|
-
/**
|
|
18
|
-
* Represents a request to check if a product item is upgradeable.
|
|
19
|
-
* This DTO contains all the necessary information for the check.
|
|
20
|
-
*/
|
|
21
|
-
class ProductUpgradeableRequestDto {
|
|
22
|
-
}
|
|
23
|
-
exports.ProductUpgradeableRequestDto = ProductUpgradeableRequestDto;
|
|
24
|
-
__decorate([
|
|
25
|
-
(0, class_validator_1.IsDefined)(),
|
|
26
|
-
(0, class_validator_1.IsObject)(),
|
|
27
|
-
(0, class_validator_1.ValidateNested)(),
|
|
28
|
-
(0, class_transformer_1.Type)(() => client_data_dto_1.ClientDataDto),
|
|
29
|
-
__metadata("design:type", client_data_dto_1.ClientDataDto)
|
|
30
|
-
], ProductUpgradeableRequestDto.prototype, "clientData", void 0);
|
|
31
|
-
__decorate([
|
|
32
|
-
(0, class_validator_1.IsDefined)(),
|
|
33
|
-
(0, class_validator_1.IsObject)(),
|
|
34
|
-
(0, class_validator_1.ValidateNested)(),
|
|
35
|
-
(0, class_transformer_1.Type)(() => product_item_data_dto_1.ProductItemDataDto),
|
|
36
|
-
__metadata("design:type", product_item_data_dto_1.ProductItemDataDto)
|
|
37
|
-
], ProductUpgradeableRequestDto.prototype, "itemData", void 0);
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ResponseStatusEnum } from '../../../enums/response-status.enum';
|
|
2
|
-
import { BaseResponse } from '../../base-response.dto';
|
|
3
|
-
/**
|
|
4
|
-
* Represents the response for a product downgradeable check.
|
|
5
|
-
* It indicates whether a product item is downgradeable and may contain additional data.
|
|
6
|
-
*/
|
|
7
|
-
export declare class ProductDowngradeableResponseDto extends BaseResponse {
|
|
8
|
-
/**
|
|
9
|
-
* The status of the response, indicating success or failure.
|
|
10
|
-
*/
|
|
11
|
-
status: ResponseStatusEnum;
|
|
12
|
-
/**
|
|
13
|
-
* The unique identifier of the product item being checked.
|
|
14
|
-
*/
|
|
15
|
-
itemId: string;
|
|
16
|
-
/**
|
|
17
|
-
* Optional data associated with the downgradeable check.
|
|
18
|
-
* Can contain details about available downgrades or reasons for failure.
|
|
19
|
-
* @optional
|
|
20
|
-
*/
|
|
21
|
-
data?: Record<string, unknown>;
|
|
22
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProductDowngradeableResponseDto = void 0;
|
|
4
|
-
const base_response_dto_1 = require("../../base-response.dto");
|
|
5
|
-
/**
|
|
6
|
-
* Represents the response for a product downgradeable check.
|
|
7
|
-
* It indicates whether a product item is downgradeable and may contain additional data.
|
|
8
|
-
*/
|
|
9
|
-
class ProductDowngradeableResponseDto extends base_response_dto_1.BaseResponse {
|
|
10
|
-
}
|
|
11
|
-
exports.ProductDowngradeableResponseDto = ProductDowngradeableResponseDto;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { ResponseStatusEnum } from '../../../enums/response-status.enum';
|
|
2
|
-
import { BaseResponse } from '../../base-response.dto';
|
|
3
|
-
/**
|
|
4
|
-
* Represents the response for a product upgradeable check.
|
|
5
|
-
* It indicates whether a product item is upgradeable and may contain additional data.
|
|
6
|
-
*/
|
|
7
|
-
export declare class ProductUpgradeableResponseDto extends BaseResponse {
|
|
8
|
-
/**
|
|
9
|
-
* The status of the response, indicating success or failure.
|
|
10
|
-
*/
|
|
11
|
-
status: ResponseStatusEnum;
|
|
12
|
-
/**
|
|
13
|
-
* The unique identifier of the product item being checked.
|
|
14
|
-
*/
|
|
15
|
-
itemId: string;
|
|
16
|
-
/**
|
|
17
|
-
* Optional data associated with the upgradeable check.
|
|
18
|
-
* Can contain details about available upgrades or reasons for failure.
|
|
19
|
-
* @optional
|
|
20
|
-
*/
|
|
21
|
-
data?: Record<string, unknown>;
|
|
22
|
-
}
|