jswagger
Version:
195 lines (194 loc) • 9.34 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = __importDefault(require("axios"));
const node_json_bigint_1 = __importDefault(require("node-json-bigint"));
const url = __importStar(require("url"));
const types_1 = require("./types");
const jswagger_common_1 = require("jswagger-common");
function extractRef(ref) {
const refMatcher = /#\/(\w+)\/(.*)/.exec(ref);
if (!refMatcher) {
return null;
}
return {
type: refMatcher[1],
name: refMatcher[2]
};
}
const REGEX_CONTENT_TYPE_APPLICATION_JSON = /application\/json(?:\s*;\s*charset=([a-zA-Z0-9_-]+))?/;
function jsonTransformResponse(data, headers) {
const jsonCheck = headers['content-type'] && REGEX_CONTENT_TYPE_APPLICATION_JSON.exec(headers['content-type']);
if (jsonCheck) {
let text = data;
if (jsonCheck[1]) {
text = Buffer.from(data, jsonCheck[1]).toString('utf8');
}
return node_json_bigint_1.default.parse(text);
}
return data;
}
function urlConcat(a, b) {
if (a.length && b.length) {
const ta = a.charAt(a.length - 1) === '/';
const tb = b.charAt(0) === '/';
if (ta === tb) {
if (ta) {
return a.concat(b.substring(1));
}
else {
return a.concat('/', b);
}
}
}
return a.concat(b);
}
class SwaggerClient {
constructor(config) {
this._config = config;
if (config.baseUrl) {
this._baseUrl = config.baseUrl;
}
else {
this._baseUrl = url.format({
protocol: config.protocol || config.spec.protocol || 'http',
host: config.host || config.spec.host,
pathname: config.spec.basePath
});
}
}
static urlConcat(a, b) {
return urlConcat(a, b);
}
api(api, options) {
const _options = options || {};
const self = this;
const apis = jswagger_common_1.findApisByTag(this._config.spec, api.tag);
const proxy = {};
const definitionClasses = api.specMetadata.classes.reduce((results, clazz) => {
const definitionName = api.specMetadata.getSwaggerDefinitionName(clazz);
results.set(definitionName, clazz);
return results;
}, new Map());
apis.forEach(item => {
let apiPath = item.path;
Object.defineProperty(proxy, item.api.operationId, {
get: () => function () {
const callOptions = arguments[0];
const securityContext = _options['securityContext'] || self._config.securityContext;
const optBody = callOptions && callOptions['body'];
const optParams = callOptions && callOptions['params'];
const reqBody = optBody;
let reqHeaders = {};
let reqQueries = {};
if (optParams) {
item.api.parameters.forEach(parameterInfo => {
if (parameterInfo.in === 'header') {
const foundItem = Object.entries(optParams).find(([key, value]) => key === parameterInfo.name);
if (foundItem) {
reqHeaders[parameterInfo.name] = foundItem[1];
}
}
else if (parameterInfo.in === 'query') {
const foundItem = Object.entries(optParams).find(([key, value]) => key === parameterInfo.name);
if (foundItem) {
reqQueries[parameterInfo.name] = foundItem[1];
}
}
else if (parameterInfo.in === 'path') {
const foundItem = Object.entries(optParams).find(([key, value]) => key === parameterInfo.name);
if (foundItem) {
apiPath = apiPath.replace(`{${parameterInfo.name}}`, foundItem[1]);
}
}
});
}
const apiUrl = new url.URL(urlConcat(self._baseUrl, apiPath));
if (securityContext) {
if (securityContext.headerReplacer) {
reqHeaders = securityContext.headerReplacer(reqHeaders);
}
if (securityContext.queryReplacer) {
reqQueries = securityContext.queryReplacer(reqQueries);
}
}
return ((() => {
if (['get', 'delete', 'head', 'options'].includes(item.method)) {
return axios_1.default[item.method](apiUrl.toString(), {
headers: reqHeaders,
params: reqQueries,
httpAgent: self._config.httpAgent,
httpsAgent: self._config.httpsAgent,
transformResponse: jsonTransformResponse
});
}
else {
return axios_1.default[item.method](apiUrl.toString(), reqBody, {
headers: reqHeaders,
params: reqQueries,
httpAgent: self._config.httpAgent,
httpsAgent: self._config.httpsAgent,
transformResponse: jsonTransformResponse
});
}
})())
.then(res => {
const responseDefinition = item.api.responses && item.api.responses[res.status.toString()];
const responseRef = responseDefinition && responseDefinition.schema && extractRef(responseDefinition.schema.$ref);
const responseClazz = responseRef && definitionClasses.get(responseRef.name);
const out = Object.assign({}, res);
if (responseClazz) {
out.data = new responseClazz({
schema: res.data
});
}
return out;
})
.catch((err) => {
if (err.response) {
const responseDefinition = item.api.responses && item.api.responses[err.response.status.toString()];
const responseRef = responseDefinition && responseDefinition.schema && responseDefinition.schema.$ref;
const responseDefinitionClass = (() => {
const refMatcher = extractRef(responseRef);
if (!refMatcher) {
return undefined;
}
return api.specMetadata.classes
.find(v => api.specMetadata.getSwaggerDefinitionName(v) === refMatcher.name);
})();
const responseVO = responseDefinitionClass ?
new responseDefinitionClass({
schema: err.response.data
}) : err.response.data;
return Promise.reject(new types_1.ApiError({
message: responseDefinition ? responseDefinition.description || err.message : err.message,
code: err.code || 'ApiError',
status: err.response.status,
data: responseVO,
headers: err.response.headers,
axiosError: err,
axiosConfig: err.config,
axiosRequest: err.request,
axiosResponse: err.response
}));
}
else {
return Promise.reject(err);
}
});
}
});
});
return proxy;
}
}
exports.default = SwaggerClient;