UNPKG

8.36 kBJavaScriptView Raw
1import { Subject } from 'rxjs/Subject';
2import 'rxjs/add/operator/map';
3import 'rxjs/add/operator/takeUntil';
4import 'rxjs/add/operator/take';
5import 'rxjs/add/operator/toPromise';
6import { Log, Level } from 'ng2-logger/browser';
7const log = Log.create('resouce-service', Level.__NOTHING);
8import { Rest } from './rest.class';
9import { RestRequest } from './rest-request';
10import { RestHeaders } from './rest-headers';
11import { Cookie } from './cookie';
12import { interpolateParamsToUrl, isValid, containsModels, getModels } from './params';
13//#endregion
14export class Resource {
15 //#endregion
16 //#region constructor
17 constructor() {
18 setTimeout(() => {
19 const zone = this.getZone();
20 if (!RestRequest.zone)
21 RestRequest.zone = zone;
22 });
23 }
24 static get listenErrors() {
25 return this._listenErrors.asObservable();
26 }
27 //#region private mthods and fields
28 getZone() {
29 const isNode = (typeof window === 'undefined');
30 if (isNode)
31 return;
32 const ng = window['ng'];
33 const getAllAngularRootElements = window['getAllAngularRootElements'];
34 if (!ng || !getAllAngularRootElements)
35 return;
36 const probe = ng.probe;
37 const coreTokens = ng.coreTokens;
38 if (!coreTokens.NgZone)
39 return;
40 const zoneClass = coreTokens.NgZone;
41 if (!probe || typeof probe !== 'function' || !getAllAngularRootElements)
42 return;
43 const angularElements = getAllAngularRootElements();
44 if (!Array.isArray(angularElements) || angularElements.length === 0)
45 return;
46 const rootElement = ng.probe(angularElements[0]);
47 if (!rootElement)
48 return;
49 const injector = rootElement.injector;
50 if (!injector || !injector.get || typeof injector.get !== 'function')
51 return;
52 const zone = injector.get(zoneClass);
53 return zone;
54 }
55 static initAngularNgZone(zone) {
56 RestRequest.zone = zone;
57 }
58 checkNestedModels(model, allModels) {
59 // if (model.indexOf('/') !== -1) { //TODO make this better, becouse now I unecesary checking shit
60 for (let p in allModels) {
61 if (allModels.hasOwnProperty(p)) {
62 let m = allModels[p];
63 if (isValid(p)) {
64 let urlModels = getModels(p);
65 if (containsModels(model, urlModels)) {
66 model = p;
67 break;
68 }
69 }
70 }
71 }
72 // }
73 return model;
74 }
75 static getModel(endpoint, model) {
76 model = Resource.prepareModel(model);
77 const e = Resource.endpoints[endpoint];
78 if (!e)
79 return undefined;
80 const r = Resource.endpoints[endpoint].models[model];
81 return Resource.endpoints[endpoint].models[model];
82 }
83 //#endregion
84 //#region create
85 static create(e, model, entityMapping, circular) {
86 const badRestRegEX = new RegExp('((\/:)[a-z]+)+', 'g');
87 const matchArr = model.match(badRestRegEX) || [];
88 const badModelsNextToEachOther = matchArr.join();
89 const atleas2DoubleDots = ((badModelsNextToEachOther.match(new RegExp(':', 'g')) || []).length >= 2);
90 if (atleas2DoubleDots && model.search(badModelsNextToEachOther) !== -1) {
91 throw new Error(`
92
93Bad rest model: ${model}
94
95Do not create rest models like this: /book/author/:bookid/:authorid
96Instead use nested approach: /book/:bookid/author/:authorid
97 `);
98 }
99 ;
100 Resource.map(e, e);
101 Resource.instance.add(e, model ? model : '', entityMapping, circular);
102 // if (model.charAt(model.length - 1) !== '/') model = `${model}/`;
103 return {
104 model: (params) => Resource.instance.api(e, interpolateParamsToUrl(params, model)),
105 replay: (method) => {
106 Resource.getModel(e, model).replay(method);
107 },
108 get headers() {
109 return Resource.getModel(e, model).headers;
110 }
111 };
112 }
113 //#endregion
114 //#region reset
115 static reset() {
116 Resource.endpoints = {};
117 }
118 //#region map
119 static map(endpoint, url) {
120 log.i('url', url);
121 let regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
122 let e = endpoint;
123 if (!regex.test(url)) {
124 throw `Url address is not correct: ${url}`;
125 }
126 if (url.charAt(url.length - 1) === '/')
127 url = url.slice(0, url.length - 1);
128 log.i('url after', url);
129 if (Resource.endpoints[e] !== undefined) {
130 if (Resource.enableWarnings)
131 console.warn('Cannot use map function at the same API endpoint again ('
132 + Resource.endpoints[e].url + ')');
133 return false;
134 }
135 Resource.endpoints[e] = {
136 url: url,
137 models: {},
138 entity: null
139 };
140 log.i('enpoints', Resource.endpoints);
141 return true;
142 }
143 //#endregion
144 static prepareModel(model) {
145 if (model.charAt(model.length - 1) === '/')
146 model = model.slice(0, model.length - 1);
147 if (model.charAt(0) === '/')
148 model = model.slice(1, model.length);
149 return model;
150 }
151 //#region add
152 /**
153 * And enipoint to application
154 *
155 * @param {E} endpoint
156 * @param {string} model
157 * @returns {boolean}
158 */
159 add(endpoint, model, entity, circular) {
160 log.i(`I am maping ${model} on ${endpoint}`);
161 model = Resource.prepareModel(model);
162 let e;
163 e = (endpoint).toString();
164 if (Resource.endpoints[e] === undefined) {
165 console.error('Endpoint is not mapped ! Cannot add model ' + model);
166 return;
167 }
168 if (Resource.endpoints[e].models[model] !== undefined) {
169 if (Resource.enableWarnings)
170 console.warn(`Model '${model}' is already defined in endpoint: `
171 + Resource.endpoints[e].url);
172 return;
173 }
174 Resource.endpoints[e].models[model] =
175 new Rest(Resource.endpoints[e].url
176 + '/' + model, Resource.request, {
177 endpoint: e,
178 path: model,
179 entity,
180 circular
181 });
182 return;
183 }
184 //#endregion
185 //#region api
186 /**
187 * Access api throught endpoint
188 *
189 * @param {E} endpoint
190 * @param {string} model
191 * @returns {Rest<T, TA>}
192 */
193 api(endpoint, model) {
194 if (model.charAt(0) === '/')
195 model = model.slice(1, model.length);
196 let e = (endpoint).toString();
197 if (Resource.endpoints[e] === undefined) {
198 throw `Endpoint: ${endpoint} is not mapped ! Cannot add model: ${model}`;
199 }
200 let allModels = Resource.endpoints[e].models;
201 let orgModel = model;
202 model = this.checkNestedModels(model, allModels);
203 if (Resource.endpoints[e].models[model] === undefined) {
204 log.d('Resource.endpoints', Resource.endpoints);
205 throw `Model '${model}' is undefined in endpoint: ${Resource.endpoints[e].url} `;
206 }
207 let res = Resource.endpoints[(endpoint).toString()].models[model];
208 if (orgModel !== model) {
209 let baseUrl = Resource.endpoints[(endpoint).toString()].url;
210 log.d('base', Resource.endpoints[(endpoint).toString()]);
211 log.d('baseUrl', baseUrl);
212 log.d('orgModel', orgModel);
213 res.__rest_endpoint = `${baseUrl}/${orgModel}`;
214 }
215 else
216 res.__rest_endpoint = undefined;
217 return res;
218 }
219}
220Resource.DEFAULT_HEADERS = RestHeaders.from({
221 'Content-Type': 'application/json',
222 'Accept': 'application/json'
223});
224Resource._listenErrors = new Subject();
225Resource.enableWarnings = true;
226Resource.instance = new Resource();
227Resource.endpoints = {};
228Resource.request = new RestRequest();
229//#endregion
230Resource.Cookies = Cookie.Instance;
231// const res = Resource.create('')
232// res.model()
233// .mock({
234// code: 500,
235// data: {},
236// isArray: true
237// })
238// .array.
239//# sourceMappingURL=resource.service.js.map
\No newline at end of file