-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelete.ts
112 lines (102 loc) · 2.89 KB
/
delete.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
import { FSStoreOptions } from "../options";
import { Request, Response } from "@opennetwork/http-representation";
import getPath from "../get-path";
import getContentLocation from "../get-content-location";
import { Fetcher } from "./";
import li from "li";
function isRimRafAvailable(options: FSStoreOptions): boolean {
if (!options.rimraf) {
return false;
}
// They requested to not check for rimraf functions, so they must have their own implementation
if (options.rimraf.noFSFunctionCheck) {
return true;
}
const required = [
"unlink",
"lstat",
"chmod",
"stat",
"rmdir",
"readdir"
];
const missing = required.findIndex(name => !((options.fs as any)[name] instanceof Function));
return missing === -1;
}
async function deleteDependentLinks(request: Request, options: FSStoreOptions, headResponse: Response, fetch: Fetcher) {
if (!options.isLinkedDependent) {
return;
}
const links = li.parse(headResponse.headers.getAll("Link").join(", "));
return await Promise.all(
Object.keys(links)
.filter(rel => options.isLinkedDependent(request, rel, links[rel]))
.map(rel => links[rel])
.map(
async url => fetch(
new Request(
url,
{
method: "DELETE",
headers: request.headers
}
)
)
)
);
}
async function handleDeleteMethod(request: Request, options: FSStoreOptions, fetch: Fetcher): Promise<Response> {
const { contentLocation } = await getContentLocation(request, options);
const headResponse = await fetch(
new Request(
contentLocation || request.url,
{
method: "HEAD",
headers: request.headers
}
),
{
ignoreLock: true
}
);
// Could be 416 or 404 etc
if (!headResponse.ok) {
return headResponse;
}
const path = await getPath(contentLocation || request.url, options);
if (path.endsWith("/")) {
// Directory
if (!isRimRafAvailable(options)) {
return new Response(undefined, {
status: 501,
statusText: options.statusCodes[501],
headers: {
Warning: "199 - Cannot delete directory, not all required fs methods are available"
}
});
}
// rimraf mutates the options provided, so create a new object
await (options.rimraf as any)(path, {
unlink: options.fs.unlink,
lstat: options.fs.lstat,
chmod: options.fs.chmod,
stat: options.fs.stat,
rmdir: options.fs.rmdir,
readdir: options.fs.readdir,
});
} else {
// File
await new Promise(
(resolve, reject) => options.fs.unlink(
path,
(error) => error ? reject(error) : resolve()
)
);
}
await deleteDependentLinks(request, options, headResponse, fetch);
return new Response(undefined, {
status: 204,
statusText: options.statusCodes[204]
});
}
export default handleDeleteMethod;