@carlsberg/openapi-aws-extensions
Version:
A library that adds API Gateway extensions to OpenAPI specification files
125 lines (124 loc) • 5.41 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addExtensions = void 0;
const aws_apigateway_1 = require("@aws-cdk/aws-apigateway");
const fs_1 = __importDefault(require("fs"));
const http_1 = require("http");
const openapi3_ts_1 = require("openapi3-ts");
const path_1 = __importDefault(require("path"));
const yaml = __importStar(require("yaml"));
function specFromJSON(str) {
return new openapi3_ts_1.OpenApiBuilder(JSON.parse(str));
}
function specFromYaml(str) {
return new openapi3_ts_1.OpenApiBuilder(yaml.parse(str));
}
function extensionForOperation(method, op, options) {
if (method === 'options') {
if (!options.cors) {
return {};
}
return {
type: aws_apigateway_1.IntegrationType.MOCK,
passthroughBehavior: aws_apigateway_1.PassthroughBehavior.WHEN_NO_MATCH,
timeoutInMillis: options.cors.timeout,
requestTemplates: { 'application/json': '{"statusCode": 200}' },
responses: {
default: {
statusCode: 200,
responseParameters: {
'method.response.header.Access-Control-Allow-Methods': "'GET,OPTIONS,POST'",
'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
'method.response.header.Access-Control-Allow-Origin': "'*'"
}
}
}
};
}
return {
type: aws_apigateway_1.IntegrationType.AWS_PROXY,
httpMethod: 'POST',
uri: `arn:\${AWS::Partition}:apigateway:\${AWS::Region}:lambda:path/2015-03-31/functions/arn:\${AWS::Partition}:lambda:\${AWS::Region}:\${AWS::AccountId}:function:${options.lambdaFunctionName}/invocations`,
passthroughBehavior: aws_apigateway_1.PassthroughBehavior.WHEN_NO_MATCH,
contentHandling: aws_apigateway_1.ContentHandling.CONVERT_TO_TEXT,
responses: Object.keys(op.responses).reduce((responses, statusCode) => {
// const response: ResponseObject = op.responses[statusCode]
return Object.assign(Object.assign({}, responses), { [statusCode]: { statusCode } });
}, {})
};
}
function addExtensionsToPath(pathItem, options) {
for (const method of http_1.METHODS.map(m => m.toLowerCase())) {
const operation = pathItem[method];
if (!operation) {
continue;
}
const extension = extensionForOperation(method, operation, options);
pathItem[method] = extension
? Object.assign(Object.assign({}, operation), { 'x-amazon-apigateway-integration': extension }) : operation;
}
return pathItem;
}
function addExtensions(input, options = { outputFormat: 'yaml' }) {
if (!options.lambdaFunctionName) {
throw new Error(`openapi-aws-extensions currently only supports Lambda integrations. The \`lambdaFunctionName\` option is required.`);
}
let builder;
if (typeof input === 'string') {
if (fs_1.default.existsSync(input) === false) {
throw new Error(`No specification file at path: ${input}`);
}
const ext = path_1.default.extname(input).replace('.', '');
const fileContents = fs_1.default.readFileSync(input, 'utf-8');
switch (ext) {
case 'json':
builder = specFromJSON(fileContents);
break;
case 'yml':
case 'yaml':
builder = specFromYaml(fileContents);
break;
default:
throw new Error(`Unsupported specification file extension: "${ext}"`);
}
if (options.outputFormat !== ext) {
options.outputFormat = ext === 'yml' ? 'yaml' : ext;
}
}
else {
builder = new openapi3_ts_1.OpenApiBuilder(input);
}
for (const pathName of Object.keys(builder.rootDoc.paths)) {
builder.rootDoc.paths[pathName] = addExtensionsToPath(builder.rootDoc.paths[pathName], options);
}
const result = options.outputFormat === 'json'
? builder.getSpecAsJson()
: builder.getSpecAsYaml();
if (options.outputFile) {
fs_1.default.writeFileSync(options.outputFile, result, { encoding: 'utf-8' });
}
return result;
}
exports.addExtensions = addExtensions;