UNPKG

46.1 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _regenerator = require("babel-runtime/regenerator");
8
9var _regenerator2 = _interopRequireDefault(_regenerator);
10
11var _keys = require("babel-runtime/core-js/object/keys");
12
13var _keys2 = _interopRequireDefault(_keys);
14
15var _typeof2 = require("babel-runtime/helpers/typeof");
16
17var _typeof3 = _interopRequireDefault(_typeof2);
18
19var _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator");
20
21var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
22
23var _cache = require("./cache");
24
25var _cache2 = _interopRequireDefault(_cache);
26
27var _uuid = require("uuid");
28
29var _uuid2 = _interopRequireDefault(_uuid);
30
31var _lodash = require("lodash");
32
33var _lodash2 = _interopRequireDefault(_lodash);
34
35function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
36
37var Promise = require("bluebird");
38var pretty = require('prettyjson');
39
40var urlLib = require("url");
41var pointer = require("json-pointer");
42var ws = require("./websocket");
43var axios = require("axios");
44var _TOKEN = require("./token");
45
46var connect = function () {
47 var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee18(_ref) {
48 var _makeResourceAndLink = function () {
49 var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(_ref3, waitTime) {
50 var path = _ref3.path,
51 data = _ref3.data,
52 headers = _ref3.headers;
53
54 var _id, linkReq, resReq, link, pathPieces, parentPath, response, newHeaders, resource;
55
56 return _regenerator2.default.wrap(function _callee$(_context) {
57 while (1) {
58 switch (_context.prev = _context.next) {
59 case 0:
60 _id = _lodash2.default.clone(data._id) || "resources/" + (0, _uuid2.default)();
61 linkReq = {
62 path: path,
63 type: data._type,
64 headers: headers,
65 data: { _id: _id }
66 };
67 // Create a version link of the tree specifies it so.
68
69 if (data._rev) linkReq.data._rev = '0-0';
70 resReq = {
71 path: "/" + _id,
72 type: data._type,
73 data: data
74 };
75 _context.prev = 4;
76 _context.next = 7;
77 return put(linkReq);
78
79 case 7:
80 link = _context.sent;
81 _context.next = 42;
82 break;
83
84 case 10:
85 _context.prev = 10;
86 _context.t0 = _context["catch"](4);
87
88 if (!(_context.t0.response && _context.t0.response.status === 412)) {
89 _context.next = 41;
90 break;
91 }
92
93 pathPieces = path.split('/');
94 parentPath = pathPieces.splice(0, pathPieces.length - 1).join('/');
95 // Wait time increases exponentially: 1s, 2s, 4s, 8s, 16s. Throw after 16s.
96
97 if (!(waitTime > 16000)) {
98 _context.next = 17;
99 break;
100 }
101
102 throw _context.t0;
103
104 case 17:
105 _context.prev = 17;
106 _context.next = 20;
107 return NOCACHEREQUEST({ method: 'get', url: DOMAIN + parentPath, headers: { "Authorization": "Bearer " + TOKEN } });
108
109 case 20:
110 response = _context.sent;
111 _context.next = 29;
112 break;
113
114 case 23:
115 _context.prev = 23;
116 _context.t1 = _context["catch"](17);
117
118 waitTime = waitTime || 1000;
119 _context.next = 28;
120 return Promise.delay(waitTime);
121
122 case 28:
123 return _context.abrupt("return", _makeResourceAndLink({ path: path, data: data, headers: headers }, waitTime * 2));
124
125 case 29:
126 if (!response.data[pathPieces[pathPieces.length - 1]]) {
127 _context.next = 33;
128 break;
129 }
130
131 resReq.path = path;
132 _context.next = 39;
133 break;
134
135 case 33:
136 waitTime = waitTime || 1000;
137 _context.next = 36;
138 return Promise.delay(waitTime);
139
140 case 36:
141 newHeaders = _lodash2.default.cloneDeep(headers);
142
143 newHeaders['if-match'] = response.headers['x-oada-rev'];
144 return _context.abrupt("return", _makeResourceAndLink({ path: path, data: data, headers: newHeaders }, waitTime * 2));
145
146 case 39:
147 _context.next = 42;
148 break;
149
150 case 41:
151 throw _context.t0;
152
153 case 42:
154 // Delete the _rev and _id keys. No need for them in the resource object.
155 delete resReq.data._rev;
156 delete resReq.data._id;
157 _context.next = 46;
158 return put(resReq);
159
160 case 46:
161 resource = _context.sent;
162 return _context.abrupt("return", { link: link, resource: resource });
163
164 case 48:
165 case "end":
166 return _context.stop();
167 }
168 }
169 }, _callee, this, [[4, 10], [17, 23]]);
170 }));
171
172 return function _makeResourceAndLink(_x2, _x3) {
173 return _ref4.apply(this, arguments);
174 };
175 }();
176
177 // Construct the request object and catch any 401s (expired token)
178 var _buildRequest = function () {
179 var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(_ref7) {
180 var method = _ref7.method,
181 url = _ref7.url,
182 path = _ref7.path,
183 headers = _ref7.headers,
184 data = _ref7.data,
185 type = _ref7.type;
186 var req;
187 return _regenerator2.default.wrap(function _callee3$(_context3) {
188 while (1) {
189 switch (_context3.prev = _context3.next) {
190 case 0:
191 if (!(!path && !url)) {
192 _context3.next = 2;
193 break;
194 }
195
196 throw new Error("Either path or url must be specified.");
197
198 case 2:
199 if (!url) {
200 _context3.next = 9;
201 break;
202 }
203
204 if (!/^\//.test(url)) {
205 _context3.next = 7;
206 break;
207 }
208
209 url = domain + url;
210 _context3.next = 9;
211 break;
212
213 case 7:
214 if (!(url.indexOf(domain) !== 0)) {
215 _context3.next = 9;
216 break;
217 }
218
219 throw new Error("'url' key must begin with the domain used to connect");
220
221 case 9:
222 method = method.toLowerCase();
223 req = {
224 method: method,
225 url: url || DOMAIN + path,
226 headers: { authorization: "Bearer " + TOKEN }
227 };
228
229 if (/\/$/.test(req.url)) req.url = req.url.slice(0, req.url.length - 1);
230
231 //handle headers
232 (0, _keys2.default)(headers || {}).forEach(function (header) {
233 req.headers[header.toLowerCase()] = headers[header];
234 });
235
236 if (method === "put" || method === 'post') {
237 req.headers["content-type"] = req.headers["content-type"] || type || data._type;
238 req.data = data;
239 }
240
241 if (method === "delete") {
242 req.headers["content-type"] = req.headers["content-type"] || type;
243 }
244 return _context3.abrupt("return", req);
245
246 case 16:
247 case "end":
248 return _context3.stop();
249 }
250 }
251 }, _callee3, this);
252 }));
253
254 return function _buildRequest(_x5) {
255 return _ref8.apply(this, arguments);
256 };
257 }();
258
259 var _sendRequest = function () {
260 var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(req) {
261 return _regenerator2.default.wrap(function _callee4$(_context4) {
262 while (1) {
263 switch (_context4.prev = _context4.next) {
264 case 0:
265 _context4.prev = 0;
266 return _context4.abrupt("return", REQUEST(req));
267
268 case 4:
269 _context4.prev = 4;
270 _context4.t0 = _context4["catch"](0);
271
272 if (!(_context4.t0 && _context4.t0.response.status === 401)) {
273 _context4.next = 10;
274 break;
275 }
276
277 _context4.next = 9;
278 return reconnect();
279
280 case 9:
281 return _context4.abrupt("return", REQUEST(req));
282
283 case 10:
284 throw _context4.t0;
285
286 case 11:
287 case "end":
288 return _context4.stop();
289 }
290 }
291 }, _callee4, this, [[0, 4]]);
292 }));
293
294 return function _sendRequest(_x6) {
295 return _ref9.apply(this, arguments);
296 };
297 }();
298
299 var get = function () {
300 var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(_ref10) {
301 var url = _ref10.url,
302 path = _ref10.path,
303 headers = _ref10.headers,
304 watch = _ref10.watch,
305 tree = _ref10.tree;
306 var req, response, pieces, treePath, subTree, stuff;
307 return _regenerator2.default.wrap(function _callee5$(_context5) {
308 while (1) {
309 switch (_context5.prev = _context5.next) {
310 case 0:
311 _context5.next = 2;
312 return _buildRequest({ method: "get", url: url, path: path, headers: headers });
313
314 case 2:
315 req = _context5.sent;
316 _context5.next = 5;
317 return _sendRequest(req);
318
319 case 5:
320 response = _context5.sent;
321
322 if (!tree) {
323 _context5.next = 17;
324 break;
325 }
326
327 pieces = urlLib.parse(req.url).path.replace(/^\//, "").split("/");
328 treePath = _convertSetupTreePath(pieces, tree);
329
330 if (pointer.has(tree, treePath)) {
331 _context5.next = 11;
332 break;
333 }
334
335 throw new Error("The path does not exist on the given tree.");
336
337 case 11:
338 //return get({url: req.url})
339 subTree = pointer.get(tree, treePath);
340 _context5.next = 14;
341 return _recursiveGet(req.url, subTree, {}, true);
342
343 case 14:
344 stuff = _context5.sent;
345
346 response.data = stuff.data;
347 response.cached = stuff.cached;
348
349 case 17:
350 if (!watch) {
351 _context5.next = 22;
352 break;
353 }
354
355 path = path || urlLib.parse(url).path;
356 req.headers["x-oada-rev"] = response.data._rev;
357 _context5.next = 22;
358 return _watch({
359 headers: req.headers,
360 path: path,
361 func: watch.func,
362 payload: watch.payload
363 });
364
365 case 22:
366 return _context5.abrupt("return", response);
367
368 case 23:
369 case "end":
370 return _context5.stop();
371 }
372 }
373 }, _callee5, this);
374 }));
375
376 return function get(_x7) {
377 return _ref11.apply(this, arguments);
378 };
379 }(); //get
380
381 var _recursiveGet = function () {
382 var _ref12 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(url, tree, data, cached) {
383 var got;
384 return _regenerator2.default.wrap(function _callee7$(_context7) {
385 while (1) {
386 switch (_context7.prev = _context7.next) {
387 case 0:
388 if (!tree._type) {
389 _context7.next = 6;
390 break;
391 }
392
393 _context7.next = 3;
394 return get({
395 url: url
396 });
397
398 case 3:
399 got = _context7.sent;
400
401 data = got.data;
402 cached = got.cached ? got.cached : false;
403
404 case 6:
405 return _context7.abrupt("return", Promise.map((0, _keys2.default)(data || {}), function () {
406 var _ref13 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(key) {
407 var res;
408 return _regenerator2.default.wrap(function _callee6$(_context6) {
409 while (1) {
410 switch (_context6.prev = _context6.next) {
411 case 0:
412 if (!((0, _typeof3.default)(data[key]) === "object")) {
413 _context6.next = 20;
414 break;
415 }
416
417 if (!tree[key]) {
418 _context6.next = 9;
419 break;
420 }
421
422 _context6.next = 4;
423 return _recursiveGet(url + "/" + key, tree[key], data[key], cached);
424
425 case 4:
426 res = _context6.sent;
427
428 cached = res.cached;
429 return _context6.abrupt("return", data[key] = res.data);
430
431 case 9:
432 if (!tree["*"]) {
433 _context6.next = 17;
434 break;
435 }
436
437 _context6.next = 12;
438 return _recursiveGet(url + "/" + key, tree["*"], data[key], cached);
439
440 case 12:
441 res = _context6.sent;
442
443 cached = res.cached;
444 return _context6.abrupt("return", data[key] = res.data);
445
446 case 17:
447 return _context6.abrupt("return");
448
449 case 18:
450 _context6.next = 21;
451 break;
452
453 case 20:
454 return _context6.abrupt("return");
455
456 case 21:
457 case "end":
458 return _context6.stop();
459 }
460 }
461 }, _callee6, this);
462 }));
463
464 return function (_x12) {
465 return _ref13.apply(this, arguments);
466 };
467 }()).then(function () {
468 return { data: data, cached: cached };
469 }));
470
471 case 7:
472 case "end":
473 return _context7.stop();
474 }
475 }
476 }, _callee7, this);
477 }));
478
479 return function _recursiveGet(_x8, _x9, _x10, _x11) {
480 return _ref12.apply(this, arguments);
481 };
482 }();
483
484 // Identify the stored resources vs those that need to be setup.
485
486
487 var _ensureTree = function () {
488 var _ref15 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(_ref14) {
489 var url = _ref14.url,
490 tree = _ref14.tree,
491 data = _ref14.data;
492 var path, pieces, firstPath, storedTree, responses, ret, parentRev;
493 return _regenerator2.default.wrap(function _callee9$(_context9) {
494 while (1) {
495 switch (_context9.prev = _context9.next) {
496 case 0:
497 //If /resources
498
499 //If /bookmarks
500 path = urlLib.parse(url).path.replace(/^\//, "");
501 pieces = path.replace(/\/$/, "").split("/");
502
503 if (data._id) {
504 firstPath = _convertSetupTreePath(pieces, tree);
505
506 pointer.set(tree, firstPath + "/_id", data._id);
507 }
508 // if (pointer.has(tree, treePath)) pointer.set(tree, treePath, _.merge(pointer.get(tree, treePath),data))
509 storedTree = {};
510 responses = [];
511 // Find the deepest part of the path that exists. Once found, work back down.
512
513 _context9.next = 7;
514 return _findDeepestResources(pieces, tree, storedTree);
515
516 case 7:
517 ret = _context9.sent;
518
519 // Create all the resources on the way down. ret.stored is an index. Slice
520 // takes the length to slice, so no need to subtract 1.
521 parentRev = ret._rev;
522 _context9.next = 11;
523 return Promise.mapSeries(pieces.slice(0, pieces.length - ret.stored), function () {
524 var _ref16 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(piece, j) {
525 var i, urlPath, treePath, content, resp;
526 return _regenerator2.default.wrap(function _callee8$(_context8) {
527 while (1) {
528 switch (_context8.prev = _context8.next) {
529 case 0:
530 i = ret.stored + 1 + j; // ret.stored exists; add one to continue beyond.
531
532 urlPath = "/" + pieces.slice(0, i + 1).join("/");
533 treePath = _convertSetupTreePath(pieces.slice(0, i + 1), tree);
534
535 if (!(pointer.has(tree, treePath + "/_type") && i <= ret.setup)) {
536 _context8.next = 14;
537 break;
538 }
539
540 _context8.next = 6;
541 return _replaceLinks(pointer.get(tree, treePath));
542
543 case 6:
544 content = _context8.sent;
545 _context8.next = 9;
546 return _makeResourceAndLink({
547 path: urlPath,
548 data: _lodash2.default.cloneDeep(content),
549 headers: { 'if-match': parentRev }
550 });
551
552 case 9:
553 resp = _context8.sent;
554
555 parentRev = resp.resource.headers['x-oada-rev'];
556 pointer.set(storedTree, urlPath, content);
557 resp.path = urlPath;
558 responses.push(resp);
559
560 case 14:
561 ;
562
563 case 15:
564 case "end":
565 return _context8.stop();
566 }
567 }
568 }, _callee8, this);
569 }));
570
571 return function (_x14, _x15) {
572 return _ref16.apply(this, arguments);
573 };
574 }());
575
576 case 11:
577 return _context9.abrupt("return", responses);
578
579 case 12:
580 case "end":
581 return _context9.stop();
582 }
583 }
584 }, _callee9, this);
585 }));
586
587 return function _ensureTree(_x13) {
588 return _ref15.apply(this, arguments);
589 };
590 }();
591
592 var _recursiveDelete = function () {
593 var _ref20 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee12(url, tree, data) {
594 var got;
595 return _regenerator2.default.wrap(function _callee12$(_context12) {
596 while (1) {
597 switch (_context12.prev = _context12.next) {
598 case 0:
599 if (!tree._type) {
600 _context12.next = 13;
601 break;
602 }
603
604 _context12.prev = 1;
605 _context12.next = 4;
606 return get({
607 url: url
608 });
609
610 case 4:
611 got = _context12.sent;
612
613 data = got.data;
614 _context12.next = 13;
615 break;
616
617 case 8:
618 _context12.prev = 8;
619 _context12.t0 = _context12["catch"](1);
620
621 if (!(_context12.t0.status === 404)) {
622 _context12.next = 13;
623 break;
624 }
625
626 data = {};
627 return _context12.abrupt("return");
628
629 case 13:
630 return _context12.abrupt("return", Promise.map((0, _keys2.default)(data || {}), function () {
631 var _ref21 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(key) {
632 var res;
633 return _regenerator2.default.wrap(function _callee10$(_context10) {
634 while (1) {
635 switch (_context10.prev = _context10.next) {
636 case 0:
637 if (!((0, _typeof3.default)(data[key]) === "object")) {
638 _context10.next = 18;
639 break;
640 }
641
642 if (!tree[key]) {
643 _context10.next = 8;
644 break;
645 }
646
647 _context10.next = 4;
648 return _recursiveDelete(url + "/" + key, tree[key], data[key]);
649
650 case 4:
651 res = _context10.sent;
652 return _context10.abrupt("return", data[key] = res.data);
653
654 case 8:
655 if (!tree["*"]) {
656 _context10.next = 15;
657 break;
658 }
659
660 _context10.next = 11;
661 return _recursiveDelete(url + "/" + key, tree["*"], data[key]);
662
663 case 11:
664 res = _context10.sent;
665 return _context10.abrupt("return", data[key] = res.data);
666
667 case 15:
668 return _context10.abrupt("return");
669
670 case 16:
671 _context10.next = 19;
672 break;
673
674 case 18:
675 return _context10.abrupt("return");
676
677 case 19:
678 case "end":
679 return _context10.stop();
680 }
681 }
682 }, _callee10, this);
683 }));
684
685 return function (_x19) {
686 return _ref21.apply(this, arguments);
687 };
688 }()).then((0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee11() {
689 var link;
690 return _regenerator2.default.wrap(function _callee11$(_context11) {
691 while (1) {
692 switch (_context11.prev = _context11.next) {
693 case 0:
694 if (!tree._type) {
695 _context11.next = 15;
696 break;
697 }
698
699 _context11.prev = 1;
700
701 if (!data._id) {
702 _context11.next = 5;
703 break;
704 }
705
706 _context11.next = 5;
707 return del({
708 path: '/' + data._id,
709 headers: { 'content-type': tree._type }
710 });
711
712 case 5:
713 _context11.next = 7;
714 return del({
715 url: url,
716 headers: {
717 'content-type': tree._type
718 }
719 });
720
721 case 7:
722 link = _context11.sent;
723 _context11.next = 15;
724 break;
725
726 case 10:
727 _context11.prev = 10;
728 _context11.t0 = _context11["catch"](1);
729
730 if (!(_context11.t0.status === 404)) {
731 _context11.next = 15;
732 break;
733 }
734
735 data = {};
736 return _context11.abrupt("return");
737
738 case 15:
739 return _context11.abrupt("return", { link: link, data: data });
740
741 case 16:
742 case "end":
743 return _context11.stop();
744 }
745 }
746 }, _callee11, this, [[1, 10]]);
747 }))));
748
749 case 14:
750 case "end":
751 return _context12.stop();
752 }
753 }
754 }, _callee12, this, [[1, 8]]);
755 }));
756
757 return function _recursiveDelete(_x16, _x17, _x18) {
758 return _ref20.apply(this, arguments);
759 };
760 }();
761
762 var del = function () {
763 var _ref24 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee13(_ref23) {
764 var url = _ref23.url,
765 path = _ref23.path,
766 type = _ref23.type,
767 headers = _ref23.headers,
768 tree = _ref23.tree,
769 unwatch = _ref23.unwatch;
770 var req, pieces, treePath, subTree, result;
771 return _regenerator2.default.wrap(function _callee13$(_context13) {
772 while (1) {
773 switch (_context13.prev = _context13.next) {
774 case 0:
775 _context13.next = 2;
776 return _buildRequest({ method: "delete", url: url, path: path, type: type, headers: headers });
777
778 case 2:
779 req = _context13.sent;
780
781 if (!unwatch) {
782 _context13.next = 6;
783 break;
784 }
785
786 path = path || urlLib.parse(url).path;
787 return _context13.abrupt("return", SOCKET.unwatch({
788 path: path,
789 headers: req.headers
790 }));
791
792 case 6:
793 if (!tree) {
794 _context13.next = 16;
795 break;
796 }
797
798 pieces = urlLib.parse(req.url).path.replace(/^\//, "").split("/");
799 treePath = _convertSetupTreePath(pieces, tree);
800
801 if (pointer.has(tree, treePath)) {
802 _context13.next = 11;
803 break;
804 }
805
806 throw new Error("The path does not exist on the given tree.");
807
808 case 11:
809 //return get({url: req.url})
810 subTree = pointer.get(tree, treePath);
811 _context13.next = 14;
812 return _recursiveDelete(req.url, subTree, {}, true);
813
814 case 14:
815 result = _context13.sent;
816 return _context13.abrupt("return", result.link);
817
818 case 16:
819 if (req.headers["content-type"]) {
820 _context13.next = 18;
821 break;
822 }
823
824 throw new Error("content-type header must be specified.");
825
826 case 18:
827 return _context13.abrupt("return", _sendRequest(req));
828
829 case 19:
830 case "end":
831 return _context13.stop();
832 }
833 }
834 }, _callee13, this);
835 }));
836
837 return function del(_x20) {
838 return _ref24.apply(this, arguments);
839 };
840 }();
841
842 // Ensure all resources down to the deepest resource are created before
843 // performing a PUT.
844
845
846 var put = function () {
847 var _ref26 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee14(_ref25) {
848 var url = _ref25.url,
849 path = _ref25.path,
850 data = _ref25.data,
851 type = _ref25.type,
852 headers = _ref25.headers,
853 tree = _ref25.tree;
854 var req, responses, pieces, treePath;
855 return _regenerator2.default.wrap(function _callee14$(_context14) {
856 while (1) {
857 switch (_context14.prev = _context14.next) {
858 case 0:
859 _context14.next = 2;
860 return _buildRequest({
861 method: "put",
862 url: url,
863 path: path,
864 data: data,
865 type: type,
866 headers: headers
867 });
868
869 case 2:
870 req = _context14.sent;
871
872 if (!tree) {
873 _context14.next = 10;
874 break;
875 }
876
877 _context14.next = 6;
878 return _ensureTree({
879 url: req.url,
880 tree: _lodash2.default.cloneDeep(tree),
881 data: data
882 });
883
884 case 6:
885 responses = _context14.sent;
886 pieces = responses.length > 0 ? responses[responses.length - 1].path.replace(/^\//, "").split("/") : urlLib.parse(req.url).path.replace(/^\//, "").split('/');
887 treePath = _convertSetupTreePath(pieces, tree) + "/_type";
888
889 if (!req.headers["content-type"] && pointer.has(tree, treePath)) req.headers["content-type"] = _lodash2.default.clone(pointer.get(tree, treePath));
890
891 case 10:
892 if (req.headers["content-type"]) {
893 _context14.next = 12;
894 break;
895 }
896
897 throw new Error("content-type header must be specified.");
898
899 case 12:
900 return _context14.abrupt("return", _sendRequest(req));
901
902 case 13:
903 case "end":
904 return _context14.stop();
905 }
906 }
907 }, _callee14, this);
908 }));
909
910 return function put(_x21) {
911 return _ref26.apply(this, arguments);
912 };
913 }();
914
915 var resetCache = function () {
916 var _ref27 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee15(name, expires) {
917 return _regenerator2.default.wrap(function _callee15$(_context15) {
918 while (1) {
919 switch (_context15.prev = _context15.next) {
920 case 0:
921 if (CACHE) {
922 _context15.next = 2;
923 break;
924 }
925
926 return _context15.abrupt("return");
927
928 case 2:
929 _context15.next = 4;
930 return CACHE.resetCache();
931
932 case 4:
933 case "end":
934 return _context15.stop();
935 }
936 }
937 }, _callee15, this);
938 }));
939
940 return function resetCache(_x22, _x23) {
941 return _ref27.apply(this, arguments);
942 };
943 }();
944
945 var disconnect = function () {
946 var _ref28 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee16() {
947 return _regenerator2.default.wrap(function _callee16$(_context16) {
948 while (1) {
949 switch (_context16.prev = _context16.next) {
950 case 0:
951 if (!CACHE) {
952 _context16.next = 3;
953 break;
954 }
955
956 _context16.next = 3;
957 return CACHE.db.close();
958
959 case 3:
960 //if (CACHE) await CACHE.db.destroy();
961 if (SOCKET) SOCKET.close();
962 if (_token.isSet()) {
963 _token.cleanUp();
964 }
965
966 case 5:
967 case "end":
968 return _context16.stop();
969 }
970 }
971 }, _callee16, this);
972 }));
973
974 return function disconnect() {
975 return _ref28.apply(this, arguments);
976 };
977 }();
978
979 var reconnect = function () {
980 var _ref29 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee17() {
981 return _regenerator2.default.wrap(function _callee17$(_context17) {
982 while (1) {
983 switch (_context17.prev = _context17.next) {
984 case 0:
985 _context17.next = 2;
986 return _token.renew();
987
988 case 2:
989 TOKEN = _context17.sent;
990
991 case 3:
992 case "end":
993 return _context17.stop();
994 }
995 }
996 }, _callee17, this);
997 }));
998
999 return function reconnect() {
1000 return _ref29.apply(this, arguments);
1001 };
1002 }();
1003
1004 // get a token
1005
1006
1007 var domain = _ref.domain,
1008 options = _ref.options,
1009 cache = _ref.cache,
1010 token = _ref.token,
1011 websocket = _ref.websocket;
1012
1013 var OFFLINE, CACHE, REQUEST, NOCACHEREQUEST, SOCKET, TOKEN, _token, DOMAIN, NAME, EXPIRES, _replaceLinks, _watch, _findDeepestResources, _convertSetupTreePath, _configureCache, _configureWs, post, socketApi;
1014
1015 return _regenerator2.default.wrap(function _callee18$(_context18) {
1016 while (1) {
1017 switch (_context18.prev = _context18.next) {
1018 case 0:
1019 post = function post(_ref19) {
1020 var url = _ref19.url,
1021 path = _ref19.path,
1022 data = _ref19.data,
1023 type = _ref19.type,
1024 headers = _ref19.headers,
1025 tree = _ref19.tree;
1026
1027 url = url || DOMAIN + path;
1028 url = url[url.length - 1] === "/" ? url + (0, _uuid2.default)() : url + "/" + (0, _uuid2.default)();
1029 return put({
1030 url: url,
1031 data: data,
1032 type: type,
1033 headers: headers,
1034 tree: tree
1035 });
1036 };
1037
1038 _configureWs = function _configureWs(_ref18) {
1039 var domain = _ref18.domain;
1040
1041 return ws(domain).then(function (socketApi) {
1042 REQUEST = socketApi.http;
1043 NOCACHEREQUEST = socketApi.http;
1044 return SOCKET = socketApi;
1045 });
1046 };
1047
1048 _configureCache = function _configureCache(_ref17) {
1049 var name = _ref17.name,
1050 req = _ref17.req,
1051 expires = _ref17.expires;
1052
1053 var res = (0, _cache2.default)({ name: name, req: req, expires: expires });
1054 REQUEST = res.api;
1055 CACHE = res;
1056 return;
1057 };
1058
1059 _convertSetupTreePath = function _convertSetupTreePath(pathPieces, tree) {
1060 var newPieces = _lodash2.default.clone(pathPieces);
1061 newPieces = pathPieces.map(function (piece, i) {
1062 if (pointer.has(tree, "/" + newPieces.slice(0, i).join("/") + "/*")) {
1063 newPieces[i] = "*";
1064 return "*";
1065 } else {
1066 return piece;
1067 }
1068 });
1069 return "/" + newPieces.join("/");
1070 };
1071
1072 _findDeepestResources = function _findDeepestResources(pieces, tree, storedTree) {
1073 var stored = 0;
1074 var setup = void 0;
1075 var _rev;
1076 // Walk down the url in reverse order
1077 return Promise.mapSeries(pieces, function (piece, i) {
1078 var z = pieces.length - 1 - i; //use z to create paths in reverse order
1079 var urlPath = "/" + pieces.slice(0, z + 1).join("/");
1080 var treePath = _convertSetupTreePath(pieces.slice(0, z + 1), tree);
1081 // Check that its in the stored tree then look for deepest _resource_.
1082 // If successful, break from the loop by throwing
1083 if (pointer.has(tree, treePath + "/_type")) {
1084 setup = setup || z;
1085 if (pointer.has(storedTree, urlPath)) {
1086 stored = _lodash2.default.clone(z);
1087 throw new Error("stored");
1088 }
1089 return get({
1090 path: urlPath
1091 }).then(function (response) {
1092 //TODO: Detect whether the returned data matches the given tree
1093 pointer.set(storedTree, urlPath, {});
1094 stored = _lodash2.default.clone(z);
1095 _rev = response.headers['x-oada-rev'];
1096 throw new Error("stored");
1097 }).catch(function (err) {
1098 if (/^stored/.test(err.message)) throw err;
1099 return;
1100 });
1101 } else return;
1102 }).catch(function (err) {
1103 // Throwing with a number error only should occur on success.
1104 if (/^stored/.test(err.message)) return { stored: stored, setup: setup };
1105 }).then(function () {
1106 return {
1107 stored: stored,
1108 setup: setup || 0,
1109 _rev: _rev
1110 };
1111 });
1112 };
1113
1114 _watch = function _watch(_ref5) {
1115 var headers = _ref5.headers,
1116 path = _ref5.path,
1117 func = _ref5.func,
1118 payload = _ref5.payload;
1119
1120 if (SOCKET) {
1121 return SOCKET.watch({
1122 path: path,
1123 headers: headers
1124 }, function () {
1125 var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(response) {
1126 var watchPayload;
1127 return _regenerator2.default.wrap(function _callee2$(_context2) {
1128 while (1) {
1129 switch (_context2.prev = _context2.next) {
1130 case 0:
1131 console.log('some response');
1132 //console.log('_watch', pretty.render(response))
1133 watchPayload = _lodash2.default.cloneDeep(payload) || {};
1134
1135 watchPayload.response = response;
1136 watchPayload.request = {
1137 url: DOMAIN + path,
1138 headers: headers,
1139 method: response.change.type
1140 };
1141
1142 if (!CACHE) {
1143 _context2.next = 7;
1144 break;
1145 }
1146
1147 _context2.next = 7;
1148 return CACHE.handleWatchChange(watchPayload);
1149
1150 case 7:
1151 if (!func) {
1152 _context2.next = 10;
1153 break;
1154 }
1155
1156 _context2.next = 10;
1157 return func(watchPayload);
1158
1159 case 10:
1160 return _context2.abrupt("return");
1161
1162 case 11:
1163 case "end":
1164 return _context2.stop();
1165 }
1166 }
1167 }, _callee2, this);
1168 }));
1169
1170 function watchResponse(_x4) {
1171 return _ref6.apply(this, arguments);
1172 }
1173
1174 return watchResponse;
1175 }());
1176 } else {
1177 // Ping a normal GET every 5 seconds in the absense of a websocket
1178 return setInterval(function () {
1179 get({ url: DOMAIN + path }).then(function (result) {
1180 func(payload);
1181 });
1182 }, 5000);
1183 }
1184 };
1185
1186 _replaceLinks = function _replaceLinks(obj) {
1187 var ret = Array.isArray(obj) ? [] : {};
1188 if (!obj) return obj; // no defined objriptors for this level
1189 return Promise.map((0, _keys2.default)(obj || {}), function (key) {
1190 if (key === "*") {
1191 // Don't put *s into oada. Ignore them
1192 return;
1193 }
1194 var val = obj[key];
1195 if ((typeof val === "undefined" ? "undefined" : (0, _typeof3.default)(val)) !== "object" || !val) {
1196 ret[key] = val; // keep it asntType: 'application/vnd.oada.harvest.1+json'
1197 return;
1198 }
1199 if (val._type) {
1200 // If it has a '_type' key, don't worry about it.
1201 //It'll get created in future iterations of ensureTree
1202 return;
1203 }
1204 if (val._id) {
1205 // If it's an object, and has an '_id', make it a link from descriptor
1206 ret[key] = { _id: val._id };
1207 if (val._rev) ret[key]._rev = val._rev;
1208 return;
1209 }
1210 // otherwise, recurse into the object looking for more links
1211 return _replaceLinks(val).then(function (result) {
1212 ret[key] = result;
1213 return;
1214 });
1215 }).then(function () {
1216 return ret;
1217 });
1218 };
1219
1220 if (domain) {
1221 _context18.next = 9;
1222 break;
1223 }
1224
1225 throw new Error("domain undefined");
1226
1227 case 9:
1228 if (!(typeof domain !== "string")) {
1229 _context18.next = 11;
1230 break;
1231 }
1232
1233 throw new Error("domain must be a string");
1234
1235 case 11:
1236 if (!(!options && !token)) {
1237 _context18.next = 13;
1238 break;
1239 }
1240
1241 throw new Error("options and token undefined");
1242
1243 case 13:
1244 if (!(token && typeof token !== "string")) {
1245 _context18.next = 15;
1246 break;
1247 }
1248
1249 throw new Error("token must be a string");
1250
1251 case 15:
1252 if (!(cache !== undefined && typeof cache !== "boolean" && (typeof cache === "undefined" ? "undefined" : (0, _typeof3.default)(cache)) !== "object")) {
1253 _context18.next = 17;
1254 break;
1255 }
1256
1257 throw new Error("cache must be either a boolean or an object with 'name' and/or 'expires' keys");
1258
1259 case 17:
1260 if (!(cache && cache.name && typeof cache.name !== "string")) {
1261 _context18.next = 19;
1262 break;
1263 }
1264
1265 throw new Error("cache name must be a string");
1266
1267 case 19:
1268 if (!(typeof websocket !== "undefined" && typeof websocket !== "boolean")) {
1269 _context18.next = 21;
1270 break;
1271 }
1272
1273 throw new Error("websocket must be boolean");
1274
1275 case 21:
1276 REQUEST = axios;
1277 NOCACHEREQUEST = axios;
1278 _token = new _TOKEN({ domain: domain, token: token, options: options });
1279
1280 if (domain) {
1281 _context18.next = 26;
1282 break;
1283 }
1284
1285 throw new Error('domain undefined');
1286
1287 case 26:
1288 DOMAIN = domain;
1289 NAME = cache && cache.name ? cache.name : urlLib.parse(domain).hostname.replace(/\./g, "_");
1290 EXPIRES = cache && cache.expires ? cache.expires : undefined;
1291
1292 // Loop over the keys of the path and determine whether the object at that level
1293 // contains a * key. The path must be updated along the way, replacing *s as
1294 // necessary.
1295
1296 _context18.next = 31;
1297 return _token.get();
1298
1299 case 31:
1300 TOKEN = _context18.sent;
1301
1302 if (!(websocket !== false)) {
1303 _context18.next = 40;
1304 break;
1305 }
1306
1307 _context18.next = 35;
1308 return ws(domain);
1309
1310 case 35:
1311 socketApi = _context18.sent;
1312
1313 REQUEST = socketApi.http;
1314 _context18.next = 39;
1315 return socketApi;
1316
1317 case 39:
1318 SOCKET = _context18.sent;
1319
1320 case 40:
1321 if (!(cache !== false)) {
1322 _context18.next = 43;
1323 break;
1324 }
1325
1326 _context18.next = 43;
1327 return _configureCache({
1328 name: NAME || (0, _uuid2.default)(),
1329 req: REQUEST,
1330 expires: EXPIRES
1331 });
1332
1333 case 43:
1334 return _context18.abrupt("return", {
1335 token: TOKEN,
1336 cache: CACHE ? CACHE : false,
1337 websocket: SOCKET ? SOCKET : false,
1338 get: get,
1339 put: put,
1340 post: post,
1341 delete: del,
1342 resetCache: resetCache,
1343 disconnect: disconnect,
1344 reconnect: reconnect
1345 });
1346
1347 case 44:
1348 case "end":
1349 return _context18.stop();
1350 }
1351 }
1352 }, _callee18, this);
1353 }));
1354
1355 function connect(_x) {
1356 return _ref2.apply(this, arguments);
1357 }
1358
1359 return connect;
1360}();
1361
1362exports.default = {
1363 connect: connect
1364};
\No newline at end of file