/
folder.js
102 lines (88 loc) · 3.29 KB
/
folder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import sortBy from 'lodash/sortBy'
import CozyClient from '../CozyClient'
import { DOCTYPE_FILES } from '../const'
import { Q } from '../queries/dsl'
const APP_DOCTYPE = 'io.cozy.apps'
const administrative = 'administrative'
const photos = 'photos'
export const MAGIC_FOLDERS = {
ADMINISTRATIVE: `${APP_DOCTYPE}/${administrative}`,
PHOTOS: `${APP_DOCTYPE}/${photos}`,
PHOTOS_BACKUP: `${APP_DOCTYPE}/${photos}/mobile`,
PHOTOS_UPLOAD: `${APP_DOCTYPE}/${photos}/upload`,
NOTES: `${APP_DOCTYPE}/notes`,
HOME: `${APP_DOCTYPE}/home`,
PAPERS: `${APP_DOCTYPE}/${administrative}/papers`,
COACH_CO2: `${APP_DOCTYPE}/${administrative}/coachco2`
}
/**
* Returns a "Magic Folder", given its id. See https://docs.cozy.io/en/cozy-doctypes/docs/io.cozy.apps/#special-iocozyapps-doctypes
*
* @param {CozyClient} client cozy-client instance
* @param {string} id Magic Folder id. `CozyFolder.magicFolders` contains the
* ids of folders that can be magic folders.
* @param {string} path Default path to use if magic folder does not exist
* @returns {Promise<import("../types").IOCozyFolder>} Folder document
*/
export const ensureMagicFolder = async (client, id, path) => {
const magicFolderDocument = {
_type: APP_DOCTYPE,
_id: id
}
const existingMagicFolder = await getReferencedFolder(
client,
magicFolderDocument
)
if (existingMagicFolder) return existingMagicFolder
const magicFoldersValues = Object.values(MAGIC_FOLDERS)
if (!magicFoldersValues.includes(id)) {
throw new Error(
`Cannot create Magic folder with id ${id}. Allowed values are ${magicFoldersValues.join(
', '
)}.`
)
}
if (!path) {
throw new Error('Magic folder default path must be defined')
}
return createFolderWithReference(client, path, magicFolderDocument)
}
/**
* The next functions are considered private and only exported for unit tests
*/
/**
* Create a folder with a reference to the given document
*
* @param {CozyClient} client - cozy-client instance
* @param {string} path - Folder path
* @param {import("../types").CozyClientDocument} document - Document to make reference to. Any doctype.
* @returns {Promise<import("../types").IOCozyFolder>} Folder document
*/
export const createFolderWithReference = async (client, path, document) => {
const collection = client.collection(DOCTYPE_FILES)
const dirId = await collection.ensureDirectoryExists(path)
await collection.addReferencesTo(document, [
{
_id: dirId
}
])
const { data: dirInfos } = await collection.get(dirId)
return dirInfos
}
/**
* Returns the most recent folder referenced by the given document
*
* @param {CozyClient} client cozy-client instance
* @param {import("../types").CozyClientDocument} document Document to get references from
* @returns {Promise<import("../types").IOCozyFolder>} Folder referenced by the given document
*/
export const getReferencedFolder = async (client, document) => {
const { included: folders } = await client.query(
Q(DOCTYPE_FILES)
.partialIndex({ type: 'directory', trashed: false })
.referencedBy(document)
)
// there can be multiple folders with the same reference in some edge cases
// when this happens we return the most recent one
return folders.length > 0 ? sortBy(folders, 'created_at').pop() : null
}