@johntalton/http-core 1.0.2 → 1.0.3

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@johntalton/http-core",
3
3
  "type": "module",
4
- "version": "1.0.2",
4
+ "version": "1.0.3",
5
5
  "license": "MIT",
6
6
  "exports": {
7
7
  ".": "./src/index.js"
@@ -15,7 +15,7 @@
15
15
  "scripts": {
16
16
  },
17
17
  "dependencies": {
18
- "@johntalton/http-util": "^5.0.1",
18
+ "@johntalton/http-util": "^5.1.2",
19
19
  "@johntalton/sse-util": "^1.0.0"
20
20
  }
21
21
  }
package/src/epilogue.js CHANGED
@@ -54,17 +54,18 @@ export function epilogue(state) {
54
54
  case 'trace': { Response.trace(stream, state.method, state.url, state.headers, meta) } break
55
55
  //
56
56
  case 'preflight': { Response.preflight(stream, state.methods, state.supportedQueryTypes, undefined, meta) } break
57
- // case 'no-content': { Response.noContent(stream, state.etag, meta)} break
57
+ case 'no-content': { Response.noContent(stream, state.etag, meta)} break
58
58
  // case 'accepted': { Response.accepted(stream, meta) } break
59
59
  case 'created': { Response.created(stream, new URL(state.location, meta.origin), state.etag, meta) } break
60
60
  case 'not-modified': { Response.notModified(stream, state.etag, state.age, { priv: true, maxAge: 60 }, meta) } break
61
61
 
62
62
  //
63
63
  // case 'multiple-choices': { Response.multipleChoices(stream, meta) } break
64
- // case 'gone': { Response.gone(stream, meta) } break
65
- // case 'moved-permanently': { Response.movedPermanently(stream, state.location, meta) } break
66
- // case 'see-other': { Response.seeOther(stream, state.location, meta) } break
67
- // case 'temporary-redirect': { Response.temporaryRedirect(stream, state.location, meta) } break
64
+ case 'gone': { Response.gone(stream, meta) } break
65
+ case 'moved-permanently': { Response.movedPermanently(stream, state.location, meta) } break
66
+ case 'see-other': { Response.seeOther(stream, state.location, meta) } break
67
+ case 'temporary-redirect': { Response.temporaryRedirect(stream, state.location, meta) } break
68
+ case 'permanent-redirect': { Response.permanentRedirect(stream, state.location, meta) } break
68
69
 
69
70
  //
70
71
  case '404': { Response.notFound(stream, state.message, meta) } break
@@ -75,13 +76,14 @@ export function epilogue(state) {
75
76
  case 'unprocessable': { Response.unprocessable(stream, meta) } break
76
77
  case 'precondition-failed': { Response.preconditionFailed(stream, meta) } break
77
78
  case 'not-satisfiable': { Response.rangeNotSatisfiable(stream, { size: state.contentLength }, meta) } break
78
- // case 'content-too-large': { Response.contentTooLarge(stream, meta) } break
79
- // case 'insufficient-storage': { Response.insufficientStorage(stream, meta) } break
80
- // case 'too-many-requests': { Response.tooManyRequests(stream, state.limit, state.policies, meta) } break
81
- // case 'unauthorized': { Response.unauthorized(stream, meta) } break
79
+ case 'content-too-large': { Response.contentTooLarge(stream, meta) } break
80
+ case 'insufficient-storage': { Response.insufficientStorage(stream, meta) } break
81
+ case 'too-many-requests': { Response.tooManyRequests(stream, state.limit, state.policies, meta) } break
82
+ case 'unauthorized': { Response.unauthorized(stream, state.challenge, meta) } break
83
+ case 'forbidden': { Response.forbidden(stream, meta) } break
82
84
  case 'unavailable': { Response.unavailable(stream, state.message, state.retryAfter, meta)} break
83
85
  case 'not-implemented': { Response.notImplemented(stream, state.message, meta)} break
84
- // case 'timeout': { Response.timeout(stream, meta) } break
86
+ case 'timeout': { Response.timeout(stream, meta) } break
85
87
 
86
88
  //
87
89
  case 'sse': {
package/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** biome-ignore-all lint/nursery/noExcessiveLinesPerFile: legacy */
1
2
  import crypto from 'node:crypto'
2
3
  import fs from 'node:fs'
3
4
  import http2 from 'node:http2'
@@ -41,14 +42,46 @@ export const KNOWN_METHODS = [
41
42
 
42
43
  /** @import { Metadata } from '@johntalton/http-util/response' */
43
44
  /** @import { BodyFuture } from '@johntalton/http-util/body' */
44
- /** @import { EtagItem, IMFFixDate, ContentRangeDirective } from '@johntalton/http-util/headers' */
45
+ /** @import { EtagItem, IMFFixDate, ContentRangeDirective, RateLimitPolicyInfo, RateLimitInfo, ChallengeItem } from '@johntalton/http-util/headers' */
45
46
  /** @import { SendBody } from '@johntalton/http-util/response' */
46
47
 
47
48
  /** @typedef {(state: RouteRequest|RouteAction) => Promise<RouteAction>} Router */
48
49
 
49
50
  /** @typedef {'request'} RouteTypeRequest */
50
- /** @typedef {'partial-bytes'|'bytes'|'json'|'404'|'sse'|'error'|'preflight'|'not-allowed'|'trace'|'created'|'unsupported-media'|'not-modified'|'precondition-failed'|'unprocessable'|'not-acceptable'|'conflict'|'not-implemented'|'unavailable'|'not-satisfiable'} RouteType */
51
- /** @typedef {'GET'|'HEAD'|'POST'|'PUT'|'OPTIONS'|'DELETE'|'TRACE'} RouteMethod */
51
+ /** @typedef {
52
+ 'partial-bytes' |
53
+ 'bytes' |
54
+ 'json' |
55
+ '404' |
56
+ 'sse' |
57
+ 'error' |
58
+ 'preflight' |
59
+ 'not-allowed' |
60
+ 'trace' |
61
+ 'created' |
62
+ 'unsupported-media' |
63
+ 'not-modified' |
64
+ 'precondition-failed' |
65
+ 'unprocessable' |
66
+ 'not-acceptable' |
67
+ 'conflict' |
68
+ 'not-implemented' |
69
+ 'unavailable' |
70
+ 'not-satisfiable' |
71
+ 'see-other' |
72
+ 'temporary-redirect' |
73
+ 'permanent-redirect' |
74
+ 'moved-permanently' |
75
+ 'gone' |
76
+ 'no-content' |
77
+ 'content-too-large' |
78
+ 'insufficient-storage' |
79
+ 'too-many-requests' |
80
+ 'unauthorized' |
81
+ 'forbidden' |
82
+ 'timeout'
83
+ } RouteType */
84
+ /** @typedef {'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'OPTIONS'|'DELETE'|'TRACE'|'QUERY'} RouteMethod */
52
85
 
53
86
  /** @typedef {string & { readonly _brand: 'sid' }} StreamID */
54
87
 
@@ -277,6 +310,85 @@ export const KNOWN_METHODS = [
277
310
  */
278
311
  /** @typedef {RouteBase & RouteNotSatisfiableBase} RouteNotSatisfiable */
279
312
 
313
+ /**
314
+ * @typedef {Object} RouteSeeOtherBase
315
+ * @property {'see-other'} type
316
+ * @property {URL} location
317
+ */
318
+ /** @typedef {RouteBase & RouteSeeOtherBase} RouteSeeOther */
319
+
320
+ /**
321
+ * @typedef {Object} RouteTemporaryRedirectBase
322
+ * @property {'temporary-redirect'} type
323
+ * @property {URL} location
324
+ */
325
+ /** @typedef {RouteBase & RouteTemporaryRedirectBase} RouteTemporaryRedirect */
326
+
327
+ /**
328
+ * @typedef {Object} RoutePermanentRedirectBase
329
+ * @property {'permanent-redirect'} type
330
+ * @property {URL} location
331
+ */
332
+ /** @typedef {RouteBase & RoutePermanentRedirectBase} RoutePermanentRedirect */
333
+
334
+ /**
335
+ * @typedef {Object} RouteMovedPermanentlyBase
336
+ * @property {'moved-permanently'} type
337
+ * @property {URL} location
338
+ */
339
+ /** @typedef {RouteBase & RouteMovedPermanentlyBase} RouteMovedPermanently */
340
+
341
+ /**
342
+ * @typedef {Object} RouteNoContentBase
343
+ * @property {'no-content'} type
344
+ * @property {EtagItem|undefined} [etag]
345
+ */
346
+ /** @typedef {RouteBase & RouteNoContentBase} RouteNoContent */
347
+
348
+ /**
349
+ * @typedef {Object} RouteGoneBase
350
+ * @property {'gone'} type
351
+ */
352
+ /** @typedef {RouteBase & RouteGoneBase} RouteGone */
353
+
354
+ /**
355
+ * @typedef {Object} RouteContentTooLargeBase
356
+ * @property {'content-too-large'} type
357
+ */
358
+ /** @typedef {RouteBase & RouteContentTooLargeBase} RouteContentTooLarge */
359
+
360
+ /**
361
+ * @typedef {Object} RouteInsufficientStorageBase
362
+ * @property {'insufficient-storage'} type
363
+ */
364
+ /** @typedef {RouteBase & RouteInsufficientStorageBase} RouteInsufficientStorage */
365
+
366
+ /**
367
+ * @typedef {Object} RouteTooManyRequestsBase
368
+ * @property {'too-many-requests'} type
369
+ * @property {RateLimitInfo} limit
370
+ * @property {Array<RateLimitPolicyInfo>} policies
371
+ */
372
+ /** @typedef {RouteBase & RouteTooManyRequestsBase} RouteTooManyRequests */
373
+
374
+ /**
375
+ * @typedef {Object} RouteUnauthorizedBase
376
+ * @property {'unauthorized'} type
377
+ * @property {Array<ChallengeItem>} challenge
378
+ */
379
+ /** @typedef {RouteBase & RouteUnauthorizedBase} RouteUnauthorized */
380
+
381
+ /**
382
+ * @typedef {Object} RouteForbiddenBase
383
+ * @property {'forbidden'} type
384
+ */
385
+ /** @typedef {RouteBase & RouteForbiddenBase} RouteForbidden */
386
+
387
+ /**
388
+ * @typedef {Object} RouteTimeoutBase
389
+ * @property {'timeout'} type
390
+ */
391
+ /** @typedef {RouteBase & RouteTimeoutBase} RouteTimeout */
280
392
 
281
393
  /**
282
394
  * @typedef {Object} RouteSSEBase
@@ -307,7 +419,19 @@ export const KNOWN_METHODS = [
307
419
  RouteNotImplemented |
308
420
  RouteUnavailable |
309
421
  RoutePartialBytes |
310
- RouteNotSatisfiable
422
+ RouteNotSatisfiable |
423
+ RouteSeeOther |
424
+ RouteTemporaryRedirect |
425
+ RoutePermanentRedirect |
426
+ RouteMovedPermanently |
427
+ RouteNoContent |
428
+ RouteGone |
429
+ RouteContentTooLarge |
430
+ RouteInsufficientStorage |
431
+ RouteTooManyRequests |
432
+ RouteUnauthorized |
433
+ RouteForbidden |
434
+ RouteTimeout
311
435
  } RouteAction */
312
436
 
313
437
  /** @typedef {Record<string, string|undefined>} RouteMatches */