Skip to content

Commit

Permalink
Export all componentSchemas
Browse files Browse the repository at this point in the history
  • Loading branch information
SamyPesse committed Oct 6, 2024
1 parent 7ff89f7 commit 4860c2e
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 15 deletions.
40 changes: 40 additions & 0 deletions src/compileComponentSchemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { builders } from "ast-types";
import { Compiler } from "./compiler";
import { compileValueSchema } from "./compileValueSchema";
import { OpenAPIValueSchema } from "./types";
import { annotateWithJSDocComment } from "./comments";

const COMMENT = `
Map of all components defined in the spec to their validation functions.
`;

/**
* Compile all component schemas to be expoerted as `components['Name']`.
*/
export function compileComponentSchemas(compiler: Compiler, schemas: {
[key: string]: OpenAPIValueSchema;
}) {
const properties = Object.entries(schemas).map(([name]) => {
return builders.property(
'init',
builders.literal(name),
compileValueSchema(compiler, schemas[name]),
);
});

return [
annotateWithJSDocComment(
builders.exportNamedDeclaration(
builders.variableDeclaration('const', [
builders.variableDeclarator(
builders.identifier('componentSchemas'),
builders.objectExpression(
properties,
),
)
]),
),
COMMENT,
),
];
}
13 changes: 2 additions & 11 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { OpenAPIRef, OpenAPISpec } from './types';
import { compileValueSchema } from './compileValueSchema';
import { hash } from './hash';
import { compileValidateRequest } from './compileValidateRequest';
import { compileComponentSchemas } from './compileComponentSchemas';

/**
* Compiler for OpenAPI specs.
Expand Down Expand Up @@ -117,23 +118,13 @@ export class Compiler {
});
}

/**
* Build the AST from the entire spec.
*/
public indexAllComponents() {
// Index all the schema components.
const schemas = this.input.components?.schemas ?? {};
Object.values(schemas).forEach((schema) => {
compileValueSchema(this, schema);
});
}

/**
* Return the AST for the program.
*/
public ast() {
return builders.program([
...compileValidateRequest(this, this.input),
...compileComponentSchemas(this, this.input.components?.schemas ?? {}),
...this.globalDeclarations,
]);
}
Expand Down
84 changes: 84 additions & 0 deletions src/tests/__snapshots__/compileValueSchema.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -49,6 +53,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -91,6 +99,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -133,6 +145,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -175,6 +191,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -217,6 +237,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -256,6 +280,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -298,6 +326,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -334,6 +366,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -374,6 +410,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -414,6 +454,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -492,6 +536,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -552,6 +600,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -589,6 +641,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -649,6 +705,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -725,6 +785,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -768,6 +832,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -826,6 +894,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -883,6 +955,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -939,6 +1015,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -1002,6 +1082,10 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down
14 changes: 14 additions & 0 deletions src/tests/__snapshots__/compiler.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {
'A': obj0,
'B': obj1
};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down Expand Up @@ -86,6 +93,13 @@ Validate a request against the OpenAPI spec
export function validateRequest(request, context) {
return new RequestError(404, 'no operation match path');
}
/**
Map of all components defined in the spec to their validation functions.
*/
export const componentSchemas = {
'A': obj0,
'B': obj1
};
export class RequestError extends Error {
/** @param {number} code HTTP code for the error
@param {string} message The error message*/
Expand Down
2 changes: 0 additions & 2 deletions src/tests/compiler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ test('components ref', () => {
},
},
});
compiler.indexAllComponents();
expect(compiler.compile()).toMatchSnapshot();
});

Expand Down Expand Up @@ -50,6 +49,5 @@ test('recursive refs', () => {
},
},
});
compiler.indexAllComponents();
expect(compiler.compile()).toMatchSnapshot();
});
25 changes: 23 additions & 2 deletions tests/gitbook.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from 'bun:test';
import { validateRequest, ValidationError } from './gitbook.validate';
import { describe, expect, test } from 'bun:test';
import { validateRequest, ValidationError, componentSchemas } from './gitbook.validate';

test('POST orgs/appleId/custom-fields', () => {
const result = validateRequest({
Expand Down Expand Up @@ -287,3 +287,24 @@ test('/orgs/xxx/synced-blocks?ids[]=foo allow string parameter as array too', ()
});
expect(result.query).toEqual({ ids: ['foo'] });
});

describe('componentSchemas', () => {
test('should export a function to validate a component', () => {
const validate = componentSchemas['ApiInformation'];
expect(validate).toBeInstanceOf(Function);
expect(validate([], {
version: '1.0.0',
build: '123',
})).toEqual({
version: '1.0.0',
build: '123',
});

const error = validate([], {
version: '1.0.0',
// Missing property
})
expect(error instanceof ValidationError ? error.path : null).toEqual([]);
expect(error instanceof ValidationError ? error.message : null).toEqual('expected "build" to be defined');
});
});

0 comments on commit 4860c2e

Please sign in to comment.