cozy-client 52.1.0 → 52.2.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.
@@ -3049,7 +3049,7 @@ var CozyClient = /*#__PURE__*/function () {
3049
3049
  CozyClient.hooks = CozyClient.hooks || {};
3050
3050
  CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
3051
3051
 
3052
- CozyClient.version = "52.1.0";
3052
+ CozyClient.version = "52.2.0";
3053
3053
 
3054
3054
  _microee.default.mixin(CozyClient);
3055
3055
 
@@ -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.findKonnectorAccountFolderByReference = exports.buildFolderPermission = exports.buildFolderPath = exports.statDirectoryByPath = exports.createDirectoryByPath = exports.ensureKonnectorFolder = void 0;
8
+ exports.findKonnectorAccountFolderByReference = exports.buildFolderPermission = exports.buildMainFolderPath = exports.buildFolderPath = exports.statDirectoryByPath = exports.createDirectoryByPath = exports.ensureKonnectorFolder = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
@@ -35,13 +35,13 @@ var DEFAULT_LOCALIZED_BASE_DIR = 'Administrative';
35
35
  * @param {Object} options - options object
36
36
  * @param {import('../types').IOCozyKonnector} options.konnector - io.cozy.konnectors document
37
37
  * @param {import('../types').IOCozyAccount} options.account - io.cozy.accounts document
38
- * @param {String} options.lang - instance current language. ex: 'fr'
38
+ * @param {string} options.lang - instance current language. ex: 'fr'
39
39
  * @returns {Promise<import('../types').IOCozyFolder>}
40
40
  */
41
41
 
42
42
  var ensureKonnectorFolder = /*#__PURE__*/function () {
43
43
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(client, _ref) {
44
- var konnector, account, lang, permissions, fileCollection, t, _yield$Promise$all, _yield$Promise$all2, adminFolder, photosFolder, sourceAccountIdentifier, alreadyExistingAccountFolder, alreadyExistingKonnectorMainFolder, path, folder, _yield$fileCollection, konnectorFolder;
44
+ var konnector, account, lang, permissions, t, _yield$Promise$all, _yield$Promise$all2, adminFolder, photosFolder, sourceAccountIdentifier, alreadyExistingAccountFolder, alreadyExistingKonnectorMainFolder, mainPath, mainFolder, path, folder;
45
45
 
46
46
  return _regenerator.default.wrap(function _callee$(_context) {
47
47
  while (1) {
@@ -49,50 +49,49 @@ var ensureKonnectorFolder = /*#__PURE__*/function () {
49
49
  case 0:
50
50
  konnector = _ref.konnector, account = _ref.account, lang = _ref.lang;
51
51
  permissions = client.collection(PERMISSIONS_DOCTYPE);
52
- fileCollection = client.collection(FILES_DOCTYPE);
53
52
  t = (0, _locales.getLocalizer)(lang);
54
- _context.next = 6;
53
+ _context.next = 5;
55
54
  return Promise.all([(0, _folder.ensureMagicFolder)(client, _folder.MAGIC_FOLDERS.ADMINISTRATIVE, t('MagicFolders.administrative')), (0, _folder.ensureMagicFolder)(client, _folder.MAGIC_FOLDERS.PHOTOS, t('MagicFolders.photos'))]);
56
55
 
57
- case 6:
56
+ case 5:
58
57
  _yield$Promise$all = _context.sent;
59
58
  _yield$Promise$all2 = (0, _slicedToArray2.default)(_yield$Promise$all, 2);
60
59
  adminFolder = _yield$Promise$all2[0];
61
60
  photosFolder = _yield$Promise$all2[1];
62
61
  sourceAccountIdentifier = (0, _account.getAccountName)(account);
63
- _context.next = 13;
62
+ _context.next = 12;
64
63
  return findKonnectorAccountFolderByReference({
65
64
  client: client,
66
65
  slug: konnector.slug,
67
66
  sourceAccountIdentifier: sourceAccountIdentifier
68
67
  });
69
68
 
70
- case 13:
69
+ case 12:
71
70
  alreadyExistingAccountFolder = _context.sent;
72
71
 
73
72
  if (!alreadyExistingAccountFolder) {
74
- _context.next = 16;
73
+ _context.next = 15;
75
74
  break;
76
75
  }
77
76
 
78
77
  return _context.abrupt("return", alreadyExistingAccountFolder);
79
78
 
80
- case 16:
81
- _context.next = 18;
79
+ case 15:
80
+ _context.next = 17;
82
81
  return findKonnectorMainFolderByReference({
83
82
  client: client,
84
83
  slug: konnector.slug
85
84
  });
86
85
 
87
- case 18:
86
+ case 17:
88
87
  alreadyExistingKonnectorMainFolder = _context.sent;
89
88
 
90
89
  if (!alreadyExistingKonnectorMainFolder) {
91
- _context.next = 23;
90
+ _context.next = 22;
92
91
  break;
93
92
  }
94
93
 
95
- _context.next = 22;
94
+ _context.next = 21;
96
95
  return saveKonnectorAccountFolder({
97
96
  client: client,
98
97
  mainFolder: alreadyExistingKonnectorMainFolder,
@@ -100,41 +99,63 @@ var ensureKonnectorFolder = /*#__PURE__*/function () {
100
99
  sourceAccountIdentifier: sourceAccountIdentifier
101
100
  });
102
101
 
103
- case 22:
102
+ case 21:
104
103
  return _context.abrupt("return", _context.sent);
105
104
 
106
- case 23:
107
- // if the previous shortcuts did not work, create the folders like we did before but with proper references
108
- path = buildFolderPath(konnector, account, {
105
+ case 22:
106
+ mainPath = buildMainFolderPath(konnector, {
109
107
  administrative: adminFolder.path,
110
108
  photos: photosFolder.path
111
109
  });
112
- _context.next = 26;
113
- return statDirectoryByPath(client, path);
110
+ _context.next = 25;
111
+ return statDirectoryByPath(client, mainPath);
114
112
 
115
- case 26:
113
+ case 25:
116
114
  _context.t0 = _context.sent;
117
115
 
118
116
  if (_context.t0) {
119
- _context.next = 31;
117
+ _context.next = 30;
120
118
  break;
121
119
  }
122
120
 
123
- _context.next = 30;
124
- return createDirectoryByPath(client, path);
121
+ _context.next = 29;
122
+ return createDirectoryByPath(client, mainPath);
125
123
 
126
- case 30:
124
+ case 29:
127
125
  _context.t0 = _context.sent;
128
126
 
129
- case 31:
130
- folder = _context.t0;
131
- _context.next = 34;
132
- return fileCollection.statById(folder.dir_id);
127
+ case 30:
128
+ mainFolder = _context.t0;
129
+ ensureKonnectorReference({
130
+ client: client,
131
+ folder: mainFolder,
132
+ konnector: konnector
133
+ }); // if the previous shortcuts did not work, create the folders like we did before but with proper references
134
+
135
+ path = buildFolderPath(konnector, account, {
136
+ administrative: adminFolder.path,
137
+ photos: photosFolder.path
138
+ });
139
+ _context.next = 35;
140
+ return statDirectoryByPath(client, path);
141
+
142
+ case 35:
143
+ _context.t1 = _context.sent;
144
+
145
+ if (_context.t1) {
146
+ _context.next = 40;
147
+ break;
148
+ }
149
+
150
+ _context.next = 39;
151
+ return createDirectoryByPath(client, path);
152
+
153
+ case 39:
154
+ _context.t1 = _context.sent;
133
155
 
134
- case 34:
135
- _yield$fileCollection = _context.sent;
136
- konnectorFolder = _yield$fileCollection.data;
137
- _context.next = 38;
156
+ case 40:
157
+ folder = _context.t1;
158
+ _context.next = 43;
138
159
  return Promise.all([permissions.add(konnector, buildFolderPermission(folder)), ensureKonnectorReference({
139
160
  client: client,
140
161
  folder: folder,
@@ -143,16 +164,12 @@ var ensureKonnectorFolder = /*#__PURE__*/function () {
143
164
  client: client,
144
165
  folder: folder,
145
166
  sourceAccountIdentifier: sourceAccountIdentifier
146
- }), ensureKonnectorReference({
147
- client: client,
148
- folder: konnectorFolder,
149
- konnector: konnector
150
167
  })]);
151
168
 
152
- case 38:
169
+ case 43:
153
170
  return _context.abrupt("return", folder);
154
171
 
155
- case 39:
172
+ case 44:
156
173
  case "end":
157
174
  return _context.stop();
158
175
  }
@@ -286,7 +303,7 @@ var statDirectoryByPath = /*#__PURE__*/function () {
286
303
  * @param {Object<string, string>} magicFolders Object containing a mapping from folder
287
304
  * identifiers (ex: $administrative) to their localized values (ex:
288
305
  * Administratif).
289
- * @returns {String} The result path
306
+ * @returns {string} The result path
290
307
  */
291
308
 
292
309
 
@@ -321,15 +338,63 @@ var buildFolderPath = function buildFolderPath(konnector, account) {
321
338
  });
322
339
  return "/".concat(renderedBaseDir, "/").concat(renderedPath);
323
340
  };
341
+ /**
342
+ * Build konnector main folder path for a given konnector.
343
+ *
344
+ * If konnector.folders[0].defaultDir exists, it is used as default directory.
345
+ *
346
+ * Occurrences of following strings in base directory are replaced by:
347
+ * * `$administrative`: Administrative folder
348
+ * * `$photos`: Photos folder
349
+ *
350
+ * Occurrences of following strings in path are replaced by:
351
+ * * `$konnector`: Konnector name
352
+ *
353
+ * If no konnectors.folders[0].defaultDir is set, the default dir used is
354
+ * * `$administrative/$konnector`
355
+ *
356
+ * @param {import('../types').IOCozyKonnector} konnector - Konnector document
357
+ * @param {Object<string, string>} magicFolders - Object containing a mapping from folder identifiers (ex: $administrative) to their localized values (ex: Administratif).
358
+ * @returns {string} The result path
359
+ */
360
+
361
+
362
+ exports.buildFolderPath = buildFolderPath;
363
+
364
+ var buildMainFolderPath = function buildMainFolderPath(konnector) {
365
+ var _konnector$folders2, _konnector$folders2$, _konnector$folders2$$, _konnector$folders2$$2, _konnector$folders2$$3;
366
+
367
+ var magicFolders = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
368
+ var fullPath = (konnector === null || konnector === void 0 ? void 0 : (_konnector$folders2 = konnector.folders) === null || _konnector$folders2 === void 0 ? void 0 : (_konnector$folders2$ = _konnector$folders2[0]) === null || _konnector$folders2$ === void 0 ? void 0 : (_konnector$folders2$$ = _konnector$folders2$.defaultDir) === null || _konnector$folders2$$ === void 0 ? void 0 : (_konnector$folders2$$2 = _konnector$folders2$$.split('/')) === null || _konnector$folders2$$2 === void 0 ? void 0 : (_konnector$folders2$$3 = _konnector$folders2$$2.slice(0, -1)) === null || _konnector$folders2$$3 === void 0 ? void 0 : _konnector$folders2$$3.join('/')) || '$administrative/$konnector';
369
+ var sanitizedPath = trim(fullPath.replace(/(\/+)/g, '/'), '/');
370
+
371
+ if (!hasBaseDir(sanitizedPath)) {
372
+ sanitizedPath = '$administrative/' + sanitizedPath;
373
+ }
374
+ /**
375
+ * Now that we have our sanitizedPath, we can split it in two strings
376
+ * * `baseDir` containing the baseDir path
377
+ * * `buildedSubDir` containing the rest of the path (ie the path without baseDir)
378
+ */
379
+
380
+
381
+ var baseDir = sanitizedPath.split('/', 1);
382
+ var buildedSubDir = buildSubDir(sanitizedPath, baseDir[0]);
383
+ var renderedBaseDir = renderBaseDir(baseDir[0], magicFolders);
384
+ var renderedPath = renderSubDir(buildedSubDir, {
385
+ konnector: konnector.name
386
+ });
387
+ return "/".concat(renderedBaseDir, "/").concat(renderedPath);
388
+ };
324
389
  /**
325
390
  * Check if the provided Path start withs our allowedBaseDirPath to see
326
391
  *
327
- * @param {String} path - path to test
392
+ * @param {string} path - path to test
328
393
  * @returns {Boolean}
329
394
  */
330
395
 
331
396
 
332
- exports.buildFolderPath = buildFolderPath;
397
+ exports.buildMainFolderPath = buildMainFolderPath;
333
398
 
334
399
  var hasBaseDir = function hasBaseDir(path) {
335
400
  return allowedBaseDirVariables.some(function (baseDirVar) {
@@ -348,9 +413,9 @@ var allowedBaseDirVariables = ['$administrative', '$photos'];
348
413
  * This method creates the subDir. We can't have an empty subDir, so we set
349
414
  * it to our default '$konnector/$account'
350
415
  *
351
- * @param {String} fullPath String containing potentially the defaultDir
352
- * @param {String} defaultDir String to remove from the fullPath
353
- * @returns {String}
416
+ * @param {string} fullPath String containing potentially the defaultDir
417
+ * @param {string} defaultDir String to remove from the fullPath
418
+ * @returns {string}
354
419
  */
355
420
 
356
421
  var buildSubDir = function buildSubDir(fullPath, defaultDir) {
@@ -367,11 +432,11 @@ var buildSubDir = function buildSubDir(fullPath, defaultDir) {
367
432
  * For example, it will render `$administrative` with the given value passed in
368
433
  * folders object. We expect to find in folders a localized value.
369
434
  *
370
- * @param {String} baseDir base directory variable, expects `$administrative`
435
+ * @param {string} baseDir base directory variable, expects `$administrative`
371
436
  * or `$photos`
372
437
  * @param {Object<string, string>} magicFolders Object indexing base directory variable with
373
438
  * corresponding localized name.
374
- * @returns {String} Localized directory
439
+ * @returns {string} Localized directory
375
440
  */
376
441
 
377
442
 
@@ -387,11 +452,11 @@ var renderBaseDir = function renderBaseDir(baseDir) {
387
452
  * Available variable are `$konnector` (konnector name) and `$account`
388
453
  * (account label, i.e. id or name)
389
454
  *
390
- * @param {String} path Path to render : ex '/Administratif/$konnector/$account'
455
+ * @param {string} path Path to render : ex '/Administratif/$konnector/$account'
391
456
  * @param {Object} variables Object mapping variable to actual values
392
457
  * @param {import('../types').IOCozyKonnector['name']} variables.konnector - konnector name
393
- * @param {String} variables.account - account name
394
- * @returns {String} Rendered path
458
+ * @param {string} [variables.account] - account name
459
+ * @returns {string} Rendered path
395
460
  */
396
461
 
397
462
 
@@ -428,9 +493,9 @@ var buildFolderPermission = function buildFolderPermission(folder) {
428
493
  /**
429
494
  * Replacer of the lodash/trim function
430
495
  *
431
- * @param {String} str - Input string
432
- * @param {String} c - String to trim from the input string
433
- * @returns {String}
496
+ * @param {string} str - Input string
497
+ * @param {string} c - String to trim from the input string
498
+ * @returns {string}
434
499
  */
435
500
 
436
501
 
@@ -44,7 +44,7 @@ describe('ensureKonnectorFolder', () => {
44
44
  mockClient.query.mockResolvedValue({
45
45
  included: []
46
46
  })
47
- mockClient.statByPath.mockRejectedValueOnce({ status: 404 })
47
+ mockClient.statByPath.mockRejectedValue({ status: 404 })
48
48
  mockClient.statById.mockResolvedValueOnce({
49
49
  data: { _id: 'parentfolderid' }
50
50
  })
@@ -54,6 +54,12 @@ describe('ensureKonnectorFolder', () => {
54
54
  dir_id: 'parentfolderid'
55
55
  }
56
56
  })
57
+ mockClient.createDirectoryByPath.mockResolvedValueOnce({
58
+ data: {
59
+ _id: 'createdfolderid',
60
+ dir_id: 'parentfolderid'
61
+ }
62
+ })
57
63
  const result = await ensureKonnectorFolder(mockClient, {
58
64
  konnector,
59
65
  account,
@@ -220,6 +226,12 @@ describe('ensureKonnectorFolder', () => {
220
226
  dir_id: 'parentfolderid'
221
227
  }
222
228
  })
229
+ mockClient.statByPath.mockResolvedValueOnce({
230
+ data: {
231
+ _id: 'alreadyexistingfolderid',
232
+ dir_id: 'parentfolderid'
233
+ }
234
+ })
223
235
  const result = await ensureKonnectorFolder(mockClient, {
224
236
  konnector: {
225
237
  name: 'konnectorName',
@@ -251,6 +263,12 @@ describe('ensureKonnectorFolder', () => {
251
263
  trashed: true
252
264
  }
253
265
  })
266
+ mockClient.statByPath.mockResolvedValueOnce({
267
+ data: {
268
+ _id: 'folderintrash',
269
+ trashed: true
270
+ }
271
+ })
254
272
  mockClient.statById.mockResolvedValueOnce({
255
273
  data: {
256
274
  _id: 'parentfolderid'
@@ -262,6 +280,12 @@ describe('ensureKonnectorFolder', () => {
262
280
  dir_id: 'parentfolderid'
263
281
  }
264
282
  })
283
+ mockClient.createDirectoryByPath.mockResolvedValueOnce({
284
+ data: {
285
+ _id: 'createdfolderid',
286
+ dir_id: 'parentfolderid'
287
+ }
288
+ })
265
289
  const result = await ensureKonnectorFolder(mockClient, {
266
290
  konnector,
267
291
  account,
@@ -288,4 +312,96 @@ describe('ensureKonnectorFolder', () => {
288
312
  { _id: 'createdfolderid', dir_id: 'parentfolderid' }
289
313
  ])
290
314
  })
315
+ it('should add proper references to konnector folder with proper name if any', async () => {
316
+ const existingKonnectorFolder = {
317
+ _id: 'konnectorFolderId',
318
+ path: '/Administratif/' + konnector.name,
319
+ type: 'directory',
320
+ referenced_by: []
321
+ }
322
+ const createdAccountFolder = {
323
+ _id: 'accountfolderid',
324
+ path: '/Administratif/' + konnector.name + '/testAccountName',
325
+ type: 'directory',
326
+ referenced_by: []
327
+ }
328
+ mockClient.query.mockResolvedValue({
329
+ included: []
330
+ })
331
+ mockClient.statByPath
332
+ .mockResolvedValueOnce({
333
+ data: existingKonnectorFolder
334
+ })
335
+ .mockResolvedValueOnce({ data: false })
336
+ mockClient.createDirectoryByPath.mockResolvedValueOnce({
337
+ data: createdAccountFolder
338
+ })
339
+
340
+ await ensureKonnectorFolder(mockClient, {
341
+ konnector,
342
+ account,
343
+ lang: 'fr'
344
+ })
345
+ expect(mockClient.addReferencesTo).toHaveBeenNthCalledWith(1, konnector, [
346
+ existingKonnectorFolder
347
+ ])
348
+ expect(mockClient.addReferencesTo).toHaveBeenNthCalledWith(2, konnector, [
349
+ createdAccountFolder
350
+ ])
351
+ expect(mockClient.addReferencesTo).toHaveBeenNthCalledWith(
352
+ 3,
353
+ {
354
+ _id: 'testAccountName',
355
+ _type: 'io.cozy.accounts.sourceAccountIdentifier'
356
+ },
357
+ [createdAccountFolder]
358
+ )
359
+ expect(mockClient.addReferencesTo).toHaveBeenCalledTimes(3)
360
+ })
361
+
362
+ it('should add proper references to konnector folder even if account folder has konnector reference', async () => {
363
+ const existingKonnectorFolder = {
364
+ _id: 'konnectorFolderId',
365
+ path: '/Administratif/' + konnector.name,
366
+ type: 'directory',
367
+ referenced_by: []
368
+ }
369
+ const existingAccountFolder = {
370
+ _id: 'accountfolderid',
371
+ path: '/Administratif/' + konnector.name + '/testAccountName',
372
+ type: 'directory',
373
+ referenced_by: [
374
+ {
375
+ type: 'io.cozy.konnectors',
376
+ id: 'io.cozy.konnectors/konnectorSlug'
377
+ }
378
+ ]
379
+ }
380
+ mockClient.query.mockResolvedValue({
381
+ included: []
382
+ })
383
+ mockClient.statByPath
384
+ .mockResolvedValueOnce({
385
+ data: existingKonnectorFolder
386
+ })
387
+ .mockResolvedValueOnce({ data: existingAccountFolder })
388
+ await ensureKonnectorFolder(mockClient, {
389
+ konnector,
390
+ account,
391
+ lang: 'fr'
392
+ })
393
+ expect(mockClient.addReferencesTo).toHaveBeenCalledTimes(2)
394
+ expect(mockClient.addReferencesTo).toHaveBeenNthCalledWith(1, konnector, [
395
+ existingKonnectorFolder
396
+ ])
397
+ expect(mockClient.addReferencesTo).toHaveBeenNthCalledWith(
398
+ 2,
399
+ {
400
+ _id: 'testAccountName',
401
+ _type: 'io.cozy.accounts.sourceAccountIdentifier'
402
+ },
403
+ [existingAccountFolder]
404
+ )
405
+ expect(mockClient.createDirectoryByPath).not.toHaveBeenCalled()
406
+ })
291
407
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-client",
3
- "version": "52.1.0",
3
+ "version": "52.2.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": "^52.0.0",
21
+ "cozy-stack-client": "^52.2.0",
22
22
  "date-fns": "2.29.3",
23
23
  "json-stable-stringify": "^1.0.1",
24
24
  "lodash": "^4.17.13",
@@ -72,5 +72,5 @@
72
72
  "react-native-ios11-devicecheck": "https://github.com/cozy/react-native-devicecheck#app-attest-v0.1"
73
73
  },
74
74
  "sideEffects": false,
75
- "gitHead": "c6762bb0c1fad4ac62f18b4118c8577a749caf2b"
75
+ "gitHead": "e1dadbc037bd2beda076f2c287bc485e2c50de80"
76
76
  }
@@ -8,6 +8,9 @@ export function statDirectoryByPath(client: CozyClient, path: string): Promise<i
8
8
  export function buildFolderPath(konnector: import('../types').IOCozyKonnector, account: import('../types').IOCozyAccount, magicFolders?: {
9
9
  [x: string]: string;
10
10
  }): string;
11
+ export function buildMainFolderPath(konnector: import('../types').IOCozyKonnector, magicFolders?: {
12
+ [x: string]: string;
13
+ }): string;
11
14
  export function buildFolderPermission(folder: import('../types').IOCozyFolder): any;
12
15
  export function findKonnectorAccountFolderByReference({ client, slug, sourceAccountIdentifier }: {
13
16
  client: CozyClient;