cozy-client 59.4.0 → 60.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.
@@ -11,7 +11,8 @@ import {
11
11
  APP_VERSION,
12
12
  SOURCE_ACCOUNT_ID,
13
13
  SOURCE_ACCOUNT_IDENTIFIER,
14
- FILE_1
14
+ FILE_1,
15
+ TODO_WITH_NONEXISTING_RELATIONSHIP
15
16
  } from './__tests__/fixtures'
16
17
  import { withIgnoreConsoleWarn } from './__tests__/console'
17
18
 
@@ -34,7 +35,7 @@ import {
34
35
  resetQuery,
35
36
  executeQueryFromState
36
37
  } from './store'
37
- import { HasManyFiles, Association, HasMany } from './associations'
38
+ import { HasManyFiles, Association } from './associations'
38
39
  import mapValues from 'lodash/mapValues'
39
40
  import FileCollection from 'cozy-stack-client/dist/FileCollection'
40
41
  import logger from './logger'
@@ -1016,7 +1017,16 @@ describe('CozyClient', () => {
1016
1017
  const NEW_TODO = {
1017
1018
  _type: 'io.cozy.todos',
1018
1019
  label: 'Buy RAM',
1019
- attachments: [{ _id: 12345, _type: 'io.cozy.files' }]
1020
+ relationships: {
1021
+ attachments: {
1022
+ data: [
1023
+ {
1024
+ _type: 'io.cozy.files',
1025
+ _id: 1
1026
+ }
1027
+ ]
1028
+ }
1029
+ }
1020
1030
  }
1021
1031
  const EXPECTED_CREATED_TODO = { _id: 67890, ...NEW_TODO }
1022
1032
  const mutation = client.getDocumentSavePlan(NEW_TODO, {
@@ -1040,9 +1050,14 @@ describe('CozyClient', () => {
1040
1050
  id: 67890,
1041
1051
  type: 'io.cozy.files'
1042
1052
  }
1043
- ]
1053
+ ],
1054
+ relationships: { icons: [{ _id: 67890, _type: 'io.cozy.files' }] }
1055
+ }
1056
+ const EXPECTED_CREATED_FILE = {
1057
+ _id: 12345,
1058
+ _type: 'io.cozy.files',
1059
+ relationships: { icons: [{ _id: 67890, _type: 'io.cozy.files' }] }
1044
1060
  }
1045
- const EXPECTED_CREATED_FILE = { _id: 12345, _type: 'io.cozy.files' }
1046
1061
  const mutation = client.getDocumentSavePlan(NEW_FILE, {
1047
1062
  icons: [
1048
1063
  {
@@ -1907,14 +1922,6 @@ describe('CozyClient', () => {
1907
1922
  )
1908
1923
  .shift()
1909
1924
  expect(doc.attachments).toBeInstanceOf(HasManyFiles)
1910
- expect(doc.authors).toBeInstanceOf(HasMany)
1911
- })
1912
-
1913
- it('makes new documents', () => {
1914
- const newTodo = client.makeNewDocument('io.cozy.todos')
1915
- expect(newTodo._type).toBe('io.cozy.todos')
1916
- expect(newTodo.attachments).not.toBe(undefined)
1917
- expect(newTodo.attachments instanceof HasManyFiles).toBe(true)
1918
1925
  })
1919
1926
 
1920
1927
  it('should not fail on null (when getting absent documents from the store)', () => {
@@ -1923,6 +1930,53 @@ describe('CozyClient', () => {
1923
1930
  .shift()
1924
1931
  expect(doc).toBe(null)
1925
1932
  })
1933
+
1934
+ it('should hydrate relationships if the relationship exists', () => {
1935
+ const resp = client.hydrateDocument(TODO_WITH_AUTHOR)
1936
+ expect(resp.authors).not.toBe(undefined)
1937
+ expect(resp.attachments).toBe(undefined)
1938
+ })
1939
+
1940
+ it('should not hydrate relationships if the relationship does not exist', () => {
1941
+ const resp = client.hydrateDocument(TODO_WITH_NONEXISTING_RELATIONSHIP)
1942
+ expect(resp.authors).toBe(undefined)
1943
+ expect(resp.attachments).toBe(undefined)
1944
+ expect(resp.broken).toBe(undefined)
1945
+ })
1946
+
1947
+ it('should not hydrate relationships if not specified', () => {
1948
+ getQueryFromState.mockReturnValueOnce({
1949
+ definition: { doctype: 'io.cozy.todos' },
1950
+ data: [TODO_WITH_AUTHOR]
1951
+ })
1952
+ const resp = client.getQueryFromState('allTodos')
1953
+ expect(resp.data[0].authors).toBe(undefined)
1954
+ expect(resp.data[0].attachments).toBe(undefined)
1955
+ })
1956
+
1957
+ it('should hydrate relationships only if the relationship does exist ', () => {
1958
+ getQueryFromState.mockReturnValueOnce({
1959
+ definition: { doctype: 'io.cozy.todos' },
1960
+ data: [TODO_WITH_AUTHOR]
1961
+ })
1962
+ const resp = client.getQueryFromState('allTodos', { hydrated: true })
1963
+ expect(resp.data[0].authors).not.toBe(undefined)
1964
+ expect(resp.data[0].attachments).toBe(undefined)
1965
+ })
1966
+
1967
+ it('should hydrate relationships if the relationship does not exist but hydration is forced', () => {
1968
+ const newClient = new CozyClient({
1969
+ schema: SCHEMA,
1970
+ autoHydrate: true
1971
+ })
1972
+ getQueryFromState.mockReturnValueOnce({
1973
+ definition: { doctype: 'io.cozy.todos' },
1974
+ data: [TODO_WITH_AUTHOR]
1975
+ })
1976
+ const resp = newClient.getQueryFromState('allTodos')
1977
+ expect(resp.data[0].authors).not.toBe(undefined)
1978
+ expect(resp.data[0].attachments).not.toBe(undefined)
1979
+ })
1926
1980
  })
1927
1981
 
1928
1982
  describe('serialization', () => {
@@ -2122,7 +2176,8 @@ describe('file creation', () => {
2122
2176
  .fn()
2123
2177
  .mockResolvedValueOnce({
2124
2178
  data: {
2125
- _id: '1337'
2179
+ _id: '1337',
2180
+ relationships: { icons: [{ _id: 1, _type: 'io.cozy.files' }] }
2126
2181
  }
2127
2182
  })
2128
2183
  .mockResolvedValueOnce({
@@ -195,6 +195,8 @@ describe('Query', () => {
195
195
  count: 0,
196
196
  fetchedPagesCount: 0,
197
197
  data: [],
198
+ storeData: [],
199
+ relationshipNames: null,
198
200
  definition: { doctype: 'io.cozy.todos' },
199
201
  fetch: expect.any(Function),
200
202
  fetchMore: expect.any(Function),
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.SCHEMA = exports.SOURCE_ACCOUNT_IDENTIFIER = exports.SOURCE_ACCOUNT_ID = exports.DOCTYPE_VERSION = exports.APP_VERSION = exports.APP_NAME = exports.FILE_2 = exports.FILE_1 = exports.TODO_WITH_AUTHOR = exports.AUTHORS = exports.TODO_WITH_RELATION = exports.TODOS = exports.TODO_4 = exports.TODO_3 = exports.TODO_2 = exports.TODO_1 = void 0;
6
+ exports.SCHEMA = exports.SOURCE_ACCOUNT_IDENTIFIER = exports.SOURCE_ACCOUNT_ID = exports.DOCTYPE_VERSION = exports.APP_VERSION = exports.APP_NAME = exports.FILE_2 = exports.FILE_1 = exports.TODO_WITH_NONEXISTING_RELATIONSHIP = exports.TODO_WITH_AUTHOR = exports.AUTHORS = exports.TODO_WITH_RELATION = exports.TODOS = exports.TODO_4 = exports.TODO_3 = exports.TODO_2 = exports.TODO_1 = void 0;
7
7
  var TODO_1 = {
8
8
  _id: 'todo_1',
9
9
  _rev: '4-43bdf4f7123f4d748645ba9536a46daa',
@@ -88,6 +88,22 @@ var TODO_WITH_AUTHOR = {
88
88
  }
89
89
  };
90
90
  exports.TODO_WITH_AUTHOR = TODO_WITH_AUTHOR;
91
+ var TODO_WITH_NONEXISTING_RELATIONSHIP = {
92
+ _id: 5,
93
+ _rev: '1-7f02bbb542fb4eb0805b130a80b9be1a',
94
+ _type: 'io.cozy.todos',
95
+ label: 'Todo with several authors',
96
+ relationships: {
97
+ broken: {
98
+ doctype: 'io.cozy.persons',
99
+ data: [{
100
+ _type: 'io.cozy.persons',
101
+ _id: 1
102
+ }]
103
+ }
104
+ }
105
+ };
106
+ exports.TODO_WITH_NONEXISTING_RELATIONSHIP = TODO_WITH_NONEXISTING_RELATIONSHIP;
91
107
  var FILE_1 = {
92
108
  _id: 1,
93
109
  _rev: '3-bd9bb7286a094842b954d9e86429090d',
@@ -25,6 +25,8 @@ var _context = require("../context");
25
25
 
26
26
  var _dsl = require("../queries/dsl");
27
27
 
28
+ var _selector = require("../store/selector");
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; }
@@ -83,7 +85,7 @@ var useQuery = function useQuery(queryDefinition, options) {
83
85
  hydrated: (0, _get.default)(options, 'hydrated', true),
84
86
  singleDocData: (0, _get.default)(options, 'singleDocData', false)
85
87
  });
86
- });
88
+ }, _selector.equalityCheckForQuery);
87
89
  (0, _react.useEffect)(function () {
88
90
  if (enabled === false) {
89
91
  return;
@@ -107,7 +107,7 @@ describe('use query', () => {
107
107
  })
108
108
 
109
109
  expect(Object.keys(current)).toEqual(
110
- expect.objectContaining([
110
+ expect.arrayContaining([
111
111
  'id',
112
112
  'definition',
113
113
  'fetchStatus',
@@ -120,6 +120,8 @@ describe('use query', () => {
120
120
  'count',
121
121
  'fetchedPagesCount',
122
122
  'data',
123
+ 'storeData',
124
+ 'relationshipNames',
123
125
  'bookmark',
124
126
  'options',
125
127
  'fetchMore',
@@ -288,7 +288,12 @@ var StackLink = /*#__PURE__*/function (_CozyLink) {
288
288
  id = query.id,
289
289
  ids = query.ids,
290
290
  referenced = query.referenced,
291
- options = (0, _objectWithoutProperties2.default)(query, ["doctype", "selector", "id", "ids", "referenced"]);
291
+ sharingId = query.sharingId,
292
+ rawOptions = (0, _objectWithoutProperties2.default)(query, ["doctype", "selector", "id", "ids", "referenced", "sharingId"]);
293
+
294
+ var options = _objectSpread(_objectSpread({}, rawOptions), {}, {
295
+ driveId: undefined
296
+ });
292
297
 
293
298
  if (!doctype) {
294
299
  _logger.default.warn('Bad query', query);
@@ -296,7 +301,13 @@ var StackLink = /*#__PURE__*/function (_CozyLink) {
296
301
  throw new Error('No doctype found in a query definition');
297
302
  }
298
303
 
299
- var collection = this.stackClient.collection(doctype);
304
+ if (doctype === _const.DOCTYPE_FILES && sharingId) {
305
+ options = _objectSpread(_objectSpread({}, options), {}, {
306
+ driveId: sharingId
307
+ });
308
+ }
309
+
310
+ var collection = this.stackClient.collection(doctype, options);
300
311
 
301
312
  if (id) {
302
313
  return collection.get(id, query);
@@ -18,7 +18,10 @@ describe('StackLink', () => {
18
18
  stackClient.collection().all.mockReset()
19
19
  await link.request(query)
20
20
  expect(stackClient.collection().all).toHaveBeenCalled()
21
- expect(stackClient.collection).toHaveBeenCalledWith('io.cozy.todos')
21
+ expect(stackClient.collection).toHaveBeenCalledWith(
22
+ 'io.cozy.todos',
23
+ expect.anything()
24
+ )
22
25
  })
23
26
 
24
27
  it('should execute queries with a selector', async () => {
@@ -36,7 +39,10 @@ describe('StackLink', () => {
36
39
  stackClient.collection().find.mockReset()
37
40
  await link.request(query)
38
41
  expect(stackClient.collection().find).toHaveBeenCalled()
39
- expect(stackClient.collection).toHaveBeenCalledWith('io.cozy.todos')
42
+ expect(stackClient.collection).toHaveBeenCalledWith(
43
+ 'io.cozy.todos',
44
+ expect.anything()
45
+ )
40
46
  })
41
47
 
42
48
  it('should use all if a no sort option is given', async () => {
@@ -44,7 +50,10 @@ describe('StackLink', () => {
44
50
  stackClient.collection().all.mockReset()
45
51
  await link.request(query)
46
52
  expect(stackClient.collection().all).toHaveBeenCalled()
47
- expect(stackClient.collection).toHaveBeenCalledWith('io.cozy.todos')
53
+ expect(stackClient.collection).toHaveBeenCalledWith(
54
+ 'io.cozy.todos',
55
+ expect.anything()
56
+ )
48
57
  })
49
58
 
50
59
  it('should use find if a partialFilter is given', async () => {
@@ -52,7 +61,10 @@ describe('StackLink', () => {
52
61
  stackClient.collection().find.mockReset()
53
62
  await link.request(query)
54
63
  expect(stackClient.collection().find).toHaveBeenCalled()
55
- expect(stackClient.collection).toHaveBeenCalledWith('io.cozy.todos')
64
+ expect(stackClient.collection).toHaveBeenCalledWith(
65
+ 'io.cozy.todos',
66
+ expect.anything()
67
+ )
56
68
  })
57
69
 
58
70
  it('should use find if fields are given', async () => {
@@ -60,7 +72,10 @@ describe('StackLink', () => {
60
72
  stackClient.collection().find.mockReset()
61
73
  await link.request(query)
62
74
  expect(stackClient.collection().find).toHaveBeenCalled()
63
- expect(stackClient.collection).toHaveBeenCalledWith('io.cozy.todos')
75
+ expect(stackClient.collection).toHaveBeenCalledWith(
76
+ 'io.cozy.todos',
77
+ expect.anything()
78
+ )
64
79
  })
65
80
  })
66
81
 
@@ -430,7 +430,8 @@ describe('File Model', () => {
430
430
  'mydoc.odt'
431
431
  )
432
432
  expect(cozyClient.stackClient.collection).toHaveBeenCalledWith(
433
- 'io.cozy.files'
433
+ 'io.cozy.files',
434
+ expect.anything()
434
435
  )
435
436
  expect(getSpy).toHaveBeenCalledWith(
436
437
  'parent',
@@ -447,7 +448,8 @@ describe('File Model', () => {
447
448
  'mydoc.odt'
448
449
  )
449
450
  expect(cozyClient.stackClient.collection).toHaveBeenCalledWith(
450
- 'io.cozy.files'
451
+ 'io.cozy.files',
452
+ expect.anything()
451
453
  )
452
454
  expect(getSpy).toHaveBeenCalledWith(
453
455
  'parent',
@@ -64,6 +64,7 @@ var QueryDefinition = /*#__PURE__*/function () {
64
64
  * @param {number|null} [options.skip] - The number of docs to skip.
65
65
  * @param {import('../types').CouchDBViewCursor} [options.cursor] - The cursor to paginate views.
66
66
  * @param {string} [options.bookmark] - The bookmark to paginate mango queries.
67
+ * @param {string} [options.sharingId] - The id of the sharing
67
68
  */
68
69
  function QueryDefinition() {
69
70
  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -82,6 +83,7 @@ var QueryDefinition = /*#__PURE__*/function () {
82
83
  this.skip = options.skip;
83
84
  this.cursor = options.cursor;
84
85
  this.bookmark = options.bookmark;
86
+ this.sharingId = options.sharingId;
85
87
  }
86
88
  /**
87
89
  * Checks if the sort order matches the index' fields order.
@@ -444,6 +446,20 @@ var QueryDefinition = /*#__PURE__*/function () {
444
446
  referenced: document
445
447
  }));
446
448
  }
449
+ /**
450
+ * Use a sharingId to query documents coming from a sharing
451
+ *
452
+ * @param {string} id - The sharing doc id
453
+ * @returns {QueryDefinition} The QueryDefinition object.
454
+ */
455
+
456
+ }, {
457
+ key: "sharingById",
458
+ value: function sharingById(id) {
459
+ return new QueryDefinition(_objectSpread(_objectSpread({}, this.toDefinition()), {}, {
460
+ sharingId: id
461
+ }));
462
+ }
447
463
  }, {
448
464
  key: "toDefinition",
449
465
  value: function toDefinition() {
@@ -461,7 +477,8 @@ var QueryDefinition = /*#__PURE__*/function () {
461
477
  limit: this.limit,
462
478
  skip: this.skip,
463
479
  cursor: this.cursor,
464
- bookmark: this.bookmark
480
+ bookmark: this.bookmark,
481
+ sharingId: this.sharingId
465
482
  };
466
483
  }
467
484
  }]);
package/dist/storage.js CHANGED
@@ -54,6 +54,11 @@ var shouldDocumentBePersisted = function shouldDocumentBePersisted(document) {
54
54
  return true;
55
55
  }
56
56
 
57
+ if (document.driveId && document._type === 'io.cozy.files') {
58
+ // Special case for files in shared drives, so remote files could be locally persisted
59
+ return true;
60
+ }
61
+
57
62
  return false;
58
63
  };
59
64
  /**