cozy-client 41.0.0 → 41.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.
@@ -2695,7 +2695,7 @@ var CozyClient = /*#__PURE__*/function () {
2695
2695
  CozyClient.hooks = CozyClient.hooks || {};
2696
2696
  CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
2697
2697
 
2698
- CozyClient.version = "41.0.0";
2698
+ CozyClient.version = "41.1.0";
2699
2699
 
2700
2700
  _microee.default.mixin(CozyClient);
2701
2701
 
@@ -47,6 +47,12 @@ Object.defineProperty(exports, "useQueryAll", {
47
47
  return _useQueryAll.default;
48
48
  }
49
49
  });
50
+ Object.defineProperty(exports, "useMutation", {
51
+ enumerable: true,
52
+ get: function get() {
53
+ return _useMutation.useMutation;
54
+ }
55
+ });
50
56
 
51
57
  var _useAppLinkWithStoreFallback = _interopRequireDefault(require("./useAppLinkWithStoreFallback"));
52
58
 
@@ -60,4 +66,6 @@ var _useQuery = _interopRequireDefault(require("./useQuery"));
60
66
 
61
67
  var _useAppsInMaintenance = _interopRequireDefault(require("./useAppsInMaintenance"));
62
68
 
63
- var _useQueryAll = _interopRequireDefault(require("./useQueryAll"));
69
+ var _useQueryAll = _interopRequireDefault(require("./useQueryAll"));
70
+
71
+ var _useMutation = require("./useMutation");
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.useMutation = void 0;
9
+
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
+
16
+ var _react = require("react");
17
+
18
+ var _propTypes = _interopRequireDefault(require("prop-types"));
19
+
20
+ var _useClient = _interopRequireDefault(require("./useClient"));
21
+
22
+ /**
23
+ * This hook manages the state during the saving of a document
24
+ *
25
+ * @returns {import("../types").UseMutationReturnValue}
26
+ */
27
+ var useMutation = function useMutation(_ref) {
28
+ var onSuccess = _ref.onSuccess,
29
+ onError = _ref.onError;
30
+ var client = (0, _useClient.default)();
31
+ /** @type {import("../types").useState<import("../types").QueryFetchStatus>} */
32
+
33
+ var _useState = (0, _react.useState)('pending'),
34
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
35
+ mutationStatus = _useState2[0],
36
+ setMutationStatus = _useState2[1];
37
+
38
+ var _useState3 = (0, _react.useState)(),
39
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
40
+ error = _useState4[0],
41
+ setError = _useState4[1];
42
+
43
+ var _useState5 = (0, _react.useState)(),
44
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
45
+ data = _useState6[0],
46
+ setData = _useState6[1];
47
+
48
+ var mutate = (0, _react.useCallback)( /*#__PURE__*/function () {
49
+ var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(doc) {
50
+ var resp;
51
+ return _regenerator.default.wrap(function _callee$(_context) {
52
+ while (1) {
53
+ switch (_context.prev = _context.next) {
54
+ case 0:
55
+ setError(undefined);
56
+ setMutationStatus('loading');
57
+ _context.prev = 2;
58
+ _context.next = 5;
59
+ return client.save(doc);
60
+
61
+ case 5:
62
+ resp = _context.sent;
63
+ setData(resp.data);
64
+
65
+ if (!(typeof onSuccess === 'function')) {
66
+ _context.next = 10;
67
+ break;
68
+ }
69
+
70
+ _context.next = 10;
71
+ return onSuccess(resp.data);
72
+
73
+ case 10:
74
+ setMutationStatus('loaded');
75
+ _context.next = 20;
76
+ break;
77
+
78
+ case 13:
79
+ _context.prev = 13;
80
+ _context.t0 = _context["catch"](2);
81
+ setMutationStatus('failed');
82
+ setError(_context.t0);
83
+
84
+ if (!(typeof onError === 'function')) {
85
+ _context.next = 20;
86
+ break;
87
+ }
88
+
89
+ _context.next = 20;
90
+ return onError(_context.t0);
91
+
92
+ case 20:
93
+ case "end":
94
+ return _context.stop();
95
+ }
96
+ }
97
+ }, _callee, null, [[2, 13]]);
98
+ }));
99
+
100
+ return function (_x) {
101
+ return _ref2.apply(this, arguments);
102
+ };
103
+ }(), [client, onError, onSuccess]);
104
+ return {
105
+ mutate: mutate,
106
+ mutationStatus: mutationStatus,
107
+ error: error,
108
+ data: data
109
+ };
110
+ };
111
+
112
+ exports.useMutation = useMutation;
113
+ useMutation.propTypes = {
114
+ /** This function is triggered when the save is successful */
115
+ onSuccess: _propTypes.default.func,
116
+
117
+ /** This function is triggered when the save has failed */
118
+ onError: _propTypes.default.func
119
+ };
@@ -0,0 +1,81 @@
1
+ import { renderHook, act } from '@testing-library/react-hooks'
2
+
3
+ import { useMutation } from './useMutation'
4
+ import useClient from './useClient'
5
+
6
+ jest.mock('./useClient')
7
+
8
+ describe('useMutation', () => {
9
+ const setup = ({ onSuccess, onError, saveSpy = jest.fn() } = {}) => {
10
+ useClient.mockReturnValue({
11
+ save: saveSpy
12
+ })
13
+
14
+ return renderHook(() =>
15
+ useMutation({
16
+ onSuccess,
17
+ onError
18
+ })
19
+ )
20
+ }
21
+
22
+ it('should be in pending status', () => {
23
+ const {
24
+ result: { current }
25
+ } = setup()
26
+ expect(current.mutationStatus).toBe('pending')
27
+ })
28
+
29
+ it('should be in loading status after mutate', async () => {
30
+ const saveSpy = jest.fn().mockImplementation(() => new Promise(() => {}))
31
+
32
+ const { result } = setup({ saveSpy })
33
+
34
+ await act(async () => {
35
+ result.current.mutate({
36
+ doctype: 'io.cozy.simpsons'
37
+ })
38
+ })
39
+
40
+ expect(result.current.mutationStatus).toBe('loading')
41
+ })
42
+
43
+ it('should be in loaded status after mutate', async () => {
44
+ const successSpy = jest.fn()
45
+ const saveSpy = jest.fn().mockResolvedValue({ data: 'test' })
46
+ const { result } = setup({
47
+ onSuccess: successSpy,
48
+ saveSpy
49
+ })
50
+
51
+ await act(async () => {
52
+ result.current.mutate({
53
+ doctype: 'io.cozy.simpsons'
54
+ })
55
+ })
56
+
57
+ expect(result.current.mutationStatus).toBe('loaded')
58
+ expect(saveSpy).toBeCalledTimes(1)
59
+ expect(successSpy).toBeCalledTimes(1)
60
+ expect(result.current.data).toBe('test')
61
+ })
62
+
63
+ it('should be in failed status after mutate', async () => {
64
+ const errorSpy = jest.fn()
65
+ const saveSpy = jest.fn().mockRejectedValue({ error: 'test' })
66
+ const { result } = setup({
67
+ onError: errorSpy,
68
+ saveSpy
69
+ })
70
+
71
+ await act(async () => {
72
+ result.current.mutate({
73
+ doctype: 'io.cozy.simpsons'
74
+ })
75
+ })
76
+
77
+ expect(result.current.mutationStatus).toBe('failed')
78
+ expect(errorSpy).toBeCalledTimes(1)
79
+ expect(result.current.error).toStrictEqual({ error: 'test' })
80
+ })
81
+ })
package/dist/types.js CHANGED
@@ -208,6 +208,14 @@ var _dsl = require("./queries/dsl");
208
208
  * @typedef {QueryState & FetchMoreAble & FetchAble} UseQueryReturnValue
209
209
  */
210
210
 
211
+ /**
212
+ * @typedef {object} UseMutationReturnValue
213
+ * @property {Function} mutate - Function to save the document
214
+ * @property {QueryFetchStatus} mutationStatus - Status of the current mutation
215
+ * @property {object} [error] - Error if the mutation failed
216
+ * @property {object} [data] - Data return after the mutation
217
+ */
218
+
211
219
  /**
212
220
  * A reference to a document
213
221
  *
@@ -540,5 +548,12 @@ var _dsl = require("./queries/dsl");
540
548
  * @property {string} pathname - The redirect link's path (i.e. 'public')
541
549
  * @property {string} hash - The redirect link's path (i.e. '/folder/SOME_FOLDER_ID')
542
550
  */
551
+
552
+ /**
553
+ * Template to type useState
554
+ *
555
+ * @template T
556
+ * @typedef {[T, import('react').Dispatch<import('react').SetStateAction<T>>]} useState
557
+ */
543
558
  var _default = {};
544
559
  exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-client",
3
- "version": "41.0.0",
3
+ "version": "41.1.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.node.js",
6
6
  "browser": "dist/index.js",
@@ -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": "407e4545f27490d0b0e1450ebcd9a70c1ab17aff"
78
+ "gitHead": "1678577c9fab7d28e9579cd4fbeab825cfcd2b9c"
79
79
  }
@@ -5,3 +5,4 @@ export { default as useClient } from "./useClient";
5
5
  export { default as useQuery } from "./useQuery";
6
6
  export { default as useAppsInMaintenance } from "./useAppsInMaintenance";
7
7
  export { default as useQueryAll } from "./useQueryAll";
8
+ export { useMutation } from "./useMutation";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This hook manages the state during the saving of a document
3
+ *
4
+ * @returns {import("../types").UseMutationReturnValue}
5
+ */
6
+ export function useMutation({ onSuccess, onError }: {
7
+ onSuccess: any;
8
+ onError: any;
9
+ }): import("../types").UseMutationReturnValue;
10
+ export namespace useMutation {
11
+ namespace propTypes {
12
+ const onSuccess: PropTypes.Requireable<(...args: any[]) => any>;
13
+ const onError: PropTypes.Requireable<(...args: any[]) => any>;
14
+ }
15
+ }
16
+ import PropTypes from "prop-types";
package/types/types.d.ts CHANGED
@@ -365,6 +365,24 @@ export type FetchAble = {
365
365
  fetch: Function;
366
366
  };
367
367
  export type UseQueryReturnValue = QueryState & FetchMoreAble & FetchAble;
368
+ export type UseMutationReturnValue = {
369
+ /**
370
+ * - Function to save the document
371
+ */
372
+ mutate: Function;
373
+ /**
374
+ * - Status of the current mutation
375
+ */
376
+ mutationStatus: QueryFetchStatus;
377
+ /**
378
+ * - Error if the mutation failed
379
+ */
380
+ error?: object;
381
+ /**
382
+ * - Data return after the mutation
383
+ */
384
+ data?: object;
385
+ };
368
386
  /**
369
387
  * A reference to a document
370
388
  */
@@ -879,4 +897,8 @@ export type RedirectLinkData = {
879
897
  */
880
898
  hash: string;
881
899
  };
900
+ /**
901
+ * Template to type useState
902
+ */
903
+ export type useState<T> = [T, import("react").Dispatch<import("react").SetStateAction<T>>];
882
904
  import { QueryDefinition } from "./queries/dsl";