UNPKG

@mbo-ez-angular/ez-http-client

Version:
467 lines (451 loc) 19.5 kB
import * as i1 from '@angular/common/http'; import * as i0 from '@angular/core'; import { Injectable } from '@angular/core'; import 'reflect-metadata'; var EzHttpRequestMethod; (function (EzHttpRequestMethod) { EzHttpRequestMethod[EzHttpRequestMethod["DELETE"] = 0] = "DELETE"; EzHttpRequestMethod[EzHttpRequestMethod["GET"] = 1] = "GET"; EzHttpRequestMethod[EzHttpRequestMethod["HEAD"] = 2] = "HEAD"; EzHttpRequestMethod[EzHttpRequestMethod["OPTIONS"] = 3] = "OPTIONS"; EzHttpRequestMethod[EzHttpRequestMethod["PATCH"] = 4] = "PATCH"; EzHttpRequestMethod[EzHttpRequestMethod["POST"] = 5] = "POST"; EzHttpRequestMethod[EzHttpRequestMethod["PUT"] = 6] = "PUT"; })(EzHttpRequestMethod || (EzHttpRequestMethod = {})); function EzHttpClient(apiPath, module) { return function (targetClass) { if (!apiPath || apiPath.length === 0) { apiPath = ''; } const apiBasePathDescriptor = { enumerable: true, configurable: true, writable: false, value: apiPath }; Object.defineProperty(targetClass, 'API_BASE_PATH', apiBasePathDescriptor); class EzHttpClientDecoratedClass extends targetClass { constructor(http) { super(); this.http = http; const httpClientPropertyDescriptor = { enumerable: true, configurable: true, writable: false, value: http }; Object.defineProperty(targetClass, 'HTTP_CLIENT', httpClientPropertyDescriptor); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: EzHttpClientDecoratedClass, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: EzHttpClientDecoratedClass, providedIn: module || 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: EzHttpClientDecoratedClass, decorators: [{ type: Injectable, args: [{ providedIn: module || 'root' }] }], ctorParameters: () => [{ type: i1.HttpClient }] }); return EzHttpClientDecoratedClass; }; } function EzHttpClientHeaders(headers) { return function (targetClass) { if (!headers) { headers = {}; } const apiHeadersDescriptor = { enumerable: true, configurable: true, writable: false, value: headers }; const parentClass = Object.getPrototypeOf(targetClass.prototype).constructor; Object.defineProperty((parentClass.name.toLowerCase() === 'object') ? targetClass : parentClass, 'EZ_HTTP_CLIENT_GLOBAL_HEADERS', apiHeadersDescriptor); return targetClass; }; } /** * Ez http client common response operators * * @param options Common response operators options * @returns decorator factory */ function EzHttpClientCommonResponseOperators(options) { return function (targetClass) { if (!options) { options = { operators: [] }; } if (!options.operators) { options.operators = []; } const apiHeadersDescriptor = { enumerable: true, configurable: true, writable: false, value: options }; const parentClass = Object.getPrototypeOf(targetClass.prototype).constructor; Object.defineProperty((parentClass.name.toLowerCase() === 'object') ? targetClass : parentClass, 'EZ_HTTP_CLIENT_COMMON_RESPONSE_OPERATORS', apiHeadersDescriptor); return targetClass; }; } const EZ_REQUEST_HEADER_META_KEY = `EzHttpHeader`; function EzHttpHeader(paramName) { return function (target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_REQUEST_HEADER_META_KEY, target, methodName) || []; requestParameters.push({ index: parameterIndex, paramName }); Reflect.defineMetadata(EZ_REQUEST_HEADER_META_KEY, requestParameters, target, methodName); }; } const EZ_REQUEST_QUERY_PARAMS_META_KEY = `EzHttpQueryParam`; function EzHttpQueryParam(paramName) { return function (target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_REQUEST_QUERY_PARAMS_META_KEY, target, methodName) || []; requestParameters.push({ index: parameterIndex, paramName }); Reflect.defineMetadata(EZ_REQUEST_QUERY_PARAMS_META_KEY, requestParameters, target, methodName); }; } const EZ_REQUEST_PART_DATA_META_KEY = `EzHttpPartData`; function EzHttpPartData(paramName) { return function (target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_REQUEST_PART_DATA_META_KEY, target, methodName) || []; requestParameters.push({ index: parameterIndex, paramName }); Reflect.defineMetadata(EZ_REQUEST_PART_DATA_META_KEY, requestParameters, target, methodName); }; } const EZ_REQUEST_PART_FILE_META_KEY = `EzHttpPartFile`; function EzHttpPartFile(paramName) { return function (target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_REQUEST_PART_FILE_META_KEY, target, methodName) || []; requestParameters.push({ index: parameterIndex, paramName }); Reflect.defineMetadata(EZ_REQUEST_PART_FILE_META_KEY, requestParameters, target, methodName); }; } const EZ_REQUEST_BODY_META_KEY = `EzHttpRequestBody`; function EzHttpRequestBody(target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_REQUEST_BODY_META_KEY, target, methodName) || []; if (requestParameters.length >= 1) { throw new Error('Only one body can be defined !'); } requestParameters.push({ index: parameterIndex, paramName: 'body' }); Reflect.defineMetadata(EZ_REQUEST_BODY_META_KEY, requestParameters, target, methodName); } const EZ_REQUEST_PARAMS_META_KEY = `EzHttpRequestParam`; function EzHttpRequestParam(paramName) { return function (target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_REQUEST_PARAMS_META_KEY, target, methodName) || []; requestParameters.push({ index: parameterIndex, paramName }); Reflect.defineMetadata(EZ_REQUEST_PARAMS_META_KEY, requestParameters, target, methodName); }; } const EZ_RESPONSE_META_KEY = `EzHttpResponse`; function EzHttpResponse(target, methodName, parameterIndex) { const requestParameters = Reflect.getOwnMetadata(EZ_RESPONSE_META_KEY, target, methodName) || []; if (requestParameters.length >= 1) { throw new Error('Only response mapping parameter can be defined !'); } requestParameters.push({ index: parameterIndex, paramName: 'response' }); Reflect.defineMetadata(EZ_RESPONSE_META_KEY, requestParameters, target, methodName); } // -------------------- DECORATORS -------------------- function EzHttpRequest(httpMethod, options) { return function (target, key, descriptor) { return apply(target, key, descriptor, httpMethod, options); }; } function EzHttpRequestDELETE(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.DELETE, options); }; } function EzHttpRequestGET(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.GET, options); }; } function EzHttpRequestHEAD(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.HEAD, options); }; } function EzHttpRequestOPTIONS(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.OPTIONS, options); }; } function EzHttpRequestPATCH(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.PATCH, options); }; } function EzHttpRequestPOST(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.POST, options); }; } function EzHttpRequestPUT(options) { return function (target, key, descriptor) { return apply(target, key, descriptor, EzHttpRequestMethod.PUT, options); }; } // -------------------- PRIVATE FUNCTIONS -------------------- /** * Resolve url to call * * @param targetObject The target object (the current object class) * @param hasParameters Indicate if the url has paameters * @param ezRequestParams The list of ezRequestParams * @param options The EzHttpRequest options * @param args The method arguments * @returns The resolved url */ function resolveUrl(targetObject, hasParameters, ezRequestParams, options, args) { let uri = options.path; // resolve uri parameters if (hasParameters && ezRequestParams.length > 0 && uri && uri.length > 0) { // replace all parameters ezRequestParams.forEach(paramDescriptor => { uri = uri?.replace(`{${paramDescriptor.paramName}}`, args[paramDescriptor.index]); }); } // build url let basePath = targetObject.constructor.API_BASE_PATH || ''; if (basePath.length > 0 && basePath.endsWith('/')) { basePath = basePath.substring(0, basePath.length - 1); } return `${basePath}${uri}`; } /** * Build the http options used pending http call * * @param options The EzHttpRequest options * @param ezQueryParams The list of query params (like ?name=Toto&surname=Titi) * @param ezRequestHeaders The list of request headers * @param args The list of method args * @param targetObject The target object (the current object class) * @returns The built HttpOptions */ function buildHttpOptions(options, ezQueryParams, ezRequestHeaders, args, targetObject) { const httpOptions = {}; const globalHeaders = targetObject.constructor.EZ_HTTP_CLIENT_GLOBAL_HEADERS; if (globalHeaders) { options.headers = Object.assign(globalHeaders, (options.headers || {})); } if (options.headers || options.consume) { httpOptions.headers = options.headers || {}; if (options.consume && options.consume.length > 0) { stripContentType(httpOptions); httpOptions.headers['Content-Type'] = options.consume; } } if (ezRequestHeaders?.length) { httpOptions.headers = httpOptions.headers || {}; ezRequestHeaders.forEach(paramDescriptor => { const paramValue = args[paramDescriptor.index]; if (paramValue) { // @ts-ignore: object is possibly 'null'. httpOptions.headers[paramDescriptor.paramName] = paramValue; } }); } if (options.responseType) { httpOptions.responseType = options.responseType; } // compute http query params if (ezQueryParams && ezQueryParams.length > 0) { httpOptions.params = {}; ezQueryParams.forEach(paramDescriptor => { const paramValue = args[paramDescriptor.index]; if (paramValue) { // @ts-ignore: object is possibly 'null'. httpOptions.params[paramDescriptor.paramName] = paramValue; } }); } return httpOptions; } /** * Remove content-type header * * @param httpOptions The http options */ function stripContentType(httpOptions) { if (!httpOptions) { return; } for (const key in httpOptions.headers) { if (key.toLowerCase() === 'content-type') { delete httpOptions.headers[key]; } } } /** * Do the http call * * @param httpClient The http client instance to use * @param url The url to call * @param httpMethod The http method to use * @param httpOptions The http call options * @param body The request body * @param responseOperators rxjs operators to apply to the response */ function doCall(httpClient, url, httpMethod, httpOptions, body, responseOperators) { let responseObservable; switch (httpMethod) { case EzHttpRequestMethod.DELETE: responseObservable = httpClient.delete(url, httpOptions); break; case EzHttpRequestMethod.GET: responseObservable = httpClient.get(url, httpOptions); break; case EzHttpRequestMethod.HEAD: responseObservable = httpClient.head(url, httpOptions); break; case EzHttpRequestMethod.OPTIONS: responseObservable = httpClient.options(url, httpOptions); break; case EzHttpRequestMethod.PATCH: responseObservable = httpClient.patch(url, body, httpOptions); break; case EzHttpRequestMethod.POST: responseObservable = httpClient.post(url, body, httpOptions); break; case EzHttpRequestMethod.PUT: responseObservable = httpClient.put(url, body, httpOptions); break; } if (responseOperators && responseOperators.length > 0) { responseOperators.forEach(op => responseObservable = responseObservable.pipe(op)); } return responseObservable; } /** * Apply the task * * @param target The target object (the current object class) * @param key The current method name * @param descriptor The method descriptor * @param httpMethod The http method to do * @param options The ez http request options * @returns The method updated descriptor */ function apply(target, key, descriptor, httpMethod, options) { if (!options) { options = {}; } if (options.path && options.path.length > 0 && !options.path.startsWith('/')) { options.path = '/' + options.path; } else if (!options.path) { options.path = ''; } let ezRequestParams = []; const hasParameters = !!options.path.match(/{\w+}/g); if (hasParameters) { ezRequestParams = Reflect.getOwnMetadata(EZ_REQUEST_PARAMS_META_KEY, target, key.toString()) || []; } const ezQueryParams = Reflect.getOwnMetadata(EZ_REQUEST_QUERY_PARAMS_META_KEY, target, key.toString()) || []; const ezRequestHeaders = Reflect.getOwnMetadata(EZ_REQUEST_HEADER_META_KEY, target, key.toString()) || []; const ezBody = Reflect.getOwnMetadata(EZ_REQUEST_BODY_META_KEY, target, key.toString()); const ezPartDatas = Reflect.getOwnMetadata(EZ_REQUEST_PART_DATA_META_KEY, target, key.toString()) || []; const ezPartFiles = Reflect.getOwnMetadata(EZ_REQUEST_PART_FILE_META_KEY, target, key.toString()) || []; const ezResponseMapper = Reflect.getOwnMetadata(EZ_RESPONSE_META_KEY, target, key.toString()); const originalMethod = descriptor.value; descriptor.value = (...args) => { // try to get http client instance const httpClient = target.constructor.HTTP_CLIENT; if (!httpClient) { throw new Error('Unable to get http client instance !'); } const url = resolveUrl(target, hasParameters, ezRequestParams, options, args); const httpOptions = buildHttpOptions(options, ezQueryParams, ezRequestHeaders, args, target); const body = ezBody?.length ? args[ezBody[0].index] : {}; const multiPartFormData = buildMultipartFormData(args, ezPartDatas, ezPartFiles, body); if (!!multiPartFormData) { stripContentType(httpOptions); console.log(httpOptions); } const commonOperatorsOptions = target.constructor.EZ_HTTP_CLIENT_COMMON_RESPONSE_OPERATORS; if (!options.responseOperators) { options.responseOperators = { operators: [] }; } const operators = []; if (commonOperatorsOptions && commonOperatorsOptions.operators && commonOperatorsOptions.operators.length && options.responseOperators.skipGlobalCommonsOperators !== true) { if (commonOperatorsOptions.before) { operators.push(...commonOperatorsOptions.operators); operators.push(...options.responseOperators.operators); } else { operators.push(...options.responseOperators.operators); operators.push(...commonOperatorsOptions.operators); } } else { operators.push(...options.responseOperators.operators); } const response = doCall(httpClient, url, httpMethod, httpOptions, !!multiPartFormData ? multiPartFormData : body, operators); if (ezResponseMapper && ezResponseMapper.length > 0) { args[ezResponseMapper[0].index] = response; return originalMethod(...args); } return response; }; return descriptor; } /** * Build multipart form data if necessary * * @param args Method args * @param ezPartDatas Part data descriptor array * @param ezPartFiles Part file descriptor array * @param body Request body * @returns FormData or undefined */ function buildMultipartFormData(args, ezPartDatas, ezPartFiles, body) { const buildFormData = (ezPartDatas && !!ezPartDatas.length) || (ezPartFiles && !!ezPartFiles.length); if (buildFormData) { const formData = new FormData(); (ezPartDatas || []).forEach(data => { const value = args[data.index]; // if type of value is not string then build blob otherwise push as is if (typeof value === 'string') { formData.append(data.paramName, value); } else { formData.append(data.paramName, new Blob([JSON.stringify(value)], { type: "application/json" })); } }); (ezPartFiles || []).forEach(data => { const value = args[data.index]; // if type of value is not File or Blob then ignore if (value instanceof File || value instanceof Blob) { formData.append(data.paramName, value); } }); if (!!body && Object.keys(body).length > 0) { // if type of body is not string then build blob otherwise push as is if (typeof body === 'string') { formData.append('body', body); } else { formData.append('body', new Blob([JSON.stringify(body)], { type: "application/json" })); } } return formData; } return undefined; } /* * Public API Surface of ez-http-client-lib */ /** * Generated bundle index. Do not edit. */ export { EZ_REQUEST_BODY_META_KEY, EZ_REQUEST_HEADER_META_KEY, EZ_REQUEST_PARAMS_META_KEY, EZ_REQUEST_PART_DATA_META_KEY, EZ_REQUEST_PART_FILE_META_KEY, EZ_REQUEST_QUERY_PARAMS_META_KEY, EZ_RESPONSE_META_KEY, EzHttpClient, EzHttpClientCommonResponseOperators, EzHttpClientHeaders, EzHttpHeader, EzHttpPartData, EzHttpPartFile, EzHttpQueryParam, EzHttpRequest, EzHttpRequestBody, EzHttpRequestDELETE, EzHttpRequestGET, EzHttpRequestHEAD, EzHttpRequestMethod, EzHttpRequestOPTIONS, EzHttpRequestPATCH, EzHttpRequestPOST, EzHttpRequestPUT, EzHttpRequestParam, EzHttpResponse }; //# sourceMappingURL=mbo-ez-angular-ez-http-client.mjs.map