@@ -21,16 +21,14 @@ const DEFAULT_LOCALIZED_BASE_DIR = 'Administrative'
21
21
* @param {Object } options - options object
22
22
* @param {import('../types').IOCozyKonnector } options.konnector - io.cozy.konnectors document
23
23
* @param {import('../types').IOCozyAccount } options.account - io.cozy.accounts document
24
- * @param {String } options.lang - instance current language. ex: 'fr'
24
+ * @param {string } options.lang - instance current language. ex: 'fr'
25
25
* @returns {Promise<import('../types').IOCozyFolder> }
26
26
*/
27
27
export const ensureKonnectorFolder = async (
28
28
client ,
29
29
{ konnector, account, lang }
30
30
) => {
31
31
const permissions = client . collection ( PERMISSIONS_DOCTYPE )
32
- const fileCollection = client . collection ( FILES_DOCTYPE )
33
-
34
32
const t = getLocalizer ( lang )
35
33
const [ adminFolder , photosFolder ] = await Promise . all ( [
36
34
ensureMagicFolder (
@@ -64,6 +62,19 @@ export const ensureKonnectorFolder = async (
64
62
} )
65
63
}
66
64
65
+ const mainPath = buildMainFolderPath ( konnector , {
66
+ administrative : adminFolder . path ,
67
+ photos : photosFolder . path
68
+ } )
69
+ const mainFolder =
70
+ ( await statDirectoryByPath ( client , mainPath ) ) ||
71
+ ( await createDirectoryByPath ( client , mainPath ) )
72
+
73
+ ensureKonnectorReference ( {
74
+ client,
75
+ folder : mainFolder ,
76
+ konnector
77
+ } )
67
78
// if the previous shortcuts did not work, create the folders like we did before but with proper references
68
79
const path = buildFolderPath ( konnector , account , {
69
80
administrative : adminFolder . path ,
@@ -73,19 +84,13 @@ export const ensureKonnectorFolder = async (
73
84
( await statDirectoryByPath ( client , path ) ) ||
74
85
( await createDirectoryByPath ( client , path ) )
75
86
76
- const { data : konnectorFolder } = await fileCollection . statById ( folder . dir_id )
77
87
await Promise . all ( [
78
88
permissions . add ( konnector , buildFolderPermission ( folder ) ) ,
79
89
ensureKonnectorReference ( { client, folder, konnector } ) ,
80
90
ensureSourceAccountIdentifierReference ( {
81
91
client,
82
92
folder,
83
93
sourceAccountIdentifier
84
- } ) ,
85
- ensureKonnectorReference ( {
86
- client,
87
- folder : konnectorFolder ,
88
- konnector
89
94
} )
90
95
] )
91
96
@@ -148,9 +153,8 @@ export const statDirectoryByPath = async (client, path) => {
148
153
* @param {Object<string, string> } magicFolders Object containing a mapping from folder
149
154
* identifiers (ex: $administrative) to their localized values (ex:
150
155
* Administratif).
151
- * @returns {String } The result path
156
+ * @returns {string } The result path
152
157
*/
153
-
154
158
export const buildFolderPath = ( konnector , account , magicFolders = { } ) => {
155
159
const fullPath =
156
160
konnector ?. folders ?. [ 0 ] ?. defaultDir || '$administrative/$konnector/$account'
@@ -178,10 +182,54 @@ export const buildFolderPath = (konnector, account, magicFolders = {}) => {
178
182
return `/${ renderedBaseDir } /${ renderedPath } `
179
183
}
180
184
185
+ /**
186
+ * Build konnector main folder path for a given konnector.
187
+ *
188
+ * If konnector.folders[0].defaultDir exists, it is used as default directory.
189
+ *
190
+ * Occurrences of following strings in base directory are replaced by:
191
+ * * `$administrative`: Administrative folder
192
+ * * `$photos`: Photos folder
193
+ *
194
+ * Occurrences of following strings in path are replaced by:
195
+ * * `$konnector`: Konnector name
196
+ *
197
+ * If no konnectors.folders[0].defaultDir is set, the default dir used is
198
+ * * `$administrative/$konnector`
199
+ *
200
+ * @param {import('../types').IOCozyKonnector } konnector - Konnector document
201
+ * @param {Object<string, string> } magicFolders - Object containing a mapping from folder identifiers (ex: $administrative) to their localized values (ex: Administratif).
202
+ * @returns {string } The result path
203
+ */
204
+ export const buildMainFolderPath = ( konnector , magicFolders = { } ) => {
205
+ const fullPath =
206
+ konnector ?. folders ?. [ 0 ] ?. defaultDir
207
+ ?. split ( '/' )
208
+ ?. slice ( 0 , - 1 )
209
+ ?. join ( '/' ) || '$administrative/$konnector'
210
+ let sanitizedPath = trim ( fullPath . replace ( / ( \/ + ) / g, '/' ) , '/' )
211
+ if ( ! hasBaseDir ( sanitizedPath ) ) {
212
+ sanitizedPath = '$administrative/' + sanitizedPath
213
+ }
214
+ /**
215
+ * Now that we have our sanitizedPath, we can split it in two strings
216
+ * * `baseDir` containing the baseDir path
217
+ * * `buildedSubDir` containing the rest of the path (ie the path without baseDir)
218
+ */
219
+ const baseDir = sanitizedPath . split ( '/' , 1 )
220
+ const buildedSubDir = buildSubDir ( sanitizedPath , baseDir [ 0 ] )
221
+
222
+ const renderedBaseDir = renderBaseDir ( baseDir [ 0 ] , magicFolders )
223
+ const renderedPath = renderSubDir ( buildedSubDir , {
224
+ konnector : konnector . name
225
+ } )
226
+ return `/${ renderedBaseDir } /${ renderedPath } `
227
+ }
228
+
181
229
/**
182
230
* Check if the provided Path start withs our allowedBaseDirPath to see
183
231
*
184
- * @param {String } path - path to test
232
+ * @param {string } path - path to test
185
233
* @returns {Boolean }
186
234
*/
187
235
const hasBaseDir = path => {
@@ -200,9 +248,9 @@ const allowedBaseDirVariables = ['$administrative', '$photos']
200
248
* This method creates the subDir. We can't have an empty subDir, so we set
201
249
* it to our default '$konnector/$account'
202
250
*
203
- * @param {String } fullPath String containing potentially the defaultDir
204
- * @param {String } defaultDir String to remove from the fullPath
205
- * @returns {String }
251
+ * @param {string } fullPath String containing potentially the defaultDir
252
+ * @param {string } defaultDir String to remove from the fullPath
253
+ * @returns {string }
206
254
*/
207
255
const buildSubDir = ( fullPath , defaultDir ) => {
208
256
let buildedSubDir = fullPath . substring ( defaultDir . length )
@@ -217,11 +265,11 @@ const buildSubDir = (fullPath, defaultDir) => {
217
265
* For example, it will render `$administrative` with the given value passed in
218
266
* folders object. We expect to find in folders a localized value.
219
267
*
220
- * @param {String } baseDir base directory variable, expects `$administrative`
268
+ * @param {string } baseDir base directory variable, expects `$administrative`
221
269
* or `$photos`
222
270
* @param {Object<string, string> } magicFolders Object indexing base directory variable with
223
271
* corresponding localized name.
224
- * @returns {String } Localized directory
272
+ * @returns {string } Localized directory
225
273
*/
226
274
const renderBaseDir = ( baseDir , magicFolders = { } ) => {
227
275
// Look for variable name into folders but without $ prefix
@@ -236,11 +284,11 @@ const renderBaseDir = (baseDir, magicFolders = {}) => {
236
284
* Available variable are `$konnector` (konnector name) and `$account`
237
285
* (account label, i.e. id or name)
238
286
*
239
- * @param {String } path Path to render : ex '/Administratif/$konnector/$account'
287
+ * @param {string } path Path to render : ex '/Administratif/$konnector/$account'
240
288
* @param {Object } variables Object mapping variable to actual values
241
289
* @param {import('../types').IOCozyKonnector['name'] } variables.konnector - konnector name
242
- * @param {String } variables.account - account name
243
- * @returns {String } Rendered path
290
+ * @param {string } [ variables.account] - account name
291
+ * @returns {string } Rendered path
244
292
*/
245
293
const renderSubDir = ( path , variables ) => {
246
294
// Trim `/` and avoid multiple `/` characters with regexp
@@ -277,9 +325,9 @@ export const buildFolderPermission = folder => {
277
325
/**
278
326
* Replacer of the lodash/trim function
279
327
*
280
- * @param {String } str - Input string
281
- * @param {String } c - String to trim from the input string
282
- * @returns {String }
328
+ * @param {string } str - Input string
329
+ * @param {string } c - String to trim from the input string
330
+ * @returns {string }
283
331
*/
284
332
const trim = ( str , c = '\\s' ) =>
285
333
str . replace ( new RegExp ( `^([${ c } ]*)(.*?)([${ c } ]*)$` ) , '$2' )
0 commit comments