cozy-client 27.3.2 → 27.4.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [27.4.0](https://github.com/cozy/cozy-client/compare/v27.3.2...v27.4.0) (2021-11-25)
7
+
8
+
9
+ ### Features
10
+
11
+ * onError Callback ([c5f65d3](https://github.com/cozy/cozy-client/commit/c5f65d33e0ab29a22b409365151173a3b7645b56))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [27.3.2](https://github.com/cozy/cozy-client/compare/v27.3.1...v27.3.2) (2021-11-17)
7
18
 
8
19
 
@@ -128,7 +128,7 @@ var DOC_UPDATE = 'update';
128
128
  * @property {boolean} [autoHydrate]
129
129
  * @property {object} [oauth]
130
130
  * @property {Function} [onTokenRefresh]
131
- * @property {Function} [onTokenRefresh]
131
+ * @property {Function} [onError] - Default callback if a query is errored
132
132
  * @property {Link} [link] - Backward compatibility
133
133
  * @property {Array<Link>} [links] - List of links
134
134
  * @property {object} [schema] - Schema description for each doctypes
@@ -1276,10 +1276,32 @@ var CozyClient = /*#__PURE__*/function () {
1276
1276
  case 24:
1277
1277
  _context8.prev = 24;
1278
1278
  _context8.t0 = _context8["catch"](15);
1279
- this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0));
1279
+ this.dispatch((0, _store.receiveQueryError)(queryId, _context8.t0)); // specific onError
1280
+
1281
+ if (!options.onError) {
1282
+ _context8.next = 31;
1283
+ break;
1284
+ }
1285
+
1286
+ options.onError(_context8.t0); // defaulted onError
1287
+
1288
+ _context8.next = 36;
1289
+ break;
1290
+
1291
+ case 31:
1292
+ if (!this.options.onError) {
1293
+ _context8.next = 35;
1294
+ break;
1295
+ }
1296
+
1297
+ this.options.onError(_context8.t0);
1298
+ _context8.next = 36;
1299
+ break;
1300
+
1301
+ case 35:
1280
1302
  throw _context8.t0;
1281
1303
 
1282
- case 28:
1304
+ case 36:
1283
1305
  case "end":
1284
1306
  return _context8.stop();
1285
1307
  }
@@ -2256,6 +2278,21 @@ var CozyClient = /*#__PURE__*/function () {
2256
2278
  }));
2257
2279
  });
2258
2280
  }
2281
+ /**
2282
+ * At any time put an error function
2283
+ *
2284
+ * @param {Function} [onError] - Set a callback for queries which are errored
2285
+ */
2286
+
2287
+ }, {
2288
+ key: "setOnError",
2289
+ value: function setOnError(onError) {
2290
+ if (this.options && this.options.onError) {
2291
+ throw new Error('On Error is already defined');
2292
+ }
2293
+
2294
+ this.options.onError = onError;
2295
+ }
2259
2296
  }, {
2260
2297
  key: "toJSON",
2261
2298
  value: function toJSON() {
@@ -2415,7 +2452,7 @@ var CozyClient = /*#__PURE__*/function () {
2415
2452
  CozyClient.hooks = CozyClient.hooks || {};
2416
2453
  CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
2417
2454
 
2418
- CozyClient.version = "27.3.2";
2455
+ CozyClient.version = "27.4.0";
2419
2456
 
2420
2457
  _microee.default.mixin(CozyClient);
2421
2458
 
@@ -162,7 +162,6 @@ describe('CozyClient initialization', () => {
162
162
  })
163
163
  }
164
164
  const client = await CozyClient.fromOldOAuthClient(oldClient)
165
- console.log({ stackClient: client.stackClient })
166
165
  expect(client.stackClient.uri).toBe(url)
167
166
  expect(client.stackClient.oauthOptions.clientID).toBe(oauth.clientID)
168
167
  expect(client.stackClient.token.accessToken).toBe(token.accessToken)
@@ -1402,6 +1401,54 @@ describe('CozyClient', () => {
1402
1401
  receiveQueryResult('allTodos', fakeResponse)
1403
1402
  )
1404
1403
  })
1404
+
1405
+ const setupOnError = () => {
1406
+ const error = new TypeError('Failed to fetch')
1407
+ requestHandler.mockReturnValueOnce(Promise.reject(error))
1408
+ const onError = jest.fn().mockReturnValueOnce(() => true)
1409
+ return onError
1410
+ }
1411
+
1412
+ it('should call onError callback when an error is thrown. Callback passed as argument', async () => {
1413
+ const onError = setupOnError()
1414
+
1415
+ await client.query(query, { as: 'allTodos', onError })
1416
+ expect(onError).toBeCalled()
1417
+ })
1418
+
1419
+ it('should call onError callback when an error is catched. It is passed during instantiation', async () => {
1420
+ const onError = setupOnError()
1421
+ const client = new CozyClient({ onError })
1422
+
1423
+ await client.query(query, { as: 'allTodos' })
1424
+ expect(onError).toBeCalled()
1425
+ })
1426
+
1427
+ it('should call onError callback when an error is catched. It is passed with setOnError', async () => {
1428
+ const onError = setupOnError()
1429
+ client.setOnError(onError)
1430
+
1431
+ await client.query(query, { as: 'allTodos' })
1432
+ expect(onError).toBeCalled()
1433
+ })
1434
+
1435
+ it('should throw an error when we call setOnError twice (or several times)', async () => {
1436
+ const client = new CozyClient({})
1437
+ const onError = () => true
1438
+
1439
+ const funcShouldThrow = () => client.setOnError(onError)
1440
+ expect(funcShouldThrow).not.toThrow()
1441
+ expect(funcShouldThrow).toThrow('On Error is already defined')
1442
+ })
1443
+
1444
+ it('should throw an error when there is no onError callback', async () => {
1445
+ const error = new TypeError('Failed to fetch')
1446
+ requestHandler.mockReturnValueOnce(Promise.reject(error))
1447
+
1448
+ await expect(client.query(query, { as: 'allTodos' })).rejects.toThrow(
1449
+ 'Failed to fetch'
1450
+ )
1451
+ })
1405
1452
  })
1406
1453
 
1407
1454
  describe('queryAll', () => {
@@ -25,6 +25,8 @@ var _types = require("../types");
25
25
 
26
26
  var _context = require("../context");
27
27
 
28
+ var _dsl = require("../queries/dsl");
29
+
28
30
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
29
31
 
30
32
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
@@ -41,15 +43,16 @@ var generateFetchMoreQueryDefinition = function generateFetchMoreQueryDefinition
41
43
  /**
42
44
  * Fetches a queryDefinition and returns the queryState
43
45
  *
44
- * @param {object} queryDefinition - Definition created with Q()
46
+ * @param {QueryDefinition} queryDefinition - Definition created with Q()
45
47
  *
46
- * @param {object} options - Options
47
- * @param {object} options.as - Name for the query [required]
48
- * @param {boolean} options.enabled - If set to false, the query won't be executed
49
- * @param {object} options.fetchPolicy - Fetch policy
50
- * @param {object} options.singleDocData - If true, the "data" returned will be
48
+ * @typedef {object} UseQueryOptions
49
+ * @property {object} as - Name for the query [required]
50
+ * @property {boolean} enabled - If set to false, the query won't be executed
51
+ * @property {object} fetchPolicy - Fetch policy
52
+ * @property {object} singleDocData - If true, the "data" returned will be
51
53
  * a single doc instead of an array for single doc queries. Defaults to false for backward
52
54
  * compatibility but will be set to true in the future.
55
+ * @property {Function} onError - Callback if the query is errored
53
56
  *
54
57
  * @returns {UseQueryReturnValue}
55
58
  */
@@ -1,13 +1,20 @@
1
1
  import { renderHook } from '@testing-library/react-hooks'
2
2
 
3
+ import CozyClient from '../CozyClient'
4
+ import CozyLink from '../CozyLink'
3
5
  import useQuery, { useQueries } from './useQuery'
4
6
  import { Q } from '../queries/dsl'
5
7
 
6
8
  import { setupClient, makeWrapper } from '../testing/utils'
7
9
  import simpsonsFixture from '../testing/simpsons.json'
8
10
 
9
- const setupQuery = ({ queryDefinition, queryOptions, storeQueries }) => {
10
- const client = setupClient({ queries: storeQueries })
11
+ const setupQuery = ({
12
+ customClient,
13
+ queryDefinition,
14
+ queryOptions,
15
+ storeQueries
16
+ }) => {
17
+ const client = customClient || setupClient({ queries: storeQueries })
11
18
  const hookResult = renderHook(() => useQuery(queryDefinition, queryOptions), {
12
19
  wrapper: makeWrapper(client)
13
20
  })
@@ -159,6 +166,30 @@ describe('use query', () => {
159
166
  expect(lastCallArgs).toMatchObject({ skip: current.data.length })
160
167
  expect(fetchMoreResult).toEqual({ data: null })
161
168
  })
169
+
170
+ it('should call onError callback when an error is thrown. Callback passed as argument', async () => {
171
+ jest.spyOn(console, 'error').mockImplementation(() => null)
172
+ const requestHandler = jest.fn()
173
+ const client = new CozyClient({
174
+ links: [new CozyLink(requestHandler)]
175
+ })
176
+ const error = new TypeError('Failed to fetch')
177
+ requestHandler.mockReturnValue(Promise.reject(error))
178
+ const onError = jest.fn().mockReturnValue(() => true)
179
+ setupQuery({
180
+ customClient: client,
181
+ queryOptions: {
182
+ as: 'fake-query',
183
+ onError
184
+ },
185
+ queryDefinition: () => Q('io.cozy.todos')
186
+ })
187
+
188
+ // TODO find a better alternative
189
+ setTimeout(() => {
190
+ expect(onError).toBeCalled()
191
+ }, 100)
192
+ })
162
193
  })
163
194
 
164
195
  describe('use queries', () => {
package/dist/types.js CHANGED
@@ -85,7 +85,8 @@ var _dsl = require("./queries/dsl");
85
85
  * @property {string} [as] - Name of the query
86
86
  * @property {Function} [fetchPolicy] - Fetch policy to bypass fetching based on what's already inside the state. See "Fetch policies"
87
87
  * @property {AutoUpdateOptions} [autoUpdate] - Options for the query auto update
88
- * @property {string} [options.update] - Does not seem to be used
88
+ * @property {string} [update] - Does not seem to be used
89
+ * @property {Function} [onError] - Callback when the query is errored
89
90
  */
90
91
 
91
92
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-client",
3
- "version": "27.3.2",
3
+ "version": "27.4.0",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.node.js",
6
6
  "browser": "dist/index.js",
@@ -69,5 +69,5 @@
69
69
  "react-native-inappbrowser-reborn": "^3.5.1"
70
70
  },
71
71
  "sideEffects": false,
72
- "gitHead": "826f995c85378bdcd76f3a62428c1d9857f0136d"
72
+ "gitHead": "1ab42dff2e9088f4a3daff29866ad7a22b093791"
73
73
  }
@@ -10,6 +10,10 @@ export type ClientOptions = {
10
10
  autoHydrate?: boolean;
11
11
  oauth?: object;
12
12
  onTokenRefresh?: Function;
13
+ /**
14
+ * - Default callback if a query is errored
15
+ */
16
+ onError?: Function;
13
17
  /**
14
18
  * - Schema description for each doctypes
15
19
  */
@@ -39,7 +43,7 @@ export type ClientOptions = {
39
43
  * @property {boolean} [autoHydrate]
40
44
  * @property {object} [oauth]
41
45
  * @property {Function} [onTokenRefresh]
42
- * @property {Function} [onTokenRefresh]
46
+ * @property {Function} [onError] - Default callback if a query is errored
43
47
  * @property {Link} [link] - Backward compatibility
44
48
  * @property {Array<Link>} [links] - List of links
45
49
  * @property {object} [schema] - Schema description for each doctypes
@@ -146,6 +150,10 @@ declare class CozyClient {
146
150
  autoHydrate?: boolean;
147
151
  oauth?: object;
148
152
  onTokenRefresh?: Function;
153
+ /**
154
+ * - Default callback if a query is errored
155
+ */
156
+ onError?: Function;
149
157
  /**
150
158
  * - If set to false, the client will not instantiate a Redux store automatically. Use this if you want to merge cozy-client's store with your own redux store. See [here](https://docs.cozy.io/en/cozy-client/react-integration/#1b-use-your-own-redux-store) for more information.
151
159
  */
@@ -640,6 +648,12 @@ declare class CozyClient {
640
648
  * @param {object} data - Data that is inserted in the store. Shape: { doctype: [data] }
641
649
  */
642
650
  setData(data: object): void;
651
+ /**
652
+ * At any time put an error function
653
+ *
654
+ * @param {Function} [onError] - Set a callback for queries which are errored
655
+ */
656
+ setOnError(onError?: Function): void;
643
657
  toJSON(): SnapshotClient;
644
658
  }
645
659
  declare namespace CozyClient {
@@ -1,24 +1,48 @@
1
1
  export function useQueries(querySpecs: any): {};
2
2
  export default useQuery;
3
+ /**
4
+ * Fetches a queryDefinition and returns the queryState
5
+ */
6
+ export type UseQueryOptions = {
7
+ /**
8
+ * - Name for the query [required]
9
+ */
10
+ as: object;
11
+ /**
12
+ * - If set to false, the query won't be executed
13
+ */
14
+ enabled: boolean;
15
+ /**
16
+ * - Fetch policy
17
+ */
18
+ fetchPolicy: object;
19
+ /**
20
+ * - If true, the "data" returned will be
21
+ * a single doc instead of an array for single doc queries. Defaults to false for backward
22
+ * compatibility but will be set to true in the future.
23
+ */
24
+ singleDocData: object;
25
+ /**
26
+ * - Callback if the query is errored
27
+ */
28
+ onError: Function;
29
+ };
3
30
  /**
4
31
  * Fetches a queryDefinition and returns the queryState
5
32
  *
6
- * @param {object} queryDefinition - Definition created with Q()
33
+ * @param {QueryDefinition} queryDefinition - Definition created with Q()
7
34
  *
8
- * @param {object} options - Options
9
- * @param {object} options.as - Name for the query [required]
10
- * @param {boolean} options.enabled - If set to false, the query won't be executed
11
- * @param {object} options.fetchPolicy - Fetch policy
12
- * @param {object} options.singleDocData - If true, the "data" returned will be
35
+ * @typedef {object} UseQueryOptions
36
+ * @property {object} as - Name for the query [required]
37
+ * @property {boolean} enabled - If set to false, the query won't be executed
38
+ * @property {object} fetchPolicy - Fetch policy
39
+ * @property {object} singleDocData - If true, the "data" returned will be
13
40
  * a single doc instead of an array for single doc queries. Defaults to false for backward
14
41
  * compatibility but will be set to true in the future.
42
+ * @property {Function} onError - Callback if the query is errored
15
43
  *
16
44
  * @returns {UseQueryReturnValue}
17
45
  */
18
- declare function useQuery(queryDefinition: object, options: {
19
- as: object;
20
- enabled: boolean;
21
- fetchPolicy: object;
22
- singleDocData: object;
23
- }): UseQueryReturnValue;
46
+ declare function useQuery(queryDefinition: QueryDefinition, options: any): UseQueryReturnValue;
47
+ import { QueryDefinition } from "../queries/dsl";
24
48
  import { UseQueryReturnValue } from "../types";
package/types/types.d.ts CHANGED
@@ -64,6 +64,10 @@ export type QueryOptions = {
64
64
  * - Does not seem to be used
65
65
  */
66
66
  update?: string;
67
+ /**
68
+ * - Callback when the query is errored
69
+ */
70
+ onError?: Function;
67
71
  };
68
72
  export type FetchMoreAble = {
69
73
  fetchMore: Function;