braid-blob 0.0.11 → 0.0.13
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/index.js +57 -10
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -37,19 +37,30 @@ braid_blob.serve = async (req, res, options = {}) => {
|
|
|
37
37
|
if (req.method === 'GET') {
|
|
38
38
|
// Handle GET request for binary files
|
|
39
39
|
|
|
40
|
+
if (our_v == null) {
|
|
41
|
+
res.statusCode = 404
|
|
42
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
43
|
+
return res.end('File Not Found')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (meta.content_type && req.headers.accept &&
|
|
47
|
+
!isAcceptable(meta.content_type, req.headers.accept)) {
|
|
48
|
+
res.statusCode = 406
|
|
49
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
50
|
+
return res.end(`Content-Type of ${meta.content_type} not in Accept: ${req.headers.accept}`)
|
|
51
|
+
}
|
|
52
|
+
|
|
40
53
|
// Set Version header;
|
|
41
54
|
// but if this is a subscription,
|
|
42
55
|
// then we set Current-Version instead
|
|
43
|
-
res.setHeader((req.subscribe ? 'Current-' : '') + 'Version',
|
|
44
|
-
our_v != null ? `"${our_v}"` : '')
|
|
56
|
+
res.setHeader((req.subscribe ? 'Current-' : '') + 'Version', `"${our_v}"`)
|
|
45
57
|
|
|
46
58
|
// Set Content-Type
|
|
47
59
|
if (meta.content_type)
|
|
48
60
|
res.setHeader('Content-Type', meta.content_type)
|
|
49
61
|
|
|
50
62
|
if (!req.subscribe)
|
|
51
|
-
return res.end(
|
|
52
|
-
await fs.promises.readFile(filename) : '')
|
|
63
|
+
return res.end(await fs.promises.readFile(filename))
|
|
53
64
|
|
|
54
65
|
if (!res.hasHeader("editable"))
|
|
55
66
|
res.setHeader("Editable", "true")
|
|
@@ -67,12 +78,11 @@ braid_blob.serve = async (req, res, options = {}) => {
|
|
|
67
78
|
|
|
68
79
|
|
|
69
80
|
// Send an immediate update when:
|
|
70
|
-
if (!req.parents ||
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
)))
|
|
81
|
+
if (!req.parents || // 1) They have no version history
|
|
82
|
+
// (need full sync)
|
|
83
|
+
!req.parents.length || // 2) Or their version is the empty set
|
|
84
|
+
our_v > 1*req.parents[0] // 3) Or our version is newer
|
|
85
|
+
)
|
|
76
86
|
return res.sendUpdate({
|
|
77
87
|
version: our_v != null ? ['' + our_v] : [],
|
|
78
88
|
body: our_v != null ? await fs.promises.readFile(filename) : ''
|
|
@@ -117,6 +127,15 @@ braid_blob.serve = async (req, res, options = {}) => {
|
|
|
117
127
|
res.setHeader("Version", our_v != null ? `"${our_v}"` : '')
|
|
118
128
|
}
|
|
119
129
|
res.end('')
|
|
130
|
+
} else if (req.method === 'DELETE') {
|
|
131
|
+
try {
|
|
132
|
+
await fs.promises.unlink(filename)
|
|
133
|
+
} catch (e) {}
|
|
134
|
+
try {
|
|
135
|
+
await fs.promises.unlink(metaname)
|
|
136
|
+
} catch (e) {}
|
|
137
|
+
res.statusCode = 204 // No Content
|
|
138
|
+
res.end('')
|
|
120
139
|
}
|
|
121
140
|
})
|
|
122
141
|
}
|
|
@@ -153,4 +172,32 @@ async function slurp(req) {
|
|
|
153
172
|
})
|
|
154
173
|
}
|
|
155
174
|
|
|
175
|
+
function isAcceptable(contentType, acceptHeader) {
|
|
176
|
+
// If no Accept header or Accept is */*, accept everything
|
|
177
|
+
if (!acceptHeader || acceptHeader === '*/*') return true;
|
|
178
|
+
|
|
179
|
+
// Parse the Accept header into individual media types
|
|
180
|
+
const acceptTypes = acceptHeader.split(',').map(type => type.trim());
|
|
181
|
+
|
|
182
|
+
for (const acceptType of acceptTypes) {
|
|
183
|
+
// Remove quality values (e.g., "text/html;q=0.9" -> "text/html")
|
|
184
|
+
const cleanAcceptType = acceptType.split(';')[0].trim();
|
|
185
|
+
|
|
186
|
+
// Exact match
|
|
187
|
+
if (cleanAcceptType === contentType) return true;
|
|
188
|
+
|
|
189
|
+
// Wildcard subtype match (e.g., "image/*" matches "image/png")
|
|
190
|
+
if (cleanAcceptType.endsWith('/*')) {
|
|
191
|
+
const acceptMain = cleanAcceptType.slice(0, -2);
|
|
192
|
+
const contentMain = contentType.split('/')[0];
|
|
193
|
+
if (acceptMain === contentMain) return true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Full wildcard
|
|
197
|
+
if (cleanAcceptType === '*/*') return true;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return false;
|
|
201
|
+
}
|
|
202
|
+
|
|
156
203
|
module.exports = braid_blob
|