UNPKG

retrofit-axios-ts

Version:

A declarative and axios based retrofit implementation for JavaScript and TypeScript.

520 lines (519 loc) 22 kB
"use strict"; 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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; 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 __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseService = void 0; /* eslint-disable @typescript-eslint/no-this-alias */ const qs = __importStar(require("qs")); const constants_1 = require("../constants"); const httpClient_1 = require("./httpClient"); const nonHTTPRequestMethod_1 = require("./helpers/nonHTTPRequestMethod"); const utils_1 = require("../utils"); const Data_1 = __importDefault(require("../resolvers/Data")); class BaseService { constructor(serviceBuilder) { this._endpoint = serviceBuilder.endpoint; this._httpClient = new httpClient_1.HttpClient(serviceBuilder); this._methodMap = new Map(); this._timeout = serviceBuilder.timeout; this._logCallback = serviceBuilder.logCallback; const methodNames = this._getInstanceMethodNames(); methodNames.forEach((methodName) => { this._methodMap[methodName] = this[methodName]; }); const self = this; for (const methodName of methodNames) { const descriptor = { enumerable: true, configurable: true, get() { const method = self._methodMap[methodName]; const methodOriginalDescriptor = Object.getOwnPropertyDescriptor(method, constants_1.NON_HTTP_REQUEST_PROPERTY_NAME); if (methodOriginalDescriptor && methodOriginalDescriptor.value === true) { return method; } if (methodName === "_logCallback") { return method; } return (...args) => __awaiter(this, void 0, void 0, function* () { return yield self._wrap(methodName, args); }); }, set: (newValue) => { self._methodMap[methodName] = newValue; }, }; Object.defineProperty(this, methodName, descriptor); } } isClientStandalone() { return this._httpClient.isStandalone(); } useRequestInterceptor(interceptor) { return this._httpClient.useRequestInterceptor(interceptor); } useResponseInterceptor(interceptor) { return this._httpClient.useResponseInterceptor(interceptor); } ejectRequestInterceptor(id) { this._httpClient.ejectRequestInterceptor(id); } ejectResponseInterceptor(id) { this._httpClient.ejectResponseInterceptor(id); } setEndpoint(endpoint) { this._endpoint = endpoint; } setLogCallback(logCallback) { this._logCallback = logCallback; } setTimeout(timeout) { this._timeout = timeout; } _getInstanceMethodNames() { let properties = []; let obj = this; do { properties = properties.concat(Object.getOwnPropertyNames(obj)); obj = Object.getPrototypeOf(obj); } while (obj); return properties.sort().filter((e, i, arr) => { return e !== arr[i + 1] && this[e] && typeof this[e] === "function"; }); } _wrap(methodName, args) { return __awaiter(this, void 0, void 0, function* () { const { url, method, headers, query, data, requestConfigParameters } = this._resolveParameters(methodName, args); const config = this._makeConfig(methodName, url, method, headers, query, data, requestConfigParameters); let error; let response; try { response = yield this._httpClient.sendRequest(config); } catch (err) { error = err; response = err.response; } if (this._logCallback) { this._logCallback(config, response); } if (error) { throw error; } return response; }); } _resolveParameters(methodName, args) { const url = this._resolveUrl(methodName, args); const method = this._resolveHttpMethod(methodName); let headers = this._resolveHeaders(methodName, args); const query = this._resolveQuery(methodName, args); const data = this._resolveData(methodName, headers, args); const signal = this._resolveSignal(methodName, args); const uploadProgressCallback = this._resolveUploadProgress(methodName, args); const downloadProgressCallback = this._resolveDownloadProgress(methodName, args); const requestConfigParameters = { signal, uploadProgress: uploadProgressCallback, downloadProgress: downloadProgressCallback, }; if (headers["content-type"] && headers["content-type"].indexOf("multipart/form-data") !== -1 && utils_1.isNode) { headers = Object.assign(Object.assign({}, headers), data.getHeaders()); } return { url, method, headers, query, data, requestConfigParameters }; } _makeConfig(methodName, url, method, headers, query, data, requestConfigParameters) { const { signal, uploadProgress, downloadProgress } = requestConfigParameters; let config = { url, method, headers, params: query, data, signal, onUploadProgress: uploadProgress, onDownloadProgress: downloadProgress, }; // response type if (this.__meta__[methodName].responseType) { config.responseType = this.__meta__[methodName].responseType; } // request transformer if (this.__meta__[methodName].requestTransformer) { config.transformRequest = this.__meta__[methodName].requestTransformer; } // response transformer if (this.__meta__[methodName].responseTransformer) { config.transformResponse = this.__meta__[methodName].responseTransformer; } // timeout config.timeout = this.__meta__[methodName].timeout || this._timeout; // deprecated if (this.__meta__[methodName].deprecated) { let hint = `[warning] Deprecated method: "${methodName}". `; if (this.__meta__[methodName].deprecatedHint) { // eslint-disable-next-line @typescript-eslint/restrict-plus-operands hint += this.__meta__[methodName].deprecatedHint; } // tslint:disable-next-line:no-console console.warn(hint); } // query array format if (this.__meta__[methodName].queryArrayFormat) { config.paramsSerializer = {}; config.paramsSerializer.serialize = (params) => { /* config.paramsSerializer.serialize = (params: any): string => { */ return qs.stringify(params, { arrayFormat: this.__meta__[methodName].queryArrayFormat, }); }; } // mix in config set by @Config config = Object.assign(Object.assign({}, config), this.__meta__[methodName].config); return config; } _resolveUrl(methodName, args) { const meta = this.__meta__; const endpoint = this._endpoint; const basePath = meta.basePath; const path = meta[methodName].path; const pathParams = meta[methodName].pathParams; const options = meta[methodName].options || {}; let url = this.makeURL(endpoint, basePath, path, options); for (const pos in pathParams) { if (pathParams[pos]) { url = url.replace(new RegExp(`\{${pathParams[pos]}}`), args[pos]); } } return url; } makeURL(endpoint, basePath, path, options) { const isAbsoluteURL = /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(path); if (isAbsoluteURL) { return path; } if (options.ignoreBasePath) { return [endpoint, path].join(""); } return [endpoint, basePath, path].join(""); } _resolveHttpMethod(methodName) { const meta = this.__meta__; return meta[methodName].method; } _resolveHeaders(methodName, args) { const meta = this.__meta__; const headers = meta[methodName].headers || {}; const headerParams = meta[methodName].headerParams; for (const pos in headerParams) { if (headerParams[pos]) { headers[headerParams[pos]] = args[pos]; } } const headerMapIndex = meta[methodName].headerMapIndex; if (headerMapIndex >= 0) { for (const key in args[headerMapIndex]) { if (args[headerMapIndex][key]) { headers[key] = args[headerMapIndex][key]; } } } return headers; } _resolveQuery(methodName, args) { const meta = this.__meta__; const query = meta[methodName].query || {}; const queryParams = meta[methodName].queryParams; for (const pos in queryParams) { if (queryParams[pos]) { query[queryParams[pos]] = args[pos]; } } const queryMapIndex = meta[methodName].queryMapIndex; if (queryMapIndex >= 0) { for (const key in args[queryMapIndex]) { if (args[queryMapIndex][key]) { query[key] = args[queryMapIndex][key]; } } } return query; } _resolveSignal(methodName, args) { const meta = this.__meta__; let signal; const abortSignal = meta[methodName].signal; if (abortSignal >= 0) { signal = args[abortSignal]; } return signal; } _resolveUploadProgress(methodName, args) { const meta = this.__meta__; let _uploadProgress; const uploadProgressIndex = meta[methodName].uploadProgressIndex; if (uploadProgressIndex >= 0) { _uploadProgress = args[uploadProgressIndex]; } return _uploadProgress; } _resolveDownloadProgress(methodName, args) { const meta = this.__meta__; let _downloadProgress; const downloadProgressIndex = meta[methodName].downloadProgressIndex; if (downloadProgressIndex >= 0) { _downloadProgress = args[downloadProgressIndex]; } return _downloadProgress; } _resolveData(methodName, headers, args) { const meta = this.__meta__; const bodyIndex = meta[methodName].bodyIndex; const fields = meta[methodName].fields || {}; const parts = meta[methodName].parts || {}; const fieldMapIndex = meta[methodName].fieldMapIndex; const gqlQuery = meta[methodName].gqlQuery; const gqlOperationName = meta[methodName].gqlOperationName; const gqlVariablesIndex = meta[methodName].gqlVariablesIndex; let data = {}; // @Body if (bodyIndex >= 0) { try { if (Array.isArray(args[bodyIndex])) { data = args[bodyIndex]; } else if (args[bodyIndex] instanceof File) { data = args[bodyIndex]; } else { data = Object.assign(Object.assign({}, data), args[bodyIndex]); } } catch (error) { data = Object.assign(Object.assign({}, data), args[bodyIndex]); } /* if (Array.isArray(args[bodyIndex])) { data = args[bodyIndex]; } else { data = { ...data, ...args[bodyIndex] }; } */ } // @Field if (Object.keys(fields).length > 0) { const reqData = {}; for (const pos in fields) { if (fields[pos]) { reqData[fields[pos]] = args[pos]; } } data = Object.assign(Object.assign({}, data), reqData); } // @FieldMap if (fieldMapIndex >= 0) { const reqData = {}; for (const key in args[fieldMapIndex]) { if (args[fieldMapIndex][key]) { reqData[key] = args[fieldMapIndex][key]; } } data = Object.assign(Object.assign({}, data), reqData); } // @MultiPart if (Object.keys(parts).length > 0) { const reqData = {}; for (const pos in parts) { if (parts[pos]) { reqData[parts[pos]] = args[pos]; } } data = Object.assign(Object.assign({}, data), reqData); } // @GraphQL if (gqlQuery) { data.query = gqlQuery; if (gqlOperationName) { data.operationName = gqlOperationName; } // @GraphQLVariables if (gqlVariablesIndex >= 0) { data.variables = args[gqlVariablesIndex]; } } const contentType = headers["content-type"] || "application/json"; const dataResolverFactory = new Data_1.default(); const dataResolver = dataResolverFactory.createDataResolver(contentType); return dataResolver.resolve(headers, data); } } __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Boolean) ], BaseService.prototype, "isClientStandalone", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Function]), __metadata("design:returntype", Number) ], BaseService.prototype, "useRequestInterceptor", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Function]), __metadata("design:returntype", Number) ], BaseService.prototype, "useResponseInterceptor", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0) ], BaseService.prototype, "ejectRequestInterceptor", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0) ], BaseService.prototype, "ejectResponseInterceptor", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", void 0) ], BaseService.prototype, "setEndpoint", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", void 0) ], BaseService.prototype, "setLogCallback", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0) ], BaseService.prototype, "setTimeout", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Array) ], BaseService.prototype, "_getInstanceMethodNames", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Promise) ], BaseService.prototype, "_wrap", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveParameters", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, String, String, Object, Object, Object, Object]), __metadata("design:returntype", Object) ], BaseService.prototype, "_makeConfig", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", String) ], BaseService.prototype, "_resolveUrl", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, String, String, Object]), __metadata("design:returntype", String) ], BaseService.prototype, "makeURL", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String]), __metadata("design:returntype", String) ], BaseService.prototype, "_resolveHttpMethod", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveHeaders", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveQuery", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveSignal", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveUploadProgress", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveDownloadProgress", null); __decorate([ nonHTTPRequestMethod_1.nonHTTPRequestMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [String, Object, Array]), __metadata("design:returntype", Object) ], BaseService.prototype, "_resolveData", null); exports.BaseService = BaseService;