@nextcloud/files 4.0.0-beta.3 → 4.0.0-beta.5
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.
- package/README.md +2 -2
- package/dist/chunks/{folder-6N4fHAic.mjs → folder-Bf-tAYWu.mjs} +11 -5
- package/dist/chunks/folder-Bf-tAYWu.mjs.map +1 -0
- package/dist/dav/dav.d.ts +26 -9
- package/dist/dav.mjs +16 -23
- package/dist/dav.mjs.map +1 -1
- package/dist/fileListHeaders.d.ts +8 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +157 -1631
- package/dist/index.mjs.map +1 -1
- package/dist/navigation/column.d.ts +9 -9
- package/dist/navigation/navigation.d.ts +11 -8
- package/dist/navigation/view.d.ts +23 -11
- package/dist/sidebar/Sidebar.d.ts +33 -0
- package/dist/sidebar/SidebarTab.d.ts +78 -0
- package/dist/sidebar/index.d.ts +2 -0
- package/dist/types.d.ts +13 -13
- package/dist/utils/filename.d.ts +1 -1
- package/package.json +13 -18
- package/dist/chunks/folder-6N4fHAic.mjs.map +0 -1
- package/dist/chunks/folder-DY0O4v7K.cjs +0 -438
- package/dist/chunks/folder-DY0O4v7K.cjs.map +0 -1
- package/dist/dav.cjs +0 -281
- package/dist/dav.cjs.map +0 -1
- package/dist/index.cjs +0 -3018
- package/dist/index.cjs.map +0 -1
package/dist/dav.cjs
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const auth = require("@nextcloud/auth");
|
|
4
|
-
const _public = require("@nextcloud/sharing/public");
|
|
5
|
-
const router = require("@nextcloud/router");
|
|
6
|
-
const cancelablePromise = require("cancelable-promise");
|
|
7
|
-
const webdav = require("webdav");
|
|
8
|
-
const folder = require("./chunks/folder-DY0O4v7K.cjs");
|
|
9
|
-
const parsePermissions = function(permString = "") {
|
|
10
|
-
let permissions = folder.Permission.NONE;
|
|
11
|
-
if (!permString) {
|
|
12
|
-
return permissions;
|
|
13
|
-
}
|
|
14
|
-
if (permString.includes("C") || permString.includes("K")) {
|
|
15
|
-
permissions |= folder.Permission.CREATE;
|
|
16
|
-
}
|
|
17
|
-
if (permString.includes("G")) {
|
|
18
|
-
permissions |= folder.Permission.READ;
|
|
19
|
-
}
|
|
20
|
-
if (permString.includes("W") || permString.includes("N") || permString.includes("V")) {
|
|
21
|
-
permissions |= folder.Permission.UPDATE;
|
|
22
|
-
}
|
|
23
|
-
if (permString.includes("D")) {
|
|
24
|
-
permissions |= folder.Permission.DELETE;
|
|
25
|
-
}
|
|
26
|
-
if (permString.includes("R")) {
|
|
27
|
-
permissions |= folder.Permission.SHARE;
|
|
28
|
-
}
|
|
29
|
-
return permissions;
|
|
30
|
-
};
|
|
31
|
-
const defaultDavProperties = [
|
|
32
|
-
"d:getcontentlength",
|
|
33
|
-
"d:getcontenttype",
|
|
34
|
-
"d:getetag",
|
|
35
|
-
"d:getlastmodified",
|
|
36
|
-
"d:creationdate",
|
|
37
|
-
"d:displayname",
|
|
38
|
-
"d:quota-available-bytes",
|
|
39
|
-
"d:resourcetype",
|
|
40
|
-
"nc:has-preview",
|
|
41
|
-
"nc:is-encrypted",
|
|
42
|
-
"nc:mount-type",
|
|
43
|
-
"oc:comments-unread",
|
|
44
|
-
"oc:favorite",
|
|
45
|
-
"oc:fileid",
|
|
46
|
-
"oc:owner-display-name",
|
|
47
|
-
"oc:owner-id",
|
|
48
|
-
"oc:permissions",
|
|
49
|
-
"oc:size"
|
|
50
|
-
];
|
|
51
|
-
const defaultDavNamespaces = {
|
|
52
|
-
d: "DAV:",
|
|
53
|
-
nc: "http://nextcloud.org/ns",
|
|
54
|
-
oc: "http://owncloud.org/ns",
|
|
55
|
-
ocs: "http://open-collaboration-services.org/ns"
|
|
56
|
-
};
|
|
57
|
-
const registerDavProperty = function(prop, namespace = { nc: "http://nextcloud.org/ns" }) {
|
|
58
|
-
if (typeof window._nc_dav_properties === "undefined") {
|
|
59
|
-
window._nc_dav_properties = [...defaultDavProperties];
|
|
60
|
-
window._nc_dav_namespaces = { ...defaultDavNamespaces };
|
|
61
|
-
}
|
|
62
|
-
const namespaces = { ...window._nc_dav_namespaces, ...namespace };
|
|
63
|
-
if (window._nc_dav_properties.find((search) => search === prop)) {
|
|
64
|
-
folder.logger.warn(`${prop} already registered`, { prop });
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
if (prop.startsWith("<") || prop.split(":").length !== 2) {
|
|
68
|
-
folder.logger.error(`${prop} is not valid. See example: 'oc:fileid'`, { prop });
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
const ns = prop.split(":")[0];
|
|
72
|
-
if (!namespaces[ns]) {
|
|
73
|
-
folder.logger.error(`${prop} namespace unknown`, { prop, namespaces });
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
window._nc_dav_properties.push(prop);
|
|
77
|
-
window._nc_dav_namespaces = namespaces;
|
|
78
|
-
return true;
|
|
79
|
-
};
|
|
80
|
-
const getDavProperties = function() {
|
|
81
|
-
if (typeof window._nc_dav_properties === "undefined") {
|
|
82
|
-
window._nc_dav_properties = [...defaultDavProperties];
|
|
83
|
-
}
|
|
84
|
-
return window._nc_dav_properties.map((prop) => `<${prop} />`).join(" ");
|
|
85
|
-
};
|
|
86
|
-
const getDavNameSpaces = function() {
|
|
87
|
-
if (typeof window._nc_dav_namespaces === "undefined") {
|
|
88
|
-
window._nc_dav_namespaces = { ...defaultDavNamespaces };
|
|
89
|
-
}
|
|
90
|
-
return Object.keys(window._nc_dav_namespaces).map((ns) => `xmlns:${ns}="${window._nc_dav_namespaces?.[ns]}"`).join(" ");
|
|
91
|
-
};
|
|
92
|
-
const getDefaultPropfind = function() {
|
|
93
|
-
return `<?xml version="1.0"?>
|
|
94
|
-
<d:propfind ${getDavNameSpaces()}>
|
|
95
|
-
<d:prop>
|
|
96
|
-
${getDavProperties()}
|
|
97
|
-
</d:prop>
|
|
98
|
-
</d:propfind>`;
|
|
99
|
-
};
|
|
100
|
-
const getFavoritesReport = function() {
|
|
101
|
-
return `<?xml version="1.0"?>
|
|
102
|
-
<oc:filter-files ${getDavNameSpaces()}>
|
|
103
|
-
<d:prop>
|
|
104
|
-
${getDavProperties()}
|
|
105
|
-
</d:prop>
|
|
106
|
-
<oc:filter-rules>
|
|
107
|
-
<oc:favorite>1</oc:favorite>
|
|
108
|
-
</oc:filter-rules>
|
|
109
|
-
</oc:filter-files>`;
|
|
110
|
-
};
|
|
111
|
-
const getRecentSearch = function(lastModified) {
|
|
112
|
-
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
113
|
-
<d:searchrequest ${getDavNameSpaces()}
|
|
114
|
-
xmlns:ns="https://github.com/icewind1991/SearchDAV/ns">
|
|
115
|
-
<d:basicsearch>
|
|
116
|
-
<d:select>
|
|
117
|
-
<d:prop>
|
|
118
|
-
${getDavProperties()}
|
|
119
|
-
</d:prop>
|
|
120
|
-
</d:select>
|
|
121
|
-
<d:from>
|
|
122
|
-
<d:scope>
|
|
123
|
-
<d:href>/files/${auth.getCurrentUser()?.uid}/</d:href>
|
|
124
|
-
<d:depth>infinity</d:depth>
|
|
125
|
-
</d:scope>
|
|
126
|
-
</d:from>
|
|
127
|
-
<d:where>
|
|
128
|
-
<d:and>
|
|
129
|
-
<d:or>
|
|
130
|
-
<d:not>
|
|
131
|
-
<d:eq>
|
|
132
|
-
<d:prop>
|
|
133
|
-
<d:getcontenttype/>
|
|
134
|
-
</d:prop>
|
|
135
|
-
<d:literal>httpd/unix-directory</d:literal>
|
|
136
|
-
</d:eq>
|
|
137
|
-
</d:not>
|
|
138
|
-
<d:eq>
|
|
139
|
-
<d:prop>
|
|
140
|
-
<oc:size/>
|
|
141
|
-
</d:prop>
|
|
142
|
-
<d:literal>0</d:literal>
|
|
143
|
-
</d:eq>
|
|
144
|
-
</d:or>
|
|
145
|
-
<d:gt>
|
|
146
|
-
<d:prop>
|
|
147
|
-
<d:getlastmodified/>
|
|
148
|
-
</d:prop>
|
|
149
|
-
<d:literal>${lastModified}</d:literal>
|
|
150
|
-
</d:gt>
|
|
151
|
-
</d:and>
|
|
152
|
-
</d:where>
|
|
153
|
-
<d:orderby>
|
|
154
|
-
<d:order>
|
|
155
|
-
<d:prop>
|
|
156
|
-
<d:getlastmodified/>
|
|
157
|
-
</d:prop>
|
|
158
|
-
<d:descending/>
|
|
159
|
-
</d:order>
|
|
160
|
-
</d:orderby>
|
|
161
|
-
<d:limit>
|
|
162
|
-
<d:nresults>100</d:nresults>
|
|
163
|
-
<ns:firstresult>0</ns:firstresult>
|
|
164
|
-
</d:limit>
|
|
165
|
-
</d:basicsearch>
|
|
166
|
-
</d:searchrequest>`;
|
|
167
|
-
};
|
|
168
|
-
function getRootPath() {
|
|
169
|
-
if (_public.isPublicShare()) {
|
|
170
|
-
return `/files/${_public.getSharingToken()}`;
|
|
171
|
-
}
|
|
172
|
-
return `/files/${auth.getCurrentUser()?.uid}`;
|
|
173
|
-
}
|
|
174
|
-
const defaultRootPath = getRootPath();
|
|
175
|
-
function getRemoteURL() {
|
|
176
|
-
const url = router.generateRemoteUrl("dav");
|
|
177
|
-
if (_public.isPublicShare()) {
|
|
178
|
-
return url.replace("remote.php", "public.php");
|
|
179
|
-
}
|
|
180
|
-
return url;
|
|
181
|
-
}
|
|
182
|
-
const defaultRemoteURL = getRemoteURL();
|
|
183
|
-
const getClient = function(remoteURL = defaultRemoteURL, headers = {}) {
|
|
184
|
-
const client = webdav.createClient(remoteURL, { headers });
|
|
185
|
-
function setHeaders(token) {
|
|
186
|
-
client.setHeaders({
|
|
187
|
-
...headers,
|
|
188
|
-
// Add this so the server knows it is an request from the browser
|
|
189
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
190
|
-
// Inject user auth
|
|
191
|
-
requesttoken: token ?? ""
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
auth.onRequestTokenUpdate(setHeaders);
|
|
195
|
-
setHeaders(auth.getRequestToken());
|
|
196
|
-
const patcher = webdav.getPatcher();
|
|
197
|
-
patcher.patch("fetch", (url, options) => {
|
|
198
|
-
const headers2 = options.headers;
|
|
199
|
-
if (headers2?.method) {
|
|
200
|
-
options.method = headers2.method;
|
|
201
|
-
delete headers2.method;
|
|
202
|
-
}
|
|
203
|
-
return fetch(url, options);
|
|
204
|
-
});
|
|
205
|
-
return client;
|
|
206
|
-
};
|
|
207
|
-
const getFavoriteNodes = (davClient, path = "/", davRoot = defaultRootPath) => {
|
|
208
|
-
const controller = new AbortController();
|
|
209
|
-
return new cancelablePromise.CancelablePromise(async (resolve, reject, onCancel) => {
|
|
210
|
-
onCancel(() => controller.abort());
|
|
211
|
-
try {
|
|
212
|
-
const contentsResponse = await davClient.getDirectoryContents(`${davRoot}${path}`, {
|
|
213
|
-
signal: controller.signal,
|
|
214
|
-
details: true,
|
|
215
|
-
data: getFavoritesReport(),
|
|
216
|
-
headers: {
|
|
217
|
-
// see getClient for patched webdav client
|
|
218
|
-
method: "REPORT"
|
|
219
|
-
},
|
|
220
|
-
includeSelf: true
|
|
221
|
-
});
|
|
222
|
-
const nodes = contentsResponse.data.filter((node) => node.filename !== path).map((result) => resultToNode(result, davRoot));
|
|
223
|
-
resolve(nodes);
|
|
224
|
-
} catch (error) {
|
|
225
|
-
reject(error);
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
};
|
|
229
|
-
const resultToNode = function(node, filesRoot = defaultRootPath, remoteURL = defaultRemoteURL) {
|
|
230
|
-
let userId = auth.getCurrentUser()?.uid;
|
|
231
|
-
if (_public.isPublicShare()) {
|
|
232
|
-
userId = userId ?? "anonymous";
|
|
233
|
-
} else if (!userId) {
|
|
234
|
-
throw new Error("No user id found");
|
|
235
|
-
}
|
|
236
|
-
const props = node.props;
|
|
237
|
-
const permissions = parsePermissions(props?.permissions);
|
|
238
|
-
const owner = String(props?.["owner-id"] || userId);
|
|
239
|
-
const id = props.fileid || 0;
|
|
240
|
-
const mtime = new Date(Date.parse(node.lastmod));
|
|
241
|
-
const crtime = new Date(Date.parse(props.creationdate));
|
|
242
|
-
const nodeData = {
|
|
243
|
-
id,
|
|
244
|
-
source: `${remoteURL}${node.filename}`,
|
|
245
|
-
mtime: !isNaN(mtime.getTime()) && mtime.getTime() !== 0 ? mtime : void 0,
|
|
246
|
-
crtime: !isNaN(crtime.getTime()) && crtime.getTime() !== 0 ? crtime : void 0,
|
|
247
|
-
mime: node.mime || "application/octet-stream",
|
|
248
|
-
// Manually cast to work around for https://github.com/perry-mitchell/webdav-client/pull/380
|
|
249
|
-
displayname: props.displayname !== void 0 ? String(props.displayname) : void 0,
|
|
250
|
-
size: props?.size || Number.parseInt(props.getcontentlength || "0"),
|
|
251
|
-
// The fileid is set to -1 for failed requests
|
|
252
|
-
status: id < 0 ? folder.NodeStatus.FAILED : void 0,
|
|
253
|
-
permissions,
|
|
254
|
-
owner,
|
|
255
|
-
root: filesRoot,
|
|
256
|
-
attributes: {
|
|
257
|
-
...node,
|
|
258
|
-
...props,
|
|
259
|
-
hasPreview: props?.["has-preview"]
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
delete nodeData.attributes?.props;
|
|
263
|
-
return node.type === "file" ? new folder.File(nodeData) : new folder.Folder(nodeData);
|
|
264
|
-
};
|
|
265
|
-
exports.defaultDavNamespaces = defaultDavNamespaces;
|
|
266
|
-
exports.defaultDavProperties = defaultDavProperties;
|
|
267
|
-
exports.defaultRemoteURL = defaultRemoteURL;
|
|
268
|
-
exports.defaultRootPath = defaultRootPath;
|
|
269
|
-
exports.getClient = getClient;
|
|
270
|
-
exports.getDavNameSpaces = getDavNameSpaces;
|
|
271
|
-
exports.getDavProperties = getDavProperties;
|
|
272
|
-
exports.getDefaultPropfind = getDefaultPropfind;
|
|
273
|
-
exports.getFavoriteNodes = getFavoriteNodes;
|
|
274
|
-
exports.getFavoritesReport = getFavoritesReport;
|
|
275
|
-
exports.getRecentSearch = getRecentSearch;
|
|
276
|
-
exports.getRemoteURL = getRemoteURL;
|
|
277
|
-
exports.getRootPath = getRootPath;
|
|
278
|
-
exports.parsePermissions = parsePermissions;
|
|
279
|
-
exports.registerDavProperty = registerDavProperty;
|
|
280
|
-
exports.resultToNode = resultToNode;
|
|
281
|
-
//# sourceMappingURL=dav.cjs.map
|
package/dist/dav.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dav.cjs","sources":["../lib/dav/davPermissions.ts","../lib/dav/davProperties.ts","../lib/dav/dav.ts"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { Permission } from '../permissions'\n\n/**\n * Parse the WebDAV permission string to a permission enum\n *\n * @param permString The DAV permission string\n */\nexport const parsePermissions = function(permString = ''): number {\n\tlet permissions = Permission.NONE\n\n\tif (!permString) { return permissions }\n\n\tif (permString.includes('C') || permString.includes('K')) { permissions |= Permission.CREATE }\n\n\tif (permString.includes('G')) { permissions |= Permission.READ }\n\n\tif (permString.includes('W') || permString.includes('N') || permString.includes('V')) { permissions |= Permission.UPDATE }\n\n\tif (permString.includes('D')) { permissions |= Permission.DELETE }\n\n\tif (permString.includes('R')) { permissions |= Permission.SHARE }\n\n\treturn permissions\n}\n","/**\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nimport { getCurrentUser } from '@nextcloud/auth'\nimport logger from '../utils/logger'\n\nexport type DavProperty = { [key: string]: string }\n\nexport const defaultDavProperties = [\n\t'd:getcontentlength',\n\t'd:getcontenttype',\n\t'd:getetag',\n\t'd:getlastmodified',\n\t'd:creationdate',\n\t'd:displayname',\n\t'd:quota-available-bytes',\n\t'd:resourcetype',\n\t'nc:has-preview',\n\t'nc:is-encrypted',\n\t'nc:mount-type',\n\t'oc:comments-unread',\n\t'oc:favorite',\n\t'oc:fileid',\n\t'oc:owner-display-name',\n\t'oc:owner-id',\n\t'oc:permissions',\n\t'oc:size',\n]\n\nexport const defaultDavNamespaces = {\n\td: 'DAV:',\n\tnc: 'http://nextcloud.org/ns',\n\toc: 'http://owncloud.org/ns',\n\tocs: 'http://open-collaboration-services.org/ns',\n}\n\n/**\n * Register custom DAV properties\n *\n * Can be used if your app introduces custom DAV properties, so e.g. the files app can make use of it.\n *\n * @param prop The property\n * @param namespace The namespace of the property\n */\nexport const registerDavProperty = function(prop: string, namespace: DavProperty = { nc: 'http://nextcloud.org/ns' }): boolean {\n\tif (typeof window._nc_dav_properties === 'undefined') {\n\t\twindow._nc_dav_properties = [...defaultDavProperties]\n\t\twindow._nc_dav_namespaces = { ...defaultDavNamespaces }\n\t}\n\n\tconst namespaces = { ...window._nc_dav_namespaces, ...namespace }\n\n\t// Check duplicates\n\tif (window._nc_dav_properties.find((search) => search === prop)) {\n\t\tlogger.warn(`${prop} already registered`, { prop })\n\t\treturn false\n\t}\n\n\tif (prop.startsWith('<') || prop.split(':').length !== 2) {\n\t\tlogger.error(`${prop} is not valid. See example: 'oc:fileid'`, { prop })\n\t\treturn false\n\t}\n\n\tconst ns = prop.split(':')[0]\n\tif (!namespaces[ns]) {\n\t\tlogger.error(`${prop} namespace unknown`, { prop, namespaces })\n\t\treturn false\n\t}\n\n\twindow._nc_dav_properties.push(prop)\n\twindow._nc_dav_namespaces = namespaces\n\treturn true\n}\n\n/**\n * Get the registered dav properties\n */\nexport const getDavProperties = function(): string {\n\tif (typeof window._nc_dav_properties === 'undefined') {\n\t\twindow._nc_dav_properties = [...defaultDavProperties]\n\t}\n\n\treturn window._nc_dav_properties.map((prop) => `<${prop} />`).join(' ')\n}\n\n/**\n * Get the registered dav namespaces\n */\nexport const getDavNameSpaces = function(): string {\n\tif (typeof window._nc_dav_namespaces === 'undefined') {\n\t\twindow._nc_dav_namespaces = { ...defaultDavNamespaces }\n\t}\n\n\treturn Object.keys(window._nc_dav_namespaces)\n\t\t.map((ns) => `xmlns:${ns}=\"${window._nc_dav_namespaces?.[ns]}\"`)\n\t\t.join(' ')\n}\n\n/**\n * Get the default PROPFIND request body\n */\nexport const getDefaultPropfind = function(): string {\n\treturn `<?xml version=\"1.0\"?>\n\t\t<d:propfind ${getDavNameSpaces()}>\n\t\t\t<d:prop>\n\t\t\t\t${getDavProperties()}\n\t\t\t</d:prop>\n\t\t</d:propfind>`\n}\n\n/**\n * Get the REPORT body to filter for favorite nodes\n */\nexport const getFavoritesReport = function(): string {\n\treturn `<?xml version=\"1.0\"?>\n\t\t<oc:filter-files ${getDavNameSpaces()}>\n\t\t\t<d:prop>\n\t\t\t\t${getDavProperties()}\n\t\t\t</d:prop>\n\t\t\t<oc:filter-rules>\n\t\t\t\t<oc:favorite>1</oc:favorite>\n\t\t\t</oc:filter-rules>\n\t\t</oc:filter-files>`\n}\n\n/**\n * Get the SEARCH body to search for recently modified files\n *\n * @param lastModified Oldest timestamp to include (Unix timestamp)\n * @example\n * ```ts\n * // SEARCH for recent files need a different DAV endpoint\n * const client = davGetClient(generateRemoteUrl('dav'))\n * // Timestamp of last week\n * const lastWeek = Math.round(Date.now() / 1000) - (60 * 60 * 24 * 7)\n * const contentsResponse = await client.getDirectoryContents(path, {\n * details: true,\n * data: davGetRecentSearch(lastWeek),\n * headers: {\n * method: 'SEARCH',\n * 'Content-Type': 'application/xml; charset=utf-8',\n * },\n * deep: true,\n * }) as ResponseDataDetailed<FileStat[]>\n * ```\n */\nexport const getRecentSearch = function(lastModified: number): string {\n\treturn `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<d:searchrequest ${getDavNameSpaces()}\n\txmlns:ns=\"https://github.com/icewind1991/SearchDAV/ns\">\n\t<d:basicsearch>\n\t\t<d:select>\n\t\t\t<d:prop>\n\t\t\t\t${getDavProperties()}\n\t\t\t</d:prop>\n\t\t</d:select>\n\t\t<d:from>\n\t\t\t<d:scope>\n\t\t\t\t<d:href>/files/${getCurrentUser()?.uid}/</d:href>\n\t\t\t\t<d:depth>infinity</d:depth>\n\t\t\t</d:scope>\n\t\t</d:from>\n\t\t<d:where>\n\t\t\t<d:and>\n\t\t\t\t<d:or>\n\t\t\t\t\t<d:not>\n\t\t\t\t\t\t<d:eq>\n\t\t\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t\t\t<d:getcontenttype/>\n\t\t\t\t\t\t\t</d:prop>\n\t\t\t\t\t\t\t<d:literal>httpd/unix-directory</d:literal>\n\t\t\t\t\t\t</d:eq>\n\t\t\t\t\t</d:not>\n\t\t\t\t\t<d:eq>\n\t\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t\t<oc:size/>\n\t\t\t\t\t\t</d:prop>\n\t\t\t\t\t\t<d:literal>0</d:literal>\n\t\t\t\t\t</d:eq>\n\t\t\t\t</d:or>\n\t\t\t\t<d:gt>\n\t\t\t\t\t<d:prop>\n\t\t\t\t\t\t<d:getlastmodified/>\n\t\t\t\t\t</d:prop>\n\t\t\t\t\t<d:literal>${lastModified}</d:literal>\n\t\t\t\t</d:gt>\n\t\t\t</d:and>\n\t\t</d:where>\n\t\t<d:orderby>\n\t\t\t<d:order>\n\t\t\t\t<d:prop>\n\t\t\t\t\t<d:getlastmodified/>\n\t\t\t\t</d:prop>\n\t\t\t\t<d:descending/>\n\t\t\t</d:order>\n\t\t</d:orderby>\n\t\t<d:limit>\n\t\t\t<d:nresults>100</d:nresults>\n\t\t\t<ns:firstresult>0</ns:firstresult>\n\t\t</d:limit>\n\t</d:basicsearch>\n</d:searchrequest>`\n}\n","/*\n * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { DAVResultResponseProps, FileStat, ResponseDataDetailed, WebDAVClient } from 'webdav'\nimport type { Node, NodeData } from '../node/index.ts'\n\nimport { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'\nimport { getSharingToken, isPublicShare } from '@nextcloud/sharing/public'\nimport { generateRemoteUrl } from '@nextcloud/router'\nimport { CancelablePromise } from 'cancelable-promise'\nimport { createClient, getPatcher } from 'webdav'\nimport { parsePermissions } from './davPermissions.ts'\nimport { getFavoritesReport } from './davProperties.ts'\nimport { File, Folder, NodeStatus } from '../node/index.ts'\n\n/**\n * Nextcloud DAV result response\n */\ninterface ResponseProps extends DAVResultResponseProps {\n\tcreationdate: string\n\tpermissions: string\n\tmime: string\n\tfileid: number\n\tsize: number\n\t'owner-id': string | number\n}\n\n/**\n * Get the DAV root path for the current user or public share\n */\nexport function getRootPath(): string {\n\tif (isPublicShare()) {\n\t\treturn `/files/${getSharingToken()}`\n\t}\n\treturn `/files/${getCurrentUser()?.uid}`\n}\n\n/**\n * The DAV root path for the current user\n * This is a cached version of `getRemoteURL`\n */\nexport const defaultRootPath = getRootPath()\n\n/**\n * Get the DAV remote URL used as base URL for the WebDAV client\n * It also handles public shares\n */\nexport function getRemoteURL(): string {\n\tconst url = generateRemoteUrl('dav')\n\tif (isPublicShare()) {\n\t\treturn url.replace('remote.php', 'public.php')\n\t}\n\treturn url\n}\n\n/**\n * The DAV remote URL used as base URL for the WebDAV client\n * This is a cached version of `getRemoteURL`\n */\nexport const defaultRemoteURL = getRemoteURL()\n\n/**\n * Get a WebDAV client configured to include the Nextcloud request token\n *\n * @param remoteURL The DAV server remote URL\n * @param headers Optional additional headers to set for every request\n */\nexport const getClient = function(remoteURL = defaultRemoteURL, headers: Record<string, string> = {}) {\n\tconst client = createClient(remoteURL, { headers })\n\n\t/**\n\t * Set headers for DAV requests\n\t * @param token CSRF token\n\t */\n\tfunction setHeaders(token: string | null) {\n\t\tclient.setHeaders({\n\t\t\t...headers,\n\t\t\t// Add this so the server knows it is an request from the browser\n\t\t\t'X-Requested-With': 'XMLHttpRequest',\n\t\t\t// Inject user auth\n\t\t\trequesttoken: token ?? '',\n\t\t})\n\t}\n\n\t// refresh headers when request token changes\n\tonRequestTokenUpdate(setHeaders)\n\tsetHeaders(getRequestToken())\n\n\t/**\n\t * Allow to override the METHOD to support dav REPORT\n\t *\n\t * @see https://github.com/perry-mitchell/webdav-client/blob/8d9694613c978ce7404e26a401c39a41f125f87f/source/request.ts\n\t */\n\tconst patcher = getPatcher()\n\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t// @ts-ignore\n\t// https://github.com/perry-mitchell/hot-patcher/issues/6\n\tpatcher.patch('fetch', (url: string, options: RequestInit): Promise<Response> => {\n\t\tconst headers = options.headers as Record<string, string>\n\t\tif (headers?.method) {\n\t\t\toptions.method = headers.method\n\t\t\tdelete headers.method\n\t\t}\n\t\treturn fetch(url, options)\n\t})\n\n\treturn client\n}\n\n/**\n * Use WebDAV to query for favorite Nodes\n *\n * @param davClient The WebDAV client to use for performing the request\n * @param path Base path for the favorites, if unset all favorites are queried\n * @param davRoot The root path for the DAV user (defaults to `defaultRootPath`)\n * @example\n * ```js\n * import { getClient, defaultRootPath, getFavoriteNodes } from '@nextcloud/files'\n *\n * const client = getClient()\n * // query favorites for the root\n * const favorites = await getFavoriteNodes(client)\n * // which is the same as writing:\n * const favorites = await getFavoriteNodes(client, '/', defaultRootPath)\n * ```\n */\nexport const getFavoriteNodes = (davClient: WebDAVClient, path = '/', davRoot = defaultRootPath): CancelablePromise<Node[]> => {\n\tconst controller = new AbortController()\n\treturn new CancelablePromise(async (resolve, reject, onCancel) => {\n\t\tonCancel(() => controller.abort())\n\t\ttry {\n\t\t\tconst contentsResponse = await davClient.getDirectoryContents(`${davRoot}${path}`, {\n\t\t\t\tsignal: controller.signal,\n\t\t\t\tdetails: true,\n\t\t\t\tdata: getFavoritesReport(),\n\t\t\t\theaders: {\n\t\t\t\t\t// see getClient for patched webdav client\n\t\t\t\t\tmethod: 'REPORT',\n\t\t\t\t},\n\t\t\t\tincludeSelf: true,\n\t\t\t}) as ResponseDataDetailed<FileStat[]>\n\n\t\t\tconst nodes = contentsResponse.data\n\t\t\t\t.filter(node => node.filename !== path) // exclude current dir\n\t\t\t\t.map((result) => resultToNode(result, davRoot))\n\t\t\tresolve(nodes)\n\t\t} catch (error) {\n\t\t\treject(error)\n\t\t}\n\t})\n}\n\n/**\n * Convert DAV result `FileStat` to `Node`\n *\n * @param node The DAV result\n * @param filesRoot The DAV files root path\n * @param remoteURL The DAV server remote URL (same as on `getClient`)\n */\nexport const resultToNode = function(node: FileStat, filesRoot = defaultRootPath, remoteURL = defaultRemoteURL): Node {\n\tlet userId = getCurrentUser()?.uid\n\tif (isPublicShare()) {\n\t\tuserId = userId ?? 'anonymous'\n\t} else if (!userId) {\n\t\tthrow new Error('No user id found')\n\t}\n\n\tconst props = node.props as ResponseProps\n\tconst permissions = parsePermissions(props?.permissions)\n\tconst owner = String(props?.['owner-id'] || userId)\n\tconst id = props.fileid || 0\n\n\tconst mtime = new Date(Date.parse(node.lastmod))\n\tconst crtime = new Date(Date.parse(props.creationdate))\n\n\tconst nodeData: NodeData = {\n\t\tid,\n\t\tsource: `${remoteURL}${node.filename}`,\n\t\tmtime: !isNaN(mtime.getTime()) && mtime.getTime() !== 0 ? mtime : undefined,\n\t\tcrtime: !isNaN(crtime.getTime()) && crtime.getTime() !== 0 ? crtime : undefined,\n\t\tmime: node.mime || 'application/octet-stream',\n\t\t// Manually cast to work around for https://github.com/perry-mitchell/webdav-client/pull/380\n\t\tdisplayname: props.displayname !== undefined ? String(props.displayname) : undefined,\n\t\tsize: props?.size || Number.parseInt(props.getcontentlength || '0'),\n\t\t// The fileid is set to -1 for failed requests\n\t\tstatus: id < 0 ? NodeStatus.FAILED : undefined,\n\t\tpermissions,\n\t\towner,\n\t\troot: filesRoot,\n\t\tattributes: {\n\t\t\t...node,\n\t\t\t...props,\n\t\t\thasPreview: props?.['has-preview'],\n\t\t},\n\t}\n\n\tdelete nodeData.attributes?.props\n\n\treturn node.type === 'file' ? new File(nodeData) : new Folder(nodeData)\n}\n"],"names":["Permission","logger","getCurrentUser","isPublicShare","getSharingToken","generateRemoteUrl","createClient","onRequestTokenUpdate","getRequestToken","getPatcher","headers","CancelablePromise","NodeStatus","File","Folder"],"mappings":"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"}
|