@sdxc/http 0.0.0-pre.1

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.
@@ -0,0 +1,486 @@
1
+ /**
2
+ * HTTP status code constants, each pairing a numeric status with its
3
+ * standard status text for use as a `Response` init.
4
+ * @author [Sergio Xalambrí](https://sergiodxa.com)
5
+ * @copyright Sergio Xalambrí 2026
6
+ */
7
+ /**
8
+ * HTTP 100 Continue status.
9
+ * Indicates the initial part of a request has been received and the client
10
+ * should continue with the request or ignore if already complete.
11
+ * @example
12
+ * return new Response(null, Continue);
13
+ * @example
14
+ * return Response.json({ message: "Continue sending" }, Continue);
15
+ */
16
+ export const Continue = { status: 100, statusText: "Continue" };
17
+ /**
18
+ * HTTP 101 Switching Protocols status.
19
+ * Indicates the server is switching to a different protocol as requested
20
+ * by the client via the Upgrade header.
21
+ * @example
22
+ * return new Response(null, SwitchingProtocols);
23
+ * @example
24
+ * return new Response(null, { ...SwitchingProtocols, headers: { Upgrade: "websocket" } });
25
+ */
26
+ export const SwitchingProtocols = { status: 101, statusText: "Switching Protocols" };
27
+ /**
28
+ * HTTP 200 OK status.
29
+ * Indicates the request succeeded. The meaning varies by HTTP method:
30
+ * GET returns the resource, POST returns the result of the action.
31
+ * @example
32
+ * return new Response(null, Ok);
33
+ * @example
34
+ * return Response.json({ data: result }, Ok);
35
+ */
36
+ export const Ok = { status: 200, statusText: "OK" };
37
+ /**
38
+ * HTTP 201 Created status.
39
+ * Indicates the request succeeded and a new resource was created.
40
+ * Typically used after POST or PUT requests.
41
+ * @example
42
+ * return new Response(null, Created);
43
+ * @example
44
+ * return Response.json({ id: newUser.id }, Created);
45
+ */
46
+ export const Created = { status: 201, statusText: "Created" };
47
+ /**
48
+ * HTTP 202 Accepted status.
49
+ * Indicates the request has been accepted for processing but processing
50
+ * has not been completed. Used for asynchronous operations.
51
+ * @example
52
+ * return new Response(null, Accepted);
53
+ * @example
54
+ * return Response.json({ jobId: "abc123" }, Accepted);
55
+ */
56
+ export const Accepted = { status: 202, statusText: "Accepted" };
57
+ /**
58
+ * HTTP 204 No Content status.
59
+ * Indicates the request succeeded but there is no content to return.
60
+ * Commonly used for DELETE operations or updates that don't return data.
61
+ * @example
62
+ * return new Response(null, NoContent);
63
+ * @example
64
+ * await deleteUser(id); return new Response(null, NoContent);
65
+ */
66
+ export const NoContent = { status: 204, statusText: "No Content" };
67
+ /**
68
+ * HTTP 205 Reset Content status.
69
+ * Indicates the request succeeded and the client should reset the document
70
+ * view. Used to clear forms after submission.
71
+ * @example
72
+ * return new Response(null, ResetContent);
73
+ * @example
74
+ * await submitForm(data); return new Response(null, ResetContent);
75
+ */
76
+ export const ResetContent = { status: 205, statusText: "Reset Content" };
77
+ /**
78
+ * HTTP 206 Partial Content status.
79
+ * Indicates the server is delivering only part of the resource due to a
80
+ * range header sent by the client. Used for resumable downloads.
81
+ * @example
82
+ * return new Response(chunk, PartialContent);
83
+ * @example
84
+ * return new Response(videoChunk, { ...PartialContent, headers: { "Content-Range": "bytes 0-999/5000" } });
85
+ */
86
+ export const PartialContent = { status: 206, statusText: "Partial Content" };
87
+ /**
88
+ * HTTP 300 Multiple Choices status.
89
+ * Indicates multiple options for the resource. The client may choose one
90
+ * or the server may provide a preferred option.
91
+ * @example
92
+ * return new Response(null, MultipleChoices);
93
+ * @example
94
+ * return Response.json({ options: ["/en/page", "/es/page"] }, MultipleChoices);
95
+ */
96
+ export const MultipleChoices = { status: 300, statusText: "Multiple Choices" };
97
+ /**
98
+ * HTTP 301 Moved Permanently status.
99
+ * Indicates the resource has been permanently moved to a new URL.
100
+ * Search engines will update their links to the new location.
101
+ * @example
102
+ * return new Response(null, { ...MovedPermanently, headers: { Location: "/new-path" } });
103
+ * @example
104
+ * return Response.redirect("/new-url", MovedPermanently.status);
105
+ */
106
+ export const MovedPermanently = { status: 301, statusText: "Moved Permanently" };
107
+ /**
108
+ * HTTP 302 Found status.
109
+ * Indicates the resource temporarily resides at a different URL.
110
+ * The client should continue using the original URL for future requests.
111
+ * @example
112
+ * return new Response(null, { ...Found, headers: { Location: "/temp-path" } });
113
+ * @example
114
+ * return Response.redirect("/temporary-url", Found.status);
115
+ */
116
+ export const Found = { status: 302, statusText: "Found" };
117
+ /**
118
+ * HTTP 303 See Other status.
119
+ * Indicates the response can be found at another URL using a GET request.
120
+ * Often used after POST to redirect to a confirmation page.
121
+ * @example
122
+ * return new Response(null, { ...SeeOther, headers: { Location: "/success" } });
123
+ * @example
124
+ * return Response.redirect("/confirmation", SeeOther.status);
125
+ */
126
+ export const SeeOther = { status: 303, statusText: "See Other" };
127
+ /**
128
+ * HTTP 304 Not Modified status.
129
+ * Indicates the resource has not been modified since the last request.
130
+ * Used for caching when If-Modified-Since or If-None-Match headers are sent.
131
+ * @example
132
+ * return new Response(null, NotModified);
133
+ * @example
134
+ * if (etag === request.headers.get("If-None-Match")) return new Response(null, NotModified);
135
+ */
136
+ export const NotModified = { status: 304, statusText: "Not Modified" };
137
+ /**
138
+ * HTTP 307 Temporary Redirect status.
139
+ * Indicates a temporary redirect that preserves the request method.
140
+ * @example
141
+ * return new Response(null, { ...TemporaryRedirect, headers: { Location: "/temp" } });
142
+ * @example
143
+ * return Response.redirect("/maintenance", TemporaryRedirect.status);
144
+ */
145
+ export const TemporaryRedirect = { status: 307, statusText: "Temporary Redirect" };
146
+ /**
147
+ * HTTP 308 Permanent Redirect status.
148
+ * Indicates a permanent redirect that preserves the request method.
149
+ * @example
150
+ * return new Response(null, { ...PermanentRedirect, headers: { Location: "/new" } });
151
+ * @example
152
+ * return Response.redirect("/new-api", PermanentRedirect.status);
153
+ */
154
+ export const PermanentRedirect = { status: 308, statusText: "Permanent Redirect" };
155
+ /**
156
+ * HTTP 400 Bad Request status.
157
+ * Indicates the server cannot process the request due to client error,
158
+ * such as malformed syntax or invalid parameters.
159
+ * @example
160
+ * return new Response(null, BadRequest);
161
+ * @example
162
+ * return Response.json({ error: "Invalid JSON" }, BadRequest);
163
+ */
164
+ export const BadRequest = { status: 400, statusText: "Bad Request" };
165
+ /**
166
+ * HTTP 401 Unauthorized status.
167
+ * Indicates the request requires authentication. The client must
168
+ * authenticate itself to get the requested response.
169
+ * @example
170
+ * return new Response(null, Unauthorized);
171
+ * @example
172
+ * return Response.json({ error: "Login required" }, Unauthorized);
173
+ */
174
+ export const Unauthorized = { status: 401, statusText: "Unauthorized" };
175
+ /**
176
+ * HTTP 402 Payment Required status.
177
+ * Reserved for future use. Originally intended for digital payment systems,
178
+ * sometimes used to indicate a feature requires payment.
179
+ * @example
180
+ * return new Response(null, PaymentRequired);
181
+ * @example
182
+ * return Response.json({ error: "Subscription required" }, PaymentRequired);
183
+ */
184
+ export const PaymentRequired = { status: 402, statusText: "Payment Required" };
185
+ /**
186
+ * HTTP 403 Forbidden status.
187
+ * Indicates the server understood the request but refuses to authorize it.
188
+ * Unlike 401, authentication will not help.
189
+ * @example
190
+ * return new Response(null, Forbidden);
191
+ * @example
192
+ * return Response.json({ error: "Access denied" }, Forbidden);
193
+ */
194
+ export const Forbidden = { status: 403, statusText: "Forbidden" };
195
+ /**
196
+ * HTTP 404 Not Found status.
197
+ * Indicates the requested resource could not be found on the server.
198
+ * The resource may have been removed or the URL is incorrect.
199
+ * @example
200
+ * return new Response(null, NotFound);
201
+ * @example
202
+ * return Response.json({ error: "User not found" }, NotFound);
203
+ */
204
+ export const NotFound = { status: 404, statusText: "Not Found" };
205
+ /**
206
+ * HTTP 405 Method Not Allowed status.
207
+ * Indicates the request method is not supported for the target resource.
208
+ * The response must include an Allow header with valid methods.
209
+ * @example
210
+ * return new Response(null, MethodNotAllowed);
211
+ * @example
212
+ * return new Response(null, { ...MethodNotAllowed, headers: { Allow: "GET, POST" } });
213
+ */
214
+ export const MethodNotAllowed = { status: 405, statusText: "Method Not Allowed" };
215
+ /**
216
+ * HTTP 406 Not Acceptable status.
217
+ * Indicates the server cannot produce a response matching the Accept
218
+ * headers sent by the client.
219
+ * @example
220
+ * return new Response(null, NotAcceptable);
221
+ * @example
222
+ * return Response.json({ error: "Cannot produce requested format" }, NotAcceptable);
223
+ */
224
+ export const NotAcceptable = { status: 406, statusText: "Not Acceptable" };
225
+ /**
226
+ * HTTP 407 Proxy Authentication Required status.
227
+ * Indicates the client must authenticate with a proxy server before
228
+ * this request can be served.
229
+ * @example
230
+ * return new Response(null, ProxyAuthRequired);
231
+ * @example
232
+ * return new Response(null, { ...ProxyAuthRequired, headers: { "Proxy-Authenticate": "Basic" } });
233
+ */
234
+ export const ProxyAuthRequired = {
235
+ status: 407,
236
+ statusText: "Proxy Authentication Required",
237
+ };
238
+ /**
239
+ * HTTP 408 Request Timeout status.
240
+ * Indicates the server timed out waiting for the request. The client
241
+ * may repeat the request without modifications.
242
+ * @example
243
+ * return new Response(null, RequestTimeout);
244
+ * @example
245
+ * return Response.json({ error: "Request took too long" }, RequestTimeout);
246
+ */
247
+ export const RequestTimeout = { status: 408, statusText: "Request Timeout" };
248
+ /**
249
+ * HTTP 409 Conflict status.
250
+ * Indicates the request conflicts with the current state of the server.
251
+ * Often used for concurrent modification errors.
252
+ * @example
253
+ * return new Response(null, Conflict);
254
+ * @example
255
+ * return Response.json({ error: "Resource already exists" }, Conflict);
256
+ */
257
+ export const Conflict = { status: 409, statusText: "Conflict" };
258
+ /**
259
+ * HTTP 410 Gone status.
260
+ * Indicates the resource is no longer available and will not be available
261
+ * again. Unlike 404, this is permanent.
262
+ * @example
263
+ * return new Response(null, Gone);
264
+ * @example
265
+ * return Response.json({ error: "Resource permanently removed" }, Gone);
266
+ */
267
+ export const Gone = { status: 410, statusText: "Gone" };
268
+ /**
269
+ * HTTP 411 Length Required status.
270
+ * Indicates the server requires a Content-Length header in the request.
271
+ * The client should resend with the header included.
272
+ * @example
273
+ * return new Response(null, LengthRequired);
274
+ * @example
275
+ * return Response.json({ error: "Content-Length header required" }, LengthRequired);
276
+ */
277
+ export const LengthRequired = { status: 411, statusText: "Length Required" };
278
+ /**
279
+ * HTTP 412 Precondition Failed status.
280
+ * Indicates one or more conditions in the request headers evaluated to
281
+ * false. Used with conditional requests.
282
+ * @example
283
+ * return new Response(null, PreconditionFailed);
284
+ * @example
285
+ * return Response.json({ error: "If-Match condition failed" }, PreconditionFailed);
286
+ */
287
+ export const PreconditionFailed = { status: 412, statusText: "Precondition Failed" };
288
+ /**
289
+ * HTTP 413 Payload Too Large status.
290
+ * Indicates the request entity is larger than the server is willing or
291
+ * able to process.
292
+ * @example
293
+ * return new Response(null, PayloadTooLarge);
294
+ * @example
295
+ * return Response.json({ error: "File exceeds 10MB limit" }, PayloadTooLarge);
296
+ */
297
+ export const PayloadTooLarge = { status: 413, statusText: "Payload Too Large" };
298
+ /**
299
+ * HTTP 414 URI Too Long status.
300
+ * Indicates the URI requested by the client is longer than the server
301
+ * is willing to interpret.
302
+ * @example
303
+ * return new Response(null, URITooLong);
304
+ * @example
305
+ * return Response.json({ error: "URL exceeds maximum length" }, URITooLong);
306
+ */
307
+ export const URITooLong = { status: 414, statusText: "URI Too Long" };
308
+ /**
309
+ * HTTP 415 Unsupported Media Type status.
310
+ * Indicates the media format of the request data is not supported by
311
+ * the server.
312
+ * @example
313
+ * return new Response(null, UnsupportedMediaType);
314
+ * @example
315
+ * return Response.json({ error: "Content-Type must be application/json" }, UnsupportedMediaType);
316
+ */
317
+ export const UnsupportedMediaType = { status: 415, statusText: "Unsupported Media Type" };
318
+ /**
319
+ * HTTP 416 Range Not Satisfiable status.
320
+ * Indicates the range specified in the Range header cannot be fulfilled.
321
+ * The range may be outside the target resource's size.
322
+ * @example
323
+ * return new Response(null, RangeNotSatisfiable);
324
+ * @example
325
+ * return new Response(null, { ...RangeNotSatisfiable, headers: { "Content-Range": "bytes 0-0/5000" } });
326
+ */
327
+ export const RangeNotSatisfiable = { status: 416, statusText: "Range Not Satisfiable" };
328
+ /**
329
+ * HTTP 417 Expectation Failed status.
330
+ * Indicates the expectation in the Expect request header cannot be met
331
+ * by the server.
332
+ * @example
333
+ * return new Response(null, ExpectationFailed);
334
+ * @example
335
+ * return Response.json({ error: "Cannot meet expectation" }, ExpectationFailed);
336
+ */
337
+ export const ExpectationFailed = { status: 417, statusText: "Expectation Failed" };
338
+ /**
339
+ * HTTP 418 I'm a teapot status.
340
+ * A playful response defined in RFC 2324. The server refuses to brew
341
+ * coffee because it is a teapot.
342
+ * @example
343
+ * return new Response(null, ImATeapot);
344
+ * @example
345
+ * return Response.json({ error: "I'm a teapot, not a coffee maker" }, ImATeapot);
346
+ */
347
+ export const ImATeapot = { status: 418, statusText: "I'm a teapot" };
348
+ /**
349
+ * HTTP 422 Unprocessable Entity status.
350
+ * Indicates the request was well-formed but contained semantic errors.
351
+ * Commonly used for validation failures.
352
+ * @example
353
+ * return new Response(null, UnprocessableEntity);
354
+ * @example
355
+ * return Response.json({ errors: { email: "Invalid format" } }, UnprocessableEntity);
356
+ */
357
+ export const UnprocessableEntity = { status: 422, statusText: "Unprocessable Entity" };
358
+ /**
359
+ * HTTP 425 Too Early status.
360
+ * Indicates the server is unwilling to process a request that might be
361
+ * replayed to avoid potential replay attacks.
362
+ * @example
363
+ * return new Response(null, TooEarly);
364
+ * @example
365
+ * return Response.json({ error: "Request sent too early" }, TooEarly);
366
+ */
367
+ export const TooEarly = { status: 425, statusText: "Too Early" };
368
+ /**
369
+ * HTTP 426 Upgrade Required status.
370
+ * Indicates the server refuses to perform the request using the current
371
+ * protocol but might after the client upgrades.
372
+ * @example
373
+ * return new Response(null, UpgradeRequired);
374
+ * @example
375
+ * return new Response(null, { ...UpgradeRequired, headers: { Upgrade: "TLS/1.3" } });
376
+ */
377
+ export const UpgradeRequired = { status: 426, statusText: "Upgrade Required" };
378
+ /**
379
+ * HTTP 428 Precondition Required status.
380
+ * Indicates the server requires the request to be conditional to prevent
381
+ * lost update problems.
382
+ * @example
383
+ * return new Response(null, PreconditionRequired);
384
+ * @example
385
+ * return Response.json({ error: "If-Match header required" }, PreconditionRequired);
386
+ */
387
+ export const PreconditionRequired = { status: 428, statusText: "Precondition Required" };
388
+ /**
389
+ * HTTP 429 Too Many Requests status.
390
+ * Indicates the user has sent too many requests in a given amount of time.
391
+ * Used for rate limiting.
392
+ * @example
393
+ * return new Response(null, TooManyRequests);
394
+ * @example
395
+ * return new Response(null, { ...TooManyRequests, headers: { "Retry-After": "60" } });
396
+ */
397
+ export const TooManyRequests = { status: 429, statusText: "Too Many Requests" };
398
+ /**
399
+ * HTTP 431 Request Header Fields Too Large status.
400
+ * Indicates the server is unwilling to process the request because the
401
+ * header fields are too large.
402
+ * @example
403
+ * return new Response(null, RequestHeaderFieldsTooLarge);
404
+ * @example
405
+ * return Response.json({ error: "Headers exceed size limit" }, RequestHeaderFieldsTooLarge);
406
+ */
407
+ export const RequestHeaderFieldsTooLarge = {
408
+ status: 431,
409
+ statusText: "Request Header Fields Too Large",
410
+ };
411
+ /**
412
+ * HTTP 451 Unavailable For Legal Reasons status.
413
+ * Indicates the resource is unavailable due to legal demands such as
414
+ * censorship or government-mandated blocks.
415
+ * @example
416
+ * return new Response(null, UnavailableForLegalReasons);
417
+ * @example
418
+ * return Response.json({ error: "Content blocked in your region" }, UnavailableForLegalReasons);
419
+ */
420
+ export const UnavailableForLegalReasons = {
421
+ status: 451,
422
+ statusText: "Unavailable For Legal Reasons",
423
+ };
424
+ /**
425
+ * HTTP 500 Internal Server Error status.
426
+ * Indicates the server encountered an unexpected condition that prevented
427
+ * it from fulfilling the request.
428
+ * @example
429
+ * return new Response(null, InternalServerError);
430
+ * @example
431
+ * return Response.json({ error: "Something went wrong" }, InternalServerError);
432
+ */
433
+ export const InternalServerError = { status: 500, statusText: "Internal Server Error" };
434
+ /**
435
+ * HTTP 501 Not Implemented status.
436
+ * Indicates the server does not support the functionality required to
437
+ * fulfill the request.
438
+ * @example
439
+ * return new Response(null, NotImplemented);
440
+ * @example
441
+ * return Response.json({ error: "Feature not implemented" }, NotImplemented);
442
+ */
443
+ export const NotImplemented = { status: 501, statusText: "Not Implemented" };
444
+ /**
445
+ * HTTP 502 Bad Gateway status.
446
+ * Indicates the server received an invalid response from an upstream
447
+ * server while acting as a gateway or proxy.
448
+ * @example
449
+ * return new Response(null, BadGateway);
450
+ * @example
451
+ * return Response.json({ error: "Upstream server error" }, BadGateway);
452
+ */
453
+ export const BadGateway = { status: 502, statusText: "Bad Gateway" };
454
+ /**
455
+ * HTTP 503 Service Unavailable status.
456
+ * Indicates the server is not ready to handle the request, often due to
457
+ * maintenance or overload.
458
+ * @example
459
+ * return new Response(null, ServiceUnavailable);
460
+ * @example
461
+ * return new Response(null, { ...ServiceUnavailable, headers: { "Retry-After": "3600" } });
462
+ */
463
+ export const ServiceUnavailable = { status: 503, statusText: "Service Unavailable" };
464
+ /**
465
+ * HTTP 504 Gateway Timeout status.
466
+ * Indicates the server acting as a gateway did not receive a timely
467
+ * response from the upstream server.
468
+ * @example
469
+ * return new Response(null, GatewayTimeout);
470
+ * @example
471
+ * return Response.json({ error: "Upstream server timed out" }, GatewayTimeout);
472
+ */
473
+ export const GatewayTimeout = { status: 504, statusText: "Gateway Timeout" };
474
+ /**
475
+ * HTTP 505 HTTP Version Not Supported status.
476
+ * Indicates the server does not support the HTTP protocol version used
477
+ * in the request.
478
+ * @example
479
+ * return new Response(null, HTTPVersionNotSupported);
480
+ * @example
481
+ * return Response.json({ error: "HTTP version not supported" }, HTTPVersionNotSupported);
482
+ */
483
+ export const HTTPVersionNotSupported = {
484
+ status: 505,
485
+ statusText: "HTTP Version Not Supported",
486
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@sdxc/http",
3
+ "version": "0.0.0-pre.1",
4
+ "description": "Response builders, content negotiation, and HTTP caching for the Fetch API",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ "./content-type": "./dist/content-type.js",
9
+ "./status-code": "./dist/status-code.js",
10
+ "./response": "./dist/response.js",
11
+ "./response/json": "./dist/response/json.js",
12
+ "./response/html": "./dist/response/html.js",
13
+ "./negotiate": "./dist/negotiate.js",
14
+ "./cache": "./dist/cache/index.js",
15
+ "./middleware/head-requests": "./dist/middleware/head-requests.js"
16
+ },
17
+ "dependencies": {
18
+ "@sdxc/crypto": "2026.9.11",
19
+ "@sdxc/duration": "2026.9.11",
20
+ "@sdxc/location": "2026.9.11",
21
+ "@sdxc/result": "2026.9.11",
22
+ "remix": "3.0.0-rc.2"
23
+ },
24
+ "gitHead": "e96a064f9208eb667923f57374e2cdaac73c72fb",
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/sergiodxa/monorepo.git",
31
+ "directory": "packages/http"
32
+ }
33
+ }