Skip to content

Commit 80536fa

Browse files
committed
Validate query parameters
1 parent bf0ec65 commit 80536fa

File tree

4 files changed

+104
-23
lines changed

4 files changed

+104
-23
lines changed

README.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,8 @@ openapi-static-validator spec.json > validate.js
1616

1717
## TODOs
1818

19-
- Parameters:
20-
- [ ] in `cookie`
21-
- [ ] in `header`
22-
- [ ] in `query`
23-
- JSONSchema `integer`
24-
- [ ] no float
19+
- [ ] `in: header` and `in: cookie` parameters
20+
- [ ] validation of `type: integer`, not just as `number`
2521

2622
## Development
2723

src/compileOperation.ts

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,93 @@ export function compileOperation(
111111

112112
// Validate query parameters
113113
const queryParameters = (operation.parameters ?? []).filter(
114-
(parameter) => compiler.resolveMaybeRef(parameter).in === 'path',
114+
(parameter) => compiler.resolveMaybeRef(parameter).in === 'query',
115115
);
116-
queryParameters.forEach((parameter) => {});
116+
queryParameters.forEach((refParameter, index) => {
117+
const parameter = compiler.resolveMaybeRef(refParameter);
118+
const paramValueIdentifier = builders.identifier(`queryParam${index}`);
119+
const resultIdentifier = builders.identifier(`queryParamResult${index}`);
120+
const schemaFn = compileValueSchema(compiler, parameter.schema);
121+
122+
// Assign the query parameter to a variable
123+
nodes.push(
124+
builders.variableDeclaration('const', [
125+
builders.variableDeclarator(
126+
paramValueIdentifier,
127+
builders.memberExpression(
128+
builders.memberExpression(
129+
requestIdentifier,
130+
builders.identifier('query'),
131+
),
132+
builders.literal(parameter.name),
133+
true,
134+
),
135+
),
136+
]),
137+
);
138+
139+
nodes.push(
140+
builders.ifStatement(
141+
builders.binaryExpression(
142+
'===',
143+
paramValueIdentifier,
144+
builders.identifier('undefined'),
145+
),
146+
builders.blockStatement(
147+
parameter.required
148+
? [
149+
builders.returnStatement(
150+
buildRequestError(
151+
400,
152+
`query parameter ${parameter.name} is required`,
153+
),
154+
),
155+
]
156+
: [],
157+
),
158+
builders.blockStatement([
159+
// Validate the value
160+
builders.variableDeclaration('const', [
161+
builders.variableDeclarator(
162+
resultIdentifier,
163+
builders.callExpression(schemaFn, [
164+
builders.arrayExpression([
165+
builders.literal('query'),
166+
builders.literal(parameter.name),
167+
]),
168+
paramValueIdentifier,
169+
contextIdentifier,
170+
]),
171+
),
172+
]),
173+
// Fail if error
174+
builders.ifStatement(
175+
builders.binaryExpression(
176+
'instanceof',
177+
resultIdentifier,
178+
ValidationErrorIdentifier,
179+
),
180+
builders.blockStatement([builders.returnStatement(resultIdentifier)]),
181+
),
182+
// Otherwise assign the value
183+
builders.expressionStatement(
184+
builders.assignmentExpression(
185+
'=',
186+
builders.memberExpression(
187+
builders.memberExpression(
188+
requestIdentifier,
189+
builders.identifier('query'),
190+
),
191+
builders.literal(parameter.name),
192+
true,
193+
),
194+
resultIdentifier,
195+
),
196+
),
197+
]),
198+
),
199+
);
200+
});
117201

118202
// Validate the body against the schema
119203
if (operation.requestBody) {

tests/__snapshots__/gitbook.test.ts.snap

Lines changed: 0 additions & 14 deletions
This file was deleted.

tests/gitbook.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from 'bun:test';
2-
import { validateRequest } from './gitbook.validate';
2+
import { validateRequest, ValidationError } from './gitbook.validate';
33

44
test('POST /spaces/1234/hive/token', () => {
55
const result = validateRequest({
@@ -40,3 +40,18 @@ test('POST orgs/appleId/custom-fields', () => {
4040
},
4141
});
4242
});
43+
44+
test('GET orgs/microsoft/collections?limit=invalid', () => {
45+
const result = validateRequest({
46+
path: '/orgs/microsoft/collections',
47+
method: 'get',
48+
headers: {
49+
'content-type': 'application/json',
50+
},
51+
query: {
52+
limit: 'invalid',
53+
},
54+
});
55+
expect(result instanceof ValidationError).toBeTruthy();
56+
expect(result.path).toEqual(['query', 'limit']);
57+
});

0 commit comments

Comments
 (0)