diff --git a/README.md b/README.md
index 87885ba..c17e810 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,8 @@ USERNAME = "USERNAME"
PASSWORD = "PASSWORD"
```
-* USERNAME: The username of WebDav.
-* PASSWORD: The password of WebDav.
+- USERNAME: The username of WebDav.
+- PASSWORD: The password of WebDav.
## Development
diff --git a/package-lock.json b/package-lock.json
index 05fc3c1..f692944 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"devDependencies": {
"@cloudflare/workers-types": "^4.20231121.0",
+ "prettier": "3.1.1",
"typescript": "^5.0.4",
"wrangler": "^3.0.0"
}
@@ -970,6 +971,21 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/prettier": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
+ "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/printable-characters": {
"version": "1.0.42",
"resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz",
diff --git a/package.json b/package.json
index 88eba47..73171b8 100644
--- a/package.json
+++ b/package.json
@@ -5,10 +5,13 @@
"scripts": {
"deploy": "wrangler deploy",
"dev": "wrangler dev",
- "start": "wrangler dev"
+ "start": "wrangler dev",
+ "lint-perttier": "prettier . --write",
+ "check-perttier": "prettier . --check"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20231121.0",
+ "prettier": "3.1.1",
"typescript": "^5.0.4",
"wrangler": "^3.0.0"
},
diff --git a/src/index.ts b/src/index.ts
index 020d50c..6f47fd6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -46,21 +46,11 @@ async function* listAll(bucket: R2Bucket, prefix: string, isRecursive: boolean =
if (r2_objects.truncated) {
cursor = r2_objects.cursor;
}
- } while (r2_objects.truncated)
+ } while (r2_objects.truncated);
}
-
-const DAV_CLASS = "1";
-const SUPPORT_METHODS = [
- "OPTIONS",
- "PROPFIND",
- "MKCOL",
- "GET",
- "HEAD",
- "PUT",
- "COPY",
- "MOVE",
-];
+const DAV_CLASS = '1';
+const SUPPORT_METHODS = ['OPTIONS', 'PROPFIND', 'MKCOL', 'GET', 'HEAD', 'PUT', 'COPY', 'MOVE'];
type DavProperties = {
creationdate: string | undefined;
@@ -71,7 +61,7 @@ type DavProperties = {
getetag: string | undefined;
getlastmodified: string | undefined;
resourcetype: string;
-}
+};
function fromR2Object(object: R2Object | null | undefined): DavProperties {
if (object === null || object === undefined) {
@@ -79,11 +69,11 @@ function fromR2Object(object: R2Object | null | undefined): DavProperties {
creationdate: new Date().toUTCString(),
displayname: undefined,
getcontentlanguage: undefined,
- getcontentlength: "0",
+ getcontentlength: '0',
getcontenttype: undefined,
getetag: undefined,
getlastmodified: new Date().toUTCString(),
- resourcetype: "",
+ resourcetype: '',
};
}
@@ -99,7 +89,6 @@ function fromR2Object(object: R2Object | null | undefined): DavProperties {
};
}
-
function make_resource_path(request: Request): string {
let path = new URL(request.url).pathname.slice(1);
path = path.endsWith('/') ? path.slice(0, -1) : path;
@@ -110,9 +99,9 @@ async function handle_options(request: Request, bucket: R2Bucket): Promise
if (resource_path !== '') page += `..
`;
for await (const object of listAll(bucket, resource_path)) {
if (object.key === resource_path) {
- continue
+ continue;
}
let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`;
page += `${object.httpMetadata?.contentDisposition ?? object.key}
`;
@@ -147,12 +136,12 @@ async function handle_get(request: Request, bucket: R2Bucket): Promise
let isR2ObjectBody = (object: R2Object | R2ObjectBody): object is R2ObjectBody => {
return 'body' in object;
- }
+ };
if (object === null) {
return new Response('Not Found', { status: 404 });
} else if (!isR2ObjectBody(object)) {
- return new Response("Precondition Failed", { status: 412 });
+ return new Response('Precondition Failed', { status: 412 });
} else {
return new Response(object.body, {
status: object.range ? 206 : 200,
@@ -160,22 +149,32 @@ async function handle_get(request: Request, bucket: R2Bucket): Promise
'Content-Type': object.httpMetadata?.contentType ?? 'application/octet-stream',
// TODO: Content-Length, Content-Range
- ...(object.httpMetadata?.contentDisposition ? {
- 'Content-Disposition': object.httpMetadata.contentDisposition,
- } : {}),
- ...(object.httpMetadata?.contentEncoding ? {
- 'Content-Encoding': object.httpMetadata.contentEncoding,
- } : {}),
- ...(object.httpMetadata?.contentLanguage ? {
- 'Content-Language': object.httpMetadata.contentLanguage,
- } : {}),
- ...(object.httpMetadata?.cacheControl ? {
- 'Cache-Control': object.httpMetadata.cacheControl,
- } : {}),
- ...(object.httpMetadata?.cacheExpiry ? {
- 'Cache-Expiry': object.httpMetadata.cacheExpiry.toISOString(),
- } : {}),
- }
+ ...(object.httpMetadata?.contentDisposition
+ ? {
+ 'Content-Disposition': object.httpMetadata.contentDisposition,
+ }
+ : {}),
+ ...(object.httpMetadata?.contentEncoding
+ ? {
+ 'Content-Encoding': object.httpMetadata.contentEncoding,
+ }
+ : {}),
+ ...(object.httpMetadata?.contentLanguage
+ ? {
+ 'Content-Language': object.httpMetadata.contentLanguage,
+ }
+ : {}),
+ ...(object.httpMetadata?.cacheControl
+ ? {
+ 'Cache-Control': object.httpMetadata.cacheControl,
+ }
+ : {}),
+ ...(object.httpMetadata?.cacheExpiry
+ ? {
+ 'Cache-Expiry': object.httpMetadata.cacheExpiry.toISOString(),
+ }
+ : {}),
+ },
});
}
}
@@ -209,10 +208,11 @@ async function handle_delete(request: Request, bucket: R2Bucket): Promise object.key);
+ let keys = r2_objects.objects.map((object) => object.key);
if (keys.length > 0) {
await bucket.delete(keys);
}
@@ -234,13 +234,14 @@ async function handle_delete(request: Request, bucket: R2Bucket): Promise object.key);
+ let keys = r2_objects.objects.map((object) => object.key);
if (keys.length > 0) {
await bucket.delete(keys);
}
@@ -267,15 +268,15 @@ async function handle_mkcol(request: Request, bucket: R2Bucket): Promise' }
+ customMetadata: { resourcetype: '' },
});
return new Response('', { status: 201 });
}
@@ -287,7 +288,7 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise
`;
- if (resource_path === "") {
+ if (resource_path === '') {
page += `
/
@@ -321,53 +322,55 @@ async function handle_propfind(request: Request, bucket: R2Bucket): Promise
HTTP/1.1 200 OK
- `
- };
+ `;
+ }
if (is_collection) {
let depth = request.headers.get('Depth') ?? 'infinity';
switch (depth) {
- case '0': break;
- case '1': {
- let prefix = resource_path === "" ? resource_path : resource_path + '/';
- for await (let object of listAll(bucket, prefix)) {
- let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`;
- page += `
-
- ${href}
-
-
- ${Object.entries(fromR2Object(object))
- .filter(([_, value]) => value !== undefined)
- .map(([key, value]) => `<${key}>${value}${key}>`)
- .join('\n ')}
-
- HTTP/1.1 200 OK
-
- `;
- }
- }
+ case '0':
break;
- case 'infinity': {
- let prefix = resource_path === "" ? resource_path : resource_path + '/';
- for await (let object of listAll(bucket, prefix, true)) {
- let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`;
- page += `
+ case '1':
+ {
+ let prefix = resource_path === '' ? resource_path : resource_path + '/';
+ for await (let object of listAll(bucket, prefix)) {
+ let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`;
+ page += `
${href}
${Object.entries(fromR2Object(object))
- .filter(([_, value]) => value !== undefined)
- .map(([key, value]) => `<${key}>${value}${key}>`)
- .join('\n ')
- }
+ .filter(([_, value]) => value !== undefined)
+ .map(([key, value]) => `<${key}>${value}${key}>`)
+ .join('\n ')}
HTTP/1.1 200 OK
`;
+ }
+ }
+ break;
+ case 'infinity':
+ {
+ let prefix = resource_path === '' ? resource_path : resource_path + '/';
+ for await (let object of listAll(bucket, prefix, true)) {
+ let href = `/${object.key + (object.customMetadata?.resourcetype === '' ? '/' : '')}`;
+ page += `
+
+ ${href}
+
+
+ ${Object.entries(fromR2Object(object))
+ .filter(([_, value]) => value !== undefined)
+ .map(([key, value]) => `<${key}>${value}${key}>`)
+ .join('\n ')}
+
+ HTTP/1.1 200 OK
+
+ `;
+ }
}
- }
break;
default: {
return new Response('Forbidden', { status: 403 });
@@ -395,8 +398,11 @@ async function handle_copy(request: Request, bucket: R2Bucket): Promise {
- let target = destination + "/" + object.key.slice(prefix.length);
- target = target.endsWith("/") ? target.slice(0, -1) : target;
+ let target = destination + '/' + object.key.slice(prefix.length);
+ target = target.endsWith('/') ? target.slice(0, -1) : target;
let src = await bucket.get(object.key);
if (src !== null) {
await bucket.put(target, src.body, {
@@ -487,8 +493,11 @@ async function handle_move(request: Request, bucket: R2Bucket): Promise {
- let target = destination + "/" + object.key.slice(prefix.length);
- target = target.endsWith("/") ? target.slice(0, -1) : target;
+ let target = destination + '/' + object.key.slice(prefix.length);
+ target = target.endsWith('/') ? target.slice(0, -1) : target;
let src = await bucket.get(object.key);
if (src !== null) {
await bucket.put(target, src.body, {
@@ -611,9 +621,9 @@ async function dispatch_handler(request: Request, bucket: R2Bucket): Promise