@hosterai/types 0.0.17 → 0.0.19
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 +12 -9
- package/dist/decorators/all-or-none-validator.spec.d.ts +1 -0
- package/dist/decorators/all-or-none-validator.spec.js +91 -0
- package/dist/decorators/all-or-none.validator.d.ts +2 -0
- package/dist/decorators/all-or-none.validator.js +71 -0
- package/dist/decorators/at-least-one-non-empty-validator.spec.d.ts +1 -0
- package/dist/decorators/at-least-one-non-empty-validator.spec.js +79 -0
- package/dist/decorators/at-least-one-non-empty.validator.d.ts +2 -0
- package/dist/decorators/at-least-one-non-empty.validator.js +43 -0
- package/dist/decorators/is-of-allowed-types-validator.spec.d.ts +1 -0
- package/dist/decorators/is-of-allowed-types-validator.spec.js +188 -0
- package/dist/decorators/is-of-allowed-types.validator.d.ts +16 -0
- package/dist/decorators/is-of-allowed-types.validator.js +105 -0
- package/dist/decorators/is-one-of-validator.spec.d.ts +1 -0
- package/dist/decorators/is-one-of-validator.spec.js +51 -0
- package/dist/decorators/is-one-of.validator.d.ts +2 -0
- package/dist/decorators/is-one-of.validator.js +19 -0
- package/dist/decorators/is-plain-object-validator.spec.d.ts +1 -0
- package/dist/decorators/is-plain-object-validator.spec.js +46 -0
- package/dist/decorators/is-plain-object.validator.d.ts +2 -0
- package/dist/decorators/is-plain-object.validator.js +30 -0
- package/dist/decorators/is-property-forbidden-validator.spec.d.ts +1 -0
- package/dist/decorators/is-property-forbidden-validator.spec.js +62 -0
- package/dist/decorators/is-property-forbidden.validator.d.ts +2 -0
- package/dist/decorators/is-property-forbidden.validator.js +22 -0
- package/dist/decorators/is-regex-validator.spec.d.ts +1 -0
- package/dist/decorators/is-regex-validator.spec.js +46 -0
- package/dist/decorators/is-regex.validator.d.ts +2 -0
- package/dist/decorators/is-regex.validator.js +32 -0
- package/dist/decorators/min-less-or-equal-validator.spec.d.ts +1 -0
- package/dist/decorators/min-less-or-equal-validator.spec.js +60 -0
- package/dist/decorators/min-less-or-equal.validator.d.ts +2 -0
- package/dist/decorators/min-less-or-equal.validator.js +58 -0
- package/dist/decorators/unique-field-in-array-validator.spec.d.ts +1 -0
- package/dist/decorators/unique-field-in-array-validator.spec.js +39 -0
- package/dist/decorators/unique-field-in-array.validator.d.ts +6 -0
- package/dist/decorators/unique-field-in-array.validator.js +47 -0
- package/dist/dtos/action.dto.js +25 -1
- package/dist/dtos/admin-panel.dto.d.ts +38 -0
- package/dist/dtos/admin-panel.dto.js +241 -0
- package/dist/dtos/client-panel.dto.d.ts +24 -0
- package/dist/dtos/client-panel.dto.js +105 -0
- package/dist/dtos/company-data.dto.js +1 -1
- package/dist/dtos/field-option.dto.js +16 -0
- package/dist/dtos/field.dto.d.ts +2 -0
- package/dist/dtos/field.dto.js +112 -2
- package/dist/dtos/info.dto.d.ts +4 -79
- package/dist/dtos/info.dto.js +141 -0
- package/dist/dtos/menu.dto.d.ts +5 -6
- package/dist/dtos/menu.dto.js +108 -0
- package/dist/dtos/multilang-text.dto.js +1 -1
- package/dist/dtos/notification/notification-info.dto.js +42 -0
- package/dist/dtos/product/product-info.dto.js +73 -0
- package/dist/dtos/product/requests/product-downgradeable-request.dto.d.ts +18 -0
- package/dist/dtos/product/requests/product-downgradeable-request.dto.js +37 -0
- package/dist/dtos/product/requests/product-upgradeable-request.dto.d.ts +18 -0
- package/dist/dtos/product/requests/product-upgradeable-request.dto.js +37 -0
- package/dist/dtos/product/responses/product-downgradeable-response.dto.d.ts +22 -0
- package/dist/dtos/product/responses/product-downgradeable-response.dto.js +11 -0
- package/dist/dtos/product/responses/product-upgradeable-response.dto.d.ts +22 -0
- package/dist/dtos/product/responses/product-upgradeable-response.dto.js +11 -0
- package/dist/dtos/settings.dto.d.ts +14 -0
- package/dist/dtos/settings.dto.js +81 -0
- package/dist/dtos/tab.dto.js +32 -0
- package/dist/dtos/unit.dto.js +47 -0
- package/dist/index.d.ts +23 -7
- package/dist/index.js +26 -7
- package/dist/openapi/schemas/components.schemas.d.ts +991 -0
- package/dist/openapi/schemas/components.schemas.js +2552 -0
- package/dist/transformers/menu.transformer.d.ts +2 -0
- package/dist/transformers/menu.transformer.js +16 -0
- package/dist/transformers/settings.transformer.d.ts +1 -0
- package/dist/transformers/settings.transformer.js +15 -0
- package/dist/validators/action-validator.spec.d.ts +1 -0
- package/dist/validators/action-validator.spec.js +67 -0
- package/dist/validators/admin-panel-more-actions-validator.spec.d.ts +1 -0
- package/dist/validators/admin-panel-more-actions-validator.spec.js +129 -0
- package/dist/validators/admin-panel-more-actions.validator.d.ts +2 -0
- package/dist/validators/admin-panel-more-actions.validator.js +11 -0
- package/dist/validators/admin-panel-tabs-validator.spec.d.ts +1 -0
- package/dist/validators/admin-panel-tabs-validator.spec.js +39 -0
- package/dist/validators/admin-panel-tabs.validator.d.ts +2 -0
- package/dist/validators/admin-panel-tabs.validator.js +11 -0
- package/dist/validators/admin-panel-validator.spec.d.ts +1 -0
- package/dist/validators/admin-panel-validator.spec.js +112 -0
- package/dist/validators/admin-panel.validator.d.ts +2 -0
- package/dist/validators/admin-panel.validator.js +14 -0
- package/dist/validators/client-data-validator.spec.d.ts +1 -0
- package/dist/validators/client-data-validator.spec.js +35 -0
- package/dist/validators/client-panel-validator.spec.d.ts +1 -0
- package/dist/validators/client-panel-validator.spec.js +51 -0
- package/dist/validators/client-panel.validator.d.ts +2 -0
- package/dist/validators/client-panel.validator.js +14 -0
- package/dist/validators/company-data-validator.spec.d.ts +1 -0
- package/dist/validators/company-data-validator.spec.js +73 -0
- package/dist/validators/field-option-validator.spec.d.ts +1 -0
- package/dist/validators/field-option-validator.spec.js +28 -0
- package/dist/validators/field-option.validator.d.ts +2 -0
- package/dist/validators/field-option.validator.js +11 -0
- package/dist/validators/field-validator.spec.d.ts +1 -0
- package/dist/validators/field-validator.spec.js +102 -0
- package/dist/validators/jwt-validator.spec.d.ts +2 -0
- package/dist/validators/jwt-validator.spec.js +43 -0
- package/dist/validators/menu-with-submenu-validator.spec.d.ts +1 -0
- package/dist/validators/menu-with-submenu-validator.spec.js +52 -0
- package/dist/validators/menu-with-submenu.validator.d.ts +2 -0
- package/dist/validators/menu-with-submenu.validator.js +11 -0
- package/dist/validators/menu-with-url-validator.spec.d.ts +1 -0
- package/dist/validators/menu-with-url-validator.spec.js +70 -0
- package/dist/validators/menu-with-url.validator.d.ts +2 -0
- package/dist/validators/menu-with-url.validator.js +11 -0
- package/dist/validators/multilang-text-validator.spec.d.ts +1 -0
- package/dist/validators/multilang-text-validator.spec.js +33 -0
- package/dist/validators/notification-info-validator.spec.d.ts +1 -0
- package/dist/validators/notification-info-validator.spec.js +82 -0
- package/dist/validators/notification-info.validator.d.ts +7 -0
- package/dist/validators/notification-info.validator.js +16 -0
- package/dist/validators/notification-request-validator.spec.d.ts +1 -0
- package/dist/validators/notification-request-validator.spec.js +115 -0
- package/dist/validators/product-create-request-validator.spec.d.ts +2 -0
- package/dist/validators/product-create-request-validator.spec.js +44 -0
- package/dist/validators/product-delete-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-delete-request-validator.spec.js +40 -0
- package/dist/validators/product-downgradable-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-downgradable-request-validator.spec.js +40 -0
- package/dist/validators/product-downgrade-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-downgrade-request-validator.spec.js +46 -0
- package/dist/validators/product-downgradeable-request-validator.d.ts +8 -0
- package/dist/validators/product-downgradeable-request-validator.js +17 -0
- package/dist/validators/product-info-validator.spec.d.ts +1 -0
- package/dist/validators/product-info-validator.spec.js +259 -0
- package/dist/validators/product-info.validator.d.ts +2 -0
- package/dist/validators/product-info.validator.js +11 -0
- package/dist/validators/product-renew-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-renew-request-validator.spec.js +40 -0
- package/dist/validators/product-suspend-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-suspend-request-validator.spec.js +40 -0
- package/dist/validators/product-unsuspend-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-unsuspend-request-validator.spec.js +40 -0
- package/dist/validators/product-upgradable-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-upgradable-request-validator.spec.js +40 -0
- package/dist/validators/product-upgrade-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-upgrade-request-validator.spec.js +46 -0
- package/dist/validators/product-upgradeable-request-validator.d.ts +8 -0
- package/dist/validators/product-upgradeable-request-validator.js +17 -0
- package/dist/validators/product-validate-attributes-request-validator.spec.d.ts +1 -0
- package/dist/validators/product-validate-attributes-request-validator.spec.js +27 -0
- package/dist/validators/receiver-email-validator.spec.d.ts +1 -0
- package/dist/validators/receiver-email-validator.spec.js +32 -0
- package/dist/validators/receiver-push-validator.spec.d.ts +1 -0
- package/dist/validators/receiver-push-validator.spec.js +31 -0
- package/dist/validators/receiver-sms-validator.spec.d.ts +1 -0
- package/dist/validators/receiver-sms-validator.spec.js +29 -0
- package/dist/validators/sender-email-validator.spec.d.ts +2 -0
- package/dist/validators/sender-email-validator.spec.js +62 -0
- package/dist/validators/sender-push-validator.spec.d.ts +1 -0
- package/dist/validators/sender-push-validator.spec.js +38 -0
- package/dist/validators/sender-sms-validator.spec.d.ts +1 -0
- package/dist/validators/sender-sms-validator.spec.js +22 -0
- package/dist/validators/settings-with-tabs-validator.spec.d.ts +1 -0
- package/dist/validators/settings-with-tabs-validator.spec.js +29 -0
- package/dist/validators/settings-with-tabs.validator.d.ts +2 -0
- package/dist/validators/settings-with-tabs.validator.js +11 -0
- package/dist/validators/settings-with-url-validator.spec.d.ts +1 -0
- package/dist/validators/settings-with-url-validator.spec.js +29 -0
- package/dist/validators/settings-with-url.validator.d.ts +2 -0
- package/dist/validators/settings-with-url.validator.js +11 -0
- package/dist/validators/unit-validator.spec.d.ts +1 -0
- package/dist/validators/unit-validator.spec.js +27 -0
- package/dist/validators/unit.validator.d.ts +2 -0
- package/dist/validators/unit.validator.js +11 -0
- package/package.json +4 -1
- package/dist/dtos/info/info-notification.dto.d.ts +0 -5
- package/dist/dtos/info/info-notification.dto.js +0 -7
- package/dist/dtos/info/info.dto.d.ts +0 -196
- package/dist/dtos/info/info.dto.js +0 -278
- package/dist/dtos/notification/notification-request.dto.d.ts +0 -20
- package/dist/dtos/notification/notification-request.dto.js +0 -31
- package/dist/dtos/receiver/receiver-email.dto.d.ts +0 -20
- package/dist/dtos/receiver/receiver-email.dto.js +0 -39
- package/dist/dtos/receiver/receiver-push.dto.d.ts +0 -15
- package/dist/dtos/receiver/receiver-push.dto.js +0 -31
- package/dist/dtos/receiver/receiver-sms.dto.d.ts +0 -11
- package/dist/dtos/receiver/receiver-sms.dto.js +0 -26
- package/dist/dtos/request.dto.d.ts +0 -20
- package/dist/dtos/request.dto.js +0 -31
- package/dist/dtos/sender/sender-email.dto.d.ts +0 -25
- package/dist/dtos/sender/sender-email.dto.js +0 -46
- package/dist/dtos/sender/sender-push.dto.d.ts +0 -31
- package/dist/dtos/sender/sender-push.dto.js +0 -50
- package/dist/dtos/sender/sender-sms.dto.d.ts +0 -15
- package/dist/dtos/sender/sender-sms.dto.js +0 -30
- package/dist/enums/message-type.enum.d.ts +0 -5
- package/dist/enums/message-type.enum.js +0 -9
package/README.md
CHANGED
|
@@ -46,6 +46,9 @@ DTOs define the shape of data that is exchanged between different parts of the s
|
|
|
46
46
|
- `info.dto.ts`: Contains all necessary information for a service integration.
|
|
47
47
|
- `jwt.dto.ts`: DTOs related to JSON Web Tokens.
|
|
48
48
|
- `menu.dto.ts`: Defines the structure for menu items.
|
|
49
|
+
- `settings.dto.ts`: Settings base DTO and variants (`SettingsWithUrlDto`, `SettingsWithTabsDto`).
|
|
50
|
+
- `admin-panel.dto.ts`: Admin panel UI configuration (tabs, moreActions, menu, settings).
|
|
51
|
+
- `client-panel.dto.ts`: Client panel UI configuration (tabs, moreActions, menu).
|
|
49
52
|
- `multilang-text.dto.ts`: A DTO for handling text in multiple languages.
|
|
50
53
|
- `response-data.dto.ts`: A generic wrapper for response data.
|
|
51
54
|
- `setup-status-response.dto.ts`: DTO for returning the setup status.
|
|
@@ -80,7 +83,7 @@ Enums provide a set of named constants for common types, preventing errors with
|
|
|
80
83
|
|
|
81
84
|
**Key Enums:**
|
|
82
85
|
|
|
83
|
-
- `
|
|
86
|
+
- `ActionsEnum`: Defines possible actions.
|
|
84
87
|
- `CountryEnum`: A list of all countries.
|
|
85
88
|
- `DurationEnum`: Defines billing durations (e.g., `MONTHLY`, `YEARLY`).
|
|
86
89
|
- `EventsEnum`: Defines triggerable events.
|
|
@@ -124,7 +127,7 @@ import {
|
|
|
124
127
|
ClientDataDto,
|
|
125
128
|
ProductItemDataDto,
|
|
126
129
|
DurationEnum,
|
|
127
|
-
validateProductCreateRequestDto,
|
|
130
|
+
validateProductCreateRequestDto,
|
|
128
131
|
} from '@hosterai/types';
|
|
129
132
|
|
|
130
133
|
// 1. Create a request object
|
|
@@ -144,15 +147,15 @@ const request: ProductCreateRequestDto = {
|
|
|
144
147
|
},
|
|
145
148
|
};
|
|
146
149
|
|
|
147
|
-
// 2. Validate the object
|
|
148
|
-
|
|
150
|
+
// 2. Validate the object (async)
|
|
151
|
+
const errors = await validateProductCreateRequestDto(request);
|
|
149
152
|
|
|
150
153
|
// 3. Check for errors
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
if (errors.length > 0) {
|
|
155
|
+
console.error('Validation failed:', errors);
|
|
156
|
+
} else {
|
|
157
|
+
console.log('Validation successful!');
|
|
158
|
+
}
|
|
156
159
|
```
|
|
157
160
|
|
|
158
161
|
## Building from Source
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
require("reflect-metadata");
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
const all_or_none_validator_1 = require("./all-or-none.validator");
|
|
15
|
+
// Pairs
|
|
16
|
+
let PairDto = class PairDto {
|
|
17
|
+
constructor(data) { Object.assign(this, data); }
|
|
18
|
+
};
|
|
19
|
+
PairDto = __decorate([
|
|
20
|
+
(0, all_or_none_validator_1.AllOrNoneProperty)(['a', 'b']),
|
|
21
|
+
__metadata("design:paramtypes", [Object])
|
|
22
|
+
], PairDto);
|
|
23
|
+
// Multiple pairs
|
|
24
|
+
let MultiPairDto = class MultiPairDto {
|
|
25
|
+
constructor(data) { Object.assign(this, data); }
|
|
26
|
+
};
|
|
27
|
+
MultiPairDto = __decorate([
|
|
28
|
+
(0, all_or_none_validator_1.AllOrNoneProperty)([
|
|
29
|
+
['a', 'b'],
|
|
30
|
+
['c', 'd'],
|
|
31
|
+
]),
|
|
32
|
+
__metadata("design:paramtypes", [Object])
|
|
33
|
+
], MultiPairDto);
|
|
34
|
+
// Group of 3+
|
|
35
|
+
let GroupDto = class GroupDto {
|
|
36
|
+
constructor(data) { Object.assign(this, data); }
|
|
37
|
+
};
|
|
38
|
+
GroupDto = __decorate([
|
|
39
|
+
(0, all_or_none_validator_1.AllOrNoneProperty)(['x', 'y', 'z']),
|
|
40
|
+
__metadata("design:paramtypes", [Object])
|
|
41
|
+
], GroupDto);
|
|
42
|
+
describe('AllOrNoneProperty', () => {
|
|
43
|
+
// Single pair
|
|
44
|
+
it('passes when both pair fields are absent', async () => {
|
|
45
|
+
const dto = new PairDto({});
|
|
46
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
47
|
+
expect(errors.length).toBe(0);
|
|
48
|
+
});
|
|
49
|
+
it('fails when one of pair fields is present and the other is absent', async () => {
|
|
50
|
+
const dto = new PairDto({ a: 1 });
|
|
51
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
52
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
53
|
+
});
|
|
54
|
+
it('passes when both pair fields are present', async () => {
|
|
55
|
+
const dto = new PairDto({ a: 1, b: 2 });
|
|
56
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
57
|
+
expect(errors.length).toBe(0);
|
|
58
|
+
});
|
|
59
|
+
// Multiple pairs
|
|
60
|
+
it('passes when all pairs are absent', async () => {
|
|
61
|
+
const dto = new MultiPairDto({});
|
|
62
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
63
|
+
expect(errors.length).toBe(0);
|
|
64
|
+
});
|
|
65
|
+
it('passes when all pairs are present', async () => {
|
|
66
|
+
const dto = new MultiPairDto({ a: 1, b: 2, c: 3, d: 4 });
|
|
67
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
68
|
+
expect(errors.length).toBe(0);
|
|
69
|
+
});
|
|
70
|
+
it('fails when one pair violates the rule', async () => {
|
|
71
|
+
const dto = new MultiPairDto({ a: 1, b: 2, c: 3 });
|
|
72
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
73
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
74
|
+
});
|
|
75
|
+
// 3+ group
|
|
76
|
+
it('passes when all group fields are absent', async () => {
|
|
77
|
+
const dto = new GroupDto({});
|
|
78
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
79
|
+
expect(errors.length).toBe(0);
|
|
80
|
+
});
|
|
81
|
+
it('fails when only a subset of group fields are present', async () => {
|
|
82
|
+
const dto = new GroupDto({ x: 1 });
|
|
83
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
84
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
85
|
+
});
|
|
86
|
+
it('passes when all group fields are present', async () => {
|
|
87
|
+
const dto = new GroupDto({ x: 1, y: 2, z: 3 });
|
|
88
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
89
|
+
expect(errors.length).toBe(0);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AllOrNoneProperty = AllOrNoneProperty;
|
|
10
|
+
const class_validator_1 = require("class-validator");
|
|
11
|
+
let AllOrNoneConstraint = class AllOrNoneConstraint {
|
|
12
|
+
validate(_, args) {
|
|
13
|
+
const object = args.object;
|
|
14
|
+
const input = args.constraints[0];
|
|
15
|
+
// Normalize to an array of groups, each group being string[] (length >= 2 preferred)
|
|
16
|
+
let groups = [];
|
|
17
|
+
if (Array.isArray(input)) {
|
|
18
|
+
if (input.length > 0 && typeof input[0] === 'string') {
|
|
19
|
+
// Single group given as string[] (could be pair or more than 2)
|
|
20
|
+
groups = [input];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// Array of groups (pairs or larger)
|
|
24
|
+
groups = input.map((g) => g);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const has = (k) => object[k] !== undefined && object[k] !== null;
|
|
28
|
+
return groups.every((group) => {
|
|
29
|
+
if (!Array.isArray(group) || group.length < 2)
|
|
30
|
+
return true; // Ignore invalid/misconfigured groups
|
|
31
|
+
const statuses = group.map((k) => has(k));
|
|
32
|
+
const allPresent = statuses.every(Boolean);
|
|
33
|
+
const allAbsent = statuses.every((v) => !v);
|
|
34
|
+
return allPresent || allAbsent;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
defaultMessage(args) {
|
|
38
|
+
const input = args.constraints[0];
|
|
39
|
+
let groups = [];
|
|
40
|
+
if (Array.isArray(input)) {
|
|
41
|
+
if (input.length > 0 && typeof input[0] === 'string') {
|
|
42
|
+
groups = [input];
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
groups = input.map((g) => g);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (groups.length === 1) {
|
|
49
|
+
const g = groups[0];
|
|
50
|
+
const list = g.join(', ');
|
|
51
|
+
return `All of (${list}) must be provided together or omitted together`;
|
|
52
|
+
}
|
|
53
|
+
const list = groups.map((g) => `(${g.join('/')})`).join(', ');
|
|
54
|
+
return `Each group must be provided together or omitted together: ${list}`;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
AllOrNoneConstraint = __decorate([
|
|
58
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'AllOrNone', async: false })
|
|
59
|
+
], AllOrNoneConstraint);
|
|
60
|
+
function AllOrNoneProperty(keysOrGroups, validationOptions) {
|
|
61
|
+
return function (constructor) {
|
|
62
|
+
(0, class_validator_1.registerDecorator)({
|
|
63
|
+
name: 'AllOrNone',
|
|
64
|
+
target: constructor,
|
|
65
|
+
propertyName: '',
|
|
66
|
+
options: validationOptions,
|
|
67
|
+
constraints: [keysOrGroups],
|
|
68
|
+
validator: AllOrNoneConstraint,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
const class_validator_1 = require("class-validator");
|
|
13
|
+
const at_least_one_non_empty_validator_1 = require("../decorators/at-least-one-non-empty.validator");
|
|
14
|
+
let TestDto = class TestDto {
|
|
15
|
+
constructor(data) {
|
|
16
|
+
Object.assign(this, data);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
TestDto = __decorate([
|
|
20
|
+
(0, at_least_one_non_empty_validator_1.AtLeastOneNonEmptyProperty)(['a', 'b', 'c'], {
|
|
21
|
+
message: 'At least one of a, b, or c must be non-empty.',
|
|
22
|
+
}),
|
|
23
|
+
__metadata("design:paramtypes", [Object])
|
|
24
|
+
], TestDto);
|
|
25
|
+
let TestDto2 = class TestDto2 {
|
|
26
|
+
constructor(data) {
|
|
27
|
+
Object.assign(this, data);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
TestDto2 = __decorate([
|
|
31
|
+
(0, at_least_one_non_empty_validator_1.AtLeastOneNonEmptyProperty)(['a', 'b', 'c']),
|
|
32
|
+
__metadata("design:paramtypes", [Object])
|
|
33
|
+
], TestDto2);
|
|
34
|
+
describe('AtLeastOneNonEmptyClass', () => {
|
|
35
|
+
it('fails when all keys are undefined', async () => {
|
|
36
|
+
const dto = new TestDto({});
|
|
37
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
38
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
39
|
+
});
|
|
40
|
+
it('fails when all keys are empty arrays/objects', async () => {
|
|
41
|
+
const dto = new TestDto({ a: [], b: {}, c: [] });
|
|
42
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
43
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
44
|
+
});
|
|
45
|
+
it('passes when one key is a non-empty array', async () => {
|
|
46
|
+
const dto = new TestDto({ a: [1], b: [], c: {} });
|
|
47
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
48
|
+
expect(errors.length).toBe(0);
|
|
49
|
+
});
|
|
50
|
+
it('passes when one key is a non-empty object', async () => {
|
|
51
|
+
const dto = new TestDto({ a: {}, b: { x: 1 }, c: [] });
|
|
52
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
53
|
+
expect(errors.length).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
it('fails when non-object types are present', async () => {
|
|
56
|
+
const dto = new TestDto({ a: 'string', b: 123, c: false });
|
|
57
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
58
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
59
|
+
});
|
|
60
|
+
it('passes when multiple keys are non-empty', async () => {
|
|
61
|
+
const dto = new TestDto({ a: [1], b: { test: true }, c: [] });
|
|
62
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
63
|
+
expect(errors.length).toBe(0);
|
|
64
|
+
});
|
|
65
|
+
it('fails when keys are missing', async () => {
|
|
66
|
+
const dto = new TestDto({ d: 'not part of the check' });
|
|
67
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
68
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
69
|
+
});
|
|
70
|
+
it('returns the default error message when validation fails', async () => {
|
|
71
|
+
const dto = new TestDto2({});
|
|
72
|
+
const errors = await (0, class_validator_1.validate)(dto);
|
|
73
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
74
|
+
const constraints = errors[0].constraints;
|
|
75
|
+
expect(constraints).toBeDefined();
|
|
76
|
+
const messages = Object.values(constraints);
|
|
77
|
+
expect(messages.some(msg => msg.includes('At least one of the following must be non-empty: a, b, c'))).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AtLeastOneNonEmptyProperty = AtLeastOneNonEmptyProperty;
|
|
10
|
+
const class_validator_1 = require("class-validator");
|
|
11
|
+
function isNonEmptyObjectOrArray(value) {
|
|
12
|
+
if (Array.isArray(value))
|
|
13
|
+
return value.length > 0;
|
|
14
|
+
if (value && typeof value === 'object')
|
|
15
|
+
return Object.keys(value).length > 0;
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
let AtLeastOneNonEmptyConstraint = class AtLeastOneNonEmptyConstraint {
|
|
19
|
+
validate(_, args) {
|
|
20
|
+
const object = args.object;
|
|
21
|
+
const keys = args.constraints[0];
|
|
22
|
+
return keys.some(key => isNonEmptyObjectOrArray(object[key]));
|
|
23
|
+
}
|
|
24
|
+
defaultMessage(args) {
|
|
25
|
+
const keys = args.constraints[0];
|
|
26
|
+
return `At least one of the following must be non-empty: ${keys.join(', ')}`;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
AtLeastOneNonEmptyConstraint = __decorate([
|
|
30
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'AtLeastOneNonEmpty', async: false })
|
|
31
|
+
], AtLeastOneNonEmptyConstraint);
|
|
32
|
+
function AtLeastOneNonEmptyProperty(keys, validationOptions) {
|
|
33
|
+
return function (constructor) {
|
|
34
|
+
(0, class_validator_1.registerDecorator)({
|
|
35
|
+
name: 'AtLeastOneNonEmpty',
|
|
36
|
+
target: constructor,
|
|
37
|
+
propertyName: "",
|
|
38
|
+
options: validationOptions,
|
|
39
|
+
constraints: [keys],
|
|
40
|
+
validator: AtLeastOneNonEmptyConstraint,
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,188 @@
|
|
|
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
|
+
require("reflect-metadata");
|
|
13
|
+
const class_validator_1 = require("class-validator");
|
|
14
|
+
const is_of_allowed_types_validator_1 = require("./is-of-allowed-types.validator");
|
|
15
|
+
class DummyObject {
|
|
16
|
+
}
|
|
17
|
+
class DummyArrayElement {
|
|
18
|
+
}
|
|
19
|
+
class TestDto {
|
|
20
|
+
}
|
|
21
|
+
__decorate([
|
|
22
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['string']),
|
|
23
|
+
__metadata("design:type", Object)
|
|
24
|
+
], TestDto.prototype, "strProp", void 0);
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['number']),
|
|
27
|
+
__metadata("design:type", Object)
|
|
28
|
+
], TestDto.prototype, "numProp", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['boolean']),
|
|
31
|
+
__metadata("design:type", Object)
|
|
32
|
+
], TestDto.prototype, "boolProp", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['object']),
|
|
35
|
+
__metadata("design:type", Object)
|
|
36
|
+
], TestDto.prototype, "objProp", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['object'], { objectClass: DummyObject }),
|
|
39
|
+
__metadata("design:type", Object)
|
|
40
|
+
], TestDto.prototype, "typedObjProp", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['array']),
|
|
43
|
+
__metadata("design:type", Object)
|
|
44
|
+
], TestDto.prototype, "arrProp", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['array'], { arrayElementClass: DummyArrayElement }),
|
|
47
|
+
__metadata("design:type", Object)
|
|
48
|
+
], TestDto.prototype, "typedArrProp", void 0);
|
|
49
|
+
__decorate([
|
|
50
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['string', 'number']),
|
|
51
|
+
__metadata("design:type", Object)
|
|
52
|
+
], TestDto.prototype, "multiTypeProp", void 0);
|
|
53
|
+
class OptionsTestDto {
|
|
54
|
+
}
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['string'], { stringPattern: /^[a-z]+$/, require: true }),
|
|
57
|
+
__metadata("design:type", Object)
|
|
58
|
+
], OptionsTestDto.prototype, "strPatternProp", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['array'], { arrayNotEmpty: true }),
|
|
61
|
+
__metadata("design:type", Object)
|
|
62
|
+
], OptionsTestDto.prototype, "arrayNotEmptyProp", void 0);
|
|
63
|
+
__decorate([
|
|
64
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['object'], { objectNotEmpty: true }),
|
|
65
|
+
__metadata("design:type", Object)
|
|
66
|
+
], OptionsTestDto.prototype, "objectNotEmptyProp", void 0);
|
|
67
|
+
class ArrayNotEmptyDto {
|
|
68
|
+
}
|
|
69
|
+
__decorate([
|
|
70
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['array'], { arrayNotEmpty: true }),
|
|
71
|
+
__metadata("design:type", Object)
|
|
72
|
+
], ArrayNotEmptyDto.prototype, "value", void 0);
|
|
73
|
+
class ObjectNotEmptyDto {
|
|
74
|
+
}
|
|
75
|
+
__decorate([
|
|
76
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['object'], { objectNotEmpty: true }),
|
|
77
|
+
__metadata("design:type", Object)
|
|
78
|
+
], ObjectNotEmptyDto.prototype, "value", void 0);
|
|
79
|
+
class ValidationOptionsDto {
|
|
80
|
+
}
|
|
81
|
+
__decorate([
|
|
82
|
+
(0, is_of_allowed_types_validator_1.IsOfAllowedTypes)(['string'], { message: 'Custom error message' }),
|
|
83
|
+
__metadata("design:type", Object)
|
|
84
|
+
], ValidationOptionsDto.prototype, "prop", void 0);
|
|
85
|
+
describe('IsOfAllowedTypes validator - compact', () => {
|
|
86
|
+
it('accepts valid types', () => {
|
|
87
|
+
const dto = new TestDto();
|
|
88
|
+
dto.strProp = 'hello';
|
|
89
|
+
dto.numProp = 42;
|
|
90
|
+
dto.boolProp = true;
|
|
91
|
+
dto.objProp = {};
|
|
92
|
+
dto.typedObjProp = new DummyObject();
|
|
93
|
+
dto.arrProp = [1, 2];
|
|
94
|
+
dto.typedArrProp = [new DummyArrayElement()];
|
|
95
|
+
dto.multiTypeProp = 'string or number';
|
|
96
|
+
expect((0, class_validator_1.validateSync)(dto)).toHaveLength(0);
|
|
97
|
+
});
|
|
98
|
+
it('rejects invalid types', () => {
|
|
99
|
+
const dto = new TestDto();
|
|
100
|
+
dto.strProp = 123;
|
|
101
|
+
dto.numProp = 'string';
|
|
102
|
+
dto.boolProp = 'true';
|
|
103
|
+
dto.objProp = 'string';
|
|
104
|
+
dto.typedObjProp = {};
|
|
105
|
+
dto.arrProp = 'not array';
|
|
106
|
+
dto.typedArrProp = [{}];
|
|
107
|
+
dto.multiTypeProp = true;
|
|
108
|
+
const errors = (0, class_validator_1.validateSync)(dto).map(e => e.property);
|
|
109
|
+
expect(new Set(errors)).toEqual(new Set([
|
|
110
|
+
'arrProp',
|
|
111
|
+
'boolProp',
|
|
112
|
+
'multiTypeProp',
|
|
113
|
+
'numProp',
|
|
114
|
+
'objProp',
|
|
115
|
+
'strProp',
|
|
116
|
+
'typedArrProp',
|
|
117
|
+
'typedObjProp',
|
|
118
|
+
]));
|
|
119
|
+
});
|
|
120
|
+
it('allows null or undefined when not required', () => {
|
|
121
|
+
const dto = new TestDto();
|
|
122
|
+
dto.strProp = null;
|
|
123
|
+
dto.numProp = undefined;
|
|
124
|
+
expect((0, class_validator_1.validateSync)(dto)).toHaveLength(0);
|
|
125
|
+
});
|
|
126
|
+
it('fails when objectClass is provided but instance check fails', () => {
|
|
127
|
+
const dto = new TestDto();
|
|
128
|
+
dto.typedObjProp = {};
|
|
129
|
+
expect((0, class_validator_1.validateSync)(dto).some(e => e.property === 'typedObjProp')).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
it('fails when arrayElementClass is provided but element check fails', () => {
|
|
132
|
+
const dto = new TestDto();
|
|
133
|
+
dto.typedArrProp = [{}];
|
|
134
|
+
expect((0, class_validator_1.validateSync)(dto).some(e => e.property === 'typedArrProp')).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
// Added coverage tests
|
|
137
|
+
it('fails if string is empty but required', () => {
|
|
138
|
+
const dto = new OptionsTestDto();
|
|
139
|
+
dto.strPatternProp = ' ';
|
|
140
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
141
|
+
expect(errors.some(e => e.property === 'strPatternProp')).toBe(true);
|
|
142
|
+
});
|
|
143
|
+
it('fails if string does not match pattern', () => {
|
|
144
|
+
const dto = new OptionsTestDto();
|
|
145
|
+
dto.strPatternProp = '123';
|
|
146
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
147
|
+
expect(errors.some(e => e.property === 'strPatternProp')).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
it('passes if string matches pattern', () => {
|
|
150
|
+
const dto = new OptionsTestDto();
|
|
151
|
+
dto.strPatternProp = 'abc';
|
|
152
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
153
|
+
expect(errors.length).toBe(0);
|
|
154
|
+
});
|
|
155
|
+
it('fails if array is empty but arrayNotEmpty true', () => {
|
|
156
|
+
const dto = new OptionsTestDto();
|
|
157
|
+
dto.arrayNotEmptyProp = [];
|
|
158
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
159
|
+
expect(errors.some(e => e.property === 'arrayNotEmptyProp')).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
it('passes if array is non-empty and arrayNotEmpty true', () => {
|
|
162
|
+
const dto = new ArrayNotEmptyDto();
|
|
163
|
+
dto.value = [1];
|
|
164
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
165
|
+
expect(errors.length).toBe(0);
|
|
166
|
+
});
|
|
167
|
+
it('fails if object is empty but objectNotEmpty true', () => {
|
|
168
|
+
const dto = new OptionsTestDto();
|
|
169
|
+
dto.objectNotEmptyProp = {};
|
|
170
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
171
|
+
expect(errors.some(e => e.property === 'objectNotEmptyProp')).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
it('passes if object is non-empty and objectNotEmpty true', () => {
|
|
174
|
+
const dto = new ObjectNotEmptyDto();
|
|
175
|
+
dto.value = { key: 'value' };
|
|
176
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
177
|
+
expect(errors.length).toBe(0);
|
|
178
|
+
});
|
|
179
|
+
it('accepts ValidationOptions as second argument', () => {
|
|
180
|
+
const dto = new ValidationOptionsDto();
|
|
181
|
+
dto.prop = 123;
|
|
182
|
+
const errors = (0, class_validator_1.validateSync)(dto);
|
|
183
|
+
expect(errors.length).toBeGreaterThan(0);
|
|
184
|
+
expect(errors[0].constraints).toBeDefined();
|
|
185
|
+
expect(errors[0].constraints).toHaveProperty('isOfAllowedTypes');
|
|
186
|
+
expect(errors[0].constraints['isOfAllowedTypes']).toContain('Custom error message');
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ValidationOptions } from 'class-validator';
|
|
2
|
+
type AllowedPrimitive = 'string' | 'number' | 'boolean';
|
|
3
|
+
type AllowedType = AllowedPrimitive | 'object' | 'array';
|
|
4
|
+
interface IsOfAllowedTypesOptions {
|
|
5
|
+
objectClass?: new (...args: any[]) => any;
|
|
6
|
+
arrayElementClass?: new (...args: any[]) => any;
|
|
7
|
+
require?: boolean;
|
|
8
|
+
objectNotEmpty?: boolean;
|
|
9
|
+
arrayNotEmpty?: boolean;
|
|
10
|
+
stringPattern?: RegExp;
|
|
11
|
+
}
|
|
12
|
+
export declare function IsOfAllowedTypes(types: AllowedType[]): PropertyDecorator;
|
|
13
|
+
export declare function IsOfAllowedTypes(types: AllowedType[], options: IsOfAllowedTypesOptions): PropertyDecorator;
|
|
14
|
+
export declare function IsOfAllowedTypes(types: AllowedType[], validationOptions: ValidationOptions): PropertyDecorator;
|
|
15
|
+
export declare function IsOfAllowedTypes(types: AllowedType[], options: IsOfAllowedTypesOptions, validationOptions: ValidationOptions): PropertyDecorator;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IsOfAllowedTypes = IsOfAllowedTypes;
|
|
4
|
+
const class_validator_1 = require("class-validator");
|
|
5
|
+
// Implementation
|
|
6
|
+
function IsOfAllowedTypes(types, optionsOrValidationOptions, validationOptions) {
|
|
7
|
+
return function (target, propertyKey) {
|
|
8
|
+
let options = {};
|
|
9
|
+
let finalValidationOptions;
|
|
10
|
+
if (optionsOrValidationOptions) {
|
|
11
|
+
if ('objectClass' in optionsOrValidationOptions ||
|
|
12
|
+
'arrayElementClass' in optionsOrValidationOptions ||
|
|
13
|
+
'require' in optionsOrValidationOptions ||
|
|
14
|
+
'objectNotEmpty' in optionsOrValidationOptions ||
|
|
15
|
+
'arrayNotEmpty' in optionsOrValidationOptions ||
|
|
16
|
+
'stringPattern' in optionsOrValidationOptions) {
|
|
17
|
+
options = optionsOrValidationOptions;
|
|
18
|
+
finalValidationOptions = validationOptions;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
finalValidationOptions = optionsOrValidationOptions;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
(0, class_validator_1.registerDecorator)({
|
|
25
|
+
name: 'isOfAllowedTypes',
|
|
26
|
+
target: target.constructor,
|
|
27
|
+
propertyName: propertyKey.toString(),
|
|
28
|
+
constraints: [types, options],
|
|
29
|
+
options: finalValidationOptions,
|
|
30
|
+
validator: {
|
|
31
|
+
validate(value, args) {
|
|
32
|
+
const [allowedTypes, opts] = args.constraints;
|
|
33
|
+
if (value === null || value === undefined) {
|
|
34
|
+
return !opts.require;
|
|
35
|
+
}
|
|
36
|
+
for (const type of allowedTypes) {
|
|
37
|
+
switch (type) {
|
|
38
|
+
case 'string':
|
|
39
|
+
if (typeof value === 'string') {
|
|
40
|
+
if (opts.require && value.trim().length === 0)
|
|
41
|
+
return false;
|
|
42
|
+
if (opts.stringPattern && !opts.stringPattern.test(value))
|
|
43
|
+
return false;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case 'number':
|
|
48
|
+
if (typeof value === 'number')
|
|
49
|
+
return true;
|
|
50
|
+
break;
|
|
51
|
+
case 'boolean':
|
|
52
|
+
if (typeof value === 'boolean')
|
|
53
|
+
return true;
|
|
54
|
+
break;
|
|
55
|
+
case 'object':
|
|
56
|
+
if (typeof value === 'object' &&
|
|
57
|
+
!Array.isArray(value) &&
|
|
58
|
+
(!opts.objectClass || value instanceof opts.objectClass)) {
|
|
59
|
+
if (opts.objectNotEmpty && Object.keys(value).length === 0) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case 'array':
|
|
66
|
+
if (Array.isArray(value) &&
|
|
67
|
+
(!opts.arrayElementClass ||
|
|
68
|
+
value.every((item) => item instanceof opts.arrayElementClass))) {
|
|
69
|
+
if (opts.arrayNotEmpty && value.length === 0) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
},
|
|
79
|
+
defaultMessage(args) {
|
|
80
|
+
const [allowedTypes, opts] = args.constraints;
|
|
81
|
+
const messages = [];
|
|
82
|
+
if (opts.require) {
|
|
83
|
+
messages.push('is required');
|
|
84
|
+
}
|
|
85
|
+
if (allowedTypes.includes('string')) {
|
|
86
|
+
if (opts.require)
|
|
87
|
+
messages.push('must be a non-empty string');
|
|
88
|
+
if (opts.stringPattern)
|
|
89
|
+
messages.push(`must match pattern ${opts.stringPattern}`);
|
|
90
|
+
}
|
|
91
|
+
if (allowedTypes.includes('array') && opts.arrayNotEmpty) {
|
|
92
|
+
messages.push('must be a non-empty array');
|
|
93
|
+
}
|
|
94
|
+
if (allowedTypes.includes('object') && opts.objectNotEmpty) {
|
|
95
|
+
messages.push('must be a non-empty object');
|
|
96
|
+
}
|
|
97
|
+
if (messages.length === 0) {
|
|
98
|
+
messages.push(`must be one of: ${allowedTypes.join(', ')}`);
|
|
99
|
+
}
|
|
100
|
+
return `${args.property} ${messages.join(' and ')}`;
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|