@vulcan-sql/build
Version:
VulcanSQL package for building projects
221 lines • 8.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OAS3SpecGenerator = void 0;
const tslib_1 = require("tslib");
const specGenerator_1 = require("../../../../models/extensions/specGenerator");
const core_1 = require("@vulcan-sql/core");
const lodash_1 = require("lodash");
let OAS3SpecGenerator = class OAS3SpecGenerator extends specGenerator_1.SpecGenerator {
constructor() {
super(...arguments);
// Follow the OpenAPI specification version 3.0.3
// see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md
this.oaiVersion = '3.0.3';
}
getSpec(schemas) {
const spec = {
openapi: this.getOAIVersion(),
info: this.getInfo(),
paths: this.getPaths(schemas),
};
return spec;
}
getOAIVersion() {
return this.oaiVersion;
}
getInfo() {
return {
title: this.getName(),
version: this.getVersion(),
description: this.getDescription(),
};
}
getPaths(schemas) {
const paths = {};
for (const schema of schemas) {
paths[this.convertToOASPath(schema.urlPath)] = this.getPath(schema);
}
return paths;
}
getPath(schema) {
return {
get: this.getOperationObject(schema, 'get'),
};
}
// "/user/:id" -> "/user/{id}"
convertToOASPath(path) {
return path.replace(/:([^/]+)/g, (_, param) => {
return `{${param}}`;
});
}
getOperationObject(schema, operation) {
return {
operationId: `${operation}${schema.urlPath}`,
summary: schema.urlPath,
description: schema.description,
responses: this.getResponsesObject(schema),
parameters: this.getParameterObject(schema),
};
}
getParameterObject(schema) {
const parameters = [];
const requests = schema.request || [];
for (const param of requests) {
parameters.push({
name: param.fieldName,
in: this.convertFieldInTypeToOASIn(param.fieldIn),
schema: this.getSchemaObjectFromParameter(param),
required: this.isParameterRequired(param),
description: param.description,
});
}
return parameters;
}
convertFieldInTypeToOASIn(fieldInType) {
switch (fieldInType) {
case core_1.FieldInType.HEADER:
return 'header';
case core_1.FieldInType.PATH:
return 'path';
case core_1.FieldInType.QUERY:
return 'query';
default:
throw new core_1.ConfigurationError(`FieldInType ${fieldInType} is not supported`);
}
}
getSchemaObjectFromParameter(parameter) {
const schema = {
type: this.convertFieldDataTypeToOASType(parameter.type),
};
for (const constraint of parameter.constraints) {
if (constraint instanceof core_1.MinValueConstraint) {
schema.minimum = constraint.getMinValue();
schema.exclusiveMinimum = constraint.isExclusive();
}
else if (constraint instanceof core_1.MaxValueConstraint) {
schema.maximum = constraint.getMaxValue();
schema.exclusiveMaximum = constraint.isExclusive();
}
else if (constraint instanceof core_1.MinLengthConstraint) {
schema.minLength = constraint.getMinLength();
}
else if (constraint instanceof core_1.MaxLengthConstraint) {
schema.maxLength = constraint.getMaxLength();
}
else if (constraint instanceof core_1.RegexConstraint) {
schema.pattern = constraint.getRegex();
}
else if (constraint instanceof core_1.EnumConstraint) {
schema.enum = constraint.getList();
}
else if (constraint instanceof core_1.TypeConstraint) {
schema.type = constraint.getType();
}
}
return schema;
}
convertFieldDataTypeToOASType(fieldDataType) {
switch (fieldDataType) {
case core_1.FieldDataType.BOOLEAN:
return 'boolean';
case core_1.FieldDataType.NUMBER:
return 'number';
case core_1.FieldDataType.STRING:
return 'string';
default:
throw new core_1.ConfigurationError(`FieldDataType ${fieldDataType} is not supported`);
}
}
isParameterRequired(parameter) {
return parameter.constraints.some((constraint) => constraint instanceof core_1.RequiredConstraint);
}
getResponsesObject(schema) {
const clientError = {
description: 'Client error',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
code: { type: 'string' },
message: { type: 'string' },
},
},
examples: this.getErrorCodes(schema.errors || []),
},
},
};
return {
'200': {
description: 'The default response',
content: {
'application/json': {
schema: this.getSchemaObjectFroResponseProperties(schema.response || []),
},
'text/csv': {
schema: {
type: 'string',
},
},
},
},
'400': (0, lodash_1.isEmpty)(clientError.content['application/json'].examples)
? undefined
: clientError,
'5XX': {
description: 'Server error',
},
};
}
getSchemaObjectFroResponseProperties(responseProperties) {
const required = responseProperties
.filter((property) => property.required)
.map((property) => property.name);
const properties = {};
for (const property of responseProperties) {
properties[property.name] =
this.getSchemaObjectFroResponseProperty(property);
}
return {
type: 'object',
properties,
required: required.length === 0 ? undefined : required,
};
}
getSchemaObjectFroResponseProperty(responseProperty) {
const basicContent = {
description: responseProperty.description,
};
if (responseProperty.type === core_1.FieldDataType.BOOLEAN) {
return Object.assign(Object.assign({}, basicContent), { type: 'boolean' });
}
else if (responseProperty.type === core_1.FieldDataType.STRING) {
return Object.assign(Object.assign({}, basicContent), { type: 'string' });
}
else if (responseProperty.type === core_1.FieldDataType.NUMBER) {
return Object.assign(Object.assign({}, basicContent), { type: 'number' });
}
else {
return Object.assign(Object.assign({}, basicContent), this.getSchemaObjectFroResponseProperties(responseProperty.type || []));
}
}
getErrorCodes(errorInfos) {
const examples = {};
for (const errorInfo of errorInfos) {
examples[errorInfo.code] = {
description: errorInfo.message,
value: {
code: errorInfo.code,
message: errorInfo.message,
},
};
}
return examples;
}
};
OAS3SpecGenerator = tslib_1.__decorate([
(0, core_1.VulcanInternalExtension)(),
(0, core_1.VulcanExtensionId)(core_1.DocumentSpec.oas3)
], OAS3SpecGenerator);
exports.OAS3SpecGenerator = OAS3SpecGenerator;
//# sourceMappingURL=oas3SpecGenerator.js.map