UNPKG

13.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const rx_http_request_1 = require("@akanass/rx-http-request");
4const operators_1 = require("rxjs/operators");
5require("reflect-metadata");
6const rx_http_request_2 = require("@akanass/rx-http-request/lib/rx-http-request");
7/**
8 *
9 */
10const pathParamMetadataKey = Symbol('__pathParam__');
11const queryMetadataKey = Symbol('__queryParam__');
12const classMetadataKey = Symbol('__class__');
13const bodyMetadataKey = Symbol('__body__');
14const pathParamPropertyMetadataKey = Symbol('__pathParamProperty__');
15const mapperMetadataKey = Symbol('__mapper__');
16const headersMetadataKey = Symbol('__headers__');
17const beforeMetadataKey = Symbol('__headers__');
18const exceptionHandlerMetadataKey = Symbol('__handlerError__');
19/**
20 *
21 */
22class Http extends rx_http_request_2.RxHttpRequest {
23 /**
24 *
25 * @param {T} interceptor
26 */
27 static addInterceptor(interceptor) {
28 this.interceptors.unshift(new interceptor());
29 }
30 /**
31 *
32 * @param {string | Partial<ConfigHttp>} config
33 * @returns {(target) => void}
34 */
35 static client(config) {
36 return target => Reflect.defineMetadata(classMetadataKey, config, target);
37 }
38 /**
39 *
40 * @param {string} url
41 * @param {Function} component
42 * @param {number} statusCodeOk
43 * @returns {Function}
44 */
45 static get(url, component, statusCodeOk = 400) {
46 return this.request('get', url, component, statusCodeOk);
47 }
48 /**
49 *
50 * @param {string} url
51 * @param {Function} component
52 * @param {number} statusCodeOk
53 * @returns {Function}
54 */
55 static post(url, component, statusCodeOk = 400) {
56 return this.request('post', url, component, statusCodeOk);
57 }
58 /**
59 *
60 * @param {string} url
61 * @param {Function} component
62 * @param {number} statusCodeOk
63 * @returns {Function}
64 */
65 static put(url, component, statusCodeOk = 400) {
66 return this.request('put', url, component, statusCodeOk);
67 }
68 /**
69 *
70 * @param {string} url
71 * @param {Function} component
72 * @param {number} statusCodeOk
73 * @returns {Function}
74 */
75 static patch(url, component, statusCodeOk = 400) {
76 return this.request('patch', url, component, statusCodeOk);
77 }
78 /**
79 *
80 * @param {string} url
81 * @param {Function} component
82 * @param {number} statusCodeOk
83 * @returns {Function}
84 */
85 static delete(url, component, statusCodeOk = 400) {
86 return this.request('delete', url, component, statusCodeOk);
87 }
88 /**
89 * @param {string} method
90 * @param {string} url
91 * @param {Function} component
92 * @param {number} statusCodeOk
93 * @returns {(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => void}
94 */
95 static request(method, urlToMatch, component, statusCodeOk) {
96 return (target, propertyKey, descriptor) => {
97 descriptor.value = (...arguments_) => {
98 const mainConfig = Reflect.getMetadata(classMetadataKey, component);
99 const pathParams = Reflect.getMetadata(pathParamMetadataKey, target, propertyKey) || [];
100 const queryParams = Reflect.getMetadata(queryMetadataKey, target, propertyKey) || [];
101 const bodyParams = Reflect.getMetadata(bodyMetadataKey, target, propertyKey) || [];
102 const mapper = Reflect.getMetadata(mapperMetadataKey, target, propertyKey) || null;
103 const especificHeaders = Reflect.getMetadata(headersMetadataKey, target, propertyKey) || null;
104 const before = Reflect.getMetadata(beforeMetadataKey, target, propertyKey) || null;
105 const exceptionHandler = Reflect.getMetadata(exceptionHandlerMetadataKey, target, propertyKey) || null;
106 // Reflect.deleteMetadata(pathParamMetadataKey, target, propertyKey);
107 const headers = new Headers();
108 let mainUrl = String();
109 const argumentsHttp = arguments_;
110 let url = String(urlToMatch);
111 url = UtilsHttp.buildPathParams(pathParams, argumentsHttp, url);
112 const queryParamsUrl = UtilsHttp.buildQueryParams(queryParams, argumentsHttp);
113 if (typeof mainConfig === 'object') {
114 mainUrl = mainConfig.url;
115 UtilsHttp.prepareHeaders(mainConfig.headers, headers);
116 }
117 else
118 mainUrl = mainConfig;
119 mainUrl = mainUrl.concat(url).concat(queryParamsUrl === '?' ? '' : queryParamsUrl);
120 const body_ = method !== 'get' ? UtilsHttp.prepareBody(bodyParams, argumentsHttp) : String();
121 if (especificHeaders)
122 Object.keys(especificHeaders)
123 .forEach(i => headers.set(i, especificHeaders[i]));
124 let request = {
125 url: mainUrl,
126 body: body_,
127 headers: headers.getHeaders(),
128 method: method,
129 };
130 request = before ? before(request) : request;
131 this.interceptors.forEach(i => request = i.intercep(request));
132 return rx_http_request_1.RxHR[method](request.url, {
133 headers: request.headers,
134 body: request.body,
135 qsStringifyOptions: {
136 arrayFormat: 'repeat',
137 },
138 })
139 .pipe(operators_1.map(value => this.mapBodyAndControlError(value, exceptionHandler, statusCodeOk)), operators_1.map(body => mapper ? mapper(body) : body));
140 };
141 };
142 }
143 /**
144 *
145 * @param value
146 * @param {Handler} exceptionHandler
147 * @param statusCodeOk
148 * @returns {any}
149 */
150 static mapBodyAndControlError(value, exceptionHandler, statusCodeOk) {
151 const { body, statusCode, request } = value.response;
152 if (statusCode < statusCodeOk) {
153 return body ? JSON.parse(body) : body;
154 }
155 else if (exceptionHandler) {
156 throw exceptionHandler(body, statusCode, request);
157 }
158 else {
159 if (body && body.message && body.error) {
160 throw new HttpRequestException(body.error, statusCode, body.message);
161 }
162 else {
163 throw new HttpRequestException(JSON.stringify(body), statusCode, String());
164 }
165 }
166 }
167 /**
168 *
169 * @param {string} param
170 * @returns {Function}
171 */
172 static pathParam(param) {
173 return (target, propertyKey, parameterIndex) => {
174 const pathParams = Reflect.getOwnMetadata(pathParamMetadataKey, target, propertyKey) || [];
175 pathParams.unshift({
176 indexArgument: parameterIndex,
177 paramValue: param,
178 });
179 Reflect.defineMetadata(pathParamMetadataKey, pathParams, target, propertyKey);
180 };
181 }
182 /**
183 *
184 * @param {string} param_
185 * @returns {Function}
186 */
187 static query(param_) {
188 return (target, propertyKey, parameterIndex) => {
189 const queryParams = Reflect.getOwnMetadata(queryMetadataKey, target, propertyKey) || [];
190 queryParams.unshift({
191 indexArgument: parameterIndex,
192 paramValue: param_,
193 });
194 Reflect.defineMetadata(queryMetadataKey, queryParams, target, propertyKey);
195 };
196 }
197 /**
198 *
199 * @param {Object} target
200 * @param {string | symbol} propertyKey
201 * @param {number} parameterIndex
202 */
203 static body(target, propertyKey, parameterIndex) {
204 const bodyParams = Reflect.getOwnMetadata(bodyMetadataKey, target, propertyKey) || [];
205 bodyParams.unshift(parameterIndex);
206 Reflect.defineMetadata(bodyMetadataKey, bodyParams, target, propertyKey);
207 }
208 /**
209 *
210 * @param {boolean} enable
211 * @returns {Function}
212 */
213 static pathParamProperty(enable = true) {
214 return (target, propertyName) => Reflect.defineMetadata(pathParamPropertyMetadataKey, { name: propertyName }, target, propertyName);
215 }
216 /**
217 *
218 * @param {Function} mapper
219 * @returns {Function}
220 */
221 static mapper(mapper) {
222 return (target, propertyKey) => Reflect.defineMetadata(mapperMetadataKey, mapper, target, propertyKey);
223 }
224 /**
225 *
226 * @param {{[p: string]: T}} headers
227 * @returns {Function}
228 */
229 static headers(headers) {
230 return (target, propertyKey) => Reflect.defineMetadata(headersMetadataKey, headers, target, propertyKey);
231 }
232 /**
233 *
234 * @param {(request: Request_) => Request_} before_
235 * @returns {(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => void}
236 */
237 static before(before_) {
238 return (target, propertyKey) => Reflect.defineMetadata(beforeMetadataKey, before_, target, propertyKey);
239 }
240 /**
241 *
242 * @param {Handler} handler
243 * @returns {(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => void}
244 */
245 static handlerError(handler) {
246 return (target, propertyKey) => Reflect.defineMetadata(exceptionHandlerMetadataKey, handler, target, propertyKey);
247 }
248}
249Http.interceptors = [];
250exports.Http = Http;
251/**
252 *
253 */
254class UtilsHttp {
255 /**
256 *
257 * @param obj
258 * @param {Headers} headers
259 */
260 static prepareHeaders(obj, headers) {
261 Object.keys(obj).forEach(key => !headers.has(obj[key]) ? headers.set(key, obj[key]) : null);
262 if (!headers.has('Content-Type')) {
263 headers.set('Content-Type', 'application/json');
264 }
265 }
266 /**
267 *
268 * @param {Param[]} params
269 * @param argumentsHttp
270 * @returns {string}
271 */
272 static buildQueryParams(params, argumentsHttp) {
273 let queryParamsUrl = '?';
274 const ampersan = '&';
275 const empty = String();
276 params = params
277 .filter(param => argumentsHttp[param.indexArgument]);
278 params
279 .forEach((param, index) => {
280 if (typeof argumentsHttp[param.indexArgument] === 'object') {
281 const keys = Object.keys(argumentsHttp[param.indexArgument]) || [];
282 let tempCont = 0;
283 for (const key in argumentsHttp[param.indexArgument]) {
284 queryParamsUrl = queryParamsUrl.concat(`${key}=${argumentsHttp[param.indexArgument][key]}${tempCont === keys.length - 1 ? empty : ampersan}`);
285 tempCont++;
286 }
287 }
288 else {
289 if (!param.paramValue)
290 return;
291 queryParamsUrl = queryParamsUrl.length > 1 ? queryParamsUrl.concat(ampersan) : queryParamsUrl;
292 queryParamsUrl = queryParamsUrl.concat(`${param.paramValue}=${argumentsHttp[param.indexArgument]}${index === params.length - 1 ? empty : ampersan}`);
293 }
294 });
295 return queryParamsUrl;
296 }
297 /**
298 *
299 * @param {Param[]} pathParam
300 * @param argumentsHttp
301 * @param {string} url
302 * @returns {string}
303 */
304 static buildPathParams(pathParam, argumentsHttp, url) {
305 url = url.replace(/\s/g, '').trim();
306 const wrapOpen = '{';
307 const wrapClose = '}';
308 pathParam
309 .filter(param => param.paramValue)
310 .forEach(param => {
311 if (!param.paramValue)
312 return;
313 const pathParam = wrapOpen.concat(param.paramValue.toString()).concat(wrapClose);
314 if (url.includes(pathParam))
315 url = url.replace(pathParam, argumentsHttp[param.indexArgument]);
316 });
317 pathParam
318 .filter(param => !param.paramValue)
319 .map(param => url += `/${argumentsHttp[param.indexArgument]}`);
320 argumentsHttp
321 .filter(arg => typeof arg === 'object')
322 .forEach(obj => {
323 Object.keys(obj).forEach(key => {
324 const keyPathParam = Reflect.getMetadata(pathParamPropertyMetadataKey, obj, key);
325 if (keyPathParam)
326 url = url.replace(`{${keyPathParam.name}}`, obj[keyPathParam.name]);
327 });
328 });
329 return url;
330 }
331 /**
332 *
333 * @param {number[]} params
334 * @param argumentsHttp
335 * @returns {any}
336 */
337 static prepareBody(params, argumentsHttp) {
338 let body = {};
339 params.forEach(i => body = Object.assign({}, body, argumentsHttp[i]));
340 return params.length ? JSON.stringify(body) : String();
341 }
342}
343/**
344 *
345 */
346class HttpRequestException {
347 constructor(error, statusCode, message) {
348 this.error = error;
349 this.statusCode = statusCode;
350 this.message = message;
351 }
352}
353exports.HttpRequestException = HttpRequestException;
354/**
355 *
356 */
357class Headers {
358 constructor() {
359 /**
360 *
361 * @type {Map<any, any>}
362 */
363 this.headers = new Map();
364 }
365 /**
366 *
367 * @param {string} key
368 * @returns {boolean}
369 */
370 has(key) {
371 return this.headers.has(key);
372 }
373 /**
374 *
375 * @param {string} key
376 * @param header
377 * @returns {this}
378 */
379 set(key, header) {
380 this.headers.set(key, header);
381 return this;
382 }
383 /**
384 *
385 * @returns {any}
386 */
387 getHeaders() {
388 const headers = Object();
389 Array.from(this.headers.keys())
390 .forEach(key => headers[key] = this.headers.get(key));
391 return headers;
392 }
393}