Skip to content

Commit 4860c2e

Browse files
committed
Export all componentSchemas
1 parent 7ff89f7 commit 4860c2e

File tree

6 files changed

+163
-15
lines changed

6 files changed

+163
-15
lines changed

src/compileComponentSchemas.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { builders } from "ast-types";
2+
import { Compiler } from "./compiler";
3+
import { compileValueSchema } from "./compileValueSchema";
4+
import { OpenAPIValueSchema } from "./types";
5+
import { annotateWithJSDocComment } from "./comments";
6+
7+
const COMMENT = `
8+
Map of all components defined in the spec to their validation functions.
9+
`;
10+
11+
/**
12+
* Compile all component schemas to be expoerted as `components['Name']`.
13+
*/
14+
export function compileComponentSchemas(compiler: Compiler, schemas: {
15+
[key: string]: OpenAPIValueSchema;
16+
}) {
17+
const properties = Object.entries(schemas).map(([name]) => {
18+
return builders.property(
19+
'init',
20+
builders.literal(name),
21+
compileValueSchema(compiler, schemas[name]),
22+
);
23+
});
24+
25+
return [
26+
annotateWithJSDocComment(
27+
builders.exportNamedDeclaration(
28+
builders.variableDeclaration('const', [
29+
builders.variableDeclarator(
30+
builders.identifier('componentSchemas'),
31+
builders.objectExpression(
32+
properties,
33+
),
34+
)
35+
]),
36+
),
37+
COMMENT,
38+
),
39+
];
40+
}

src/compiler.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { OpenAPIRef, OpenAPISpec } from './types';
55
import { compileValueSchema } from './compileValueSchema';
66
import { hash } from './hash';
77
import { compileValidateRequest } from './compileValidateRequest';
8+
import { compileComponentSchemas } from './compileComponentSchemas';
89

910
/**
1011
* Compiler for OpenAPI specs.
@@ -117,23 +118,13 @@ export class Compiler {
117118
});
118119
}
119120

120-
/**
121-
* Build the AST from the entire spec.
122-
*/
123-
public indexAllComponents() {
124-
// Index all the schema components.
125-
const schemas = this.input.components?.schemas ?? {};
126-
Object.values(schemas).forEach((schema) => {
127-
compileValueSchema(this, schema);
128-
});
129-
}
130-
131121
/**
132122
* Return the AST for the program.
133123
*/
134124
public ast() {
135125
return builders.program([
136126
...compileValidateRequest(this, this.input),
127+
...compileComponentSchemas(this, this.input.components?.schemas ?? {}),
137128
...this.globalDeclarations,
138129
]);
139130
}

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

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Validate a request against the OpenAPI spec
1010
export function validateRequest(request, context) {
1111
return new RequestError(404, 'no operation match path');
1212
}
13+
/**
14+
Map of all components defined in the spec to their validation functions.
15+
*/
16+
export const componentSchemas = {};
1317
export class RequestError extends Error {
1418
/** @param {number} code HTTP code for the error
1519
@param {string} message The error message*/
@@ -49,6 +53,10 @@ Validate a request against the OpenAPI spec
4953
export function validateRequest(request, context) {
5054
return new RequestError(404, 'no operation match path');
5155
}
56+
/**
57+
Map of all components defined in the spec to their validation functions.
58+
*/
59+
export const componentSchemas = {};
5260
export class RequestError extends Error {
5361
/** @param {number} code HTTP code for the error
5462
@param {string} message The error message*/
@@ -91,6 +99,10 @@ Validate a request against the OpenAPI spec
9199
export function validateRequest(request, context) {
92100
return new RequestError(404, 'no operation match path');
93101
}
102+
/**
103+
Map of all components defined in the spec to their validation functions.
104+
*/
105+
export const componentSchemas = {};
94106
export class RequestError extends Error {
95107
/** @param {number} code HTTP code for the error
96108
@param {string} message The error message*/
@@ -133,6 +145,10 @@ Validate a request against the OpenAPI spec
133145
export function validateRequest(request, context) {
134146
return new RequestError(404, 'no operation match path');
135147
}
148+
/**
149+
Map of all components defined in the spec to their validation functions.
150+
*/
151+
export const componentSchemas = {};
136152
export class RequestError extends Error {
137153
/** @param {number} code HTTP code for the error
138154
@param {string} message The error message*/
@@ -175,6 +191,10 @@ Validate a request against the OpenAPI spec
175191
export function validateRequest(request, context) {
176192
return new RequestError(404, 'no operation match path');
177193
}
194+
/**
195+
Map of all components defined in the spec to their validation functions.
196+
*/
197+
export const componentSchemas = {};
178198
export class RequestError extends Error {
179199
/** @param {number} code HTTP code for the error
180200
@param {string} message The error message*/
@@ -217,6 +237,10 @@ Validate a request against the OpenAPI spec
217237
export function validateRequest(request, context) {
218238
return new RequestError(404, 'no operation match path');
219239
}
240+
/**
241+
Map of all components defined in the spec to their validation functions.
242+
*/
243+
export const componentSchemas = {};
220244
export class RequestError extends Error {
221245
/** @param {number} code HTTP code for the error
222246
@param {string} message The error message*/
@@ -256,6 +280,10 @@ Validate a request against the OpenAPI spec
256280
export function validateRequest(request, context) {
257281
return new RequestError(404, 'no operation match path');
258282
}
283+
/**
284+
Map of all components defined in the spec to their validation functions.
285+
*/
286+
export const componentSchemas = {};
259287
export class RequestError extends Error {
260288
/** @param {number} code HTTP code for the error
261289
@param {string} message The error message*/
@@ -298,6 +326,10 @@ Validate a request against the OpenAPI spec
298326
export function validateRequest(request, context) {
299327
return new RequestError(404, 'no operation match path');
300328
}
329+
/**
330+
Map of all components defined in the spec to their validation functions.
331+
*/
332+
export const componentSchemas = {};
301333
export class RequestError extends Error {
302334
/** @param {number} code HTTP code for the error
303335
@param {string} message The error message*/
@@ -334,6 +366,10 @@ Validate a request against the OpenAPI spec
334366
export function validateRequest(request, context) {
335367
return new RequestError(404, 'no operation match path');
336368
}
369+
/**
370+
Map of all components defined in the spec to their validation functions.
371+
*/
372+
export const componentSchemas = {};
337373
export class RequestError extends Error {
338374
/** @param {number} code HTTP code for the error
339375
@param {string} message The error message*/
@@ -374,6 +410,10 @@ Validate a request against the OpenAPI spec
374410
export function validateRequest(request, context) {
375411
return new RequestError(404, 'no operation match path');
376412
}
413+
/**
414+
Map of all components defined in the spec to their validation functions.
415+
*/
416+
export const componentSchemas = {};
377417
export class RequestError extends Error {
378418
/** @param {number} code HTTP code for the error
379419
@param {string} message The error message*/
@@ -414,6 +454,10 @@ Validate a request against the OpenAPI spec
414454
export function validateRequest(request, context) {
415455
return new RequestError(404, 'no operation match path');
416456
}
457+
/**
458+
Map of all components defined in the spec to their validation functions.
459+
*/
460+
export const componentSchemas = {};
417461
export class RequestError extends Error {
418462
/** @param {number} code HTTP code for the error
419463
@param {string} message The error message*/
@@ -492,6 +536,10 @@ Validate a request against the OpenAPI spec
492536
export function validateRequest(request, context) {
493537
return new RequestError(404, 'no operation match path');
494538
}
539+
/**
540+
Map of all components defined in the spec to their validation functions.
541+
*/
542+
export const componentSchemas = {};
495543
export class RequestError extends Error {
496544
/** @param {number} code HTTP code for the error
497545
@param {string} message The error message*/
@@ -552,6 +600,10 @@ Validate a request against the OpenAPI spec
552600
export function validateRequest(request, context) {
553601
return new RequestError(404, 'no operation match path');
554602
}
603+
/**
604+
Map of all components defined in the spec to their validation functions.
605+
*/
606+
export const componentSchemas = {};
555607
export class RequestError extends Error {
556608
/** @param {number} code HTTP code for the error
557609
@param {string} message The error message*/
@@ -589,6 +641,10 @@ Validate a request against the OpenAPI spec
589641
export function validateRequest(request, context) {
590642
return new RequestError(404, 'no operation match path');
591643
}
644+
/**
645+
Map of all components defined in the spec to their validation functions.
646+
*/
647+
export const componentSchemas = {};
592648
export class RequestError extends Error {
593649
/** @param {number} code HTTP code for the error
594650
@param {string} message The error message*/
@@ -649,6 +705,10 @@ Validate a request against the OpenAPI spec
649705
export function validateRequest(request, context) {
650706
return new RequestError(404, 'no operation match path');
651707
}
708+
/**
709+
Map of all components defined in the spec to their validation functions.
710+
*/
711+
export const componentSchemas = {};
652712
export class RequestError extends Error {
653713
/** @param {number} code HTTP code for the error
654714
@param {string} message The error message*/
@@ -725,6 +785,10 @@ Validate a request against the OpenAPI spec
725785
export function validateRequest(request, context) {
726786
return new RequestError(404, 'no operation match path');
727787
}
788+
/**
789+
Map of all components defined in the spec to their validation functions.
790+
*/
791+
export const componentSchemas = {};
728792
export class RequestError extends Error {
729793
/** @param {number} code HTTP code for the error
730794
@param {string} message The error message*/
@@ -768,6 +832,10 @@ Validate a request against the OpenAPI spec
768832
export function validateRequest(request, context) {
769833
return new RequestError(404, 'no operation match path');
770834
}
835+
/**
836+
Map of all components defined in the spec to their validation functions.
837+
*/
838+
export const componentSchemas = {};
771839
export class RequestError extends Error {
772840
/** @param {number} code HTTP code for the error
773841
@param {string} message The error message*/
@@ -826,6 +894,10 @@ Validate a request against the OpenAPI spec
826894
export function validateRequest(request, context) {
827895
return new RequestError(404, 'no operation match path');
828896
}
897+
/**
898+
Map of all components defined in the spec to their validation functions.
899+
*/
900+
export const componentSchemas = {};
829901
export class RequestError extends Error {
830902
/** @param {number} code HTTP code for the error
831903
@param {string} message The error message*/
@@ -883,6 +955,10 @@ Validate a request against the OpenAPI spec
883955
export function validateRequest(request, context) {
884956
return new RequestError(404, 'no operation match path');
885957
}
958+
/**
959+
Map of all components defined in the spec to their validation functions.
960+
*/
961+
export const componentSchemas = {};
886962
export class RequestError extends Error {
887963
/** @param {number} code HTTP code for the error
888964
@param {string} message The error message*/
@@ -939,6 +1015,10 @@ Validate a request against the OpenAPI spec
9391015
export function validateRequest(request, context) {
9401016
return new RequestError(404, 'no operation match path');
9411017
}
1018+
/**
1019+
Map of all components defined in the spec to their validation functions.
1020+
*/
1021+
export const componentSchemas = {};
9421022
export class RequestError extends Error {
9431023
/** @param {number} code HTTP code for the error
9441024
@param {string} message The error message*/
@@ -1002,6 +1082,10 @@ Validate a request against the OpenAPI spec
10021082
export function validateRequest(request, context) {
10031083
return new RequestError(404, 'no operation match path');
10041084
}
1085+
/**
1086+
Map of all components defined in the spec to their validation functions.
1087+
*/
1088+
export const componentSchemas = {};
10051089
export class RequestError extends Error {
10061090
/** @param {number} code HTTP code for the error
10071091
@param {string} message The error message*/

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ Validate a request against the OpenAPI spec
1010
export function validateRequest(request, context) {
1111
return new RequestError(404, 'no operation match path');
1212
}
13+
/**
14+
Map of all components defined in the spec to their validation functions.
15+
*/
16+
export const componentSchemas = {
17+
'A': obj0,
18+
'B': obj1
19+
};
1320
export class RequestError extends Error {
1421
/** @param {number} code HTTP code for the error
1522
@param {string} message The error message*/
@@ -86,6 +93,13 @@ Validate a request against the OpenAPI spec
8693
export function validateRequest(request, context) {
8794
return new RequestError(404, 'no operation match path');
8895
}
96+
/**
97+
Map of all components defined in the spec to their validation functions.
98+
*/
99+
export const componentSchemas = {
100+
'A': obj0,
101+
'B': obj1
102+
};
89103
export class RequestError extends Error {
90104
/** @param {number} code HTTP code for the error
91105
@param {string} message The error message*/

src/tests/compiler.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ test('components ref', () => {
2222
},
2323
},
2424
});
25-
compiler.indexAllComponents();
2625
expect(compiler.compile()).toMatchSnapshot();
2726
});
2827

@@ -50,6 +49,5 @@ test('recursive refs', () => {
5049
},
5150
},
5251
});
53-
compiler.indexAllComponents();
5452
expect(compiler.compile()).toMatchSnapshot();
5553
});

tests/gitbook.test.ts

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

44
test('POST orgs/appleId/custom-fields', () => {
55
const result = validateRequest({
@@ -287,3 +287,24 @@ test('/orgs/xxx/synced-blocks?ids[]=foo allow string parameter as array too', ()
287287
});
288288
expect(result.query).toEqual({ ids: ['foo'] });
289289
});
290+
291+
describe('componentSchemas', () => {
292+
test('should export a function to validate a component', () => {
293+
const validate = componentSchemas['ApiInformation'];
294+
expect(validate).toBeInstanceOf(Function);
295+
expect(validate([], {
296+
version: '1.0.0',
297+
build: '123',
298+
})).toEqual({
299+
version: '1.0.0',
300+
build: '123',
301+
});
302+
303+
const error = validate([], {
304+
version: '1.0.0',
305+
// Missing property
306+
})
307+
expect(error instanceof ValidationError ? error.path : null).toEqual([]);
308+
expect(error instanceof ValidationError ? error.message : null).toEqual('expected "build" to be defined');
309+
});
310+
});

0 commit comments

Comments
 (0)