Skip to content

Commit 1e5c047

Browse files
committed
✨ add mutually exclusive validation
1 parent a9bb86e commit 1e5c047

File tree

3 files changed

+253
-154
lines changed

3 files changed

+253
-154
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Expose, Type } from 'class-transformer';
2+
import {
3+
IsBoolean,
4+
IsEnum,
5+
IsOptional,
6+
IsSemVer,
7+
IsString,
8+
isString,
9+
IsUrl,
10+
ValidateNested,
11+
} from 'class-validator';
12+
13+
import { applyDecorators, IsRecord } from '../../utils';
14+
15+
export const IsRequiredValue = (): PropertyDecorator =>
16+
applyDecorators(Expose(), IsString());
17+
18+
export const IsSingleValue = (): PropertyDecorator =>
19+
applyDecorators(Expose(), IsOptional(), IsString());
20+
21+
export const IsMultiValue = (): PropertyDecorator =>
22+
applyDecorators(Expose(), IsOptional(), IsString({ each: true }));
23+
24+
export const IsURLValue = (): PropertyDecorator =>
25+
applyDecorators(Expose(), IsOptional(), IsUrl());
26+
27+
export const IsVersionValue = (): PropertyDecorator =>
28+
applyDecorators(Expose(), IsOptional(), IsSemVer());
29+
30+
export const IsSwitchValue = (): PropertyDecorator =>
31+
applyDecorators(Expose(), IsOptional(), IsBoolean());
32+
33+
export const IsNamedValue = (): PropertyDecorator =>
34+
applyDecorators(
35+
Expose(),
36+
IsOptional(),
37+
IsRecord([isString], [isString], {
38+
message: ({ property }) => `"${property}" is not a valid named value`,
39+
}),
40+
);
41+
42+
export const IsEnumValue = (
43+
entity: Record<string, unknown>,
44+
): PropertyDecorator => applyDecorators(Expose(), IsOptional(), IsEnum(entity));
45+
46+
export const IsNestedValue = (clazz: { new (): object }): PropertyDecorator =>
47+
applyDecorators(
48+
Expose(),
49+
Type(() => clazz),
50+
IsOptional(),
51+
ValidateNested(),
52+
);
Lines changed: 76 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
import { Expose, Type } from 'class-transformer';
2-
import {
3-
IsBoolean,
4-
IsEnum,
5-
IsObject,
6-
IsOptional,
7-
IsSemVer,
8-
IsString,
9-
IsUrl,
10-
ValidateNested,
11-
} from 'class-validator';
12-
131
import {
142
CompatibilityValue,
153
InjectInto,
@@ -21,230 +9,164 @@ import {
219
StrictHeadersProps,
2210
SwitchValue,
2311
} from '../../types';
12+
import { MutuallyExclusive } from '../../utils';
13+
import {
14+
IsEnumValue,
15+
IsMultiValue,
16+
IsNamedValue,
17+
IsNestedValue,
18+
IsRequiredValue,
19+
IsSingleValue,
20+
IsSwitchValue,
21+
IsURLValue,
22+
IsVersionValue,
23+
} from './decorators';
2424

2525
class Compatibility implements CompatibilityValue {
2626
[x: string]: SingleValue;
2727

28-
@Expose()
29-
@IsOptional()
30-
@IsString()
31-
public readonly firefox?: string;
32-
33-
@Expose()
34-
@IsOptional()
35-
@IsString()
36-
public readonly chrome?: string;
37-
38-
@Expose()
39-
@IsOptional()
40-
@IsString()
41-
public readonly opera?: string;
42-
43-
@Expose()
44-
@IsOptional()
45-
@IsString()
46-
public readonly safari?: string;
47-
48-
@Expose()
49-
@IsOptional()
50-
@IsString()
51-
public readonly edge?: string;
28+
@IsSingleValue()
29+
public readonly firefox?: SingleValue;
30+
31+
@IsSingleValue()
32+
public readonly chrome?: SingleValue;
33+
34+
@IsSingleValue()
35+
public readonly opera?: SingleValue;
36+
37+
@IsSingleValue()
38+
public readonly safari?: SingleValue;
39+
40+
@IsSingleValue()
41+
public readonly edge?: SingleValue;
5242
}
5343

5444
export class Headers implements StrictHeadersProps {
55-
@Expose()
56-
@IsString()
45+
@IsRequiredValue()
5746
public readonly name!: SingleValue;
5847

59-
@Expose()
60-
@IsOptional()
61-
@IsSemVer()
48+
@IsVersionValue()
6249
public readonly version?: SingleValue;
6350

64-
@Expose()
65-
@IsOptional()
66-
@IsString()
51+
@IsSingleValue()
6752
public readonly namespace?: SingleValue;
6853

69-
@Expose()
70-
@IsOptional()
71-
@IsString()
54+
@IsSingleValue()
7255
public readonly author?: SingleValue;
7356

74-
@Expose()
75-
@IsOptional()
76-
@IsString()
57+
@IsSingleValue()
7758
public readonly description?: SingleValue;
7859

79-
@Expose()
80-
@IsOptional()
81-
@IsUrl()
60+
@IsURLValue()
61+
@MutuallyExclusive('homepage')
8262
public readonly homepage?: SingleValue;
8363

84-
@Expose()
85-
@IsOptional()
86-
@IsUrl()
64+
@IsURLValue()
65+
@MutuallyExclusive('homepage')
8766
public readonly homepageURL?: SingleValue;
8867

89-
@Expose()
90-
@IsOptional()
91-
@IsUrl()
68+
@IsURLValue()
69+
@MutuallyExclusive('homepage')
9270
public readonly website?: SingleValue;
9371

94-
@Expose()
95-
@IsOptional()
96-
@IsUrl()
72+
@IsURLValue()
73+
@MutuallyExclusive('homepage')
9774
public readonly source?: SingleValue;
9875

99-
@Expose()
100-
@IsOptional()
101-
@IsUrl()
76+
@IsURLValue()
77+
@MutuallyExclusive('icon')
10278
public readonly icon?: SingleValue;
10379

104-
@Expose()
105-
@IsOptional()
106-
@IsUrl()
80+
@IsURLValue()
81+
@MutuallyExclusive('icon')
10782
public readonly iconURL?: SingleValue;
10883

109-
@Expose()
110-
@IsOptional()
111-
@IsUrl()
84+
@IsURLValue()
85+
@MutuallyExclusive('icon')
11286
public readonly defaulticon?: SingleValue;
11387

114-
@Expose()
115-
@IsOptional()
116-
@IsUrl()
88+
@IsURLValue()
89+
@MutuallyExclusive('icon64')
11790
public readonly icon64?: SingleValue;
11891

119-
@Expose()
120-
@IsOptional()
121-
@IsUrl()
92+
@IsURLValue()
93+
@MutuallyExclusive('icon64')
12294
public readonly icon64URL?: SingleValue;
12395

124-
@Expose()
125-
@IsOptional()
126-
@IsUrl()
96+
@IsURLValue()
12797
public readonly updateURL?: SingleValue;
12898

129-
@Expose()
130-
@IsOptional()
131-
@IsUrl()
99+
@IsURLValue()
100+
@MutuallyExclusive('downloadURL')
132101
public readonly downloadURL?: SingleValue;
133102

134-
@Expose()
135-
@IsOptional()
136-
@IsUrl()
103+
@IsURLValue()
104+
@MutuallyExclusive('downloadURL')
137105
public readonly installURL?: SingleValue;
138106

139-
@Expose()
140-
@IsOptional()
141-
@IsUrl()
107+
@IsURLValue()
142108
public readonly supportURL?: SingleValue;
143109

144-
@Expose()
145-
@IsOptional()
146-
@IsString({ each: true })
110+
@IsMultiValue()
147111
public readonly include?: MultiValue;
148112

149-
@Expose()
150-
@IsOptional()
151-
@IsString({ each: true })
113+
@IsMultiValue()
152114
public readonly match?: MultiValue;
153115

154-
@Expose()
155-
@IsOptional()
156-
@IsString({ each: true })
116+
@IsMultiValue()
157117
public readonly 'exclude-match'?: MultiValue;
158118

159-
@Expose()
160-
@IsOptional()
161-
@IsString({ each: true })
119+
@IsMultiValue()
162120
public readonly exclude?: MultiValue;
163121

164-
@Expose()
165-
@IsOptional()
166-
@IsString({ each: true })
122+
@IsMultiValue()
167123
public readonly require?: MultiValue;
168124

169-
@Expose()
170-
@IsOptional()
171-
@IsObject()
125+
@IsNamedValue()
172126
public readonly resource?: NamedValue;
173127

174-
@Expose()
175-
@IsOptional()
176-
@IsString({ each: true })
128+
@IsMultiValue()
177129
public readonly connect?: MultiValue;
178130

179-
@Expose()
180-
@IsOptional()
181-
@IsString({ each: true })
131+
@IsMultiValue()
182132
public readonly grant?: MultiValue;
183133

184-
@Expose()
185-
@IsOptional()
186-
@IsString({ each: true })
134+
@IsMultiValue()
187135
public readonly webRequest?: MultiValue;
188136

189-
@Expose()
190-
@IsOptional()
191-
@IsBoolean()
137+
@IsSwitchValue()
192138
public readonly noframes?: SwitchValue;
193139

194-
@Expose()
195-
@IsOptional()
196-
@IsBoolean()
140+
@IsSwitchValue()
197141
public readonly unwrap?: SwitchValue;
198142

199-
@Expose()
200-
@IsOptional()
201-
@IsObject()
143+
@IsNamedValue()
202144
public readonly antifeature?: NamedValue;
203145

204-
@Expose()
205-
@IsOptional()
206-
@IsEnum(RunAt)
146+
@IsEnumValue(RunAt)
207147
public readonly 'run-at'?: RunAt;
208148

209-
@Expose()
210-
@IsOptional()
211-
@IsString()
149+
@IsSingleValue()
212150
public readonly copyright?: SingleValue;
213151

214-
@Expose()
215-
@IsOptional()
216-
@IsEnum(Sandbox)
152+
@IsEnumValue(Sandbox)
217153
public readonly sandbox?: Sandbox;
218154

219-
@Expose()
220-
@IsOptional()
221-
@IsEnum(InjectInto)
155+
@IsEnumValue(InjectInto)
222156
public readonly 'inject-into'?: InjectInto;
223157

224-
@Expose()
225-
@IsOptional()
226-
@IsString()
158+
@IsSingleValue()
227159
public readonly license?: SingleValue;
228160

229-
@Expose()
230-
@IsOptional()
231-
@IsUrl()
161+
@IsURLValue()
232162
public readonly contributionURL?: SingleValue;
233163

234-
@Expose()
235-
@IsOptional()
236-
@IsString()
164+
@IsSingleValue()
237165
public readonly contributionAmount?: SingleValue;
238166

239-
@Expose()
240-
@Type(() => Compatibility)
241-
@IsOptional()
242-
@ValidateNested()
167+
@IsNestedValue(Compatibility)
243168
public readonly compatible?: Compatibility;
244169

245-
@Expose()
246-
@Type(() => Compatibility)
247-
@IsOptional()
248-
@ValidateNested()
170+
@IsNestedValue(Compatibility)
249171
public readonly incompatible?: Compatibility;
250172
}

0 commit comments

Comments
 (0)