Skip to content

Commit bf0ec65

Browse files
committed
Add support for checking format against context
1 parent f6e89ec commit bf0ec65

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ openapi-static-validator spec.json > validate.js
2020
- [ ] in `cookie`
2121
- [ ] in `header`
2222
- [ ] in `query`
23-
- JSONSchema `string` validation of:
24-
- [ ] `format`
2523
- JSONSchema `integer`
2624
- [ ] no float
2725

src/compileValueSchema.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ function compileNumberSchema(
622622
}
623623

624624
function compileStringSchema(compiler: Compiler, schema: OpenAPIStringSchema) {
625-
return compiler.declareValidationFunction(schema, ({ value, error }) => {
625+
return compiler.declareValidationFunction(schema, ({ value, context, path, error }) => {
626626
const enumCheck = compileEnumableCheck(compiler, schema, value, error);
627627
if (enumCheck) {
628628
return enumCheck;
@@ -641,6 +641,44 @@ function compileStringSchema(compiler: Compiler, schema: OpenAPIStringSchema) {
641641
),
642642
);
643643

644+
// Validate the format using the potential `context?.formatString?.[schema.format]`
645+
if (schema.format) {
646+
const formatResult = builders.identifier('formatResult');
647+
648+
nodes.push(
649+
builders.variableDeclaration('const', [
650+
builders.variableDeclarator(
651+
formatResult,
652+
builders.callExpression.from({
653+
callee: builders.memberExpression.from({
654+
object: builders.memberExpression.from({
655+
object: context,
656+
property: builders.identifier('formatString'),
657+
optional: true,
658+
}),
659+
property: builders.literal(schema.format),
660+
computed: true,
661+
optional: true,
662+
}),
663+
optional: true,
664+
arguments: [value, path],
665+
}),
666+
),
667+
]),
668+
);
669+
670+
nodes.push(
671+
builders.ifStatement(
672+
builders.binaryExpression(
673+
'instanceof',
674+
formatResult,
675+
ValidationErrorIdentifier,
676+
),
677+
builders.blockStatement([builders.returnStatement(formatResult)]),
678+
),
679+
);
680+
}
681+
644682
if (schema.minLength) {
645683
nodes.push(
646684
builders.ifStatement(

src/tests/__snapshots__/compileValueSchema.test.ts.snap

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,40 @@ function obj0(path, value, context) {
157157
}"
158158
`;
159159

160+
exports[`String with pattern 2`] = `
161+
"/**
162+
Validate a request against the OpenAPI spec
163+
@param {{ method: string; path: string; body?: any; query: Record<string, string>; headers: Record<string, string>; }} request - Input request to validate
164+
@param {{ stringFormats?: { [format: string]: (value: string, path: string[]) => ValidationError | null } }} [context] - Context object to pass to validation functions
165+
@returns {{ operationId?: string; params: Record<string, string>; query: Record<string, string>; body?: any; headers: Record<string, string>; }}
166+
*/
167+
export function validateRequest(request, context) {
168+
return new RequestError(404, 'no operation match path');
169+
}
170+
export class RequestError extends Error {
171+
constructor(code, message) {
172+
super(message);
173+
this.code = code;
174+
}
175+
}
176+
export class ValidationError extends RequestError {
177+
constructor(path, message) {
178+
super(409, message);
179+
this.path = path;
180+
}
181+
}
182+
function obj0(path, value, context) {
183+
if (typeof value !== 'string') {
184+
return new ValidationError(path, 'Expected a string');
185+
}
186+
const formatResult = context?.formatString?.['uri']?.(value, path);
187+
if (formatResult instanceof ValidationError) {
188+
return formatResult;
189+
}
190+
return value;
191+
}"
192+
`;
193+
160194
exports[`Objects with a required prop 1`] = `
161195
"/**
162196
Validate a request against the OpenAPI spec

src/tests/compileValueSchema.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ describe('String', () => {
5252
});
5353
expect(compiler.compile()).toMatchSnapshot();
5454
});
55+
56+
test('with pattern', () => {
57+
const compiler = new Compiler();
58+
compileValueSchema(compiler, {
59+
type: 'string',
60+
format: 'uri',
61+
});
62+
expect(compiler.compile()).toMatchSnapshot();
63+
});
5564
});
5665

5766
describe('Objects', () => {

0 commit comments

Comments
 (0)