1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _regenerator = require('babel-runtime/regenerator');
|
8 |
|
9 | var _regenerator2 = _interopRequireDefault(_regenerator);
|
10 |
|
11 | var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
|
12 |
|
13 | var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
|
14 |
|
15 | var _typeof2 = require('babel-runtime/helpers/typeof');
|
16 |
|
17 | var _typeof3 = _interopRequireDefault(_typeof2);
|
18 |
|
19 | var _keys = require('babel-runtime/core-js/object/keys');
|
20 |
|
21 | var _keys2 = _interopRequireDefault(_keys);
|
22 |
|
23 | var _cache = require('./cache');
|
24 |
|
25 | var _cache2 = _interopRequireDefault(_cache);
|
26 |
|
27 | var _uuid = require('uuid');
|
28 |
|
29 | var _uuid2 = _interopRequireDefault(_uuid);
|
30 |
|
31 | var _lodash = require('lodash');
|
32 |
|
33 | var _lodash2 = _interopRequireDefault(_lodash);
|
34 |
|
35 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
36 |
|
37 | var urlLib = require('url');
|
38 | var pointer = require('json-pointer');
|
39 | var websocket = require('./websocket');
|
40 | var Promise = require('bluebird');
|
41 | var axios = require('axios');
|
42 | var oadaIdClient = require('@oada/oada-id-client');
|
43 |
|
44 | var connect = function connect(_ref) {
|
45 | var _this3 = this;
|
46 |
|
47 |
|
48 |
|
49 | var put = function () {
|
50 | var _ref13 = (0, _asyncToGenerator3.default)( _regenerator2.default.mark(function _callee3(_ref12) {
|
51 | var url = _ref12.url,
|
52 | path = _ref12.path,
|
53 | data = _ref12.data,
|
54 | type = _ref12.type,
|
55 | headers = _ref12.headers,
|
56 | tree = _ref12.tree;
|
57 | var req, pieces, treePath;
|
58 | return _regenerator2.default.wrap(function _callee3$(_context3) {
|
59 | while (1) {
|
60 | switch (_context3.prev = _context3.next) {
|
61 | case 0:
|
62 | req = {
|
63 | method: 'put',
|
64 | url: url || DOMAIN + path,
|
65 | headers: _lodash2.default.merge({ 'Authorization': 'Bearer ' + TOKEN }, headers),
|
66 | data: data
|
67 | };
|
68 |
|
69 | if (type) req.headers['Content-Type'] = type;
|
70 |
|
71 | if (!tree) {
|
72 | _context3.next = 5;
|
73 | break;
|
74 | }
|
75 |
|
76 | _context3.next = 5;
|
77 | return _ensureTree({
|
78 | url: req.url,
|
79 | tree: _lodash2.default.cloneDeep(tree),
|
80 | data: data
|
81 | });
|
82 |
|
83 | case 5:
|
84 | pieces = urlLib.parse(req.url).path.replace(/^\//, '').split('/');
|
85 | treePath = _convertSetupTreePath(pieces, tree) + '/_type';
|
86 |
|
87 | if (pointer.has(tree, treePath)) req.headers['Content-Type'] = pointer.get(tree, treePath);
|
88 | return _context3.abrupt('return', REQUEST(req));
|
89 |
|
90 | case 9:
|
91 | case 'end':
|
92 | return _context3.stop();
|
93 | }
|
94 | }
|
95 | }, _callee3, this);
|
96 | }));
|
97 |
|
98 | return function put(_x3) {
|
99 | return _ref13.apply(this, arguments);
|
100 | };
|
101 | }();
|
102 |
|
103 | var resetCache = function () {
|
104 | var _ref14 = (0, _asyncToGenerator3.default)( _regenerator2.default.mark(function _callee4(name, exp) {
|
105 | return _regenerator2.default.wrap(function _callee4$(_context4) {
|
106 | while (1) {
|
107 | switch (_context4.prev = _context4.next) {
|
108 | case 0:
|
109 | if (CACHE) {
|
110 | _context4.next = 2;
|
111 | break;
|
112 | }
|
113 |
|
114 | return _context4.abrupt('return');
|
115 |
|
116 | case 2:
|
117 | _context4.next = 4;
|
118 | return CACHE.resetCache();
|
119 |
|
120 | case 4:
|
121 | return _context4.abrupt('return', _configureCache({
|
122 | name: NAME,
|
123 | req: SOCKET.http || axios,
|
124 | exp: exp || EXP
|
125 | }));
|
126 |
|
127 | case 5:
|
128 | case 'end':
|
129 | return _context4.stop();
|
130 | }
|
131 | }
|
132 | }, _callee4, this);
|
133 | }));
|
134 |
|
135 | return function resetCache(_x4, _x5) {
|
136 | return _ref14.apply(this, arguments);
|
137 | };
|
138 | }();
|
139 |
|
140 | var domain = _ref.domain,
|
141 | options = _ref.options,
|
142 | cache = _ref.cache,
|
143 | token = _ref.token,
|
144 | noWebsocket = _ref.noWebsocket;
|
145 |
|
146 | var CACHE = undefined;
|
147 | var REQUEST = axios;
|
148 | var SOCKET = undefined;
|
149 | var TOKEN = undefined;
|
150 | var DOMAIN = domain;
|
151 | var NAME = urlLib.parse(domain).hostname.replace(/\./g, '_');
|
152 | var EXP = cache ? cache.exp : undefined;
|
153 |
|
154 | if (!DOMAIN) throw 'domain undefined';
|
155 |
|
156 | function _replaceLinks(obj) {
|
157 | var ret = Array.isArray(obj) ? [] : {};
|
158 | if (!obj) return obj;
|
159 | return Promise.map((0, _keys2.default)(obj || {}), function (key) {
|
160 | if (key === '*') {
|
161 |
|
162 | return;
|
163 | }
|
164 | var val = obj[key];
|
165 | if ((typeof val === 'undefined' ? 'undefined' : (0, _typeof3.default)(val)) !== 'object' || !val) {
|
166 | ret[key] = val;
|
167 | return;
|
168 | }
|
169 | if (val._type) {
|
170 |
|
171 |
|
172 | return;
|
173 | }
|
174 | if (val._id) {
|
175 |
|
176 | ret[key] = { _id: obj[key]._id };
|
177 | if (val._rev) ret[key]._rev = '0-0';
|
178 | return;
|
179 | }
|
180 |
|
181 | return _replaceLinks(val).then(function (result) {
|
182 | ret[key] = result;
|
183 | return;
|
184 | });
|
185 | }).then(function () {
|
186 | return ret;
|
187 | });
|
188 | }
|
189 |
|
190 | function _makeResourceAndLink(_ref2) {
|
191 | var path = _ref2.path,
|
192 | data = _ref2.data;
|
193 |
|
194 | var req = {
|
195 | path: data._id ? '/' + data._id : '/resources/' + (0, _uuid2.default)(),
|
196 | type: data._type,
|
197 | data: data
|
198 | };
|
199 | var link = {
|
200 | path: path,
|
201 | type: data._type,
|
202 | data: { _id: data._id || req.path.replace(/^\//, '') }
|
203 | };
|
204 | if (data._rev) link.data._rev = '0-0';
|
205 | return put(link).then(function () {
|
206 | return put(req);
|
207 | });
|
208 | }
|
209 |
|
210 | function _watch(_ref3) {
|
211 | var _this = this;
|
212 |
|
213 | var headers = _ref3.headers,
|
214 | path = _ref3.path,
|
215 | func = _ref3.func,
|
216 | payload = _ref3.payload;
|
217 |
|
218 | if (SOCKET) {
|
219 | return SOCKET.watch({
|
220 | path: path,
|
221 | headers: headers
|
222 | }, function () {
|
223 | var _ref4 = (0, _asyncToGenerator3.default)( _regenerator2.default.mark(function _callee(response) {
|
224 | return _regenerator2.default.wrap(function _callee$(_context) {
|
225 | while (1) {
|
226 | switch (_context.prev = _context.next) {
|
227 | case 0:
|
228 | if (!payload) payload = {};
|
229 | payload.response = response;
|
230 | payload.request = {
|
231 | url: DOMAIN + path,
|
232 | headers: headers,
|
233 | method: payload.response.change.type
|
234 | };
|
235 |
|
236 | if (!CACHE) {
|
237 | _context.next = 6;
|
238 | break;
|
239 | }
|
240 |
|
241 | _context.next = 6;
|
242 | return CACHE.handleWatchChange(payload);
|
243 |
|
244 | case 6:
|
245 | return _context.abrupt('return', func(payload));
|
246 |
|
247 | case 7:
|
248 | case 'end':
|
249 | return _context.stop();
|
250 | }
|
251 | }
|
252 | }, _callee, this);
|
253 | }));
|
254 |
|
255 | function watchResponse(_x) {
|
256 | return _ref4.apply(this, arguments);
|
257 | }
|
258 |
|
259 | return watchResponse;
|
260 | }());
|
261 | } else {
|
262 |
|
263 | return setInterval(function () {
|
264 | _this.get({ url: url }).then(function (result) {
|
265 | func(payload);
|
266 | });
|
267 | }, 5000);
|
268 | }
|
269 | }
|
270 |
|
271 | function get(_ref5) {
|
272 | var _this2 = this;
|
273 |
|
274 | var url = _ref5.url,
|
275 | path = _ref5.path,
|
276 | headers = _ref5.headers,
|
277 | watch = _ref5.watch,
|
278 | tree = _ref5.tree;
|
279 |
|
280 | var req = {
|
281 | method: 'get',
|
282 | url: url || DOMAIN + path,
|
283 | headers: _lodash2.default.merge({ 'Authorization': 'Bearer ' + TOKEN }, headers)
|
284 | };
|
285 |
|
286 | var prom = void 0;
|
287 |
|
288 | if (tree) {
|
289 |
|
290 | var pieces = urlLib.parse(req.url).path.replace(/^\//, '').split('/');
|
291 | var treePath = _convertSetupTreePath(pieces, tree);
|
292 | if (!pointer.has(tree, treePath)) return get({ url: url });
|
293 | tree = pointer.get(tree, treePath);
|
294 | prom = _recursiveGet(req.url, tree, {}).then(function (res) {
|
295 | return {
|
296 | data: res,
|
297 | status: 200
|
298 | };
|
299 | }).catch(function (err) {
|
300 | return;
|
301 | });
|
302 | } else {
|
303 | prom = REQUEST(req);
|
304 | }
|
305 |
|
306 | return prom.then(function () {
|
307 | var _ref6 = (0, _asyncToGenerator3.default)( _regenerator2.default.mark(function _callee2(response) {
|
308 | return _regenerator2.default.wrap(function _callee2$(_context2) {
|
309 | while (1) {
|
310 | switch (_context2.prev = _context2.next) {
|
311 | case 0:
|
312 | if (!watch) {
|
313 | _context2.next = 6;
|
314 | break;
|
315 | }
|
316 |
|
317 | path = path || urlLib.parse(url).path;
|
318 | req.headers['x-oada-rev'] = response.data._rev;
|
319 | console.log(path, response.data._rev);
|
320 | _context2.next = 6;
|
321 | return _watch({
|
322 | headers: req.headers,
|
323 | path: path,
|
324 | func: watch.func,
|
325 | payload: watch.payload
|
326 | });
|
327 |
|
328 | case 6:
|
329 | return _context2.abrupt('return', response);
|
330 |
|
331 | case 7:
|
332 | case 'end':
|
333 | return _context2.stop();
|
334 | }
|
335 | }
|
336 | }, _callee2, _this2);
|
337 | }));
|
338 |
|
339 | return function (_x2) {
|
340 | return _ref6.apply(this, arguments);
|
341 | };
|
342 | }());
|
343 | }
|
344 |
|
345 | function _recursiveGet(url, tree, returnData) {
|
346 | return Promise.try(function () {
|
347 |
|
348 | if (tree._type) {
|
349 |
|
350 | return get({
|
351 | url: url
|
352 | }).then(function (response) {
|
353 | returnData = response.data;
|
354 | return;
|
355 | });
|
356 | }
|
357 | return tree;
|
358 | }).then(function () {
|
359 |
|
360 | return Promise.map((0, _keys2.default)(tree || {}), function (key) {
|
361 |
|
362 |
|
363 | if (key === '*') {
|
364 | return Promise.map((0, _keys2.default)(returnData || {}), function (resKey) {
|
365 | if (resKey.charAt(0) === '_') return;
|
366 | return _recursiveGet(url + '/' + resKey, tree[key] || {}, returnData[resKey]).then(function (res) {
|
367 | return returnData[resKey] = res;
|
368 | });
|
369 | });
|
370 | } else if ((0, _typeof3.default)(tree[key]) === 'object') {
|
371 | return _recursiveGet(url + '/' + key, tree[key] || {}, returnData[key]).then(function (res) {
|
372 | return returnData[key] = res;
|
373 | });
|
374 | } else return returnData[key];
|
375 | }).then(function () {
|
376 | return returnData;
|
377 | });
|
378 | }).catch(function (err) {
|
379 | if (err.response.status === 404) {
|
380 | return;
|
381 | }
|
382 | throw err;
|
383 | });
|
384 | }
|
385 |
|
386 |
|
387 | function _findDeepestResources(pieces, tree, cachedTree) {
|
388 | var cached = 0;
|
389 | var setup = void 0;
|
390 |
|
391 | return Promise.mapSeries(pieces, function (piece, i) {
|
392 | var z = pieces.length - 1 - i;
|
393 | var urlPath = '/' + pieces.slice(0, z + 1).join('/');
|
394 | var treePath = _convertSetupTreePath(pieces.slice(0, z + 1), tree);
|
395 |
|
396 |
|
397 | if (pointer.has(tree, treePath + '/_type')) {
|
398 | setup = setup || z;
|
399 | if (pointer.has(cachedTree, urlPath)) {
|
400 | cached = _lodash2.default.clone(z);
|
401 | throw new Error('cached');
|
402 | }
|
403 | return get({
|
404 | path: urlPath
|
405 | }).then(function (response) {
|
406 | pointer.set(cachedTree, urlPath, {});
|
407 | cached = _lodash2.default.clone(z);
|
408 | throw new Error('cached');
|
409 | }).catch(function (err) {
|
410 |
|
411 | if (/^cached/.test(err.message)) throw err;
|
412 | return;
|
413 | });
|
414 | }
|
415 | return;
|
416 | }).catch(function (err) {
|
417 |
|
418 | if (/^cached/.test(err.message)) return { cached: cached, setup: setup };
|
419 | }).then(function () {
|
420 | return {
|
421 | cached: cached,
|
422 | setup: setup || 0
|
423 | };
|
424 | });
|
425 | }
|
426 |
|
427 |
|
428 |
|
429 |
|
430 | function _convertSetupTreePath(pathPieces, tree) {
|
431 | var newPieces = _lodash2.default.clone(pathPieces);
|
432 | newPieces = pathPieces.map(function (piece, i) {
|
433 | if (pointer.has(tree, '/' + newPieces.slice(0, i).join('/') + '/*')) {
|
434 | newPieces[i] = '*';
|
435 | return '*';
|
436 | } else {
|
437 | return piece;
|
438 | }
|
439 | });
|
440 | return '/' + newPieces.join('/');
|
441 | }
|
442 |
|
443 | function _ensureTree(_ref7) {
|
444 | var url = _ref7.url,
|
445 | tree = _ref7.tree,
|
446 | data = _ref7.data;
|
447 |
|
448 |
|
449 |
|
450 |
|
451 | var path = urlLib.parse(url).path.replace(/^\//, '');
|
452 | var pieces = path.replace(/\/$/, '').split('/');
|
453 | if (data._id) {
|
454 | var firstPath = _convertSetupTreePath(pieces, tree);
|
455 | pointer.set(tree, firstPath + '/_id', data._id);
|
456 | }
|
457 |
|
458 | var cachedTree = {};
|
459 |
|
460 | return _findDeepestResources(pieces, tree, cachedTree).then(function (ret) {
|
461 |
|
462 |
|
463 | return Promise.mapSeries(pieces.slice(0, pieces.length - ret.cached), function (piece, j) {
|
464 | var i = ret.cached + 1 + j;
|
465 | var urlPath = '/' + pieces.slice(0, i + 1).join('/');
|
466 | var treePath = _convertSetupTreePath(pieces.slice(0, i + 1), tree);
|
467 | if (pointer.has(tree, treePath + '/_type') && i <= ret.setup) {
|
468 |
|
469 | return _replaceLinks(pointer.get(tree, treePath)).then(function (content) {
|
470 | return _makeResourceAndLink({
|
471 | path: urlPath,
|
472 | data: _lodash2.default.cloneDeep(content)
|
473 | }).then(function (resp) {
|
474 | pointer.set(cachedTree, urlPath, content);
|
475 | return resp;
|
476 | }).catch(function (err) {
|
477 | return err;
|
478 | });
|
479 | });
|
480 | } else return;
|
481 | });
|
482 | }).then(function (responses) {
|
483 | return responses[responses.length - 1];
|
484 | }).catch(function (err) {
|
485 | return err;
|
486 | });
|
487 | }
|
488 |
|
489 | function post(_ref8) {
|
490 | var url = _ref8.url,
|
491 | path = _ref8.path,
|
492 | data = _ref8.data,
|
493 | type = _ref8.type,
|
494 | headers = _ref8.headers,
|
495 | tree = _ref8.tree;
|
496 |
|
497 | url = url || DOMAIN + path;
|
498 | url = url[url.length - 1] === '/' ? url + (0, _uuid2.default)() : url + '/' + (0, _uuid2.default)();
|
499 | return put({
|
500 | url: url,
|
501 | data: data,
|
502 | type: type,
|
503 | headers: headers,
|
504 | tree: tree
|
505 | });
|
506 | }
|
507 |
|
508 | function del(_ref9) {
|
509 | var url = _ref9.url,
|
510 | path = _ref9.path,
|
511 | headers = _ref9.headers,
|
512 | unwatch = _ref9.unwatch;
|
513 |
|
514 | var req = {
|
515 | method: 'delete',
|
516 | url: url || DOMAIN + path,
|
517 | headers: _lodash2.default.merge({ 'Authorization': 'Bearer ' + TOKEN }, headers)
|
518 | };
|
519 |
|
520 | if (unwatch) {
|
521 | console.log('UNWATCHING');
|
522 | path = path || urlLib.parse(url).path;
|
523 | return SOCKET.unwatch({
|
524 | path: path,
|
525 | headers: req.headers
|
526 | }).then(function () {
|
527 | console.log('UNWATCHING DONE');
|
528 | return;
|
529 | });
|
530 | }
|
531 |
|
532 | return REQUEST(req);
|
533 | }
|
534 |
|
535 | function _configureCache(_ref10) {
|
536 | var name = _ref10.name,
|
537 | req = _ref10.req,
|
538 | exp = _ref10.exp;
|
539 |
|
540 | var res = (0, _cache2.default)({ name: name, req: req, exp: exp });
|
541 | REQUEST = res.api;
|
542 | CACHE = res;
|
543 | return;
|
544 | }
|
545 |
|
546 | function _configureWs(_ref11) {
|
547 | var domain = _ref11.domain;
|
548 |
|
549 | return websocket(domain).then(function (socketApi) {
|
550 | REQUEST = socketApi.http;
|
551 | return SOCKET = socketApi;
|
552 | });
|
553 | }
|
554 |
|
555 | function disconnect() {
|
556 | if (CACHE) CACHE.db.destroy();
|
557 | if (CACHE) CACHE.db.close();
|
558 | if (SOCKET) SOCKET.close();
|
559 | }
|
560 |
|
561 | var urlObj = urlLib.parse(domain);
|
562 | var prom = void 0;
|
563 | if (token) {
|
564 | prom = Promise.resolve({ access_token: token });
|
565 | } else {
|
566 | if (typeof window === 'undefined') {
|
567 | prom = oadaIdClient.node(urlObj.host, options);
|
568 | } else {
|
569 |
|
570 | var gat = Promise.promisify(oadaIdClient.getAccessToken);
|
571 | prom = gat(urlObj.host, options);
|
572 | }
|
573 | }
|
574 | return prom.then(function () {
|
575 | var _ref15 = (0, _asyncToGenerator3.default)( _regenerator2.default.mark(function _callee5(result) {
|
576 | var wsProm;
|
577 | return _regenerator2.default.wrap(function _callee5$(_context5) {
|
578 | while (1) {
|
579 | switch (_context5.prev = _context5.next) {
|
580 | case 0:
|
581 | TOKEN = result.access_token;
|
582 | wsProm = void 0;
|
583 |
|
584 | if (!noWebsocket) {
|
585 | wsProm = websocket(domain).then(function (socketApi) {
|
586 | REQUEST = socketApi.http;
|
587 | return SOCKET = socketApi;
|
588 | });
|
589 | } else wsProm = Promise.resolve();
|
590 | return _context5.abrupt('return', wsProm.then(function () {
|
591 | var cacheProm = void 0;
|
592 | if (cache === false) return;
|
593 | return _configureCache({
|
594 | name: NAME || (0, _uuid2.default)(),
|
595 | req: REQUEST,
|
596 | exp: EXP
|
597 | });
|
598 | }));
|
599 |
|
600 | case 4:
|
601 | case 'end':
|
602 | return _context5.stop();
|
603 | }
|
604 | }
|
605 | }, _callee5, _this3);
|
606 | }));
|
607 |
|
608 | return function (_x6) {
|
609 | return _ref15.apply(this, arguments);
|
610 | };
|
611 | }()).then(function (f) {
|
612 | return {
|
613 | token: TOKEN,
|
614 |
|
615 |
|
616 | get: get,
|
617 | put: put,
|
618 | post: post,
|
619 | delete: del,
|
620 | resetCache: resetCache,
|
621 | disconnect: disconnect
|
622 | };
|
623 | });
|
624 | };
|
625 |
|
626 | exports.default = {
|
627 | connect: connect
|
628 | }; |
\ | No newline at end of file |