UNPKG

10.8 kBJavaScriptView Raw
1import { diffChars } from 'diff';
2import * as _ from 'lodash';
3import { Log, Level } from 'ng2-logger/browser';
4import { Helpers } from './helpers';
5const log = Log.create('ng2-rest params', Level.__NOTHING);
6/** check if string is a valid pattern */
7export function isValid(pattern) {
8 return (new RegExp('\/:[a-zA-Z]*', 'g')).test(pattern.replace('://', ''));
9}
10export function check(url, pattern) {
11 if (!Helpers.checkValidUrl(url)) {
12 console.error(`[ng2-rest] Incorrect url: ${url}`);
13 return false;
14 }
15 if (url.charAt(url.length - 1) === '/')
16 url = url.slice(0, url.length - 2);
17 if (pattern.charAt(pattern.length - 1) === '/')
18 pattern = pattern.slice(0, url.length - 2);
19 pattern = pattern.replace(/\//g, '\/');
20 pattern = pattern.replace(new RegExp('\/:[a-zA-Z]*', 'g'), '.+');
21 let reg = new RegExp(pattern, 'g');
22 return reg.test(url);
23}
24export function getModels(pattern) {
25 let m = pattern.match(new RegExp('[a-z-A-Z]*\/:', 'g'));
26 return m.map(p => p.replace('/:', ''));
27}
28export function getRestPramsNames(pattern) {
29 if (pattern.charAt(pattern.length - 1) !== '/')
30 pattern = `${pattern}/`;
31 let m = pattern.match(new RegExp(':[a-zA-Z]*\/', 'g'));
32 let res = m.map(p => p.replace(':', '').replace('/', ''));
33 return res.filter(p => p.trim() !== '');
34}
35export function containsModels(url, models) {
36 if (url.charAt(0) !== '/')
37 url = '/' + url;
38 // url = url.replace(new RegExp('\/', 'g'), '');
39 let res = models.filter(m => {
40 let word = '/' + m;
41 log.d('word', word);
42 let iii = url.indexOf(word);
43 log.d('iii', iii);
44 if (iii + word.length < url.length && url.charAt(iii + word.length) !== '/') {
45 return false;
46 }
47 if (iii !== -1) {
48 url = url.replace(new RegExp('\/' + m, 'g'), '');
49 return true;
50 }
51 return false;
52 }).length;
53 log.d('containsModels', res);
54 return res === models.length;
55}
56export function stars(n) {
57 let res = '';
58 for (let i = 0; i < n; i++)
59 res += '*';
60 return res;
61}
62export function getRestParams(url, pattern) {
63 let res = {};
64 let models = getRestPramsNames(pattern);
65 log.d('models', models);
66 models.forEach(m => {
67 pattern = pattern.replace(`:${m}`, stars(m.length));
68 });
69 let currentModel = undefined;
70 diffChars(pattern, url).forEach(d => {
71 log.d('d', d);
72 if (d.added) {
73 if (!isNaN(Number(d.value)))
74 res[currentModel] = Number(d.value);
75 else if (d.value.trim() === 'true')
76 res[currentModel] = true;
77 else if (d.value.trim() === 'false')
78 res[currentModel] = false;
79 else
80 res[currentModel] = decodeURIComponent(d.value);
81 currentModel = undefined;
82 }
83 let m = d.value.replace(':', "");
84 log.d('model m', m);
85 if (d.removed) {
86 currentModel = models.shift();
87 }
88 });
89 return res;
90}
91export const regexisPath = /[^\..]+(\.[^\..]+)+/g;
92/**
93 * Models like books/:id
94 */
95function cutUrlModel(params, models, output) {
96 if (models.length === 0)
97 return output.join('\/');
98 let m = models.pop();
99 let param = m.match(/:[a-zA-Z0-9\.]+/)[0].replace(':', '');
100 const paramIsPath = regexisPath.test(param);
101 log.i('cut param', param);
102 let model = m.match(/[a-zA-Z0-9]+\//)[0].replace('\/', '');
103 if (params === undefined ||
104 (paramIsPath ? _.get(params, param) === undefined : params[param] === undefined) ||
105 param === 'undefined') {
106 output.length = 0;
107 output.unshift(model);
108 return cutUrlModel(params, models, output);
109 }
110 else {
111 if (paramIsPath) {
112 log.i('param is path', param);
113 let mrep = m.replace(new RegExp(`:${param}`, 'g'), `${_.get(params, param)}`);
114 output.unshift(mrep);
115 return cutUrlModel(params, models, output);
116 }
117 else {
118 log.i('param is normal', param);
119 let mrep = m.replace(new RegExp(`:${param}`, 'g'), `${params[param]}`);
120 output.unshift(mrep);
121 return cutUrlModel(params, models, output);
122 }
123 }
124}
125export function interpolateParamsToUrl(params, url) {
126 const regexInt = /\[\[([^\..]+\.[^\..]+)+\]\]/g;
127 url = url.split('/').map(p => {
128 // log.d('url parts', p)
129 let isParam = p.startsWith(':');
130 if (isParam) {
131 let part = p.slice(1);
132 // log.d('url param part', p)
133 if (regexInt.test(part)) {
134 // let level = (url.split('.').length - 1)
135 part = part.replace('[[', '');
136 part = part.replace(']]', '');
137 }
138 return `:${part}`;
139 }
140 return p;
141 }).join('/');
142 // log.i('URL TO EXPOSE', url)
143 // log.i('params', params)
144 let slash = {
145 start: url.charAt(0) === '\/',
146 end: url.charAt(url.length - 1) === '\/'
147 };
148 let morePramsOnEnd = url.match(/(\/:[a-zA-Z0-9\.]+){2,10}/g);
149 if (morePramsOnEnd && (Array.isArray(morePramsOnEnd) && morePramsOnEnd.length === 1)) {
150 // log.i('morePramsOnEnd', morePramsOnEnd)
151 let m = morePramsOnEnd[0];
152 let match = m.match(/\/:[a-zA-Z0-9\.]+/g);
153 // log.i('match', match)
154 match.forEach(e => {
155 let c = e.replace('\/:', '');
156 // log.i('c', c)
157 if (regexisPath.test(c)) {
158 url = url.replace(e, `/${_.get(params, c)}`);
159 }
160 else {
161 url = url.replace(e, `/${params[c]}`);
162 }
163 // log.i('prog url', url)
164 });
165 return url;
166 }
167 let nestedParams = url.match(/[a-zA-Z0-9]+\/:[a-zA-Z0-9\.]+/g);
168 if (!nestedParams || (Array.isArray(nestedParams) && nestedParams.length === 0))
169 return url;
170 // check alone params
171 if (!slash.end)
172 url = `${url}/`;
173 let addUndefinedForAlone = (!/:[a-zA-Z0-9\.]+\/$/g.test(url) && /[a-zA-Z0-9]+\/$/g.test(url));
174 let replace = (nestedParams.length > 1 ? nestedParams.join('\/') : nestedParams[0]) +
175 (addUndefinedForAlone ? '\/' + url.match(/[a-zA-Z0-9]+\/$/g)[0] : '\/');
176 let beginHref = url.replace(replace, '');
177 if (addUndefinedForAlone) {
178 url = url.replace(/\/$/g, '/:undefined');
179 nestedParams = url.match(/[a-zA-Z0-9]+\/:[a-zA-Z0-9\.]+/g);
180 url = cutUrlModel(params, nestedParams, []);
181 }
182 else {
183 url = cutUrlModel(params, nestedParams, []);
184 }
185 url = beginHref + url;
186 if (url.charAt(url.length - 1) !== '/' && slash.end)
187 url = `${url}/`;
188 if (url.charAt(0) !== '\/' && slash.start)
189 url = `/${url}`;
190 return url;
191}
192/**
193 * Get query params from url, like 'ex' in /api/books?ex=value
194*/
195export function decodeUrl(url) {
196 let regex = /[?&]([^=#]+)=([^&#]*)/g, params = {}, match;
197 while (match = regex.exec(url)) {
198 params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
199 }
200 let paramsObject = params;
201 for (let p in paramsObject) {
202 if (paramsObject[p] === undefined) {
203 delete paramsObject[p];
204 continue;
205 }
206 if (paramsObject.hasOwnProperty(p)) {
207 // chcek if property is number
208 let n = Number(params[p]);
209 if (!isNaN(n)) {
210 params[p] = n;
211 continue;
212 }
213 if (typeof params[p] === 'string') {
214 // check if property is object
215 let json;
216 try {
217 json = JSON.parse(params[p]);
218 }
219 catch (error) { }
220 if (json !== undefined) {
221 params[p] = json;
222 continue;
223 }
224 // chcek if property value is like regular rexpression
225 // let regexExpression;
226 // try {
227 // regexExpression = new RegExp(params[p]);
228 // } catch (e) { }
229 // if (regexExpression !== undefined) params[p] = regexExpression;
230 }
231 }
232 }
233 return params;
234}
235/**
236 * Create query params string for url
237 *
238 * @export
239 * @param {UrlParams[]} params
240 * @returns {string}
241 */
242export function getParamsUrl(params, doNotSerialize = false) {
243 let urlparts = [];
244 if (!params)
245 return '';
246 if (!(params instanceof Array))
247 return '';
248 if (params.length === 0)
249 return '';
250 params.forEach(urlparam => {
251 if (JSON.stringify(urlparam) !== '{}') {
252 let parameters = [];
253 let paramObject = urlparam;
254 for (let p in paramObject) {
255 if (paramObject[p] === undefined)
256 delete paramObject[p];
257 if (paramObject.hasOwnProperty(p) && typeof p === 'string' && p !== 'regex' && !(paramObject[p] instanceof RegExp)) {
258 if (p.length > 0 && p[0] === '/') {
259 let newName = p.slice(1, p.length - 1);
260 urlparam[newName] = urlparam[p];
261 urlparam[p] = undefined;
262 p = newName;
263 }
264 if (p.length > 0 && p[p.length - 1] === '/') {
265 let newName = p.slice(0, p.length - 2);
266 urlparam[newName] = urlparam[p];
267 urlparam[p] = undefined;
268 p = newName;
269 }
270 let v = urlparam[p];
271 if (v instanceof Object) {
272 urlparam[p] = JSON.stringify(urlparam[p]);
273 }
274 urlparam[p] = doNotSerialize ? urlparam[p] : encodeURIComponent(urlparam[p]);
275 if (urlparam.regex !== undefined && urlparam.regex instanceof RegExp) {
276 if (!urlparam.regex.test(urlparam[p])) {
277 console.warn(`Data: ${urlparam[p]} incostistent with regex ${urlparam.regex.source}`);
278 }
279 }
280 parameters.push(`${p}=${urlparam[p]}`);
281 }
282 }
283 urlparts.push(parameters.join('&'));
284 }
285 });
286 let join = urlparts.join().trim();
287 if (join.trim() === '')
288 return '';
289 return `?${urlparts.join('&')}`;
290}
291function transform(o) {
292 if (typeof o === 'object') {
293 return encodeURIComponent(JSON.stringify(o));
294 }
295 return o;
296}
297export function prepareUrlOldWay(params) {
298 if (!params)
299 return this.endpoint;
300 if (typeof params === 'object') {
301 params = transform(params);
302 }
303 return this.endpoint + '/' + params;
304}
305//# sourceMappingURL=params.js.map
\No newline at end of file