cozy-client 47.6.0 → 48.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2620,6 +2620,54 @@ var CozyClient = /*#__PURE__*/function () {
2620
2620
 
2621
2621
  return saveAfterFetchSettings;
2622
2622
  }()
2623
+ /**
2624
+ * Reset a query
2625
+ *
2626
+ * This method will reset the query state to its initial state and refetch it.
2627
+ *
2628
+ * @param {string} queryId - Query id
2629
+ * @returns {Promise<import("./types").QueryState>} - Query state
2630
+ */
2631
+
2632
+ }, {
2633
+ key: "resetQuery",
2634
+ value: function () {
2635
+ var _resetQuery2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(queryId) {
2636
+ var query;
2637
+ return _regenerator.default.wrap(function _callee21$(_context21) {
2638
+ while (1) {
2639
+ switch (_context21.prev = _context21.next) {
2640
+ case 0:
2641
+ _context21.prev = 0;
2642
+ this.dispatch((0, _store.resetQuery)(queryId));
2643
+ query = this.getQueryFromState(queryId);
2644
+ _context21.next = 5;
2645
+ return this.query(query.definition, {
2646
+ as: queryId
2647
+ });
2648
+
2649
+ case 5:
2650
+ return _context21.abrupt("return", _context21.sent);
2651
+
2652
+ case 8:
2653
+ _context21.prev = 8;
2654
+ _context21.t0 = _context21["catch"](0);
2655
+ throw _context21.t0;
2656
+
2657
+ case 11:
2658
+ case "end":
2659
+ return _context21.stop();
2660
+ }
2661
+ }
2662
+ }, _callee21, this, [[0, 8]]);
2663
+ }));
2664
+
2665
+ function resetQuery(_x22) {
2666
+ return _resetQuery2.apply(this, arguments);
2667
+ }
2668
+
2669
+ return resetQuery;
2670
+ }()
2623
2671
  }], [{
2624
2672
  key: "fromOldClient",
2625
2673
  value: function fromOldClient(oldClient, options) {
@@ -2642,22 +2690,22 @@ var CozyClient = /*#__PURE__*/function () {
2642
2690
  }, {
2643
2691
  key: "fromOldOAuthClient",
2644
2692
  value: function () {
2645
- var _fromOldOAuthClient = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee21(oldClient, options) {
2693
+ var _fromOldOAuthClient = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee22(oldClient, options) {
2646
2694
  var credentials, oauthOptions, client;
2647
- return _regenerator.default.wrap(function _callee21$(_context21) {
2695
+ return _regenerator.default.wrap(function _callee22$(_context22) {
2648
2696
  while (1) {
2649
- switch (_context21.prev = _context21.next) {
2697
+ switch (_context22.prev = _context22.next) {
2650
2698
  case 0:
2651
2699
  if (!oldClient._oauth) {
2652
- _context21.next = 12;
2700
+ _context22.next = 12;
2653
2701
  break;
2654
2702
  }
2655
2703
 
2656
- _context21.next = 3;
2704
+ _context22.next = 3;
2657
2705
  return oldClient.authorize();
2658
2706
 
2659
2707
  case 3:
2660
- credentials = _context21.sent;
2708
+ credentials = _context22.sent;
2661
2709
  oauthOptions = {
2662
2710
  oauth: credentials.client,
2663
2711
  token: credentials.token,
@@ -2668,28 +2716,28 @@ var CozyClient = /*#__PURE__*/function () {
2668
2716
  }, oauthOptions), options));
2669
2717
 
2670
2718
  if (!client.loginPromise) {
2671
- _context21.next = 9;
2719
+ _context22.next = 9;
2672
2720
  break;
2673
2721
  }
2674
2722
 
2675
- _context21.next = 9;
2723
+ _context22.next = 9;
2676
2724
  return client.loginPromise;
2677
2725
 
2678
2726
  case 9:
2679
- return _context21.abrupt("return", client);
2727
+ return _context22.abrupt("return", client);
2680
2728
 
2681
2729
  case 12:
2682
2730
  throw new Error('Cannot instantiate a new client: old client is not an OAuth client. CozyClient.fromOldClient might be more suitable.');
2683
2731
 
2684
2732
  case 13:
2685
2733
  case "end":
2686
- return _context21.stop();
2734
+ return _context22.stop();
2687
2735
  }
2688
2736
  }
2689
- }, _callee21);
2737
+ }, _callee22);
2690
2738
  }));
2691
2739
 
2692
- function fromOldOAuthClient(_x22, _x23) {
2740
+ function fromOldOAuthClient(_x23, _x24) {
2693
2741
  return _fromOldOAuthClient.apply(this, arguments);
2694
2742
  }
2695
2743
 
@@ -2782,7 +2830,7 @@ var CozyClient = /*#__PURE__*/function () {
2782
2830
  CozyClient.hooks = CozyClient.hooks || {};
2783
2831
  CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
2784
2832
 
2785
- CozyClient.version = "47.6.0";
2833
+ CozyClient.version = "48.1.0";
2786
2834
 
2787
2835
  _microee.default.mixin(CozyClient);
2788
2836
 
@@ -30,7 +30,8 @@ import {
30
30
  receiveMutationError,
31
31
  getQueryFromState,
32
32
  getRawQueryFromState,
33
- loadQuery
33
+ loadQuery,
34
+ resetQuery
34
35
  } from './store'
35
36
  import { HasManyFiles, Association, HasMany } from './associations'
36
37
  import mapValues from 'lodash/mapValues'
@@ -1872,6 +1873,37 @@ describe('CozyClient', () => {
1872
1873
  })
1873
1874
  })
1874
1875
  })
1876
+
1877
+ describe('resetQuery', () => {
1878
+ const fakeResponse = {
1879
+ data: [TODO_1, TODO_2, TODO_3]
1880
+ }
1881
+
1882
+ afterEach(() => {
1883
+ jest.restoreAllMocks()
1884
+ })
1885
+
1886
+ it('should reset the query state and refetch it', async () => {
1887
+ requestHandler.mockResolvedValue(fakeResponse)
1888
+ const queryDefinition = Q('io.cozy.todos')
1889
+ const queryId = 'allTodos'
1890
+ getQueryFromState.mockReturnValue({
1891
+ definition: queryDefinition,
1892
+ id: queryId,
1893
+ data: fakeResponse
1894
+ })
1895
+
1896
+ await client.resetQuery(queryId)
1897
+
1898
+ const dispatchCalls = client.store.dispatch.mock.calls
1899
+ const firstDispatchCall = dispatchCalls[0]
1900
+ expect(firstDispatchCall[0]).toEqual(resetQuery(queryId))
1901
+ const lastDispatchCall = dispatchCalls[dispatchCalls.length - 1]
1902
+ expect(lastDispatchCall[0]).toEqual(
1903
+ receiveQueryResult('allTodos', fakeResponse)
1904
+ )
1905
+ })
1906
+ })
1875
1907
  })
1876
1908
 
1877
1909
  describe('file creation', () => {
@@ -195,7 +195,7 @@
195
195
  },
196
196
  "vehicle": {
197
197
  "licenseNumber": "Vehicle registration number",
198
- "confidentialNumber": "Confidential code"
198
+ "confidentialNumber": "Confidential vehicle registration code"
199
199
  },
200
200
  "vehicle_registration": {
201
201
  "number": "Vehicle registration number (VIN)"
@@ -195,7 +195,7 @@
195
195
  },
196
196
  "vehicle": {
197
197
  "licenseNumber": "Plaque d'immatriculation",
198
- "confidentialNumber": "Code confidentiel"
198
+ "confidentialNumber": "Code confidentiel de la carte grise"
199
199
  },
200
200
  "vehicle_registration": {
201
201
  "number": "Numéro de la carte grise (VIN)"
@@ -457,25 +457,29 @@ var getFullpath = /*#__PURE__*/function () {
457
457
  }();
458
458
  /**
459
459
  * Move file to destination.
460
+ * Manage 4 cases :
461
+ * - Move inside a Cozy server
462
+ * - Move inside a Nextcloud server
463
+ * - Move from a Nextcloud server to Cozy
464
+ * - Move from Cozy to a Nextcloud server
460
465
  *
461
- * @param {CozyClient} client - The CozyClient instance
462
- * @param {string} fileId - The file's id (required)
463
- * @param {object} destination - The destination object containing:
464
- * @param {string} destination.folderId - The destination folder's id (required)
465
- * @param {string} destination.path - The file's path after the move (optional, used to optimize performance in case of conflict)
466
- * @param {boolean} force - Whether we should overwrite, i.e. put to trash, the destination in case of conflict (defaults to false).
467
- * @returns {Promise} - A promise that returns the move action response and the deleted file id (if any) if resolved or an Error if rejected
468
- *
466
+ * @param {CozyClient} client - The CozyClient instance
467
+ * @param {import('../types').IOCozyFile | import('../types').NextcloudFile} file - The file to move (required)
468
+ * @param {import('../types').IOCozyFolder | import('../types').NextcloudFile} destination - The destination folder (required)
469
+ * @param {object} options - The options
470
+ * @param {boolean} options.force - Whether we should overwrite,
471
+ * i.e. put to trash, the destination in case of conflict (defaults to false).
472
+ * @returns {Promise<{moved: undefined|import('../types').IOCozyFile, deleted: null|string[] }>} - A promise that returns the move action response (if any)
473
+ * and the deleted file id (if any) if resolved or an Error if rejected
469
474
  */
470
475
 
471
476
 
472
477
  exports.getFullpath = getFullpath;
473
478
 
474
479
  var move = /*#__PURE__*/function () {
475
- var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(client, fileId, destination) {
476
- var force,
477
- folderId,
478
- path,
480
+ var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(client, file, destination) {
481
+ var _ref6,
482
+ force,
479
483
  resp,
480
484
  destinationPath,
481
485
  _yield$client$query2,
@@ -489,84 +493,141 @@ var move = /*#__PURE__*/function () {
489
493
  while (1) {
490
494
  switch (_context4.prev = _context4.next) {
491
495
  case 0:
492
- force = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : false;
493
- folderId = destination.folderId, path = destination.path;
494
- _context4.prev = 2;
495
- _context4.next = 5;
496
- return client.collection(_const.DOCTYPE_FILES).updateFileMetadata(fileId, {
497
- dir_id: folderId
496
+ _ref6 = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {
497
+ force: false
498
+ }, force = _ref6.force;
499
+ _context4.prev = 1;
500
+
501
+ if (!(file._type === 'io.cozy.remote.nextcloud.files')) {
502
+ _context4.next = 10;
503
+ break;
504
+ }
505
+
506
+ if (!(destination._type === 'io.cozy.remote.nextcloud.files')) {
507
+ _context4.next = 7;
508
+ break;
509
+ }
510
+
511
+ _context4.next = 6;
512
+ return client.collection('io.cozy.remote.nextcloud.files').move(file, destination);
513
+
514
+ case 6:
515
+ return _context4.abrupt("return", {
516
+ moved: undefined,
517
+ deleted: null
518
+ });
519
+
520
+ case 7:
521
+ _context4.next = 9;
522
+ return client.collection('io.cozy.remote.nextcloud.files').moveToCozy(file, destination);
523
+
524
+ case 9:
525
+ return _context4.abrupt("return", {
526
+ moved: undefined,
527
+ deleted: null
528
+ });
529
+
530
+ case 10:
531
+ if (!(destination._type === 'io.cozy.remote.nextcloud.files')) {
532
+ _context4.next = 14;
533
+ break;
534
+ }
535
+
536
+ _context4.next = 13;
537
+ return client.collection('io.cozy.remote.nextcloud.files').moveFromCozy(destination, file);
538
+
539
+ case 13:
540
+ return _context4.abrupt("return", {
541
+ moved: undefined,
542
+ deleted: null
498
543
  });
499
544
 
500
- case 5:
545
+ case 14:
546
+ _context4.next = 19;
547
+ break;
548
+
549
+ case 16:
550
+ _context4.prev = 16;
551
+ _context4.t0 = _context4["catch"](1);
552
+ throw _context4.t0;
553
+
554
+ case 19:
555
+ _context4.prev = 19;
556
+ _context4.next = 22;
557
+ return client.collection(_const.DOCTYPE_FILES).updateFileMetadata(file._id, {
558
+ dir_id: destination._id
559
+ });
560
+
561
+ case 22:
501
562
  resp = _context4.sent;
502
563
  return _context4.abrupt("return", {
503
564
  moved: resp.data,
504
565
  deleted: null
505
566
  });
506
567
 
507
- case 9:
508
- _context4.prev = 9;
509
- _context4.t0 = _context4["catch"](2);
568
+ case 26:
569
+ _context4.prev = 26;
570
+ _context4.t1 = _context4["catch"](19);
510
571
 
511
- if (!(_context4.t0.status === 409 && force)) {
512
- _context4.next = 35;
572
+ if (!(_context4.t1.status === 409 && force)) {
573
+ _context4.next = 52;
513
574
  break;
514
575
  }
515
576
 
516
- if (!path) {
517
- _context4.next = 16;
577
+ if (!destination.path) {
578
+ _context4.next = 33;
518
579
  break;
519
580
  }
520
581
 
521
- destinationPath = path;
522
- _context4.next = 24;
582
+ destinationPath = destination.path;
583
+ _context4.next = 41;
523
584
  break;
524
585
 
525
- case 16:
526
- _context4.next = 18;
527
- return client.query((0, _dsl.Q)(_const.DOCTYPE_FILES).getById(fileId));
586
+ case 33:
587
+ _context4.next = 35;
588
+ return client.query((0, _dsl.Q)(_const.DOCTYPE_FILES).getById(file._id));
528
589
 
529
- case 18:
590
+ case 35:
530
591
  _yield$client$query2 = _context4.sent;
531
592
  movedFile = _yield$client$query2.data;
532
593
  filename = movedFile.name;
533
- _context4.next = 23;
534
- return getFullpath(client, folderId, filename);
594
+ _context4.next = 40;
595
+ return getFullpath(client, destination._id, filename);
535
596
 
536
- case 23:
597
+ case 40:
537
598
  destinationPath = _context4.sent;
538
599
 
539
- case 24:
540
- _context4.next = 26;
600
+ case 41:
601
+ _context4.next = 43;
541
602
  return client.collection(_const.DOCTYPE_FILES).statByPath(destinationPath);
542
603
 
543
- case 26:
604
+ case 43:
544
605
  conflictResp = _context4.sent;
545
- _context4.next = 29;
606
+ _context4.next = 46;
546
607
  return client.collection(_const.DOCTYPE_FILES).destroy(conflictResp.data);
547
608
 
548
- case 29:
549
- _context4.next = 31;
550
- return client.collection(_const.DOCTYPE_FILES).updateFileMetadata(fileId, {
551
- dir_id: folderId
609
+ case 46:
610
+ _context4.next = 48;
611
+ return client.collection(_const.DOCTYPE_FILES).updateFileMetadata(file._id, {
612
+ dir_id: destination._id
552
613
  });
553
614
 
554
- case 31:
615
+ case 48:
555
616
  _resp = _context4.sent;
556
617
  return _context4.abrupt("return", {
557
618
  moved: _resp.data,
558
619
  deleted: conflictResp.data.id
559
620
  });
560
621
 
561
- case 35:
562
- throw _context4.t0;
622
+ case 52:
623
+ throw _context4.t1;
563
624
 
564
- case 36:
625
+ case 53:
565
626
  case "end":
566
627
  return _context4.stop();
567
628
  }
568
629
  }
569
- }, _callee4, null, [[2, 9]]);
630
+ }, _callee4, null, [[1, 16], [19, 26]]);
570
631
  }));
571
632
 
572
633
  return function move(_x9, _x10, _x11) {
@@ -588,7 +649,7 @@ var move = /*#__PURE__*/function () {
588
649
  exports.move = move;
589
650
 
590
651
  var overrideFileForPath = /*#__PURE__*/function () {
591
- var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(client, dirPath, file, metadata) {
652
+ var _ref7 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(client, dirPath, file, metadata) {
592
653
  var path, filesCollection, existingFile, _existingFile$data, fileId, dirId, resp, _dirId, createdFile;
593
654
 
594
655
  return _regenerator.default.wrap(function _callee5$(_context5) {
@@ -652,7 +713,7 @@ var overrideFileForPath = /*#__PURE__*/function () {
652
713
  }));
653
714
 
654
715
  return function overrideFileForPath(_x12, _x13, _x14, _x15) {
655
- return _ref6.apply(this, arguments);
716
+ return _ref7.apply(this, arguments);
656
717
  };
657
718
  }();
658
719
  /**
@@ -730,7 +791,7 @@ var generateFileNameForRevision = function generateFileNameForRevision(file, rev
730
791
  exports.generateFileNameForRevision = generateFileNameForRevision;
731
792
 
732
793
  var uploadFileWithConflictStrategy = /*#__PURE__*/function () {
733
- var _ref7 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(client, file, options) {
794
+ var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee6(client, file, options) {
734
795
  var name, dirId, conflictStrategy, conflictOptions, path, existingFile, fileId, resp, _splitFilename2, filename, extension, newFileName;
735
796
 
736
797
  return _regenerator.default.wrap(function _callee6$(_context6) {
@@ -804,7 +865,7 @@ var uploadFileWithConflictStrategy = /*#__PURE__*/function () {
804
865
  }));
805
866
 
806
867
  return function uploadFileWithConflictStrategy(_x16, _x17, _x18) {
807
- return _ref7.apply(this, arguments);
868
+ return _ref8.apply(this, arguments);
808
869
  };
809
870
  }();
810
871
  /**
@@ -817,7 +878,7 @@ var uploadFileWithConflictStrategy = /*#__PURE__*/function () {
817
878
  exports.uploadFileWithConflictStrategy = uploadFileWithConflictStrategy;
818
879
 
819
880
  var readMobileFile = /*#__PURE__*/function () {
820
- var _ref8 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(fileURL) {
881
+ var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee10(fileURL) {
821
882
  var p;
822
883
  return _regenerator.default.wrap(function _callee10$(_context10) {
823
884
  while (1) {
@@ -828,13 +889,13 @@ var readMobileFile = /*#__PURE__*/function () {
828
889
  */
829
890
  p = new Promise(function (resolve, reject) {
830
891
  var onResolvedLocalFS = /*#__PURE__*/function () {
831
- var _ref9 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(fileEntry) {
892
+ var _ref10 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee9(fileEntry) {
832
893
  return _regenerator.default.wrap(function _callee9$(_context9) {
833
894
  while (1) {
834
895
  switch (_context9.prev = _context9.next) {
835
896
  case 0:
836
897
  fileEntry.file( /*#__PURE__*/function () {
837
- var _ref10 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(file) {
898
+ var _ref11 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee8(file) {
838
899
  var reader;
839
900
  return _regenerator.default.wrap(function _callee8$(_context8) {
840
901
  while (1) {
@@ -867,7 +928,7 @@ var readMobileFile = /*#__PURE__*/function () {
867
928
  }));
868
929
 
869
930
  return function (_x21) {
870
- return _ref10.apply(this, arguments);
931
+ return _ref11.apply(this, arguments);
871
932
  };
872
933
  }(), function (err) {
873
934
  // Since this module is pretty recent, let's have this info in sentry if needed
@@ -885,7 +946,7 @@ var readMobileFile = /*#__PURE__*/function () {
885
946
  }));
886
947
 
887
948
  return function onResolvedLocalFS(_x20) {
888
- return _ref9.apply(this, arguments);
949
+ return _ref10.apply(this, arguments);
889
950
  };
890
951
  }();
891
952
 
@@ -916,7 +977,7 @@ var readMobileFile = /*#__PURE__*/function () {
916
977
  }));
917
978
 
918
979
  return function readMobileFile(_x19) {
919
- return _ref8.apply(this, arguments);
980
+ return _ref9.apply(this, arguments);
920
981
  };
921
982
  }();
922
983
  /**
@@ -931,7 +992,7 @@ var readMobileFile = /*#__PURE__*/function () {
931
992
  exports.readMobileFile = readMobileFile;
932
993
 
933
994
  var doMobileUpload = /*#__PURE__*/function () {
934
- var _ref12 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(client, fileURL, options) {
995
+ var _ref13 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee11(client, fileURL, options) {
935
996
  var file;
936
997
  return _regenerator.default.wrap(function _callee11$(_context11) {
937
998
  while (1) {
@@ -953,7 +1014,7 @@ var doMobileUpload = /*#__PURE__*/function () {
953
1014
  }));
954
1015
 
955
1016
  return function doMobileUpload(_x22, _x23, _x24) {
956
- return _ref12.apply(this, arguments);
1017
+ return _ref13.apply(this, arguments);
957
1018
  };
958
1019
  }();
959
1020
  /**
@@ -1013,7 +1074,7 @@ var isFromKonnector = function isFromKonnector(file) {
1013
1074
  exports.isFromKonnector = isFromKonnector;
1014
1075
 
1015
1076
  var fetchBlobFileById = /*#__PURE__*/function () {
1016
- var _ref13 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(client, fileId) {
1077
+ var _ref14 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee12(client, fileId) {
1017
1078
  var fileColl, fileBin, fileBlob;
1018
1079
  return _regenerator.default.wrap(function _callee12$(_context12) {
1019
1080
  while (1) {
@@ -1041,7 +1102,7 @@ var fetchBlobFileById = /*#__PURE__*/function () {
1041
1102
  }));
1042
1103
 
1043
1104
  return function fetchBlobFileById(_x25, _x26) {
1044
- return _ref13.apply(this, arguments);
1105
+ return _ref14.apply(this, arguments);
1045
1106
  };
1046
1107
  }();
1047
1108
 
@@ -16,6 +16,9 @@ const updateFileMetadataSpy = jest.fn().mockName('updateFileMetadata')
16
16
  const createFileSpy = jest.fn().mockName('createFileSpy')
17
17
  const updateFileSpy = jest.fn().mockName('updateFileSpy')
18
18
  const fetchFileContentByIdSpy = jest.fn().mockName('fetchFileContentById')
19
+ const moveSpy = jest.fn().mockName('move')
20
+ const moveToCozySpy = jest.fn().mockName('moveToCozy')
21
+ const moveFromCozySpy = jest.fn().mockName('moveFromCozy')
19
22
 
20
23
  beforeAll(() => {
21
24
  cozyClient.stackClient.collection.mockReturnValue({
@@ -25,7 +28,10 @@ beforeAll(() => {
25
28
  updateFileMetadata: updateFileMetadataSpy,
26
29
  createFile: createFileSpy,
27
30
  updateFile: updateFileSpy,
28
- fetchFileContentById: fetchFileContentByIdSpy
31
+ fetchFileContentById: fetchFileContentByIdSpy,
32
+ move: moveSpy,
33
+ moveToCozy: moveToCozySpy,
34
+ moveFromCozy: moveFromCozySpy
29
35
  })
30
36
  })
31
37
 
@@ -439,23 +445,46 @@ describe('File Model', () => {
439
445
  })
440
446
 
441
447
  describe('move', () => {
442
- const fileId = 'file-2295478c'
443
- const folderId = 'dir-b1e1c256'
448
+ const cozyFile = {
449
+ _id: 'file-2295478c',
450
+ _type: 'io.cozy.files',
451
+ name: 'mydoc.odt',
452
+ dir_id: 'io.cozy.files.root-dir'
453
+ }
454
+ const cozyFolder = {
455
+ _id: 'dir-b1e1c256',
456
+ _type: 'io.cozy.files',
457
+ dir_id: 'io.cozy.files.root-dir',
458
+ path: '/'
459
+ }
460
+ const nextcloudFolder = {
461
+ _id: 'folder-12435',
462
+ _type: 'io.cozy.remote.nextcloud.files',
463
+ path: '/Photos',
464
+ name: 'Photos'
465
+ }
466
+
467
+ const nextcloudFile = {
468
+ _id: 'file-12345',
469
+ _type: 'io.cozy.remote.nextcloud.files',
470
+ path: '/Photos/Penguins.jpg',
471
+ name: 'Penguins.jpg'
472
+ }
444
473
 
445
474
  afterEach(() => {
446
475
  jest.restoreAllMocks()
447
476
  jest.clearAllMocks()
448
477
  })
449
478
 
450
- it('should move a file to another destination', async () => {
479
+ it('should move a io.cozy.file to another io.cozy.file', async () => {
451
480
  updateFileMetadataSpy.mockResolvedValue({
452
481
  data: {
453
- id: fileId,
454
- dir_id: folderId,
482
+ id: cozyFile._id,
483
+ dir_id: cozyFolder._id,
455
484
  _type: 'io.cozy.files'
456
485
  }
457
486
  })
458
- const result = await fileModel.move(cozyClient, fileId, { folderId })
487
+ const result = await fileModel.move(cozyClient, cozyFile, cozyFolder)
459
488
  expect(updateFileMetadataSpy).toHaveBeenCalled()
460
489
  expect(result).toEqual({
461
490
  deleted: null,
@@ -472,7 +501,7 @@ describe('File Model', () => {
472
501
  status: 409
473
502
  })
474
503
  try {
475
- await fileModel.move(cozyClient, fileId, { folderId })
504
+ await fileModel.move(cozyClient, cozyFile, cozyFolder)
476
505
  } catch (e) {
477
506
  expect(e).toEqual({ status: 409 })
478
507
  }
@@ -486,14 +515,14 @@ describe('File Model', () => {
486
515
  })
487
516
  updateFileMetadataSpy.mockResolvedValue({
488
517
  data: {
489
- id: fileId,
490
- dir_id: folderId,
518
+ id: cozyFile._id,
519
+ dir_id: cozyFolder._id,
491
520
  _type: 'io.cozy.files'
492
521
  }
493
522
  })
494
523
  getSpy.mockResolvedValue({
495
524
  data: {
496
- id: fileId,
525
+ id: cozyFile._id,
497
526
  name: 'mydoc.odt',
498
527
  _type: 'io.cozy.files'
499
528
  }
@@ -504,12 +533,9 @@ describe('File Model', () => {
504
533
  _type: 'io.cozy.files'
505
534
  }
506
535
  })
507
- const result = await fileModel.move(
508
- cozyClient,
509
- fileId,
510
- { folderId },
511
- true
512
- )
536
+ const result = await fileModel.move(cozyClient, cozyFile, cozyFolder, {
537
+ force: true
538
+ })
513
539
  expect(updateFileMetadataSpy).toHaveBeenCalled()
514
540
  expect(destroySpy).toHaveBeenCalled()
515
541
  expect(result).toEqual({
@@ -522,41 +548,34 @@ describe('File Model', () => {
522
548
  })
523
549
  })
524
550
 
525
- it('should use destination.path if it is given', async () => {
526
- const DELETED_FILE_ID = 'deleted-c097ffca'
527
-
528
- updateFileMetadataSpy.mockRejectedValueOnce({
529
- status: 409
530
- })
531
- updateFileMetadataSpy.mockResolvedValue({
532
- data: {
533
- id: fileId,
534
- dir_id: folderId,
535
- _type: 'io.cozy.files'
536
- }
537
- })
538
- statByPathSpy.mockResolvedValue({
539
- data: {
540
- id: DELETED_FILE_ID,
541
- _type: 'io.cozy.files'
542
- }
543
- })
551
+ it('should move a Nextcloud file inside a Nextcloud folder', async () => {
544
552
  const result = await fileModel.move(
545
553
  cozyClient,
546
- fileId,
547
- { folderId, path: '/mydir/mydoc.odt' },
548
- true
554
+ nextcloudFile,
555
+ nextcloudFolder
549
556
  )
550
- expect(getSpy).not.toHaveBeenCalled()
551
- expect(updateFileMetadataSpy).toHaveBeenCalled()
552
- expect(destroySpy).toHaveBeenCalled()
557
+ expect(moveSpy).toBeCalledWith(nextcloudFile, nextcloudFolder)
553
558
  expect(result).toEqual({
554
- deleted: DELETED_FILE_ID,
555
- moved: {
556
- id: 'file-2295478c',
557
- dir_id: 'dir-b1e1c256',
558
- _type: 'io.cozy.files'
559
- }
559
+ deleted: null,
560
+ moved: undefined
561
+ })
562
+ })
563
+
564
+ it('should move a Nexcloud file into a Cozy folder', async () => {
565
+ const result = await fileModel.move(cozyClient, nextcloudFile, cozyFolder)
566
+ expect(moveToCozySpy).toBeCalledWith(nextcloudFile, cozyFolder)
567
+ expect(result).toEqual({
568
+ deleted: null,
569
+ moved: undefined
570
+ })
571
+ })
572
+
573
+ it('should move a Cozy file to a Nextcloud folder', async () => {
574
+ const result = await fileModel.move(cozyClient, cozyFile, nextcloudFolder)
575
+ expect(moveFromCozySpy).toBeCalledWith(nextcloudFolder, cozyFile)
576
+ expect(result).toEqual({
577
+ deleted: null,
578
+ moved: undefined
560
579
  })
561
580
  })
562
581
  })
@@ -19,6 +19,12 @@ Object.defineProperty(exports, "loadQuery", {
19
19
  return _queries.loadQuery;
20
20
  }
21
21
  });
22
+ Object.defineProperty(exports, "resetQuery", {
23
+ enumerable: true,
24
+ get: function get() {
25
+ return _queries.resetQuery;
26
+ }
27
+ });
22
28
  Object.defineProperty(exports, "receiveQueryResult", {
23
29
  enumerable: true,
24
30
  get: function get() {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.QueryIDGenerator = exports.getQueryFromSlice = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports.default = exports.updateData = exports.makeSorterFromDefinition = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.sortAndLimitDocsIds = exports.isReceivingData = exports.isQueryAction = void 0;
8
+ exports.QueryIDGenerator = exports.getQueryFromSlice = exports.resetQuery = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports.default = exports.updateData = exports.makeSorterFromDefinition = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.sortAndLimitDocsIds = exports.isReceivingData = exports.isQueryAction = void 0;
9
9
 
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
 
@@ -58,7 +58,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
58
58
  var INIT_QUERY = 'INIT_QUERY';
59
59
  var LOAD_QUERY = 'LOAD_QUERY';
60
60
  var RECEIVE_QUERY_RESULT = 'RECEIVE_QUERY_RESULT';
61
- var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR'; // Read if the devtools are open to store the execution time
61
+ var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR';
62
+ var RESET_QUERY = 'RESET_QUERY'; // Read if the devtools are open to store the execution time
62
63
  // This is done at runtime to not read the value everytime
63
64
  // we receive a result. So you have to refresh your page
64
65
  // in order to get the stats
@@ -66,7 +67,7 @@ var RECEIVE_QUERY_ERROR = 'RECEIVE_QUERY_ERROR'; // Read if the devtools are ope
66
67
  var executionStatsEnabled = (0, _cozyFlags.default)('debug');
67
68
 
68
69
  var isQueryAction = function isQueryAction(action) {
69
- return [INIT_QUERY, LOAD_QUERY, RECEIVE_QUERY_RESULT, RECEIVE_QUERY_ERROR].indexOf(action.type) !== -1;
70
+ return [INIT_QUERY, LOAD_QUERY, RECEIVE_QUERY_RESULT, RECEIVE_QUERY_ERROR, RESET_QUERY].indexOf(action.type) !== -1;
70
71
  };
71
72
 
72
73
  exports.isQueryAction = isQueryAction;
@@ -273,6 +274,13 @@ var query = function query() {
273
274
  lastErrorUpdate: Date.now()
274
275
  });
275
276
 
277
+ case RESET_QUERY:
278
+ return _objectSpread(_objectSpread({}, queryInitialState), {}, {
279
+ id: action.queryId,
280
+ definition: state.definition,
281
+ options: state.options
282
+ });
283
+
276
284
  default:
277
285
  return state;
278
286
  }
@@ -658,11 +666,27 @@ var receiveQueryError = function receiveQueryError(queryId, error) {
658
666
  queryId: queryId,
659
667
  error: error
660
668
  }, options);
661
- }; // selectors
669
+ };
670
+ /**
671
+ * Reset the query state to its initial state
672
+ *
673
+ * @param {string} queryId - id of the query
674
+ * @returns {object} - Redux action to dispatch
675
+ */
662
676
 
663
677
 
664
678
  exports.receiveQueryError = receiveQueryError;
665
679
 
680
+ var resetQuery = function resetQuery(queryId) {
681
+ return {
682
+ type: RESET_QUERY,
683
+ queryId: queryId
684
+ };
685
+ }; // selectors
686
+
687
+
688
+ exports.resetQuery = resetQuery;
689
+
666
690
  var mapIdsToDocuments = function mapIdsToDocuments(documents, doctype, ids) {
667
691
  return ids.map(function (id) {
668
692
  return (0, _documents.getDocumentFromSlice)(documents, doctype, id);
package/dist/types.js CHANGED
@@ -20,6 +20,7 @@ var _dsl = require("./queries/dsl");
20
20
  * @typedef {"io.cozy.account"} AccountsDoctype
21
21
  * @typedef {"io.cozy.konnectors"} KonnectorsDoctype
22
22
  * @typedef {"io.cozy.triggers"} TriggersDoctype
23
+ * @typedef {"io.cozy.remote.nextcloud.files"} NextcloudFilesDoctype
23
24
  * @typedef {AccountsDoctype|TriggersDoctype|KonnectorsDoctype|NotesDoctype|AppsDoctype|SettingsDoctype|OAuthClientsDoctype|FilesDoctype} KnownDoctype
24
25
  * @typedef {KnownDoctype|string} Doctype
25
26
  */
@@ -453,6 +454,19 @@ var _dsl = require("./queries/dsl");
453
454
  * @typedef {CozyClientDocument & FolderDocument} IOCozyFolder - An io.cozy.files document
454
455
  */
455
456
 
457
+ /**
458
+ * @typedef {object} NextcloudFile - An io.cozy.remote.nextcloud document after normalization
459
+ * @property {string} [_id] - Id of the file
460
+ * @property {string} [id] - Id of the file
461
+ * @property {NextcloudFilesDoctype} _type - Doctype of the folder
462
+ * @property {string} name - Name of the file
463
+ * @property {string} path - Path to the file
464
+ * @property {string} parentPath - Path to the folder containing the file
465
+ * @property {'file'|'directory'} type - Type of the file
466
+ * @property {object} cozyMetadata - Mime of the file
467
+ * @property {string} cozyMetadata.sourceAccount - Id of the io.cozy.account associated to the Nextcloud
468
+ */
469
+
456
470
  /**
457
471
  * @typedef {object} OAuthClientDocument - An io.cozy.oauth.clients document
458
472
  * @property {string} _id - Id of the client
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-client",
3
- "version": "47.6.0",
3
+ "version": "48.1.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.node.js",
6
6
  "browser": "dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "@types/jest": "^26.0.20",
19
19
  "@types/lodash": "^4.14.170",
20
20
  "btoa": "^1.2.1",
21
- "cozy-stack-client": "^47.4.0",
21
+ "cozy-stack-client": "^48.0.0",
22
22
  "date-fns": "2.29.3",
23
23
  "json-stable-stringify": "^1.0.1",
24
24
  "lodash": "^4.17.13",
@@ -75,5 +75,5 @@
75
75
  "react-native-ios11-devicecheck": "https://github.com/cozy/react-native-devicecheck#app-attest-v0.1"
76
76
  },
77
77
  "sideEffects": false,
78
- "gitHead": "ea8b7909ac8241fcc443fc16536985b702966e40"
78
+ "gitHead": "86a86b58b0506bd50b97b9a44a5d6314cea8cdee"
79
79
  }
@@ -742,6 +742,15 @@ declare class CozyClient {
742
742
  * @returns {Promise<any>} - The result of the `client.save()` call
743
743
  */
744
744
  saveAfterFetchSettings<T_2 extends string>(slug: string, itemsOrSetter: Record<string, any> | ((oldValue: any) => Record<T_2, any>), setterKeys?: T_2[]): Promise<any>;
745
+ /**
746
+ * Reset a query
747
+ *
748
+ * This method will reset the query state to its initial state and refetch it.
749
+ *
750
+ * @param {string} queryId - Query id
751
+ * @returns {Promise<import("./types").QueryState>} - Query state
752
+ */
753
+ resetQuery(queryId: string): Promise<import("./types").QueryState>;
745
754
  }
746
755
  declare namespace CozyClient {
747
756
  export const hooks: {};
@@ -50,10 +50,12 @@ export function hasMetadataAttribute({ file, attribute }: {
50
50
  attribute: string;
51
51
  }): boolean;
52
52
  export function getFullpath(client: CozyClient, dirId: string, name: string): Promise<string>;
53
- export function move(client: CozyClient, fileId: string, destination: {
54
- folderId: string;
55
- path: string;
56
- }, force?: boolean): Promise<any>;
53
+ export function move(client: CozyClient, file: import('../types').IOCozyFile | import('../types').NextcloudFile, destination: import('../types').IOCozyFolder | import('../types').NextcloudFile, { force }?: {
54
+ force: boolean;
55
+ }): Promise<{
56
+ moved: undefined | import('../types').IOCozyFile;
57
+ deleted: null | string[];
58
+ }>;
57
59
  export function overrideFileForPath(client: CozyClient, dirPath: string, file: object, metadata: object): Promise<import("../types").IOCozyFile>;
58
60
  export function generateNewFileNameOnConflict(filenameWithoutExtension: string, conflictOptions?: import('../types').ConflictOptions): string;
59
61
  export function generateFileNameForRevision(file: import("../types").IOCozyFile, revision: object, f: Function): string;
@@ -24,5 +24,5 @@ declare function combinedReducer(state: {
24
24
  export function resetState(): {
25
25
  type: string;
26
26
  };
27
- export { initQuery, loadQuery, receiveQueryResult, receiveQueryError } from "./queries";
27
+ export { initQuery, loadQuery, resetQuery, receiveQueryResult, receiveQueryError } from "./queries";
28
28
  export { initMutation, receiveMutationResult, receiveMutationError } from "./mutations";
@@ -13,6 +13,7 @@ export function initQuery(queryId: string, queryDefinition: QueryDefinition, opt
13
13
  export function loadQuery(queryId: string, options?: import("../types").QueryOptions): object;
14
14
  export function receiveQueryResult(queryId: string, response: object, options?: import("../types").QueryOptions): object;
15
15
  export function receiveQueryError(queryId: string, error: object, options?: import("../types").QueryOptions): object;
16
+ export function resetQuery(queryId: string): object;
16
17
  export function getQueryFromSlice(state: any, queryId: any, documents: any): any;
17
18
  export class QueryIDGenerator {
18
19
  idCounter: number;
package/types/types.d.ts CHANGED
@@ -9,6 +9,7 @@ export type FilesDoctype = "io.cozy.files";
9
9
  export type AccountsDoctype = "io.cozy.account";
10
10
  export type KonnectorsDoctype = "io.cozy.konnectors";
11
11
  export type TriggersDoctype = "io.cozy.triggers";
12
+ export type NextcloudFilesDoctype = "io.cozy.remote.nextcloud.files";
12
13
  export type KnownDoctype = "io.cozy.files" | "io.cozy.account" | "io.cozy.triggers" | "io.cozy.konnectors" | "io.cozy.notes" | "io.cozy.apps" | "io.cozy.settings" | "io.cozy-oauth.clients";
13
14
  export type Doctype = string;
14
15
  export type AccountsDocument = {
@@ -805,6 +806,45 @@ export type FolderDocument = {
805
806
  * - An io.cozy.files document
806
807
  */
807
808
  export type IOCozyFolder = CozyClientDocument & FolderDocument;
809
+ /**
810
+ * - An io.cozy.remote.nextcloud document after normalization
811
+ */
812
+ export type NextcloudFile = {
813
+ /**
814
+ * - Id of the file
815
+ */
816
+ _id?: string;
817
+ /**
818
+ * - Id of the file
819
+ */
820
+ id?: string;
821
+ /**
822
+ * - Doctype of the folder
823
+ */
824
+ _type: NextcloudFilesDoctype;
825
+ /**
826
+ * - Name of the file
827
+ */
828
+ name: string;
829
+ /**
830
+ * - Path to the file
831
+ */
832
+ path: string;
833
+ /**
834
+ * - Path to the folder containing the file
835
+ */
836
+ parentPath: string;
837
+ /**
838
+ * - Type of the file
839
+ */
840
+ type: 'file' | 'directory';
841
+ /**
842
+ * - Mime of the file
843
+ */
844
+ cozyMetadata: {
845
+ sourceAccount: string;
846
+ };
847
+ };
808
848
  /**
809
849
  * - An io.cozy.oauth.clients document
810
850
  */