@ozanarslan/corpus 0.0.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.
- package/LICENSE.txt +20 -0
- package/README.md +337 -0
- package/dist/App/index.d.ts +377 -0
- package/dist/App/index.d.ts.map +1 -0
- package/dist/C.namespace.d.ts +27 -0
- package/dist/C.namespace.d.ts.map +1 -0
- package/dist/Config/index.d.ts +163 -0
- package/dist/Config/index.d.ts.map +1 -0
- package/dist/Context/ContextAccess/index.d.ts +50 -0
- package/dist/Context/ContextAccess/index.d.ts.map +1 -0
- package/dist/Context/index.d.ts +162 -0
- package/dist/Context/index.d.ts.map +1 -0
- package/dist/Controller/index.d.ts +164 -0
- package/dist/Controller/index.d.ts.map +1 -0
- package/dist/Cookies/index.d.ts +81 -0
- package/dist/Cookies/index.d.ts.map +1 -0
- package/dist/Cors/index.d.ts +135 -0
- package/dist/Cors/index.d.ts.map +1 -0
- package/dist/Exception/index.d.ts +85 -0
- package/dist/Exception/index.d.ts.map +1 -0
- package/dist/Globals/AppsRegistry/index.d.ts +48 -0
- package/dist/Globals/AppsRegistry/index.d.ts.map +1 -0
- package/dist/Globals/ParsersRegistry/index.d.ts +93 -0
- package/dist/Globals/ParsersRegistry/index.d.ts.map +1 -0
- package/dist/Globals/index.d.ts +109 -0
- package/dist/Globals/index.d.ts.map +1 -0
- package/dist/Headers/index.d.ts +208 -0
- package/dist/Headers/index.d.ts.map +1 -0
- package/dist/Middleware/index.d.ts +125 -0
- package/dist/Middleware/index.d.ts.map +1 -0
- package/dist/ParserBase/BodyParser/index.d.ts +138 -0
- package/dist/ParserBase/BodyParser/index.d.ts.map +1 -0
- package/dist/ParserBase/FormDataParser/index.d.ts +57 -0
- package/dist/ParserBase/FormDataParser/index.d.ts.map +1 -0
- package/dist/ParserBase/SchemaParser/index.d.ts +143 -0
- package/dist/ParserBase/SchemaParser/index.d.ts.map +1 -0
- package/dist/ParserBase/SearchParamsParser/index.d.ts +61 -0
- package/dist/ParserBase/SearchParamsParser/index.d.ts.map +1 -0
- package/dist/ParserBase/URLParamsParser/index.d.ts +32 -0
- package/dist/ParserBase/URLParamsParser/index.d.ts.map +1 -0
- package/dist/ParserBase/index.d.ts +92 -0
- package/dist/ParserBase/index.d.ts.map +1 -0
- package/dist/RateLimiter/index.d.ts +321 -0
- package/dist/RateLimiter/index.d.ts.map +1 -0
- package/dist/Request/index.d.ts +81 -0
- package/dist/Request/index.d.ts.map +1 -0
- package/dist/Res/index.d.ts +353 -0
- package/dist/Res/index.d.ts.map +1 -0
- package/dist/RouteBase/BundleRoute/index.d.ts +268 -0
- package/dist/RouteBase/BundleRoute/index.d.ts.map +1 -0
- package/dist/RouteBase/FileRoute/index.d.ts +121 -0
- package/dist/RouteBase/FileRoute/index.d.ts.map +1 -0
- package/dist/RouteBase/Route/index.d.ts +83 -0
- package/dist/RouteBase/Route/index.d.ts.map +1 -0
- package/dist/RouteBase/StaticRoute/index.d.ts +149 -0
- package/dist/RouteBase/StaticRoute/index.d.ts.map +1 -0
- package/dist/RouteBase/WebSocketRoute/index.d.ts +117 -0
- package/dist/RouteBase/WebSocketRoute/index.d.ts.map +1 -0
- package/dist/RouteBase/index.d.ts +206 -0
- package/dist/RouteBase/index.d.ts.map +1 -0
- package/dist/Server/index.d.ts +44 -0
- package/dist/Server/index.d.ts.map +1 -0
- package/dist/XFile/index.d.ts +202 -0
- package/dist/XFile/index.d.ts.map +1 -0
- package/dist/exports.d.ts +11 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +47 -0
- package/dist/initialize.d.ts +22 -0
- package/dist/initialize.d.ts.map +1 -0
- package/dist/utils/assert.d.ts +7 -0
- package/dist/utils/assert.d.ts.map +1 -0
- package/dist/utils/is.d.ts +17 -0
- package/dist/utils/is.d.ts.map +1 -0
- package/dist/utils/lazy.d.ts +27 -0
- package/dist/utils/lazy.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +31 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/object.d.ts +20 -0
- package/dist/utils/object.d.ts.map +1 -0
- package/dist/utils/path.d.ts +6 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/tuple.d.ts +3 -0
- package/dist/utils/tuple.d.ts.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response building: status codes, body serialization, streaming, and cookies.
|
|
3
|
+
*
|
|
4
|
+
* A {@link Res} is what a handler shapes on its way to a native `Response`. It
|
|
5
|
+
* is created lazily on {@link Context.res}, so a handler that just returns a
|
|
6
|
+
* value never constructs one; reach for it when the response needs a status,
|
|
7
|
+
* headers, cookies, or a body form that a plain return value cannot express —
|
|
8
|
+
* a file, a redirect, or a stream.
|
|
9
|
+
*
|
|
10
|
+
* Body serialization is inferred from the value's type at
|
|
11
|
+
* {@link Res.toNativeResponse} time, so an object becomes JSON, a typed array
|
|
12
|
+
* stays binary, and a stream passes through untouched — each with a matching
|
|
13
|
+
* `Content-Type` unless one was set explicitly.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { Res, Status } from "@ozanarslan/corpus";
|
|
17
|
+
*
|
|
18
|
+
* new Res({ id: 1 }, { status: Status.CREATED });
|
|
19
|
+
* new Res().file("./report.pdf");
|
|
20
|
+
* new Res().redirect("/login");
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @module Res
|
|
24
|
+
*/
|
|
25
|
+
import { Cookies } from "../Cookies";
|
|
26
|
+
import { type ContentDispositionDefinition } from "../Headers";
|
|
27
|
+
import { type MaybePromise, type Nullable } from "../utils/is";
|
|
28
|
+
import type { ValueOf } from "../utils/object";
|
|
29
|
+
import { XFile } from "../XFile";
|
|
30
|
+
/** Commonly used HTTP status codes. */
|
|
31
|
+
declare const Status: {
|
|
32
|
+
/** Continue: Request received, please continue */
|
|
33
|
+
readonly CONTINUE: 100;
|
|
34
|
+
/** Switching Protocols: Protocol change request approved */
|
|
35
|
+
readonly SWITCHING_PROTOCOLS: 101;
|
|
36
|
+
/** Processing (WebDAV) */
|
|
37
|
+
readonly PROCESSING: 102;
|
|
38
|
+
/** Early Hints */
|
|
39
|
+
readonly EARLY_HINTS: 103;
|
|
40
|
+
/** OK: Request succeeded */
|
|
41
|
+
readonly OK: 200;
|
|
42
|
+
/** Created: Resource created */
|
|
43
|
+
readonly CREATED: 201;
|
|
44
|
+
/** Accepted: Request accepted but not completed */
|
|
45
|
+
readonly ACCEPTED: 202;
|
|
46
|
+
/** Non-Authoritative Information */
|
|
47
|
+
readonly NON_AUTHORITATIVE_INFORMATION: 203;
|
|
48
|
+
/** No Content: Request succeeded, no body returned */
|
|
49
|
+
readonly NO_CONTENT: 204;
|
|
50
|
+
/** Reset Content: Clear form or view */
|
|
51
|
+
readonly RESET_CONTENT: 205;
|
|
52
|
+
/** Partial Content: Partial GET successful (e.g. range requests) */
|
|
53
|
+
readonly PARTIAL_CONTENT: 206;
|
|
54
|
+
/** Multi-Status (WebDAV) */
|
|
55
|
+
readonly MULTI_STATUS: 207;
|
|
56
|
+
/** Already Reported (WebDAV) */
|
|
57
|
+
readonly ALREADY_REPORTED: 208;
|
|
58
|
+
/** IM Used (HTTP Delta encoding) */
|
|
59
|
+
readonly IM_USED: 226;
|
|
60
|
+
/** Multiple Choices */
|
|
61
|
+
readonly MULTIPLE_CHOICES: 300;
|
|
62
|
+
/** Moved Permanently: Resource moved to a new URL */
|
|
63
|
+
readonly MOVED_PERMANENTLY: 301;
|
|
64
|
+
/** Found: Resource temporarily under different URI */
|
|
65
|
+
readonly FOUND: 302;
|
|
66
|
+
/** See Other: Redirect to another URI using GET */
|
|
67
|
+
readonly SEE_OTHER: 303;
|
|
68
|
+
/** Not Modified: Cached version is still valid */
|
|
69
|
+
readonly NOT_MODIFIED: 304;
|
|
70
|
+
/** Use Proxy: Deprecated */
|
|
71
|
+
readonly USE_PROXY: 305;
|
|
72
|
+
/** Temporary Redirect: Resource temporarily at another URI */
|
|
73
|
+
readonly TEMPORARY_REDIRECT: 307;
|
|
74
|
+
/** Permanent Redirect: Resource permanently at another URI */
|
|
75
|
+
readonly PERMANENT_REDIRECT: 308;
|
|
76
|
+
/** Bad Request: Malformed request */
|
|
77
|
+
readonly BAD_REQUEST: 400;
|
|
78
|
+
/** Unauthorized: Missing or invalid auth credentials */
|
|
79
|
+
readonly UNAUTHORIZED: 401;
|
|
80
|
+
/** Payment Required: Reserved for future use */
|
|
81
|
+
readonly PAYMENT_REQUIRED: 402;
|
|
82
|
+
/** Forbidden: Authenticated but no permission */
|
|
83
|
+
readonly FORBIDDEN: 403;
|
|
84
|
+
/** Not Found: Resource does not exist */
|
|
85
|
+
readonly NOT_FOUND: 404;
|
|
86
|
+
/** Method Not Allowed: HTTP method not allowed */
|
|
87
|
+
readonly METHOD_NOT_ALLOWED: 405;
|
|
88
|
+
/** Not Acceptable: Response not acceptable by client */
|
|
89
|
+
readonly NOT_ACCEPTABLE: 406;
|
|
90
|
+
/** Proxy Authentication Required */
|
|
91
|
+
readonly PROXY_AUTHENTICATION_REQUIRED: 407;
|
|
92
|
+
/** Request Timeout: Server timeout waiting for client */
|
|
93
|
+
readonly REQUEST_TIMEOUT: 408;
|
|
94
|
+
/** Conflict: Request conflict (e.g. duplicate resource) */
|
|
95
|
+
readonly CONFLICT: 409;
|
|
96
|
+
/** Gone: Resource is no longer available */
|
|
97
|
+
readonly GONE: 410;
|
|
98
|
+
/** Length Required: Missing Content-Length header */
|
|
99
|
+
readonly LENGTH_REQUIRED: 411;
|
|
100
|
+
/** Precondition Failed */
|
|
101
|
+
readonly PRECONDITION_FAILED: 412;
|
|
102
|
+
/** Payload Too Large */
|
|
103
|
+
readonly PAYLOAD_TOO_LARGE: 413;
|
|
104
|
+
/** URI Too Long */
|
|
105
|
+
readonly URI_TOO_LONG: 414;
|
|
106
|
+
/** Unsupported Media Type */
|
|
107
|
+
readonly UNSUPPORTED_MEDIA_TYPE: 415;
|
|
108
|
+
/** Range Not Satisfiable */
|
|
109
|
+
readonly RANGE_NOT_SATISFIABLE: 416;
|
|
110
|
+
/** Expectation Failed */
|
|
111
|
+
readonly EXPECTATION_FAILED: 417;
|
|
112
|
+
/** I'm a teapot: Joke response for coffee machines */
|
|
113
|
+
readonly IM_A_TEAPOT: 418;
|
|
114
|
+
/** Misdirected Request: Sent to the wrong server */
|
|
115
|
+
readonly MISDIRECTED_REQUEST: 421;
|
|
116
|
+
/** Unprocessable Entity (WebDAV) */
|
|
117
|
+
readonly UNPROCESSABLE_ENTITY: 422;
|
|
118
|
+
/** Locked (WebDAV) */
|
|
119
|
+
readonly LOCKED: 423;
|
|
120
|
+
/** Failed Dependency (WebDAV) */
|
|
121
|
+
readonly FAILED_DEPENDENCY: 424;
|
|
122
|
+
/** Too Early: Request might be replayed */
|
|
123
|
+
readonly TOO_EARLY: 425;
|
|
124
|
+
/** Upgrade Required */
|
|
125
|
+
readonly UPGRADE_REQUIRED: 426;
|
|
126
|
+
/** Precondition Required */
|
|
127
|
+
readonly PRECONDITION_REQUIRED: 428;
|
|
128
|
+
/** Too Many Requests: Rate limiting */
|
|
129
|
+
readonly TOO_MANY_REQUESTS: 429;
|
|
130
|
+
/** Request Header Fields Too Large */
|
|
131
|
+
readonly REQUEST_HEADER_FIELDS_TOO_LARGE: 431;
|
|
132
|
+
/** Unavailable For Legal Reasons */
|
|
133
|
+
readonly UNAVAILABLE_FOR_LEGAL_REASONS: 451;
|
|
134
|
+
/** Internal Server Error: Unhandled server error */
|
|
135
|
+
readonly INTERNAL_SERVER_ERROR: 500;
|
|
136
|
+
/** Not Implemented: Endpoint/method not implemented */
|
|
137
|
+
readonly NOT_IMPLEMENTED: 501;
|
|
138
|
+
/** Bad Gateway: Invalid response from upstream server */
|
|
139
|
+
readonly BAD_GATEWAY: 502;
|
|
140
|
+
/** Service Unavailable: Server temporarily overloaded/down */
|
|
141
|
+
readonly SERVICE_UNAVAILABLE: 503;
|
|
142
|
+
/** Gateway Timeout: No response from upstream server */
|
|
143
|
+
readonly GATEWAY_TIMEOUT: 504;
|
|
144
|
+
/** HTTP Version Not Supported */
|
|
145
|
+
readonly HTTP_VERSION_NOT_SUPPORTED: 505;
|
|
146
|
+
/** Variant Also Negotiates */
|
|
147
|
+
readonly VARIANT_ALSO_NEGOTIATES: 506;
|
|
148
|
+
/** Insufficient Storage (WebDAV) */
|
|
149
|
+
readonly INSUFFICIENT_STORAGE: 507;
|
|
150
|
+
/** Loop Detected (WebDAV) */
|
|
151
|
+
readonly LOOP_DETECTED: 508;
|
|
152
|
+
/** Not Extended */
|
|
153
|
+
readonly NOT_EXTENDED: 510;
|
|
154
|
+
/** Network Authentication Required */
|
|
155
|
+
readonly NETWORK_AUTHENTICATION_REQUIRED: 511;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* An HTTP status code. The {@link Status} constants are suggested, but any
|
|
159
|
+
* number is assignable.
|
|
160
|
+
*/
|
|
161
|
+
type Status = ValueOf<typeof Status> | (number & {});
|
|
162
|
+
/**
|
|
163
|
+
* Produces the events for a server-sent event stream, used by {@link Res.sse}.
|
|
164
|
+
*
|
|
165
|
+
* @param send - Emits one event. `data` is JSON-serialized; `event` names the
|
|
166
|
+
* event type for a client listening on something other than `message`, and `id`
|
|
167
|
+
* lets a client resume from where it left off.
|
|
168
|
+
* @returns Nothing when the source is finite — the stream is closed for you once
|
|
169
|
+
* it resolves — or a cleanup function when it is open-ended, in which case the
|
|
170
|
+
* stream stays open and the function runs if the client disconnects.
|
|
171
|
+
*/
|
|
172
|
+
type SseSource = (send: (item: {
|
|
173
|
+
data: unknown;
|
|
174
|
+
event?: string;
|
|
175
|
+
id?: string;
|
|
176
|
+
}) => void) => MaybePromise<void | (() => void)>;
|
|
177
|
+
/**
|
|
178
|
+
* Produces the lines for a newline-delimited JSON stream, used by
|
|
179
|
+
* {@link Res.ndjson}.
|
|
180
|
+
*
|
|
181
|
+
* @param send - Emits one item, JSON-serialized on its own line.
|
|
182
|
+
* @returns Nothing to close the stream when the source resolves, or a cleanup
|
|
183
|
+
* function to keep it open and be told when the client disconnects.
|
|
184
|
+
*/
|
|
185
|
+
type NdjsonSource = (send: (item: unknown) => void) => MaybePromise<void | (() => void)>;
|
|
186
|
+
/** A `ResponseInit` that can also carry cookies. */
|
|
187
|
+
interface ResInit extends ResponseInit {
|
|
188
|
+
/** Cookies to seed {@link Res.cookies} with. */
|
|
189
|
+
cookies?: Cookies;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* A response under construction.
|
|
193
|
+
*
|
|
194
|
+
* Everything is mutable until {@link Res.toNativeResponse} is called, so a
|
|
195
|
+
* {@link Middleware} can adjust a response a route handler already built. The
|
|
196
|
+
* body is kept as the original value rather than serialized eagerly, which is
|
|
197
|
+
* what lets the content type be inferred from it at the very end.
|
|
198
|
+
*
|
|
199
|
+
* Headers and cookies are both lazy, so an untouched response allocates neither.
|
|
200
|
+
* The chainable methods — {@link Res.file}, {@link Res.redirect},
|
|
201
|
+
* {@link Res.sse} and the rest — set the body and its headers together and
|
|
202
|
+
* return `this`.
|
|
203
|
+
*
|
|
204
|
+
* @typeParam R - The body type, carried from the route's own response type.
|
|
205
|
+
*/
|
|
206
|
+
declare class Res<R = unknown> {
|
|
207
|
+
/**
|
|
208
|
+
* Creates a response.
|
|
209
|
+
*
|
|
210
|
+
* @param body - The body value. Serialized by {@link resolveResBody} at
|
|
211
|
+
* {@link Res.toNativeResponse} time, not now.
|
|
212
|
+
* @param init - Status, status text, headers and cookies. See
|
|
213
|
+
* {@link ResInit}.
|
|
214
|
+
*/
|
|
215
|
+
constructor(body?: Nullable<BodyInit | R>, init?: ResInit);
|
|
216
|
+
/**
|
|
217
|
+
* The body to send. Assign any value — objects become JSON, typed arrays stay
|
|
218
|
+
* binary, streams pass through — and {@link resolveResBody} works out the rest
|
|
219
|
+
* at serialization time.
|
|
220
|
+
*/
|
|
221
|
+
body: Nullable<BodyInit | R>;
|
|
222
|
+
/** The status code. Defaults to {@link Status.OK}. */
|
|
223
|
+
status: number;
|
|
224
|
+
/** The status text. Empty by default, which lets the runtime supply the standard phrase. */
|
|
225
|
+
statusText: string;
|
|
226
|
+
/** Backing store for {@link Res.headers}, created on first access. */
|
|
227
|
+
private _headers;
|
|
228
|
+
/**
|
|
229
|
+
* The response headers.
|
|
230
|
+
*
|
|
231
|
+
* Reading them rewrites the `Set-Cookie` lines from {@link Res.cookies} first,
|
|
232
|
+
* so the two views never disagree — and writing `Set-Cookie` here feeds back
|
|
233
|
+
* into the cookie map. Values may be numbers or booleans, since
|
|
234
|
+
* {@link patchGlobalHeaders} has stringified setters.
|
|
235
|
+
*
|
|
236
|
+
* @returns The headers, created on first access.
|
|
237
|
+
*/
|
|
238
|
+
get headers(): Headers;
|
|
239
|
+
/** Backing store for {@link Res.cookies}, created on first access. */
|
|
240
|
+
private _cookies;
|
|
241
|
+
/**
|
|
242
|
+
* The cookies to send, as a mutable map.
|
|
243
|
+
*
|
|
244
|
+
* This is the authoritative view: the map is serialized into `Set-Cookie`
|
|
245
|
+
* whenever {@link Res.headers} is read, so deleting a cookie here removes its
|
|
246
|
+
* header. Values are percent-encoded on serialization, which is what keeps a
|
|
247
|
+
* CRLF in a cookie value from splitting the response.
|
|
248
|
+
*
|
|
249
|
+
* @returns The {@link Cookies} map, created on first access.
|
|
250
|
+
*/
|
|
251
|
+
get cookies(): Cookies;
|
|
252
|
+
/**
|
|
253
|
+
* Serializes everything into a native `Response`.
|
|
254
|
+
*
|
|
255
|
+
* The content type inferred from the body is applied only when none was set
|
|
256
|
+
* explicitly, so a handler's own choice always wins. `X-Content-Type-Options:
|
|
257
|
+
* nosniff` is set unconditionally — without it a browser will sniff a
|
|
258
|
+
* `text/plain` body that looks like markup and render it as HTML, turning any
|
|
259
|
+
* reflected value into XSS.
|
|
260
|
+
*
|
|
261
|
+
* @returns The response to send over the wire. Called by
|
|
262
|
+
* {@link App.respond}.
|
|
263
|
+
*/
|
|
264
|
+
toNativeResponse(): Response;
|
|
265
|
+
/**
|
|
266
|
+
* Turns the response into a server-sent event stream.
|
|
267
|
+
*
|
|
268
|
+
* Sets the body to a stream and the headers browsers require for `EventSource`
|
|
269
|
+
* to work — the event stream type, no caching, and a kept-alive connection.
|
|
270
|
+
*
|
|
271
|
+
* @param source - The {@link SseSource} producing events. Return a cleanup
|
|
272
|
+
* function from it to keep the stream open indefinitely.
|
|
273
|
+
* @param retry - Reconnection delay in milliseconds, sent with every event to
|
|
274
|
+
* tell the client how long to wait before reconnecting.
|
|
275
|
+
* @returns This response, for chaining.
|
|
276
|
+
*/
|
|
277
|
+
sse(source: SseSource, retry?: number): this;
|
|
278
|
+
/**
|
|
279
|
+
* Turns the response into a newline-delimited JSON stream.
|
|
280
|
+
*
|
|
281
|
+
* Each item is serialized onto its own line, so a client can parse results as
|
|
282
|
+
* they arrive instead of waiting for a whole array. Useful for large result
|
|
283
|
+
* sets and progressive output where the event semantics of {@link Res.sse} are
|
|
284
|
+
* not needed.
|
|
285
|
+
*
|
|
286
|
+
* @param source - The {@link NdjsonSource} producing items. Return a cleanup
|
|
287
|
+
* function from it to keep the stream open indefinitely.
|
|
288
|
+
* @returns This response, for chaining.
|
|
289
|
+
*/
|
|
290
|
+
ndjson(source: NdjsonSource): this;
|
|
291
|
+
/**
|
|
292
|
+
* Streams a file as the response body, without reading it into memory. Prefer
|
|
293
|
+
* this over {@link Res.file} for anything large.
|
|
294
|
+
*
|
|
295
|
+
* @param fileOrPath - An {@link XFile} or a path to one.
|
|
296
|
+
* @param disposition - `"inline"` to display in the browser, `"attachment"` to
|
|
297
|
+
* prompt a download under the file's own name.
|
|
298
|
+
* @returns This response, for chaining.
|
|
299
|
+
* @throws {@link Exception} with {@link Status.NOT_FOUND} when the file does
|
|
300
|
+
* not exist.
|
|
301
|
+
*/
|
|
302
|
+
streamFile(fileOrPath: XFile | string, disposition: ContentDispositionDefinition["disposition"]): this;
|
|
303
|
+
/**
|
|
304
|
+
* Sends a file as the response body, read into memory so it can carry an exact
|
|
305
|
+
* `Content-Length`. Use {@link Res.streamFile} instead for large files.
|
|
306
|
+
*
|
|
307
|
+
* @param fileOrPath - An {@link XFile} or a path to one.
|
|
308
|
+
* @returns This response, for chaining.
|
|
309
|
+
* @throws {@link Exception} with {@link Status.NOT_FOUND} when the file does
|
|
310
|
+
* not exist.
|
|
311
|
+
*/
|
|
312
|
+
file(fileOrPath: XFile | string): this;
|
|
313
|
+
/**
|
|
314
|
+
* Redirects the client to another URL.
|
|
315
|
+
*
|
|
316
|
+
* @param url - Where to send the client, absolute or relative.
|
|
317
|
+
* @param status - Which redirect to use. Defaults to {@link Status.FOUND}, a
|
|
318
|
+
* temporary redirect that browsers do not cache. See
|
|
319
|
+
* {@link Res.permanentRedirect}, {@link Res.temporaryRedirect} and
|
|
320
|
+
* {@link Res.seeOther} for the named alternatives.
|
|
321
|
+
* @returns This response, for chaining.
|
|
322
|
+
*/
|
|
323
|
+
redirect(url: string | URL, status?: 301 | 302 | 303 | 307 | 308): this;
|
|
324
|
+
/**
|
|
325
|
+
* Redirects with {@link Status.MOVED_PERMANENTLY}, which browsers and search
|
|
326
|
+
* engines cache indefinitely. Use it only when the resource has really moved
|
|
327
|
+
* for good.
|
|
328
|
+
*
|
|
329
|
+
* @param url - Where to send the client.
|
|
330
|
+
* @returns This response, for chaining.
|
|
331
|
+
*/
|
|
332
|
+
permanentRedirect(url: string | URL): this;
|
|
333
|
+
/**
|
|
334
|
+
* Redirects with {@link Status.TEMPORARY_REDIRECT}, which preserves the
|
|
335
|
+
* original method and body — unlike {@link Status.FOUND}, which clients
|
|
336
|
+
* commonly turn into a GET.
|
|
337
|
+
*
|
|
338
|
+
* @param url - Where to send the client.
|
|
339
|
+
* @returns This response, for chaining.
|
|
340
|
+
*/
|
|
341
|
+
temporaryRedirect(url: string | URL): this;
|
|
342
|
+
/**
|
|
343
|
+
* Redirects with {@link Status.SEE_OTHER}, which explicitly switches the
|
|
344
|
+
* client to a GET. This is the correct redirect after a successful POST, since
|
|
345
|
+
* it stops a refresh from resubmitting the form.
|
|
346
|
+
*
|
|
347
|
+
* @param url - Where to send the client.
|
|
348
|
+
* @returns This response, for chaining.
|
|
349
|
+
*/
|
|
350
|
+
seeOther(url: string | URL): this;
|
|
351
|
+
}
|
|
352
|
+
export { Res, Status };
|
|
353
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Res/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serving for a directory of built front-end files: hashed assets, an entry
|
|
3
|
+
* document, and per-file-class caching.
|
|
4
|
+
*
|
|
5
|
+
* {@link BundleRoute} is the {@link RouteVariant.bundle} member of the
|
|
6
|
+
* {@link RouteBase} family. It serves any directory of servable files, deriving
|
|
7
|
+
* cache headers from what kind of file each one is — immutable for build-hashed
|
|
8
|
+
* assets, revalidated for the entry document, and a configurable fallback for
|
|
9
|
+
* everything else. Its distinguishing behaviour is the entry-document fallback:
|
|
10
|
+
* a path that resolves to no file is answered with the entry HTML instead of a
|
|
11
|
+
* 404, which is what makes a single-page app survive a hard refresh on a client
|
|
12
|
+
* route. That fallback is the main use, not the only one — {@link StaticRoute}
|
|
13
|
+
* remains the plainer choice when a bundle's caching and fallback behaviour is
|
|
14
|
+
* not wanted.
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* new BundleRoute("/*", "./dist");
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @module BundleRoute
|
|
21
|
+
*/
|
|
22
|
+
import type { ContextHandler } from "../../Context";
|
|
23
|
+
import { type CacheControlDefinition } from "../../Headers";
|
|
24
|
+
import { Method } from "../../Request";
|
|
25
|
+
import { type Res } from "../../Res";
|
|
26
|
+
import { RouteBase, RouteVariant, type RouteConfig } from "..";
|
|
27
|
+
import { type MaybePromise } from "../../utils/is";
|
|
28
|
+
import { type Tuple } from "../../utils/tuple";
|
|
29
|
+
import { XFile } from "../../XFile";
|
|
30
|
+
/**
|
|
31
|
+
* A {@link CacheControlDefinition} that also names the path it applies to,
|
|
32
|
+
* relative to {@link BundleRoute.dir}.
|
|
33
|
+
*/
|
|
34
|
+
interface CacheControlDefinitionWithPath extends CacheControlDefinition {
|
|
35
|
+
/**
|
|
36
|
+
* Path relative to {@link BundleRoute.dir}. Falls back to the corresponding
|
|
37
|
+
* {@link DEFAULT_DEFINITION} value when omitted.
|
|
38
|
+
*/
|
|
39
|
+
path?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Describes the layout of a bundle directory and the caching policy for each
|
|
43
|
+
* class of file within it. See {@link DEFAULT_DEFINITION} for the values used
|
|
44
|
+
* when this is not supplied.
|
|
45
|
+
*/
|
|
46
|
+
interface BundleRouteDefinition {
|
|
47
|
+
/**
|
|
48
|
+
* The entry document — its path within the bundle, and how it should be
|
|
49
|
+
* cached. Also the file served by the fallback in
|
|
50
|
+
* {@link BundleRoute.resolveFile}.
|
|
51
|
+
*/
|
|
52
|
+
indexHtml: CacheControlDefinitionWithPath;
|
|
53
|
+
/**
|
|
54
|
+
* The directory holding build-hashed assets, and how they should be cached.
|
|
55
|
+
* Files below it are matched by path segment, not by extension.
|
|
56
|
+
*/
|
|
57
|
+
assetsDir: CacheControlDefinitionWithPath;
|
|
58
|
+
/**
|
|
59
|
+
* Caching for every file that is neither the entry document nor under the
|
|
60
|
+
* assets directory. Omit it to send no `Cache-Control` for those files.
|
|
61
|
+
*/
|
|
62
|
+
fallback?: CacheControlDefinition;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* What a {@link BundleRoute} handler resolves to: a stream for non-HTML files,
|
|
66
|
+
* bytes for HTML, or a string or {@link Res} when
|
|
67
|
+
* {@link BundleRoute.onFileNotFound} is overridden to return one.
|
|
68
|
+
*/
|
|
69
|
+
type BundleRouteRes = ReadableStream<Uint8Array> | Uint8Array | string | Res;
|
|
70
|
+
/**
|
|
71
|
+
* Serves a directory of built files.
|
|
72
|
+
*
|
|
73
|
+
* Register it on a wildcard endpoint so every path below it reaches the route.
|
|
74
|
+
* A request resolves in three steps: the endpoint prefix is stripped to a
|
|
75
|
+
* sub-path by {@link BundleRoute.resolveSubPath}, the sub-path is joined onto
|
|
76
|
+
* {@link BundleRoute.dir} by {@link BundleRoute.resolveTargetPath}, and
|
|
77
|
+
* {@link BundleRoute.resolveFile} serves the result if it exists. When it does
|
|
78
|
+
* not and the request is not for an HTML file, the entry document named by
|
|
79
|
+
* {@link BundleRoute.indexHtmlPath} is served instead.
|
|
80
|
+
*
|
|
81
|
+
* Files are matched against {@link BundleRoute.definition} to pick their
|
|
82
|
+
* `Cache-Control`: the entry document, anything under
|
|
83
|
+
* {@link BundleRoute.assetsDirPath}, and everything else each get their own
|
|
84
|
+
* policy.
|
|
85
|
+
*
|
|
86
|
+
* Paths that escape {@link BundleRoute.dir} are rejected by
|
|
87
|
+
* {@link BundleRoute.isTraversalAttempt} before the filesystem is touched, so
|
|
88
|
+
* `..` segments cannot reach files outside the directory.
|
|
89
|
+
*
|
|
90
|
+
* @typeParam E - The literal endpoint type, carried so the endpoint stays
|
|
91
|
+
* narrowly typed at the call site.
|
|
92
|
+
*/
|
|
93
|
+
declare class BundleRoute<E extends string = string> extends RouteBase<never, never, never, BundleRouteRes, E> {
|
|
94
|
+
/**
|
|
95
|
+
* Creates a bundle route for subclasses, which declare
|
|
96
|
+
* {@link BundleRoute.endpoint} and {@link BundleRoute.dir} as class fields and
|
|
97
|
+
* call {@link RouteBase.register} themselves.
|
|
98
|
+
*/
|
|
99
|
+
constructor();
|
|
100
|
+
/**
|
|
101
|
+
* Creates a bundle route and registers it on the nearest {@link App}.
|
|
102
|
+
*
|
|
103
|
+
* @param endpoint - The path to serve the directory under. Use a wildcard so
|
|
104
|
+
* nested paths reach the route.
|
|
105
|
+
* @param dir - Directory to serve from. Every resolved path is confined to it.
|
|
106
|
+
* @param definition - Optional {@link BundleRouteDefinition} overriding the
|
|
107
|
+
* bundle layout and caching policy. Defaults to {@link DEFAULT_DEFINITION}.
|
|
108
|
+
*/
|
|
109
|
+
constructor(endpoint: E, dir: string, definition?: BundleRouteDefinition);
|
|
110
|
+
/**
|
|
111
|
+
* Directory the files are served from. Every path resolved by the route is
|
|
112
|
+
* confined to it.
|
|
113
|
+
*/
|
|
114
|
+
dir: string;
|
|
115
|
+
/**
|
|
116
|
+
* Sub-paths that are answered with the entry document rather than the file
|
|
117
|
+
* they name. A trailing `*` makes a pattern a prefix match; leading slashes
|
|
118
|
+
* are optional.
|
|
119
|
+
*
|
|
120
|
+
* Useful when a client-side route collides with a real file in the directory,
|
|
121
|
+
* or to keep a build artefact from being reachable.
|
|
122
|
+
*/
|
|
123
|
+
ignore: Array<string>;
|
|
124
|
+
/**
|
|
125
|
+
* The bundle's layout and caching policy. Defaults to
|
|
126
|
+
* {@link DEFAULT_DEFINITION}.
|
|
127
|
+
*/
|
|
128
|
+
definition: BundleRouteDefinition;
|
|
129
|
+
/**
|
|
130
|
+
* Path of the entry document within {@link BundleRoute.dir}.
|
|
131
|
+
*
|
|
132
|
+
* @returns The path from {@link BundleRouteDefinition.indexHtml}, or the
|
|
133
|
+
* {@link DEFAULT_DEFINITION} value when it declares none.
|
|
134
|
+
*/
|
|
135
|
+
get indexHtmlPath(): string;
|
|
136
|
+
/**
|
|
137
|
+
* Path of the hashed-assets directory within {@link BundleRoute.dir}.
|
|
138
|
+
*
|
|
139
|
+
* @returns The path from {@link BundleRouteDefinition.assetsDir}, or the
|
|
140
|
+
* {@link DEFAULT_DEFINITION} value when it declares none.
|
|
141
|
+
*/
|
|
142
|
+
get assetsDirPath(): string;
|
|
143
|
+
/**
|
|
144
|
+
* Lists every file this route can serve, as sub-paths relative to
|
|
145
|
+
* {@link BundleRoute.dir}.
|
|
146
|
+
*
|
|
147
|
+
* Walks {@link BundleRoute.dir} recursively and returns each file's path
|
|
148
|
+
* with a leading `/`, matching what {@link BundleRoute.resolveSubPath} would
|
|
149
|
+
* produce for a request reaching that file. Useful for generating a sitemap
|
|
150
|
+
* or verifying what a deployed bundle actually contains.
|
|
151
|
+
*
|
|
152
|
+
* @returns The sub-paths of every file under {@link BundleRoute.dir}.
|
|
153
|
+
*/
|
|
154
|
+
getEndpoints(): Array<string>;
|
|
155
|
+
/**
|
|
156
|
+
* Decides what to serve when a request resolves to no readable file — an HTML
|
|
157
|
+
* file that is genuinely missing, a directory with no entry document, or a
|
|
158
|
+
* path rejected by {@link BundleRoute.isTraversalAttempt}.
|
|
159
|
+
*
|
|
160
|
+
* Replace it to serve a custom 404 page or redirect instead of throwing.
|
|
161
|
+
*
|
|
162
|
+
* @param subPath - The request path with the endpoint prefix stripped, as the
|
|
163
|
+
* client asked for it.
|
|
164
|
+
* @returns The {@link BundleRouteRes} to send instead.
|
|
165
|
+
* @throws {@link Exception} with {@link Status.NOT_FOUND} by default.
|
|
166
|
+
*/
|
|
167
|
+
onFileNotFound: (subPath: string) => MaybePromise<BundleRouteRes>;
|
|
168
|
+
/**
|
|
169
|
+
* Resolves a filesystem path to a readable {@link XFile}, applying the
|
|
170
|
+
* entry-document fallback.
|
|
171
|
+
*
|
|
172
|
+
* A missing non-HTML path falls back to the entry document, which is what
|
|
173
|
+
* serves client-side routes. A missing HTML path does not fall back — asking
|
|
174
|
+
* for a specific document that does not exist is a real 404 rather than a
|
|
175
|
+
* client route.
|
|
176
|
+
*
|
|
177
|
+
* @param targetPath - Path produced by {@link BundleRoute.resolveTargetPath}.
|
|
178
|
+
* @returns The {@link XFile} to serve, or `null` when nothing readable was
|
|
179
|
+
* found, which sends the request to {@link BundleRoute.onFileNotFound}.
|
|
180
|
+
*/
|
|
181
|
+
protected resolveFile(targetPath: string): XFile | null;
|
|
182
|
+
/**
|
|
183
|
+
* Strips the route's own prefix from a request pathname, leaving the path
|
|
184
|
+
* relative to {@link BundleRoute.dir}.
|
|
185
|
+
*
|
|
186
|
+
* Both `/*` and `*` endpoint suffixes are handled, and a pathname that does
|
|
187
|
+
* not start with the prefix is returned untouched. The result is percent-decoded,
|
|
188
|
+
* since {@link URL.pathname} leaves escapes like `%20` intact and filesystem
|
|
189
|
+
* paths need the literal characters.
|
|
190
|
+
*
|
|
191
|
+
* @param pathname - The pathname of the incoming request.
|
|
192
|
+
* @returns The bundle-relative sub-path, `""` or `/` for the route root.
|
|
193
|
+
*/
|
|
194
|
+
protected resolveSubPath(pathname: string): string;
|
|
195
|
+
/**
|
|
196
|
+
* Joins a sub-path onto {@link BundleRoute.dir} to get the file to read.
|
|
197
|
+
*
|
|
198
|
+
* The route root maps to the entry document, as does any sub-path matching
|
|
199
|
+
* {@link BundleRoute.ignore}. The result is not yet known to be safe —
|
|
200
|
+
* {@link BundleRoute.isTraversalAttempt} checks it before it is opened.
|
|
201
|
+
*
|
|
202
|
+
* @param subPath - The sub-path from {@link BundleRoute.resolveSubPath}.
|
|
203
|
+
* @returns The joined filesystem path.
|
|
204
|
+
*/
|
|
205
|
+
protected resolveTargetPath(subPath: string): string;
|
|
206
|
+
/**
|
|
207
|
+
* Reports whether a resolved path escapes {@link BundleRoute.dir}.
|
|
208
|
+
*
|
|
209
|
+
* Both sides are fully resolved before comparison, so `..` segments and
|
|
210
|
+
* encoded variants are normalised away rather than matched textually. The
|
|
211
|
+
* separator check keeps a sibling directory sharing the root's name prefix
|
|
212
|
+
* from passing.
|
|
213
|
+
*
|
|
214
|
+
* @param targetPath - Path from {@link BundleRoute.resolveTargetPath}.
|
|
215
|
+
* @returns `true` when the path lies outside the served directory, in which
|
|
216
|
+
* case the request goes to {@link BundleRoute.onFileNotFound} without the file
|
|
217
|
+
* being opened.
|
|
218
|
+
*/
|
|
219
|
+
protected isTraversalAttempt(targetPath: string): boolean;
|
|
220
|
+
/**
|
|
221
|
+
* Produces the response body and headers for a resolved file.
|
|
222
|
+
*
|
|
223
|
+
* `Cache-Control` is chosen by matching the file against
|
|
224
|
+
* {@link BundleRoute.definition}: the entry document first, then anything
|
|
225
|
+
* under {@link BundleRoute.assetsDirPath}, then
|
|
226
|
+
* {@link BundleRouteDefinition.fallback}. No fallback means no header.
|
|
227
|
+
*
|
|
228
|
+
* Non-HTML files are streamed and carry an inline
|
|
229
|
+
* `Content-Disposition`, so large assets are never buffered. HTML is read into
|
|
230
|
+
* memory instead, which lets it carry an exact `Content-Length` — the entry
|
|
231
|
+
* document is small and served constantly, so the length is worth more than
|
|
232
|
+
* the streaming.
|
|
233
|
+
*
|
|
234
|
+
* @param file - The {@link XFile} resolved for the request.
|
|
235
|
+
* @returns A {@link Tuple} of the body and the headers to set on
|
|
236
|
+
* {@link Res.headers}.
|
|
237
|
+
*/
|
|
238
|
+
protected resolveResponseData(file: XFile): Tuple<ReadableStream | Uint8Array, Record<string, string>>;
|
|
239
|
+
/** Marks this route as {@link RouteVariant.bundle} for {@link App} route compilation. */
|
|
240
|
+
readonly variant: RouteVariant;
|
|
241
|
+
/** Bundles answer {@link Method.GET} only. */
|
|
242
|
+
readonly method: Method;
|
|
243
|
+
/**
|
|
244
|
+
* The path the directory is served under. Use a wildcard so nested paths reach
|
|
245
|
+
* the route; {@link BundleRoute.resolveSubPath} strips the wildcard suffix.
|
|
246
|
+
*/
|
|
247
|
+
endpoint: E;
|
|
248
|
+
/**
|
|
249
|
+
* Bundles take no params, search or body, so no {@link RouteConfig} schemas
|
|
250
|
+
* apply.
|
|
251
|
+
*/
|
|
252
|
+
readonly config?: RouteConfig<never, never, never, BundleRouteRes>;
|
|
253
|
+
/**
|
|
254
|
+
* Serves the file a request resolves to.
|
|
255
|
+
*
|
|
256
|
+
* Resolves the sub-path and target path, rejects traversal attempts, reads the
|
|
257
|
+
* file, then sets the headers from {@link BundleRoute.resolveResponseData} on
|
|
258
|
+
* {@link Context.res} and returns the body. Anything that fails to resolve
|
|
259
|
+
* goes to {@link BundleRoute.onFileNotFound}.
|
|
260
|
+
*
|
|
261
|
+
* @param c - The {@link Context} for the request.
|
|
262
|
+
* @returns The file body — a stream for non-HTML, bytes for HTML — or whatever
|
|
263
|
+
* {@link BundleRoute.onFileNotFound} produced.
|
|
264
|
+
*/
|
|
265
|
+
handler: ContextHandler<never, never, never, BundleRouteRes>;
|
|
266
|
+
}
|
|
267
|
+
export { BundleRoute };
|
|
268
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/RouteBase/BundleRoute/index.ts"],"names":[],"mappings":"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"}
|