3 Commits

Author SHA1 Message Date
Michael Wolf
bd3779acef Fill out http codes object 2025-11-17 18:06:59 -06:00
Michael Wolf
c21638c5d5 Fill out content types object 2025-11-17 18:06:42 -06:00
Michael Wolf
d125f61c4c Stake out dir 2025-11-17 11:38:36 -06:00
3 changed files with 128 additions and 12 deletions

1
express/.gitignore vendored
View File

@@ -1 +1,2 @@
out/ out/
dist/

View File

@@ -2,8 +2,7 @@ import { Extensible } from "./interfaces";
export type ContentType = string; export type ContentType = string;
// FIXME: Fill this out (get an AI to do it) // tx claude https://claude.ai/share/344fc7bd-5321-4763-af2f-b82275e9f865
const contentTypes = { const contentTypes = {
text: { text: {
plain: "text/plain", plain: "text/plain",
@@ -11,6 +10,9 @@ const contentTypes = {
css: "text/css", css: "text/css",
javascript: "text/javascript", javascript: "text/javascript",
xml: "text/xml", xml: "text/xml",
csv: "text/csv",
markdown: "text/markdown",
calendar: "text/calendar",
}, },
image: { image: {
jpeg: "image/jpeg", jpeg: "image/jpeg",
@@ -18,23 +20,103 @@ const contentTypes = {
gif: "image/gif", gif: "image/gif",
svgPlusXml: "image/svg+xml", svgPlusXml: "image/svg+xml",
webp: "image/webp", webp: "image/webp",
bmp: "image/bmp",
ico: "image/x-icon",
tiff: "image/tiff",
avif: "image/avif",
}, },
audio: { audio: {
mpeg: "audio/mpeg", mpeg: "audio/mpeg",
wav: "audio/wav", wav: "audio/wav",
ogg: "audio/ogg",
webm: "audio/webm",
aac: "audio/aac",
midi: "audio/midi",
opus: "audio/opus",
flac: "audio/flac",
}, },
video: { video: {
mp4: "video/mp4", mp4: "video/mp4",
webm: "video/webm", webm: "video/webm",
xMsvideo: "video/x-msvideo", xMsvideo: "video/x-msvideo",
mpeg: "video/mpeg",
ogg: "video/ogg",
quicktime: "video/quicktime",
xMatroska: "video/x-matroska",
}, },
application: { application: {
json: "application/json", json: "application/json",
pdf: "application/pdf", pdf: "application/pdf",
zip: "application/zip", zip: "application/zip",
xWwwFormUrlencoded: "x-www-form-urlencoded", xWwwFormUrlencoded: "application/x-www-form-urlencoded",
octetStream: "octet-stream", octetStream: "application/octet-stream",
xml: "application/xml",
gzip: "application/gzip",
javascript: "application/javascript",
ld_json: "application/ld+json",
msword: "application/msword",
vndOpenxmlformatsOfficedocumentWordprocessingmlDocument:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
vndMsExcel: "application/vnd.ms-excel",
vndOpenxmlformatsOfficedocumentSpreadsheetmlSheet:
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
vndMsPowerpoint: "application/vnd.ms-powerpoint",
vndOpenxmlformatsOfficedocumentPresentationmlPresentation:
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
sql: "application/sql",
graphql: "application/graphql",
wasm: "application/wasm",
xTar: "application/x-tar",
x7zCompressed: "application/x-7z-compressed",
xRarCompressed: "application/x-rar-compressed",
},
multipart: {
formData: "multipart/form-data",
byteranges: "multipart/byteranges",
},
font: {
woff: "font/woff",
woff2: "font/woff2",
ttf: "font/ttf",
otf: "font/otf",
}, },
}; };
export { contentTypes }; export { contentTypes };
/*
possible additions for later
Looking at what's there, here are a few gaps that might be worth filling:
Streaming/Modern Web:
application/x-ndjson or application/jsonlines - newline-delimited JSON (popular for streaming APIs)
text/event-stream - Server-Sent Events
API/Data Exchange:
application/yaml or text/yaml - YAML files
application/protobuf - Protocol Buffers
application/msgpack - MessagePack
Archives you're missing:
application/x-bzip2 - bzip2 compression
Images:
image/heic - HEIC/HEIF (common on iOS)
Fonts:
application/vnd.ms-fontobject - EOT fonts (legacy but still seen)
Text:
text/rtf - Rich Text Format
The most impactful would probably be text/event-stream (if you do any SSE), application/x-ndjson (common in modern APIs), and maybe text/yaml. The rest are more situational.
But honestly, what you have covers 95% of common web development scenarios. You can definitely add as you go when you encounter specific needs!
*/

View File

@@ -11,33 +11,66 @@ type CodeDefinitions = {
[K: string]: HttpCode; [K: string]: HttpCode;
}; };
}; };
// FIXME: Figure out how to brand CodeDefinitions in a way that isn't
// tedious.
// tx claude https://claude.ai/share/344fc7bd-5321-4763-af2f-b82275e9f865
const httpCodes: CodeDefinitions = { const httpCodes: CodeDefinitions = {
success: { success: {
OK: { code: 200, name: "OK", description: "" }, OK: { code: 200, name: "OK", description: "" },
Created: { code: 201, name: "Created" }, Created: { code: 201, name: "Created" },
Accepted: { code: 202, name: "Accepted" }, Accepted: { code: 202, name: "Accepted" },
NoContent: { code: 204, name: "No content" }, NonAuthoritativeInformation: {
code: 203,
name: "Non-Authoritative Information",
},
NoContent: { code: 204, name: "No Content" },
ResetContent: { code: 205, name: "Reset Content" },
PartialContent: { code: 206, name: "Partial Content" },
}, },
redirection: { redirection: {
// later MultipleChoices: { code: 300, name: "Multiple Choices" },
MovedPermanently: { code: 301, name: "Moved Permanently" },
Found: { code: 302, name: "Found" },
SeeOther: { code: 303, name: "See Other" },
NotModified: { code: 304, name: "Not Modified" },
TemporaryRedirect: { code: 307, name: "Temporary Redirect" },
PermanentRedirect: { code: 308, name: "Permanent Redirect" },
}, },
clientErrors: { clientErrors: {
BadRequest: { code: 400, name: "Bad Request" }, BadRequest: { code: 400, name: "Bad Request" },
Unauthorized: { code: 401, name: "Unauthorized" }, Unauthorized: { code: 401, name: "Unauthorized" },
PaymentRequired: { code: 402, name: "Payment Required" },
Forbidden: { code: 403, name: "Forbidden" }, Forbidden: { code: 403, name: "Forbidden" },
NotFound: { code: 404, name: "Not Found" }, NotFound: { code: 404, name: "Not Found" },
MethodNotAllowed: { code: 405, name: "Method Not Allowed" }, MethodNotAllowed: { code: 405, name: "Method Not Allowed" },
NotAcceptable: { code: 406, name: "Not Acceptable" }, NotAcceptable: { code: 406, name: "Not Acceptable" },
// More later ProxyAuthenticationRequired: {
code: 407,
name: "Proxy Authentication Required",
},
RequestTimeout: { code: 408, name: "Request Timeout" },
Conflict: { code: 409, name: "Conflict" },
Gone: { code: 410, name: "Gone" },
LengthRequired: { code: 411, name: "Length Required" },
PreconditionFailed: { code: 412, name: "Precondition Failed" },
PayloadTooLarge: { code: 413, name: "Payload Too Large" },
URITooLong: { code: 414, name: "URI Too Long" },
UnsupportedMediaType: { code: 415, name: "Unsupported Media Type" },
RangeNotSatisfiable: { code: 416, name: "Range Not Satisfiable" },
ExpectationFailed: { code: 417, name: "Expectation Failed" },
ImATeapot: { code: 418, name: "I'm a teapot" },
UnprocessableEntity: { code: 422, name: "Unprocessable Entity" },
TooManyRequests: { code: 429, name: "Too Many Requests" },
}, },
serverErrors: { serverErrors: {
InternalServerError: { code: 500, name: "Internal Server Error" }, InternalServerError: { code: 500, name: "Internal Server Error" },
NotImplemented: { code: 500, name: "Not implemented" }, NotImplemented: { code: 501, name: "Not Implemented" },
// more later BadGateway: { code: 502, name: "Bad Gateway" },
ServiceUnavailable: { code: 503, name: "Service Unavailable" },
GatewayTimeout: { code: 504, name: "Gateway Timeout" },
HTTPVersionNotSupported: {
code: 505,
name: "HTTP Version Not Supported",
},
}, },
}; };
export { httpCodes }; export { httpCodes };