UNPKG

10.8 kBJavaScriptView Raw
1import { __awaiter } from "tslib";
2import { Subject } from 'rxjs/Subject';
3import 'rxjs/add/operator/map';
4import 'rxjs/add/operator/takeUntil';
5import 'rxjs/add/operator/take';
6import * as _ from 'lodash';
7import { Models } from './models';
8import { RestHeaders } from './rest-headers';
9import { Helpers, Level } from 'ng2-logger/browser';
10import axios from 'axios';
11import { Resource } from './resource.service';
12import { Log } from 'ng2-logger/browser';
13import { isUndefined } from 'util';
14import { RequestCache } from './request-cache';
15const log = Log.create('rest-resource', Level.__NOTHING);
16const jobIDkey = 'jobID';
17//#region mock request
18//#endregion
19export class RestRequest {
20 constructor() {
21 this.subjectInuUse = {};
22 this.meta = {};
23 //#endregion
24 this.replaySubjects = {};
25 }
26 handlerResult(options, sourceRequest) {
27 if (isUndefined(options)) {
28 options = {};
29 }
30 const { res, jobid, isArray, method } = options;
31 if (typeof res !== 'object')
32 throw new Error('[ng2-rest] No resposnse for request. ');
33 if (Helpers.isBrowser) {
34 res.headers = RestHeaders.from(res.headers);
35 }
36 // error no internet
37 if (res.error) {
38 this.subjectInuUse[jobid].error(new Models.HttpResponseError(res.error, res.data, res.headers, res.code));
39 return;
40 }
41 const entity = this.meta[jobid].entity;
42 const circular = this.meta[jobid].circular;
43 // normal request case
44 this.subjectInuUse[jobid].next(new Models.HttpResponse(sourceRequest, res.data, res.headers, res.code, entity, circular, isArray));
45 return;
46 }
47 checkCache(sourceRequest, jobid) {
48 const existedInCache = RequestCache.findBy(sourceRequest);
49 if (existedInCache) {
50 log.i('cache exists', existedInCache);
51 this.subjectInuUse[jobid].next(existedInCache);
52 return true;
53 }
54 log.i('cache not exists', existedInCache);
55 return false;
56 }
57 req(url, method, headers, body, jobid, isArray = false, mockHttp) {
58 return __awaiter(this, void 0, void 0, function* () {
59 if (this.checkCache({
60 url,
61 body,
62 isArray,
63 method
64 }, jobid)) {
65 return;
66 }
67 var response;
68 if (mockHttp) {
69 if (typeof mockHttp === 'object') {
70 response = {
71 data: mockHttp.data,
72 status: mockHttp.code,
73 headers: mockHttp.headers,
74 statusText: mockHttp.error,
75 config: {}
76 };
77 }
78 else if (typeof mockHttp === 'function') {
79 const r = mockHttp(url, method, headers, body);
80 response = {
81 data: r.data,
82 status: r.code,
83 headers: r.headers,
84 statusText: r.error,
85 config: {}
86 };
87 }
88 }
89 try {
90 if (!response) {
91 response = yield axios({
92 url,
93 method,
94 data: body,
95 responseType: 'text',
96 headers: headers.toJSON()
97 });
98 }
99 this.handlerResult({
100 res: {
101 code: response.status,
102 data: JSON.stringify(response.data),
103 isArray,
104 jobid,
105 headers: RestHeaders.from(response.headers)
106 },
107 method,
108 jobid,
109 isArray
110 }, {
111 url,
112 body,
113 method,
114 isArray,
115 });
116 }
117 catch (catchedError) {
118 // console.log('ERROR RESPONESE catchedError typeof ', typeof catchedError)
119 // console.log('ERROR RESPONESE catchedError', catchedError)
120 if (typeof catchedError === 'object' && catchedError.response && catchedError.response.data) {
121 const err = catchedError.response.data;
122 const msg = catchedError.response.data.message || '';
123 let stack = (err.stack || '').split('\n');
124 Resource['_listenErrors'].next({
125 msg,
126 stack,
127 data: catchedError.response.data
128 });
129 }
130 const error = (catchedError && catchedError.response) ? `[${catchedError.response.statusText}]: ` : '';
131 this.handlerResult({
132 res: {
133 code: (catchedError && catchedError.response) ? catchedError.response.status : undefined,
134 error: `${error}${catchedError.message}`,
135 data: (catchedError && catchedError.response) ? JSON.stringify(catchedError.response.data) : undefined,
136 isArray,
137 jobid,
138 headers: RestHeaders.from(catchedError && catchedError.response && catchedError.response.headers)
139 },
140 method,
141 jobid,
142 isArray
143 }, {
144 url,
145 body,
146 isArray,
147 method
148 });
149 }
150 });
151 }
152 getSubject(method, meta) {
153 if (_.isUndefined(this.replaySubjects[meta.endpoint])) {
154 log.i(`[getSubject][recreate] (${meta.endpoint}) `);
155 this.replaySubjects[meta.endpoint] = {};
156 }
157 if (_.isUndefined(this.replaySubjects[meta.endpoint][meta.path])) {
158 log.i(`[getSubject][recreate] (${meta.endpoint})(${meta.path}) `);
159 this.replaySubjects[meta.endpoint][meta.path] = {};
160 }
161 if (_.isUndefined(this.replaySubjects[meta.endpoint][meta.path][method])) {
162 log.i(`[getSubject][recreate] (${meta.endpoint})(${meta.path})(${method}) `);
163 this.replaySubjects[meta.endpoint][meta.path][method] = {
164 subject: new Subject(),
165 data: undefined,
166 };
167 }
168 const replay = this.replaySubjects[meta.endpoint][meta.path][method];
169 const id = RestRequest.jobId++;
170 replay.id = id;
171 const subject = replay.subject;
172 subject[jobIDkey] = id;
173 this.meta[id] = meta;
174 this.subjectInuUse[id] = subject;
175 return replay;
176 }
177 //#region http methods
178 metaReq(method, url, body, headers, meta, isArray, mockHttp) {
179 const replay = this.getSubject(method, meta);
180 replay.data = { url, body, headers, isArray };
181 setTimeout(() => this.req(url, method, headers, body, replay.id, isArray, mockHttp));
182 const resp = replay.subject.asObservable().take(1).toPromise();
183 resp.observable = replay.subject.asObservable();
184 resp.cache = RequestCache.findBy({
185 body,
186 isArray,
187 method,
188 url
189 });
190 return resp;
191 }
192 get(url, body, headers, meta, isArray, mockHttp) {
193 return this.metaReq('get', url, body, headers, meta, isArray, mockHttp);
194 }
195 head(url, body, headers, meta, isArray, mockHttp) {
196 return this.metaReq('head', url, body, headers, meta, isArray, mockHttp);
197 }
198 delete(url, body, headers, meta, isArray, mockHttp) {
199 return this.metaReq('delete', url, body, headers, meta, isArray, mockHttp);
200 }
201 post(url, body, headers, meta, isArray, mockHttp) {
202 return this.metaReq('post', url, body, headers, meta, isArray, mockHttp);
203 }
204 put(url, body, headers, meta, isArray, mockHttp) {
205 return this.metaReq('put', url, body, headers, meta, isArray, mockHttp);
206 }
207 patch(url, body, headers, meta, isArray, mockHttp) {
208 return this.metaReq('patch', url, body, headers, meta, isArray, mockHttp);
209 }
210 jsonp(url, body, headers, meta, isArray, mockHttp) {
211 const replay = this.getSubject('jsonp', meta);
212 const jobid = replay.id;
213 const method = 'jsonp';
214 setTimeout(() => {
215 if (url.endsWith('/'))
216 url = url.slice(0, url.length - 1);
217 let num = Math.round(10000 * Math.random());
218 let callbackMethodName = "cb_" + num;
219 window[callbackMethodName] = (data) => {
220 if (this.checkCache({
221 url,
222 body,
223 isArray,
224 method
225 }, jobid)) {
226 return;
227 }
228 this.handlerResult({
229 res: {
230 data, isArray
231 },
232 method,
233 jobid,
234 isArray
235 }, {
236 url,
237 body,
238 isArray,
239 method,
240 });
241 };
242 let sc = document.createElement('script');
243 sc.src = `${url}?callback=${callbackMethodName}`;
244 document.body.appendChild(sc);
245 document.body.removeChild(sc);
246 });
247 // return replay.subject.asObservable();
248 const resp = replay.subject.asObservable().take(1).toPromise();
249 resp.observable = replay.subject.asObservable();
250 resp.cache = RequestCache.findBy({
251 body,
252 isArray,
253 method,
254 url
255 });
256 return resp;
257 }
258 replay(method, meta) {
259 const replay = this.getSubject(method, meta);
260 if (!replay.data) {
261 console.warn(`Canno replay first ${method} request from ${meta.endpoint}/${meta.path}`);
262 return;
263 }
264 ;
265 if (replay && replay.subject && Array.isArray(replay.subject.observers) &&
266 replay.subject.observers.length == 0) {
267 console.warn(`No observators for ${method} request from ${meta.endpoint}/${meta.path}`);
268 return;
269 }
270 const url = replay.data.url;
271 const headers = replay.data.headers;
272 const body = replay.data.body;
273 const isArray = replay.data.isArray;
274 setTimeout(() => this.req(url, method, headers, body, replay.id, isArray));
275 }
276}
277RestRequest.jobId = 0;
278//# sourceMappingURL=rest-request.js.map
\No newline at end of file