UNPKG

jswagger

Version:
195 lines (194 loc) 9.34 kB
"use strict"; 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;