NeahNew/node_modules/webdav/dist/node/operations/directoryContents.js
2025-05-03 14:17:46 +02:00

55 lines
2.8 KiB
JavaScript

import pathPosix from "path-posix";
import { joinURL, normaliseHREF } from "../tools/url.js";
import { encodePath, makePathAbsolute, normalisePath } from "../tools/path.js";
import { parseXML, prepareFileFromProps } from "../tools/dav.js";
import { request, prepareRequestOptions } from "../request.js";
import { handleResponseCode, processGlobFilter, processResponsePayload } from "../response.js";
export async function getDirectoryContents(context, remotePath, options = {}) {
const requestOptions = prepareRequestOptions({
url: joinURL(context.remoteURL, encodePath(remotePath), "/"),
method: "PROPFIND",
headers: {
Accept: "text/plain,application/xml",
Depth: options.deep ? "infinity" : "1"
}
}, context, options);
const response = await request(requestOptions, context);
handleResponseCode(context, response);
const responseData = await response.text();
if (!responseData) {
throw new Error("Failed parsing directory contents: Empty response");
}
const davResp = await parseXML(responseData);
const _remotePath = makePathAbsolute(remotePath);
const remoteBasePath = makePathAbsolute(context.remoteBasePath || context.remotePath);
let files = getDirectoryFiles(davResp, remoteBasePath, _remotePath, options.details, options.includeSelf);
if (options.glob) {
files = processGlobFilter(files, options.glob);
}
return processResponsePayload(response, files, options.details);
}
function getDirectoryFiles(result, serverremoteBasePath, requestPath, isDetailed = false, includeSelf = false) {
const serverBase = pathPosix.join(serverremoteBasePath, "/");
// Extract the response items (directory contents)
const { multistatus: { response: responseItems } } = result;
// Map all items to a consistent output structure (results)
const nodes = responseItems.map(item => {
// HREF is the file path (in full) - The href is already XML entities decoded (e.g. foo&bar is reverted to foo&bar)
const href = normaliseHREF(item.href);
// Each item should contain a stat object
const { propstat: { prop: props } } = item;
// Process the true full filename (minus the base server path)
const filename = serverBase === "/"
? decodeURIComponent(normalisePath(href))
: normalisePath(pathPosix.relative(decodeURIComponent(serverBase), decodeURIComponent(href)));
return prepareFileFromProps(props, filename, isDetailed);
});
// If specified, also return the current directory
if (includeSelf) {
return nodes;
}
// Else, filter out the item pointing to the current directory (not needed)
return nodes.filter(item => item.basename &&
(item.type === "file" || item.filename !== requestPath.replace(/\/$/, "")));
}