@sleeksky/alt-swagger
Version:
A fluent, programmatic API for generating OpenAPI 3.0 specifications with TypeScript support. Define REST API endpoints, schemas, parameters, and security using a simple, chainable syntax.
227 lines • 7.78 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ref = void 0;
exports.tag = tag;
exports.server = server;
exports.get = get;
exports.post = post;
exports.put = put;
exports.patch = patch;
exports.del = del;
exports.security = security;
exports.swaggerDoc = swaggerDoc;
exports.reset = reset;
exports.remove = remove;
/**
Author: Yusuf Bhabhrawala
*/
require("./utils");
const _ = __importStar(require("lodash"));
const utils_1 = require("./utils");
const paths = {};
const components = {};
const tags = [];
const servers = [];
function reset() {
Object.keys(paths).forEach((key) => delete paths[key]);
Object.keys(components).forEach((key) => delete components[key]);
tags.splice(0, tags.length);
servers.splice(0, servers.length);
}
function server(url, description) {
servers.push({ url, description });
}
function api(opt) {
// Parse path for shortcuts: path?query^header??req#tag
let pathStr = opt.path.replace(/\s/g, "");
// Check for # (tag) - must be last in string
const hashIndex = pathStr.indexOf('#');
if (hashIndex !== -1) {
const tagFromPath = pathStr.substring(hashIndex + 1);
pathStr = pathStr.substring(0, hashIndex);
if (!opt.tag)
opt.tag = tagFromPath;
}
// Check for ?? (request body)
const doubleQIndex = pathStr.indexOf('??');
if (doubleQIndex !== -1) {
const reqFromPath = pathStr.substring(doubleQIndex + 2);
pathStr = pathStr.substring(0, doubleQIndex);
if (!opt.req)
opt.req = reqFromPath;
}
// Check for ^ (header)
const caretIndex = pathStr.indexOf('^');
if (caretIndex !== -1) {
const headerFromPath = pathStr.substring(caretIndex + 1);
pathStr = pathStr.substring(0, caretIndex);
if (!opt.header)
opt.header = headerFromPath;
}
// Check for ? (query)
const queryIndex = pathStr.indexOf('?');
if (queryIndex !== -1) {
const queryFromPath = pathStr.substring(queryIndex + 1);
pathStr = pathStr.substring(0, queryIndex);
if (!opt.query)
opt.query = queryFromPath;
}
// Use cleaned path
opt.path = pathStr;
let path = `${(0, utils_1.pathClean)(opt.path)}.${opt.method}`;
let spec = _.get(paths, path, null);
if (!spec) {
spec = { parameters: [], responses: {}, description: "" };
const pathParams = (0, utils_1.pathParameters)(opt.path);
if (pathParams.length > 0)
spec.parameters = pathParams;
_.set(paths, path, spec);
}
let ext = {};
const req = (flatSch) => {
let schema = flatSch.match(/^#/) ? { $ref: flatSch } : (0, utils_1.toSwaggerSchema)(flatSch);
spec.requestBody = {
content: { "application/json": { schema } },
};
return ext;
};
const res = (code, flatSch) => {
let schema = flatSch.match(/^#/) ? { $ref: flatSch } : (0, utils_1.toSwaggerSchema)(flatSch);
spec.responses[code] = {
content: { [schema.type === "string" ? "text/plain" : "application/json"]: { schema } },
description: "",
};
return ext;
};
const query = (strArr) => {
if (!_.isArray(strArr))
strArr = strArr.split(",");
strArr.forEach((str) => {
spec.parameters.push((0, utils_1.toParameter)('query', str));
});
return ext;
};
const header = (strArr) => {
if (!_.isArray(strArr))
strArr = strArr.split(",");
strArr.forEach((str) => {
spec.parameters.push((0, utils_1.toParameter)('header', str));
});
return ext;
};
const tag = (str) => { spec.tags = [str]; return ext; };
const summary = (str) => { spec.summary = str; return ext; };
const desc = (str) => { spec.description = str; return ext; };
const security = (str) => { spec.security = [{ [str]: [] }]; return ext; };
const deprecate = () => { spec.deprecated = true; return ext; };
const remove = () => { _.unset(paths, `${(0, utils_1.pathClean)(opt.path)}.${opt.method}`); };
const body = req; // alias for req
Object.assign(ext, { req, body, res, query, header, tag, summary, desc, deprecate, remove, security });
// support all ext in parameters
Object.keys(ext).forEach(k => {
if (opt[k])
ext[k](opt[k]);
});
Object.keys(opt).filter(k => k.match(/^[0-9]+$/)).forEach(k => ext.res(parseInt(k), opt[k]));
return ext;
}
function get(path = "", opt = {}) {
opt.method = "get";
opt.path = path;
return api(opt);
}
function post(path = "", opt = {}) {
opt.method = "post";
opt.path = path;
return api(opt);
}
function put(path = "", opt = {}) {
opt.method = "put";
opt.path = path;
return api(opt);
}
function patch(path = "", opt = {}) {
opt.method = "patch";
opt.path = path;
return api(opt);
}
function del(path = "", opt = {}) {
opt.method = "delete";
opt.path = path;
return api(opt);
}
function remove({ path, tag }) {
if (path)
_.unset(paths, `${(0, utils_1.pathClean)(path)}`);
if (tag) {
Object.keys(paths).forEach(p => {
Object.keys(paths[p]).forEach(method => {
if (paths[p][method].tags && paths[p][method].tags.includes(tag))
_.unset(paths[p], method);
});
});
}
}
function security(name, { type = "http", schema = "bearer", bearerFormat = null, required = true } = {}) {
components.securitySchemes = components.securitySchemes || {};
components.securitySchemes[name] = { type, scheme: schema, bearerFormat, "in": "header", required };
return `#/components/securitySchemes/${name}`;
}
function _ref({ type, name, def }) {
components[type] = components[type] || {};
components[type][name] = def;
return `#/components/${type}/${name}`;
}
const ref = {
schema(name, flatSch) {
return _ref({ type: "schemas", name, def: (0, utils_1.toSwaggerSchema)(flatSch) });
}
};
exports.ref = ref;
function tag(name, description) {
tags.push({ name, description });
}
function swaggerDoc(title) {
return {
info: { title: title || "", version: "1.0.0" },
openapi: "3.0.0",
servers,
tags,
paths,
components,
};
}
//# sourceMappingURL=index.js.map