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.
Files changed (4) hide show
  1. package/README.md +7 -2
  2. package/index.js +2 -3
  3. package/package.json +1 -1
  4. 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 `body`.
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
- Note that this is only available with the `writable: true` flag.
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/lite.js'
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hypercore-fetch",
3
- "version": "9.7.0",
3
+ "version": "9.8.0",
4
4
  "description": "Implementation of Fetch that uses the Dat SDK for loading p2p content",
5
5
  "type": "module",
6
6
  "main": "index.js",
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.ok(lastModified, 'Last-Modified header got set')
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(created, {
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.only('DELETE a drive from storage', async (t) => {
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
- }), t
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 empty root directory')
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) => {