Skip to content

Commit 79aba63

Browse files
committed
Convert string as number to support numbers in query params
1 parent eadf9dc commit 79aba63

File tree

4 files changed

+107
-14
lines changed

4 files changed

+107
-14
lines changed

src/compileValueSchema.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,12 +616,48 @@ function compileNumberSchema(
616616
return [...nodes, ...enumCheck];
617617
}
618618

619+
// Try to convert the value to a number
619620
nodes.push(
620621
builders.ifStatement(
621622
builders.binaryExpression(
622-
'!==',
623+
'===',
623624
builders.unaryExpression('typeof', value),
624-
builders.literal('number'),
625+
builders.literal('string'),
626+
),
627+
builders.blockStatement([
628+
builders.expressionStatement(
629+
builders.assignmentExpression(
630+
'=',
631+
value,
632+
builders.callExpression(
633+
builders.memberExpression(
634+
builders.identifier('Number'),
635+
builders.identifier('parseFloat'),
636+
),
637+
[value],
638+
),
639+
),
640+
),
641+
]),
642+
),
643+
);
644+
645+
nodes.push(
646+
builders.ifStatement(
647+
builders.logicalExpression(
648+
'||',
649+
builders.binaryExpression(
650+
'!==',
651+
builders.unaryExpression('typeof', value),
652+
builders.literal('number'),
653+
),
654+
builders.callExpression(
655+
builders.memberExpression(
656+
builders.identifier('Number'),
657+
builders.identifier('isNaN'),
658+
),
659+
[value],
660+
),
625661
),
626662
builders.blockStatement([builders.returnStatement(error('expected a number'))]),
627663
),

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

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export class ValidationError extends RequestError {
2929
}
3030
}
3131
function obj0(path, value, context) {
32-
if (typeof value !== 'number') {
32+
if (typeof value === 'string') {
33+
value = Number.parseFloat(value);
34+
}
35+
if (typeof value !== 'number' || Number.isNaN(value)) {
3336
return new ValidationError(path, 'expected a number');
3437
}
3538
return value;
@@ -65,7 +68,10 @@ export class ValidationError extends RequestError {
6568
}
6669
}
6770
function obj0(path, value, context) {
68-
if (typeof value !== 'number') {
71+
if (typeof value === 'string') {
72+
value = Number.parseFloat(value);
73+
}
74+
if (typeof value !== 'number' || Number.isNaN(value)) {
6975
return new ValidationError(path, 'expected a number');
7076
}
7177
return value;
@@ -104,7 +110,10 @@ function obj0(path, value, context) {
104110
if (value === null) {
105111
return value;
106112
}
107-
if (typeof value !== 'number') {
113+
if (typeof value === 'string') {
114+
value = Number.parseFloat(value);
115+
}
116+
if (typeof value !== 'number' || Number.isNaN(value)) {
108117
return new ValidationError(path, 'expected a number');
109118
}
110119
return value;
@@ -256,7 +265,10 @@ export class ValidationError extends RequestError {
256265
}
257266
}
258267
function obj1(path, value, context) {
259-
if (typeof value !== 'number') {
268+
if (typeof value === 'string') {
269+
value = Number.parseFloat(value);
270+
}
271+
if (typeof value !== 'number' || Number.isNaN(value)) {
260272
return new ValidationError(path, 'expected a number');
261273
}
262274
return value;
@@ -331,7 +343,10 @@ export class ValidationError extends RequestError {
331343
}
332344
}
333345
function obj1(path, value, context) {
334-
if (typeof value !== 'number') {
346+
if (typeof value === 'string') {
347+
value = Number.parseFloat(value);
348+
}
349+
if (typeof value !== 'number' || Number.isNaN(value)) {
335350
return new ValidationError(path, 'expected a number');
336351
}
337352
return value;
@@ -425,7 +440,10 @@ export class ValidationError extends RequestError {
425440
}
426441
}
427442
function obj1(path, value, context) {
428-
if (typeof value !== 'number') {
443+
if (typeof value === 'string') {
444+
value = Number.parseFloat(value);
445+
}
446+
if (typeof value !== 'number' || Number.isNaN(value)) {
429447
return new ValidationError(path, 'expected a number');
430448
}
431449
return value;
@@ -482,7 +500,10 @@ export class ValidationError extends RequestError {
482500
}
483501
}
484502
function obj1(path, value, context) {
485-
if (typeof value !== 'number') {
503+
if (typeof value === 'string') {
504+
value = Number.parseFloat(value);
505+
}
506+
if (typeof value !== 'number' || Number.isNaN(value)) {
486507
return new ValidationError(path, 'expected a number');
487508
}
488509
return value;
@@ -713,7 +734,10 @@ export class ValidationError extends RequestError {
713734
}
714735
}
715736
function obj1(path, value, context) {
716-
if (typeof value !== 'number') {
737+
if (typeof value === 'string') {
738+
value = Number.parseFloat(value);
739+
}
740+
if (typeof value !== 'number' || Number.isNaN(value)) {
717741
return new ValidationError(path, 'expected a number');
718742
}
719743
return value;
@@ -766,7 +790,10 @@ export class ValidationError extends RequestError {
766790
}
767791
}
768792
function obj1(path, value, context) {
769-
if (typeof value !== 'number') {
793+
if (typeof value === 'string') {
794+
value = Number.parseFloat(value);
795+
}
796+
if (typeof value !== 'number' || Number.isNaN(value)) {
770797
return new ValidationError(path, 'expected a number');
771798
}
772799
return value;
@@ -826,7 +853,10 @@ export class ValidationError extends RequestError {
826853
}
827854
}
828855
function obj2(path, value, context) {
829-
if (typeof value !== 'number') {
856+
if (typeof value === 'string') {
857+
value = Number.parseFloat(value);
858+
}
859+
if (typeof value !== 'number' || Number.isNaN(value)) {
830860
return new ValidationError(path, 'expected a number');
831861
}
832862
return value;

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ export class ValidationError extends RequestError {
2929
}
3030
}
3131
function obj0(path, value, context) {
32-
if (typeof value !== 'number') {
32+
if (typeof value === 'string') {
33+
value = Number.parseFloat(value);
34+
}
35+
if (typeof value !== 'number' || Number.isNaN(value)) {
3336
return new ValidationError(path, 'expected a number');
3437
}
3538
return value;
@@ -102,7 +105,10 @@ export class ValidationError extends RequestError {
102105
}
103106
}
104107
function obj0(path, value, context) {
105-
if (typeof value !== 'number') {
108+
if (typeof value === 'string') {
109+
value = Number.parseFloat(value);
110+
}
111+
if (typeof value !== 'number' || Number.isNaN(value)) {
106112
return new ValidationError(path, 'expected a number');
107113
}
108114
return value;

tests/gitbook.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ test('GET orgs/microsoft/collections?limit=invalid', () => {
5555
expect(result instanceof ValidationError ? result.path : null).toEqual(['query', 'limit']);
5656
});
5757

58+
test('GET orgs/microsoft/collections?limit=10', () => {
59+
const result = validateRequest({
60+
path: '/orgs/microsoft/collections',
61+
method: 'get',
62+
headers: {
63+
'content-type': 'application/json',
64+
},
65+
query: {
66+
limit: '10',
67+
},
68+
});
69+
expect(result).toMatchObject({
70+
params: {
71+
organizationId: 'microsoft',
72+
},
73+
query: {
74+
limit: 10,
75+
},
76+
});
77+
});
78+
5879
test('POST orgs/appleId/custom-fields', () => {
5980
const result = validateRequest({
6081
path: '/orgs/appleId/spaces',

0 commit comments

Comments
 (0)