70 lines
2.4 KiB
JavaScript
70 lines
2.4 KiB
JavaScript
import { joinURL } from "../tools/url.js";
|
|
import { encodePath, getAllDirectories, normalisePath } from "../tools/path.js";
|
|
import { request, prepareRequestOptions } from "../request.js";
|
|
import { handleResponseCode } from "../response.js";
|
|
import { getStat } from "./stat.js";
|
|
export async function createDirectory(context, dirPath, options = {}) {
|
|
if (options.recursive === true)
|
|
return createDirectoryRecursively(context, dirPath, options);
|
|
const requestOptions = prepareRequestOptions({
|
|
url: joinURL(context.remoteURL, ensureCollectionPath(encodePath(dirPath))),
|
|
method: "MKCOL"
|
|
}, context, options);
|
|
const response = await request(requestOptions, context);
|
|
handleResponseCode(context, response);
|
|
}
|
|
/**
|
|
* Ensure the path is a proper "collection" path by ensuring it has a trailing "/".
|
|
* The proper format of collection according to the specification does contain the trailing slash.
|
|
* http://www.webdav.org/specs/rfc4918.html#rfc.section.5.2
|
|
* @param path Path of the collection
|
|
* @return string Path of the collection with appended trailing "/" in case the `path` does not have it.
|
|
*/
|
|
function ensureCollectionPath(path) {
|
|
if (!path.endsWith("/")) {
|
|
return path + "/";
|
|
}
|
|
return path;
|
|
}
|
|
async function createDirectoryRecursively(context, dirPath, options = {}) {
|
|
const paths = getAllDirectories(normalisePath(dirPath));
|
|
paths.sort((a, b) => {
|
|
if (a.length > b.length) {
|
|
return 1;
|
|
}
|
|
else if (b.length > a.length) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
});
|
|
let creating = false;
|
|
for (const testPath of paths) {
|
|
if (creating) {
|
|
await createDirectory(context, testPath, {
|
|
...options,
|
|
recursive: false
|
|
});
|
|
continue;
|
|
}
|
|
try {
|
|
const testStat = (await getStat(context, testPath));
|
|
if (testStat.type !== "directory") {
|
|
throw new Error(`Path includes a file: ${dirPath}`);
|
|
}
|
|
}
|
|
catch (err) {
|
|
const error = err;
|
|
if (error.status === 404) {
|
|
creating = true;
|
|
await createDirectory(context, testPath, {
|
|
...options,
|
|
recursive: false
|
|
});
|
|
}
|
|
else {
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
}
|