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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
import $ from 'cafy';
import { ID } from '../../../../../misc/cafy-id';
import { publishDriveStream } from '../../../../../services/stream';
import define from '../../../define';
import { ApiError } from '../../../error';
import { DriveFolders } from '../../../../../models';
export const meta = {
desc: {
'ja-JP': '指定したドライブのフォルダの情報を更新します。',
'en-US': 'Update specified folder of drive.'
},
tags: ['drive'],
requireCredential: true as const,
kind: 'write:drive',
params: {
folderId: {
validator: $.type(ID),
desc: {
'ja-JP': '対象のフォルダID',
'en-US': 'Target folder ID'
}
},
name: {
validator: $.optional.str.pipe(DriveFolders.validateFolderName),
desc: {
'ja-JP': 'フォルダ名',
'en-US': 'Folder name'
}
},
parentId: {
validator: $.optional.nullable.type(ID),
desc: {
'ja-JP': '親フォルダID',
'en-US': 'Parent folder ID'
}
}
},
errors: {
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'f7974dac-2c0d-4a27-926e-23583b28e98e'
},
noSuchParentFolder: {
message: 'No such parent folder.',
code: 'NO_SUCH_PARENT_FOLDER',
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1'
},
recursiveNesting: {
message: 'It can not be structured like nesting folders recursively.',
code: 'NO_SUCH_PARENT_FOLDER',
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1'
},
}
};
export default define(meta, async (ps, user) => {
// Fetch folder
const folder = await DriveFolders.findOne({
id: ps.folderId,
userId: user.id
});
if (folder == null) {
throw new ApiError(meta.errors.noSuchFolder);
}
if (ps.name) folder.name = ps.name;
if (ps.parentId !== undefined) {
if (ps.parentId === folder.id) {
throw new ApiError(meta.errors.recursiveNesting);
} else if (ps.parentId === null) {
folder.parentId = null;
} else {
// Get parent folder
const parent = await DriveFolders.findOne({
id: ps.parentId,
userId: user.id
});
if (parent == null) {
throw new ApiError(meta.errors.noSuchParentFolder);
}
// Check if the circular reference will occur
async function checkCircle(folderId: any): Promise<boolean> {
// Fetch folder
const folder2 = await DriveFolders.findOne({
id: folderId
});
if (folder2!.id === folder!.id) {
return true;
} else if (folder2!.parentId) {
return await checkCircle(folder2!.parentId);
} else {
return false;
}
}
if (parent.parentId !== null) {
if (await checkCircle(parent.parentId)) {
throw new ApiError(meta.errors.recursiveNesting);
}
}
folder.parentId = parent.id;
}
}
// Update
DriveFolders.update(folder.id, {
name: folder.name,
parentId: folder.parentId
});
const folderObj = await DriveFolders.pack(folder);
// Publish folderUpdated event
publishDriveStream(user.id, 'folderUpdated', folderObj);
return folderObj;
});
|