Skip to content

Commit b98c7bd

Browse files
export schema validator
1 parent 7e70626 commit b98c7bd

File tree

3 files changed

+50
-47
lines changed

3 files changed

+50
-47
lines changed

src/validate/validate_schema.ts

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import {ValidationError} from '../error/validation_error';
2-
import {getType} from '../util/get_type';
3-
import {deepUnbundle, unbundle} from '../util/unbundle_jsonlint';
4-
import { isObjectLiteral } from '../util/is_object_literal';
5-
6-
/**
7-
* Validates a schema object to ensure it adheres to the expected structure and rules.
8-
*
9-
* @param value - The schema object to validate. Can be of any type.
10-
* @param key - The key associated with the schema being validated.
11-
* @returns An array of `ValidationError` objects if validation fails, or the result of specific type validation functions.
12-
* @throws ValidationError - If the schema does not meet the required structure or contains invalid properties.
13-
*/
14-
export function validateSchema(value: unknown, key: string) {
1+
import { ValidationError } from "../error/validation_error";
2+
import { getType } from "../util/get_type";
3+
import { deepUnbundle, unbundle } from "../util/unbundle_jsonlint";
4+
import { isObjectLiteral } from "../util/is_object_literal";
5+
6+
interface ValidateSchemaOptions {
7+
key: string;
8+
value: unknown;
9+
}
10+
11+
export function validateSchema({
12+
key,
13+
value,
14+
}: ValidateSchemaOptions): ValidationError[] {
1515
if (!isObjectLiteral(value)) {
1616
return [
1717
new ValidationError(
@@ -31,28 +31,26 @@ export function validateSchema(value: unknown, key: string) {
3131
];
3232
}
3333
if (value.default === undefined) {
34-
return [
35-
new ValidationError(`${key}`, value, 'default is required'),
36-
];
34+
return [new ValidationError(`${key}`, value, "default is required")];
3735
}
3836

3937
switch (unbundle(value.type)) {
40-
case 'string':
38+
case "string":
4139
return validateString(value, key);
42-
case 'number':
40+
case "number":
4341
return validateNumber(value, key);
44-
case 'boolean':
42+
case "boolean":
4543
return validateBoolean(value, key);
46-
case 'array': {
44+
case "array": {
4745
return validateArray(value, key);
4846
}
4947
default: {
5048
if (value.type !== undefined) {
5149
return [
5250
new ValidationError(
53-
'type',
51+
"type",
5452
value.type,
55-
'expected string, number or boolean'
53+
"expected string, number or boolean"
5654
),
5755
];
5856
}
@@ -63,9 +61,9 @@ export function validateSchema(value: unknown, key: string) {
6361
}
6462

6563
function validateString(schema: Record<string, unknown>, key: string) {
66-
if (typeof unbundle(schema.default) !== 'string') {
64+
if (typeof unbundle(schema.default) !== "string") {
6765
return [
68-
new ValidationError(`${key}.default`, schema.default, 'string expected'),
66+
new ValidationError(`${key}.default`, schema.default, "string expected"),
6967
];
7068
}
7169

@@ -78,25 +76,25 @@ function validateNumber(schema: Record<string, unknown>, key: string) {
7876
new ValidationError(
7977
`${key}.default`,
8078
schema.default,
81-
'default is required'
79+
"default is required"
8280
),
8381
];
8482
}
8583

86-
if (typeof defaultValue !== 'number') {
84+
if (typeof defaultValue !== "number") {
8785
return [
88-
new ValidationError(`${key}.default`, schema.default, 'number expected'),
86+
new ValidationError(`${key}.default`, schema.default, "number expected"),
8987
];
9088
}
9189

9290
if (schema.minimum !== undefined) {
9391
const minimum = unbundle(schema.minimum);
94-
if (typeof minimum !== 'number') {
92+
if (typeof minimum !== "number") {
9593
return [
9694
new ValidationError(
9795
`${key}.default`,
9896
schema.default,
99-
'must be a number'
97+
"must be a number"
10098
),
10199
];
102100
}
@@ -114,12 +112,12 @@ function validateNumber(schema: Record<string, unknown>, key: string) {
114112

115113
if (schema.maximum !== undefined) {
116114
const maximum = unbundle(schema.maximum);
117-
if (typeof maximum !== 'number') {
115+
if (typeof maximum !== "number") {
118116
return [
119117
new ValidationError(
120118
`${key}.default`,
121119
schema.default,
122-
'must be a number'
120+
"must be a number"
123121
),
124122
];
125123
}
@@ -141,7 +139,7 @@ function validateNumber(schema: Record<string, unknown>, key: string) {
141139
function validateEnum(schema: Record<string, unknown>, key: string) {
142140
if (!Array.isArray(schema.enum)) {
143141
return [
144-
new ValidationError(`${key}.enum`, schema.enum, 'expected an array'),
142+
new ValidationError(`${key}.enum`, schema.enum, "expected an array"),
145143
];
146144
}
147145

@@ -150,7 +148,7 @@ function validateEnum(schema: Record<string, unknown>, key: string) {
150148
new ValidationError(
151149
`${key}.enum`,
152150
schema.enum,
153-
'expected at least 1 element'
151+
"expected at least 1 element"
154152
),
155153
];
156154
}
@@ -162,7 +160,7 @@ function validateEnum(schema: Record<string, unknown>, key: string) {
162160
new ValidationError(
163161
`${key}.default`,
164162
schema.default,
165-
'expected one of the enum values: ' + schema.enum.join(', ')
163+
"expected one of the enum values: " + schema.enum.join(", ")
166164
),
167165
];
168166
}
@@ -173,17 +171,17 @@ function validateEnum(schema: Record<string, unknown>, key: string) {
173171
function validateArray(schema: Record<string, unknown>, key: string) {
174172
if (!Array.isArray(schema.default)) {
175173
return [
176-
new ValidationError(`${key}.default`, schema.default, 'array expected'),
174+
new ValidationError(`${key}.default`, schema.default, "array expected"),
177175
];
178176
}
179177

180178
if (schema.items === undefined) {
181-
return [new ValidationError(`${key}.items`, schema.items, 'is required')];
179+
return [new ValidationError(`${key}.items`, schema.items, "is required")];
182180
}
183181

184182
if (!isObjectLiteral(schema.items)) {
185183
return [
186-
new ValidationError(`${key}.items`, schema.items, 'object expected'),
184+
new ValidationError(`${key}.items`, schema.items, "object expected"),
187185
];
188186
}
189187

@@ -201,13 +199,13 @@ function validateArray(schema: Record<string, unknown>, key: string) {
201199

202200
for (let index = 0; index < schema.default.length; index++) {
203201
const item = schema.default[index];
204-
const itemErrors = validateSchema(
205-
{
202+
const itemErrors = validateSchema({
203+
key: `${key}[${index}]`,
204+
value: {
206205
...schema.items,
207206
default: item,
208207
},
209-
`${key}[${index}]`
210-
);
208+
});
211209

212210
errors.push(...itemErrors);
213211
}
@@ -216,9 +214,9 @@ function validateArray(schema: Record<string, unknown>, key: string) {
216214
}
217215

218216
function validateBoolean(schema: Record<string, unknown>, key: string) {
219-
if (typeof unbundle(schema.default) != 'boolean') {
217+
if (typeof unbundle(schema.default) != "boolean") {
220218
return [
221-
new ValidationError(`${key}.default`, schema.default, 'boolean expected'),
219+
new ValidationError(`${key}.default`, schema.default, "boolean expected"),
222220
];
223221
}
224222

src/validate/validate_state.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {ValidationError} from '../error/validation_error';
22
import {getType} from '../util/get_type';
3-
import { isObjectLiteral } from '../util/is_object_literal';
4-
import { validateSchema } from './validate_schema';
3+
import {isObjectLiteral} from '../util/is_object_literal';
4+
import {validateSchema} from './validate_schema';
55

66
interface ValidateStateOptions {
77
key: 'state';
@@ -22,7 +22,10 @@ export function validateState(options: ValidateStateOptions) {
2222
const errors = [];
2323
for (const key in options.value) {
2424
const schema = options.value[key];
25-
const propertyErrors = validateSchema(schema, `${options.key}.${key}`);
25+
const propertyErrors = validateSchema({
26+
key: `${options.key}.${key}`,
27+
value: schema,
28+
});
2629
errors.push(...propertyErrors);
2730
}
2831
return errors;

src/validate_style.min.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {validatePaintProperty} from './validate/validate_paint_property';
1414
import {validateLayoutProperty} from './validate/validate_layout_property';
1515
import {validateSprite} from './validate/validate_sprite';
1616
import {validateGlyphsUrl} from './validate/validate_glyphs_url';
17+
import {validateSchema} from './validate/validate_schema';
1718
import {ValidationError} from './error/validation_error';
1819
import type {StyleSpecification} from './types.g';
1920

@@ -72,6 +73,7 @@ validateStyleMin.layer = wrapCleanErrors(injectValidateSpec(validateLayer));
7273
validateStyleMin.filter = wrapCleanErrors(injectValidateSpec(validateFilter));
7374
validateStyleMin.paintProperty = wrapCleanErrors(injectValidateSpec(validatePaintProperty));
7475
validateStyleMin.layoutProperty = wrapCleanErrors(injectValidateSpec(validateLayoutProperty));
76+
validateStyleMin.schema = wrapCleanErrors(injectValidateSpec(validateSchema));
7577

7678
function injectValidateSpec(validator: (options: object) => any) {
7779
return function(options) {

0 commit comments

Comments
 (0)