Skip to content

Commit 6ecde5c

Browse files
Merge pull request #1427 from opencomponents/add-enum
add enum prop for params
2 parents aae3768 + 8e76424 commit 6ecde5c

File tree

4 files changed

+305
-43
lines changed

4 files changed

+305
-43
lines changed

src/registry/domain/validators/component-parameters.ts

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,44 @@ const validateParameter = (
77
): boolean => {
88
const expected = expectedType.toLowerCase();
99

10-
if (expected === 'boolean') {
11-
return typeof parameter === 'boolean';
10+
switch (expected) {
11+
case 'boolean':
12+
return typeof parameter === 'boolean';
13+
case 'number':
14+
return typeof parameter === 'number';
15+
case 'string':
16+
return typeof parameter === 'string';
17+
default:
18+
return false;
1219
}
13-
if (expected === 'number') {
14-
return typeof parameter === 'number';
15-
}
16-
if (expected === 'string') {
17-
return typeof parameter === 'string';
18-
}
19-
20-
return false;
2120
};
2221

2322
interface ValidationResult {
2423
isValid: boolean;
2524
errors: {
26-
mandatory?: Record<string, string>;
27-
types?: Record<string, string>;
28-
message?: string;
25+
mandatory: Record<string, string>;
26+
types: Record<string, string>;
27+
message: string;
2928
};
3029
}
3130

3231
export default function componentParameters(
3332
requestParameters: Record<string, string | number | boolean>,
3433
expectedParameters: Record<string, OcParameter> = {}
3534
): ValidationResult {
36-
const result: ValidationResult = { isValid: true, errors: {} };
37-
const mandatoryParameters: string[] = [];
38-
39-
for (const [expectedParameterName, expectedParameter] of Object.entries(
40-
expectedParameters
41-
)) {
42-
if (expectedParameter.mandatory) {
43-
mandatoryParameters.push(expectedParameterName);
44-
}
45-
}
35+
const result: ValidationResult = {
36+
isValid: true,
37+
errors: { mandatory: {}, types: {}, message: '' }
38+
};
39+
requestParameters = requestParameters || {};
40+
expectedParameters = expectedParameters || {};
41+
const mandatoryParameters: string[] = Object.entries(expectedParameters)
42+
.filter(([_, expectedParameter]) => expectedParameter.mandatory)
43+
.map(([expectedParameterName]) => expectedParameterName);
4644

4745
for (const mandatoryParameterName of mandatoryParameters) {
48-
if (
49-
typeof requestParameters === 'object' &&
50-
// biome-ignore lint/suspicious/noPrototypeBuiltins: hasOwnProperty is fine
51-
!requestParameters.hasOwnProperty(mandatoryParameterName)
52-
) {
53-
if (!result.errors.mandatory) {
54-
result.errors.mandatory = {};
55-
result.isValid = false;
56-
}
57-
46+
if (!(mandatoryParameterName in requestParameters)) {
47+
result.isValid = false;
5848
result.errors.mandatory[mandatoryParameterName] =
5949
strings.errors.registry.MANDATORY_PARAMETER_MISSING_CODE;
6050
}
@@ -63,21 +53,27 @@ export default function componentParameters(
6353
for (const [requestParameterName, requestParameter] of Object.entries(
6454
requestParameters
6555
)) {
66-
if (
67-
typeof expectedParameters === 'object' &&
68-
// biome-ignore lint/suspicious/noPrototypeBuiltins: hasOwnProperty is fine
69-
expectedParameters.hasOwnProperty(requestParameterName)
70-
) {
56+
if (expectedParameters[requestParameterName]) {
7157
const expectedType = expectedParameters[requestParameterName].type;
7258

7359
if (!validateParameter(requestParameter, expectedType)) {
74-
if (!result.errors.types) {
75-
result.errors.types = {};
76-
result.isValid = false;
77-
}
78-
60+
result.isValid = false;
7961
result.errors.types[requestParameterName] =
8062
strings.errors.registry.PARAMETER_WRONG_FORMAT_CODE;
63+
continue; // Skip enum validation if type validation fails
64+
}
65+
66+
const expectedValues = expectedParameters[requestParameterName].enum;
67+
if (
68+
expectedValues &&
69+
!(expectedValues as any).includes(requestParameter)
70+
) {
71+
result.isValid = false;
72+
result.errors.types[requestParameterName] =
73+
strings.errors.registry.PARAMETER_WRONG_VALUE(
74+
requestParameterName,
75+
expectedValues as string[]
76+
);
8177
}
8278
}
8379
}

src/resources/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ export default {
149149
PARAMETER_WRONG_FORMAT: (parameters: string): string =>
150150
`Parameters are not correctly formatted: ${parameters}`,
151151
PARAMETER_WRONG_FORMAT_CODE: 'wrong type',
152+
PARAMETER_WRONG_VALUE: (parameter: string, values: string[]): string =>
153+
`Parameter ${parameter} is not a valid value. Allowed values are: ${values.join(', ')}`,
154+
PARAMETER_WRONG_VALUE_CODE: 'wrong value',
152155
PLUGIN_NOT_IMPLEMENTED: (plugins: string): string =>
153156
`registry does not implement plugins: ${plugins}`,
154157
PLUGIN_NOT_VALID: (plugin: string): string =>

src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ export interface OcParameter {
5959
description?: string;
6060
example?: string;
6161
mandatory?: boolean;
62+
/**
63+
* You can optionally restrict the values of the parameter to a specific set of values.
64+
* @example
65+
* ```ts
66+
* {
67+
* type: 'string',
68+
* enum: ['foo', 'bar', 'baz']
69+
* }
70+
*/
71+
enum?: string[] | number[] | boolean[];
6272
type: 'string' | 'boolean' | 'number';
6373
}
6474

0 commit comments

Comments
 (0)