-
Notifications
You must be signed in to change notification settings - Fork 12
/
node.ts
179 lines (157 loc) · 4 KB
/
node.ts
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/**
* @copyright Copyright (c) 2022 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { basename, extname, dirname } from 'path'
import { Permission } from '../permissions'
import { FileType } from './fileType'
import NodeData, { Attribute, validateData } from './nodeData'
export abstract class Node {
private _data: NodeData
private _attributes: Attribute[]
private _knownDavService = /(remote|public)\.php\/(web)?dav/i
constructor(data: NodeData, davService?: RegExp) {
// Validate data
validateData(data)
this._data = data
this._attributes = data.attributes || {} as any
delete this._data.attributes
if (davService) {
this._knownDavService = davService
}
}
/**
* Get the source url to this object
*/
get source(): string {
// strip any ending slash
return this._data.source.replace(/\/$/i, '')
}
/**
* Get this object name
*/
get basename(): string {
return basename(this.source)
}
/**
* Get this object's extension
*/
get extension(): string|null {
return extname(this.source)
}
/**
* Get the directory path leading to this object
* Will use the relative path to root if available
*/
get dirname(): string {
if (this.root) {
return dirname(this.source.split(this.root).pop() || '/')
}
return dirname(this.source)
}
/**
* Is it a file or a folder ?
*/
abstract get type(): FileType
/**
* Get the file mime
*/
get mime(): string|undefined {
return this._data.mime
}
/**
* Get the file size
*/
get size(): number|undefined {
return this._data.size
}
/**
* Get the file attribute
*/
get attributes(): Attribute {
return this._attributes
}
/**
* Get the file permissions
*/
get permissions(): Permission {
// If this is not a dav ressource, we can only read it
if (this.owner === null && !this.isDavRessource) {
return Permission.READ
}
return this._data.permissions || Permission.READ
}
/**
* Get the file owner
*/
get owner(): string|null {
// Remote ressources have no owner
if (!this.isDavRessource) {
return null
}
return this._data.owner
}
/**
* Is this a dav-related ressource ?
*/
get isDavRessource(): boolean {
return this.source.match(this._knownDavService) !== null
}
/**
* Get the dav root of this object
*/
get root(): string|null {
// If provided (recommended), use the root and strip away the ending slash
if (this._data.root) {
return this._data.root.replace(/^(.+)\/$/, '$1')
}
// Use the source to get the root from the dav service
if (this.isDavRessource) {
const root = dirname(this.source)
return root.split(this._knownDavService).pop() || null
}
return null
}
/**
* Get the absolute path of this object relative to the root
*/
get path(): string|null {
return (this.dirname + '/' + this.basename).replace(/\/\//g, '/')
}
/**
* Move the node to a new destination
*
* @param {string} destination the new source.
* e.g. https://cloud.domain.com/remote.php/dav/files/emma/Photos/picture.jpg
*/
move(destination: string) {
this._data.source = destination
}
/**
* Rename the node
* This aliases the move method for easier usage
*/
rename(basename) {
if (basename.includes('/')) {
throw new Error('Invalid basename')
}
this.move(dirname(this.source) + '/' + basename)
}
}