hypercore-fetch 9.7.0 → 9.8.0
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/README.md +7 -2
- package/index.js +2 -3
- package/package.json +1 -1
- package/test.js +15 -14
package/README.md
CHANGED
|
@@ -120,13 +120,18 @@ Note that this is only available with the `writable: true` flag.
|
|
|
120
120
|
|
|
121
121
|
### `fetch('hyper://NAME/example.txt', {method: 'PUT', body: 'Hello World'})`
|
|
122
122
|
|
|
123
|
-
You can add files to archives using a `PUT` method along with a
|
|
123
|
+
You can add files to archives using a `PUT` method along with a
|
|
124
|
+
`body`. Note that this is only available with the `writable: true`
|
|
125
|
+
flag.
|
|
124
126
|
|
|
125
127
|
The `body` can be any of the options supported by the Fetch API such as a `String`, `Blob`, `FormData`, or `ReadableStream`.
|
|
126
128
|
|
|
127
129
|
`NAME` can either be the 52 character [z32 encoded](https://github.com/mafintosh/z32) key for a Hyperdrive or Hypercore , or a domain to parse with the [DNSLink](https://www.dnslink.io/) standard.
|
|
128
130
|
|
|
129
|
-
|
|
131
|
+
The mtime metadata is automatically set to the current time when
|
|
132
|
+
uploading. To override this value, pass a `Last-Modified` header with a value
|
|
133
|
+
set to a date string according to [RFC
|
|
134
|
+
7231](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1).
|
|
130
135
|
|
|
131
136
|
An attempt to `PUT` a file to a hyperdrive which is not writable will
|
|
132
137
|
fail with status `403`.
|
package/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { posix } from 'path'
|
|
|
3
3
|
import { Readable, pipelinePromise } from 'streamx'
|
|
4
4
|
import Hyperdrive from 'hyperdrive'
|
|
5
5
|
import { makeRoutedFetch } from 'make-fetch'
|
|
6
|
-
import mime from 'mime/
|
|
6
|
+
import mime from 'mime/index.js'
|
|
7
7
|
import parseRange from 'range-parser'
|
|
8
8
|
import { EventIterator } from 'event-iterator'
|
|
9
9
|
|
|
@@ -397,6 +397,7 @@ export default async function makeHyperFetch ({
|
|
|
397
397
|
const { hostname, pathname: rawPathname } = new URL(request.url)
|
|
398
398
|
const pathname = decodeURI(ensureLeadingSlash(rawPathname))
|
|
399
399
|
const contentType = request.headers.get('Content-Type') || ''
|
|
400
|
+
const mtime = Date.parse(request.headers.get('Last-Modified')) || Date.now()
|
|
400
401
|
const isFormData = contentType.includes('multipart/form-data')
|
|
401
402
|
|
|
402
403
|
const drive = await getDrive(`hyper://${hostname}/`, true)
|
|
@@ -405,8 +406,6 @@ export default async function makeHyperFetch ({
|
|
|
405
406
|
return { status: 403, body: `Cannot PUT file to read-only drive: ${drive.url}`, headers: { Location: request.url } }
|
|
406
407
|
}
|
|
407
408
|
|
|
408
|
-
const mtime = Date.now()
|
|
409
|
-
|
|
410
409
|
if (isFormData) {
|
|
411
410
|
// It's a form! Get the files out and process them
|
|
412
411
|
const formData = await request.formData()
|
package/package.json
CHANGED
package/test.js
CHANGED
|
@@ -142,9 +142,13 @@ test('PUT file', async (t) => {
|
|
|
142
142
|
|
|
143
143
|
const uploadLocation = new URL('./example.txt', created)
|
|
144
144
|
|
|
145
|
+
const fakeDate = new Date(Date.parse(0)).toUTCString()
|
|
145
146
|
const uploadResponse = await fetch(uploadLocation, {
|
|
146
147
|
method: 'put',
|
|
147
|
-
body: SAMPLE_CONTENT
|
|
148
|
+
body: SAMPLE_CONTENT,
|
|
149
|
+
headers: {
|
|
150
|
+
'Last-Modified': fakeDate
|
|
151
|
+
}
|
|
148
152
|
})
|
|
149
153
|
|
|
150
154
|
await checkResponse(uploadResponse, t, 'upload successful')
|
|
@@ -159,7 +163,7 @@ test('PUT file', async (t) => {
|
|
|
159
163
|
|
|
160
164
|
t.equal(contentType, 'text/plain; charset=utf-8', 'Content got expected mime type')
|
|
161
165
|
t.equal(content, SAMPLE_CONTENT, 'Got uploaded content back out')
|
|
162
|
-
t.
|
|
166
|
+
t.equal(lastModified, fakeDate, 'Last-Modified header was set to value of Date header')
|
|
163
167
|
})
|
|
164
168
|
test('PUT FormData', async (t) => {
|
|
165
169
|
const created = await nextURL(t)
|
|
@@ -287,7 +291,7 @@ test('DELETE a directory', async (t) => {
|
|
|
287
291
|
})
|
|
288
292
|
await checkResponse(uploadResponse, t)
|
|
289
293
|
|
|
290
|
-
const deleteResponse = await fetch(
|
|
294
|
+
const deleteResponse = await fetch(uploadLocation, {
|
|
291
295
|
method: 'delete'
|
|
292
296
|
})
|
|
293
297
|
await checkResponse(deleteResponse, t, 'Able to DELETE')
|
|
@@ -297,7 +301,7 @@ test('DELETE a directory', async (t) => {
|
|
|
297
301
|
const entries = await listDirRequest.json()
|
|
298
302
|
t.deepEqual(entries, [], 'subfolder got deleted')
|
|
299
303
|
})
|
|
300
|
-
test
|
|
304
|
+
test('DELETE a drive from storage', async (t) => {
|
|
301
305
|
const created = await nextURL(t)
|
|
302
306
|
|
|
303
307
|
const uploadLocation = new URL('./subfolder/example.txt', created)
|
|
@@ -585,17 +589,10 @@ test('Handle empty string pathname', async (t) => {
|
|
|
585
589
|
await fetch(urlNoTrailingSlash, {
|
|
586
590
|
method: 'put',
|
|
587
591
|
body: formData
|
|
588
|
-
}),
|
|
592
|
+
}),
|
|
593
|
+
t
|
|
589
594
|
)
|
|
590
595
|
|
|
591
|
-
// DELETE
|
|
592
|
-
await checkResponse(await fetch(urlNoTrailingSlash, { method: 'DELETE' }), t)
|
|
593
|
-
|
|
594
|
-
// HEAD
|
|
595
|
-
const headResponse = await fetch(urlNoTrailingSlash, { method: 'HEAD' })
|
|
596
|
-
await checkResponse(headResponse, t)
|
|
597
|
-
t.deepEqual(headResponse.headers.get('Etag'), '5', 'HEAD request returns correct Etag')
|
|
598
|
-
|
|
599
596
|
// HEAD (versioned)
|
|
600
597
|
const versionedHeadResponse = await fetch(versionedURLNoTrailingSlash, { method: 'HEAD' })
|
|
601
598
|
await checkResponse(versionedHeadResponse, t)
|
|
@@ -604,12 +601,16 @@ test('Handle empty string pathname', async (t) => {
|
|
|
604
601
|
// GET
|
|
605
602
|
const getResponse = await fetch(urlNoTrailingSlash)
|
|
606
603
|
await checkResponse(getResponse, t)
|
|
607
|
-
t.deepEqual(await getResponse.json(), [], 'Returns
|
|
604
|
+
t.deepEqual(await getResponse.json(), ['example.txt', 'example2.txt'], 'Returns directory listing')
|
|
608
605
|
|
|
609
606
|
// GET (versioned)
|
|
610
607
|
const versionedGetResponse = await fetch(versionedURLNoTrailingSlash)
|
|
611
608
|
await checkResponse(versionedGetResponse, t)
|
|
612
609
|
t.deepEqual(await versionedGetResponse.json(), ['example.txt', 'example2.txt'], 'Returns root directory prior to DELETE')
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
// DELETE
|
|
613
|
+
await checkResponse(await fetch(urlNoTrailingSlash, { method: 'DELETE' }), t, 'Able to delete root')
|
|
613
614
|
})
|
|
614
615
|
|
|
615
616
|
test('Return status 403 Forbidden on attempt to modify read-only hyperdrive', async (t) => {
|