@ozanarslan/corpus-cli 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 +196 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +1448 -0
- package/dist/getConfig-lU3I2Ejy.mjs +324 -0
- package/dist/index.d.mts +1178 -0
- package/dist/index.mjs +595 -0
- package/package.json +48 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import "oxc-parser";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
//#region ../corpus/dist/utils/is.d.ts
|
|
5
|
+
type Nullable<T> = T | null;
|
|
6
|
+
type Optional<T> = T | undefined;
|
|
7
|
+
type Maybe<T> = Optional<Nullable<T>>;
|
|
8
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
9
|
+
type MaybeArray<T> = T | Array<T>;
|
|
10
|
+
type OrString$1<T> = T | (string & {});
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region ../corpus/dist/Cookies/index.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* A cookie map with header-parsing constructors.
|
|
15
|
+
*
|
|
16
|
+
* Everything `Bun.CookieMap` offers is available unchanged; the two static
|
|
17
|
+
* methods are the additions. Use {@link Cookies.fromHeader} for what a client
|
|
18
|
+
* sent and {@link Cookies.fromSetCookieHeaders} for what a server is sending
|
|
19
|
+
* back — reading a response's own cookies, or following them in a client.
|
|
20
|
+
*/
|
|
21
|
+
declare class Cookies extends Bun.CookieMap {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a cookie map, forwarding to the native constructor.
|
|
24
|
+
*
|
|
25
|
+
* `Bun.CookieMap` is a native class that ignores `new.target`, so instances
|
|
26
|
+
* come back with the base prototype and none of the subclass members attached.
|
|
27
|
+
* The prototype is reattached here, which is what makes subclassing work at
|
|
28
|
+
* all.
|
|
29
|
+
*
|
|
30
|
+
* @param args - The native {@link Bun.CookieMap} constructor arguments.
|
|
31
|
+
*/
|
|
32
|
+
constructor(...args: ConstructorParameters<typeof Bun.CookieMap>);
|
|
33
|
+
/**
|
|
34
|
+
* Builds a map from an inbound `Cookie` header.
|
|
35
|
+
*
|
|
36
|
+
* @param cookieHeader - The raw `Cookie` header value, as sent by the client.
|
|
37
|
+
* @returns The cookies it carried. Repeated names resolve to the last
|
|
38
|
+
* occurrence.
|
|
39
|
+
*/
|
|
40
|
+
static fromHeader(cookieHeader: string): Cookies;
|
|
41
|
+
/**
|
|
42
|
+
* Builds a map from outbound `Set-Cookie` headers, preserving each cookie's
|
|
43
|
+
* attributes.
|
|
44
|
+
*
|
|
45
|
+
* @param headers - The raw `Set-Cookie` values, one per cookie.
|
|
46
|
+
* @returns The cookies they describe. Repeated names resolve to the last
|
|
47
|
+
* occurrence.
|
|
48
|
+
*/
|
|
49
|
+
static fromSetCookieHeaders(headers: string[]): Cookies;
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region ../corpus/dist/utils/object.d.ts
|
|
53
|
+
type ValueOf<T> = T[keyof T];
|
|
54
|
+
declare global {
|
|
55
|
+
interface ObjectConstructor {
|
|
56
|
+
keys<O extends object>(o: O): Array<keyof O>;
|
|
57
|
+
values<O extends object>(o: O): Array<O[keyof O]>;
|
|
58
|
+
entries<O extends object>(o: O): Array<[keyof O, O[keyof O]]>;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region ../corpus/dist/Headers/index.d.ts
|
|
63
|
+
/**
|
|
64
|
+
* A value accepted by the patched header setters. Numbers and booleans are
|
|
65
|
+
* stringified on the way in, so a byte length or a flag can be passed as-is.
|
|
66
|
+
*/
|
|
67
|
+
type HeadersInitValue = string | number | boolean;
|
|
68
|
+
/**
|
|
69
|
+
* What {@link Headers.setMany} accepts: entry pairs, a plain object, or another
|
|
70
|
+
* `Headers` instance.
|
|
71
|
+
*/
|
|
72
|
+
type CustomHeadersInit = [string, HeadersInitValue][] | Record<string, HeadersInitValue> | Headers;
|
|
73
|
+
/** Just some common headers. See [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers) for the full spec. */
|
|
74
|
+
declare const HeaderKey: {
|
|
75
|
+
/** Controls caching mechanisms for requests and responses. */
|
|
76
|
+
readonly CacheControl: "Cache-Control";
|
|
77
|
+
/** Specifies the media type of the resource or data. */
|
|
78
|
+
readonly ContentType: "Content-Type";
|
|
79
|
+
/** Indicates the size of the entity-body in bytes. */
|
|
80
|
+
readonly ContentLength: "Content-Length";
|
|
81
|
+
/** Whether to display payload inline within the page or prompt the user to download it as an attachment. */
|
|
82
|
+
readonly ContentDisposition: "Content-Disposition";
|
|
83
|
+
/** Specifies the character encodings that are acceptable. */
|
|
84
|
+
readonly AcceptEncoding: "Accept-Encoding";
|
|
85
|
+
/** Informs the server about the types of data that can be sent back. */
|
|
86
|
+
readonly Accept: "Accept";
|
|
87
|
+
/** Contains the credentials to authenticate with the server. */
|
|
88
|
+
readonly Authorization: "Authorization";
|
|
89
|
+
/** The user agent string of the client software. */
|
|
90
|
+
readonly UserAgent: "User-Agent";
|
|
91
|
+
/** The domain name of the server and port number. */
|
|
92
|
+
readonly Host: "Host";
|
|
93
|
+
/** The address of the previous web page from which the current request originated. */
|
|
94
|
+
readonly Referer: "Referer";
|
|
95
|
+
/** Indicates whether the connection should be kept alive. */
|
|
96
|
+
readonly Connection: "Connection";
|
|
97
|
+
/** Requests that the server switch to a different protocol (e.g. WebSocket). */
|
|
98
|
+
readonly Upgrade: "Upgrade";
|
|
99
|
+
/** Used to specify directives that must be obeyed by caching mechanisms. */
|
|
100
|
+
readonly Pragma: "Pragma";
|
|
101
|
+
/** The date and time at which the message was sent. */
|
|
102
|
+
readonly Date: "Date";
|
|
103
|
+
/** Makes the request conditional based on the ETag of the resource. */
|
|
104
|
+
readonly IfNoneMatch: "If-None-Match";
|
|
105
|
+
/** Makes the request conditional based on the last modification date. */
|
|
106
|
+
readonly IfModifiedSince: "If-Modified-Since";
|
|
107
|
+
/** An identifier for a specific version of a resource. */
|
|
108
|
+
readonly ETag: "ETag";
|
|
109
|
+
/** The date and time after which the response is considered stale. */
|
|
110
|
+
readonly Expires: "Expires";
|
|
111
|
+
/** The last modification date of the resource. */
|
|
112
|
+
readonly LastModified: "Last-Modified";
|
|
113
|
+
/** Indicates the URL to redirect a page to. */
|
|
114
|
+
readonly Location: "Location";
|
|
115
|
+
/** Defines the authentication method that should be used. */
|
|
116
|
+
readonly WWWAuthenticate: "WWW-Authenticate";
|
|
117
|
+
/** Determines how long the results of a preflight request can be cached. */
|
|
118
|
+
readonly AccessControlMaxAge: "Access-Control-Max-Age";
|
|
119
|
+
/** Indicates whether the response can be shared with resources with credentials. */
|
|
120
|
+
readonly AccessControlAllowCredentials: "Access-Control-Allow-Credentials";
|
|
121
|
+
/** Indicates which HTTP method will be used in the actual CORS request. */
|
|
122
|
+
readonly AccessControlRequestMethod: "Access-Control-Request-Method";
|
|
123
|
+
/** Indicates which headers can be exposed to the browser in a CORS response. */
|
|
124
|
+
readonly AccessControlExposeHeaders: "Access-Control-Expose-Headers";
|
|
125
|
+
/** Indicates which origins are allowed to access the resource. */
|
|
126
|
+
readonly AccessControlAllowOrigin: "Access-Control-Allow-Origin";
|
|
127
|
+
/** Specifies the HTTP methods allowed when accessing the resource in a CORS request. */
|
|
128
|
+
readonly AccessControlAllowMethods: "Access-Control-Allow-Methods";
|
|
129
|
+
/** Specifies the HTTP headers allowed in a CORS request. */
|
|
130
|
+
readonly AccessControlAllowHeaders: "Access-Control-Allow-Headers";
|
|
131
|
+
/** Sends cookies from the server to the client. */
|
|
132
|
+
readonly SetCookie: "Set-Cookie";
|
|
133
|
+
/** Sends cookies from the client to the server. */
|
|
134
|
+
readonly Cookie: "Cookie";
|
|
135
|
+
/** Determines which headers should be used to select a response from cache when content negotiation is in use. */
|
|
136
|
+
readonly Vary: "Vary";
|
|
137
|
+
/** Set to "nosniff" by default in {@link Res}. */
|
|
138
|
+
readonly XContentTypeOptions: "X-Content-Type-Options";
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* A header name. The {@link HeaderKey} constants are suggested, but
|
|
142
|
+
* {@link OrString} keeps any custom header name assignable — the enum is a
|
|
143
|
+
* convenience, not a restriction.
|
|
144
|
+
*/
|
|
145
|
+
type HeaderKey = OrString$1<ValueOf<typeof HeaderKey>>;
|
|
146
|
+
/**
|
|
147
|
+
* A caching policy, rendered into a `Cache-Control` value by
|
|
148
|
+
* {@link createCacheControlHeader}. Used by {@link FileRoute.cache} and by each
|
|
149
|
+
* entry of a {@link BundleRouteDefinition}.
|
|
150
|
+
*/
|
|
151
|
+
interface CacheControlDefinition {
|
|
152
|
+
/** Allows shared caches — proxies and CDNs — to store the response, not just the browser. */
|
|
153
|
+
public?: boolean;
|
|
154
|
+
/** How long the response stays fresh, in seconds. */
|
|
155
|
+
maxAge?: number;
|
|
156
|
+
/** Promises the response will never change, so the browser skips revalidation entirely. Only meaningful with a content hash in the URL. */
|
|
157
|
+
immutable?: boolean;
|
|
158
|
+
/** Caches the response but revalidates before every use. Overrides the other directives except `noStore`. */
|
|
159
|
+
noCache?: boolean;
|
|
160
|
+
/** Forbids storing the response anywhere. Overrides every other directive. */
|
|
161
|
+
noStore?: boolean;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* How a response body should be presented, rendered by
|
|
165
|
+
* {@link createContentDispositionHeader}.
|
|
166
|
+
*/
|
|
167
|
+
interface ContentDispositionDefinition {
|
|
168
|
+
/** `"inline"` to display in the browser, `"attachment"` to prompt a download. */
|
|
169
|
+
disposition: "attachment" | "inline";
|
|
170
|
+
/** The name to save the file under. Omit it to let the client decide. */
|
|
171
|
+
filename?: string;
|
|
172
|
+
}
|
|
173
|
+
declare global {
|
|
174
|
+
/**
|
|
175
|
+
* The `Headers` surface after {@link patchGlobalHeaders} has run.
|
|
176
|
+
*
|
|
177
|
+
* The existing methods are re-declared to accept a {@link HeaderKey} and a
|
|
178
|
+
* {@link HeadersInitValue}; the rest are additions.
|
|
179
|
+
*/
|
|
180
|
+
interface Headers {
|
|
181
|
+
/** Adds a value without replacing existing ones. An array appends each item as its own header line. */
|
|
182
|
+
append(name: HeaderKey, value: MaybeArray<HeadersInitValue>): void;
|
|
183
|
+
/** Sets a header, replacing any existing value. Numbers and booleans are stringified. */
|
|
184
|
+
set(name: HeaderKey, value: HeadersInitValue): void;
|
|
185
|
+
/** Reads a header, falling back to the lowercased name. */
|
|
186
|
+
get(name: HeaderKey): Nullable<string>;
|
|
187
|
+
/** Reports whether a header is present, falling back to the lowercased name. */
|
|
188
|
+
has(name: HeaderKey): boolean;
|
|
189
|
+
/** Sets many headers at once. See {@link CustomHeadersInit}. */
|
|
190
|
+
setMany(init: CustomHeadersInit): void;
|
|
191
|
+
/** Sets `Cache-Control` from a {@link CacheControlDefinition}. */
|
|
192
|
+
setCacheControl(def: CacheControlDefinition): void;
|
|
193
|
+
/** Sets `Content-Disposition` from a {@link ContentDispositionDefinition}. */
|
|
194
|
+
setContentDisposition(def: ContentDispositionDefinition): void;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region ../corpus/dist/XFile/index.d.ts
|
|
199
|
+
/**
|
|
200
|
+
* A file at a path.
|
|
201
|
+
*
|
|
202
|
+
* The path is the only state; nothing is read at construction, so an XFile
|
|
203
|
+
* doesn't officially exist (get it?) and can be written from scratch.
|
|
204
|
+
* The path-manipulation members — {@link XFile.name}, {@link XFile.extension},
|
|
205
|
+
* {@link XFile.sibling} — are pure string work and never touch the disk.
|
|
206
|
+
*
|
|
207
|
+
* Reads are synchronous. The routes that use it read either once at startup or
|
|
208
|
+
* per request from the OS page cache, so the simpler API is worth more than the
|
|
209
|
+
* async one.
|
|
210
|
+
*/
|
|
211
|
+
declare class XFile {
|
|
212
|
+
/** Fallback extension for extension-less files, defaults to "txt" */
|
|
213
|
+
private readonly fallbackExtension;
|
|
214
|
+
/**
|
|
215
|
+
* Creates a file handle. Nothing is read or checked until an operation asks
|
|
216
|
+
* for it.
|
|
217
|
+
*
|
|
218
|
+
* @param pathOrBunFile - The path of the file or BunFile directly.
|
|
219
|
+
* @param fallbackExtension - Fallback extension for extension-less files,
|
|
220
|
+
* defaults to "txt". It decides what {@link XFile.mimeType} reports for a file
|
|
221
|
+
* whose name carries no extension.
|
|
222
|
+
*/
|
|
223
|
+
constructor(
|
|
224
|
+
/** The path of the file or BunFile directly. */
|
|
225
|
+
pathOrBunFile: string | Bun.BunFile,
|
|
226
|
+
/** Fallback extension for extension-less files, defaults to "txt" */
|
|
227
|
+
fallbackExtension?: string);
|
|
228
|
+
/** The underlying Bun file, used for streaming. */
|
|
229
|
+
readonly bunFile: Bun.BunFile;
|
|
230
|
+
/** The path this handle points at, as given. */
|
|
231
|
+
readonly path: string;
|
|
232
|
+
/** Matches either path separator, so paths split correctly on any platform. */
|
|
233
|
+
private readonly SEP;
|
|
234
|
+
/** The extension separator. */
|
|
235
|
+
private readonly DOT;
|
|
236
|
+
/** The empty string, used as a join separator and a replacement target. */
|
|
237
|
+
private readonly EMPTY;
|
|
238
|
+
/**
|
|
239
|
+
* Joins parts with no separator.
|
|
240
|
+
*
|
|
241
|
+
* @param parts - The strings to concatenate.
|
|
242
|
+
* @returns The joined string.
|
|
243
|
+
*/
|
|
244
|
+
private readonly concat;
|
|
245
|
+
/**
|
|
246
|
+
* Reads the file content and returns it as a string.
|
|
247
|
+
* @param encoding defaults to "utf8"
|
|
248
|
+
* @returns The decoded contents.
|
|
249
|
+
* @throws {@link Error} when the file does not exist.
|
|
250
|
+
*/
|
|
251
|
+
text(encoding?: BufferEncoding): string;
|
|
252
|
+
/**
|
|
253
|
+
* Opens a readable stream to the file's content.
|
|
254
|
+
*
|
|
255
|
+
* @returns The stream. This is what the file-serving routes return for large
|
|
256
|
+
* bodies, so nothing is buffered in memory.
|
|
257
|
+
*/
|
|
258
|
+
stream(): ReadableStream<Uint8Array>;
|
|
259
|
+
/**
|
|
260
|
+
* Checks if the file exists in the file system.
|
|
261
|
+
*
|
|
262
|
+
* Deliberately uses Node's `fs` rather than Bun's: `Bun.file().exists()`
|
|
263
|
+
* caches, and this handle's `BunFile` was created before the file may have
|
|
264
|
+
* been deleted, so it would report a stale answer.
|
|
265
|
+
*
|
|
266
|
+
* @returns `true` when the file exists right now.
|
|
267
|
+
*/
|
|
268
|
+
exists(): boolean;
|
|
269
|
+
/**
|
|
270
|
+
* Writes to the file, directories are created recursively.
|
|
271
|
+
*
|
|
272
|
+
* @param data - The contents to write, replacing anything already there.
|
|
273
|
+
*/
|
|
274
|
+
write(data: string | ArrayBuffer | Uint8Array): void;
|
|
275
|
+
/**
|
|
276
|
+
* Deletes the file.
|
|
277
|
+
*
|
|
278
|
+
* @throws {@link Error} when the file does not exist.
|
|
279
|
+
*/
|
|
280
|
+
unlink(): void;
|
|
281
|
+
/**
|
|
282
|
+
* Reads the file content and returns it as a Uint8Array.
|
|
283
|
+
*
|
|
284
|
+
* @returns The raw bytes. Used where an exact `Content-Length` is wanted; see
|
|
285
|
+
* {@link XFile.stream} for the alternative.
|
|
286
|
+
* @throws {@link Error} when the file does not exist.
|
|
287
|
+
*/
|
|
288
|
+
bytes(): Buffer<ArrayBuffer>;
|
|
289
|
+
/**
|
|
290
|
+
* Returns file metadata (size, dates, etc.)
|
|
291
|
+
*
|
|
292
|
+
* @returns The stats.
|
|
293
|
+
* @throws {@link Error} when the file does not exist.
|
|
294
|
+
*/
|
|
295
|
+
stat(): fs.Stats;
|
|
296
|
+
/**
|
|
297
|
+
* Returns the file size in bytes, or null if the file doesn't exist. Unlike
|
|
298
|
+
* {@link XFile.stat}, a missing file is not an error here.
|
|
299
|
+
*
|
|
300
|
+
* @returns The size in bytes, or `null`.
|
|
301
|
+
*/
|
|
302
|
+
size(): number | null;
|
|
303
|
+
/**
|
|
304
|
+
* Copies the file to a destination path, creating directories recursively.
|
|
305
|
+
*
|
|
306
|
+
* @param dest - Where to copy it.
|
|
307
|
+
* @returns A handle to the copy, carrying this handle's fallback extension.
|
|
308
|
+
*/
|
|
309
|
+
copyTo(dest: string): XFile;
|
|
310
|
+
/**
|
|
311
|
+
* Moves (renames) the file to a destination path, creating directories recursively.
|
|
312
|
+
*
|
|
313
|
+
* @param dest - Where to move it.
|
|
314
|
+
* @returns A handle to the new location. This handle still points at the old
|
|
315
|
+
* path, which no longer exists.
|
|
316
|
+
*/
|
|
317
|
+
moveTo(dest: string): XFile;
|
|
318
|
+
/**
|
|
319
|
+
* Appends data to the file.
|
|
320
|
+
*
|
|
321
|
+
* @param data - The contents to add at the end. Unlike {@link XFile.write},
|
|
322
|
+
* parent directories are not created.
|
|
323
|
+
*/
|
|
324
|
+
append(data: string | Uint8Array): void;
|
|
325
|
+
/**
|
|
326
|
+
* Returns a new XFile pointing to a sibling path (same directory, different name).
|
|
327
|
+
*
|
|
328
|
+
* @param filename - The sibling's full name, extension included.
|
|
329
|
+
* @returns A handle to the sibling. Nothing is created on disk.
|
|
330
|
+
*/
|
|
331
|
+
sibling(filename: string): XFile;
|
|
332
|
+
/**
|
|
333
|
+
* Returns a new XFile with a different extension.
|
|
334
|
+
*
|
|
335
|
+
* @param ext - The new extension, without the leading dot.
|
|
336
|
+
* @returns A handle to the renamed path. Nothing is moved on disk.
|
|
337
|
+
*/
|
|
338
|
+
withExtension(ext: string): XFile;
|
|
339
|
+
/**
|
|
340
|
+
* The absolute directory path containing this file.
|
|
341
|
+
*
|
|
342
|
+
* @returns The directory path.
|
|
343
|
+
*/
|
|
344
|
+
get dir(): string;
|
|
345
|
+
/**
|
|
346
|
+
* The name of the file without the extension.
|
|
347
|
+
*
|
|
348
|
+
* @returns The bare name.
|
|
349
|
+
*/
|
|
350
|
+
get name(): string;
|
|
351
|
+
/**
|
|
352
|
+
* The file extension (e.g., "html", "md"), excluding the leading dot.
|
|
353
|
+
*
|
|
354
|
+
* @returns The lowercased extension, or the fallback extension when the name
|
|
355
|
+
* has none.
|
|
356
|
+
*/
|
|
357
|
+
get extension(): string;
|
|
358
|
+
/**
|
|
359
|
+
* The full name of the file, including the extension.
|
|
360
|
+
*
|
|
361
|
+
* @returns The name with its extension. This is what the file-serving routes
|
|
362
|
+
* send as the `Content-Disposition` filename.
|
|
363
|
+
*/
|
|
364
|
+
get fullname(): string;
|
|
365
|
+
/**
|
|
366
|
+
* Gets the parent directory names as an array, ordered from the immediate parent up to the root.
|
|
367
|
+
*
|
|
368
|
+
* @returns The directory names, nearest first. Empty segments are dropped, so
|
|
369
|
+
* a leading or doubled separator does not produce blanks.
|
|
370
|
+
*/
|
|
371
|
+
get parentDirs(): string[];
|
|
372
|
+
/**
|
|
373
|
+
* The standard MIME type associated with the file's extension.
|
|
374
|
+
*
|
|
375
|
+
* Resolved from the extension alone — the file's contents are never read, and
|
|
376
|
+
* it need not exist. Any parameters such as `charset` are stripped, so the
|
|
377
|
+
* result is safe to use as a bare `Content-Type`.
|
|
378
|
+
*
|
|
379
|
+
* @returns The MIME type, or `"application/octet-stream"` when the extension
|
|
380
|
+
* maps to nothing known.
|
|
381
|
+
*/
|
|
382
|
+
get mimeType(): string;
|
|
383
|
+
}
|
|
384
|
+
//#endregion
|
|
385
|
+
//#region ../corpus/dist/Res/index.d.ts
|
|
386
|
+
/**
|
|
387
|
+
* Produces the events for a server-sent event stream, used by {@link Res.sse}.
|
|
388
|
+
*
|
|
389
|
+
* @param send - Emits one event. `data` is JSON-serialized; `event` names the
|
|
390
|
+
* event type for a client listening on something other than `message`, and `id`
|
|
391
|
+
* lets a client resume from where it left off.
|
|
392
|
+
* @returns Nothing when the source is finite — the stream is closed for you once
|
|
393
|
+
* it resolves — or a cleanup function when it is open-ended, in which case the
|
|
394
|
+
* stream stays open and the function runs if the client disconnects.
|
|
395
|
+
*/
|
|
396
|
+
type SseSource = (send: (item: {
|
|
397
|
+
data: unknown;
|
|
398
|
+
event?: string;
|
|
399
|
+
id?: string;
|
|
400
|
+
}) => void) => MaybePromise<void | (() => void)>;
|
|
401
|
+
/**
|
|
402
|
+
* Produces the lines for a newline-delimited JSON stream, used by
|
|
403
|
+
* {@link Res.ndjson}.
|
|
404
|
+
*
|
|
405
|
+
* @param send - Emits one item, JSON-serialized on its own line.
|
|
406
|
+
* @returns Nothing to close the stream when the source resolves, or a cleanup
|
|
407
|
+
* function to keep it open and be told when the client disconnects.
|
|
408
|
+
*/
|
|
409
|
+
type NdjsonSource = (send: (item: unknown) => void) => MaybePromise<void | (() => void)>;
|
|
410
|
+
/** A `ResponseInit` that can also carry cookies. */
|
|
411
|
+
interface ResInit extends ResponseInit {
|
|
412
|
+
/** Cookies to seed {@link Res.cookies} with. */
|
|
413
|
+
cookies?: Cookies;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A response under construction.
|
|
417
|
+
*
|
|
418
|
+
* Everything is mutable until {@link Res.toNativeResponse} is called, so a
|
|
419
|
+
* {@link Middleware} can adjust a response a route handler already built. The
|
|
420
|
+
* body is kept as the original value rather than serialized eagerly, which is
|
|
421
|
+
* what lets the content type be inferred from it at the very end.
|
|
422
|
+
*
|
|
423
|
+
* Headers and cookies are both lazy, so an untouched response allocates neither.
|
|
424
|
+
* The chainable methods — {@link Res.file}, {@link Res.redirect},
|
|
425
|
+
* {@link Res.sse} and the rest — set the body and its headers together and
|
|
426
|
+
* return `this`.
|
|
427
|
+
*
|
|
428
|
+
* @typeParam R - The body type, carried from the route's own response type.
|
|
429
|
+
*/
|
|
430
|
+
declare class Res<R = unknown> {
|
|
431
|
+
/**
|
|
432
|
+
* Creates a response.
|
|
433
|
+
*
|
|
434
|
+
* @param body - The body value. Serialized by {@link resolveResBody} at
|
|
435
|
+
* {@link Res.toNativeResponse} time, not now.
|
|
436
|
+
* @param init - Status, status text, headers and cookies. See
|
|
437
|
+
* {@link ResInit}.
|
|
438
|
+
*/
|
|
439
|
+
constructor(body?: Nullable<BodyInit | R>, init?: ResInit);
|
|
440
|
+
/**
|
|
441
|
+
* The body to send. Assign any value — objects become JSON, typed arrays stay
|
|
442
|
+
* binary, streams pass through — and {@link resolveResBody} works out the rest
|
|
443
|
+
* at serialization time.
|
|
444
|
+
*/
|
|
445
|
+
body: Nullable<BodyInit | R>;
|
|
446
|
+
/** The status code. Defaults to {@link Status.OK}. */
|
|
447
|
+
status: number;
|
|
448
|
+
/** The status text. Empty by default, which lets the runtime supply the standard phrase. */
|
|
449
|
+
statusText: string;
|
|
450
|
+
/** Backing store for {@link Res.headers}, created on first access. */
|
|
451
|
+
private _headers;
|
|
452
|
+
/**
|
|
453
|
+
* The response headers.
|
|
454
|
+
*
|
|
455
|
+
* Reading them rewrites the `Set-Cookie` lines from {@link Res.cookies} first,
|
|
456
|
+
* so the two views never disagree — and writing `Set-Cookie` here feeds back
|
|
457
|
+
* into the cookie map. Values may be numbers or booleans, since
|
|
458
|
+
* {@link patchGlobalHeaders} has stringified setters.
|
|
459
|
+
*
|
|
460
|
+
* @returns The headers, created on first access.
|
|
461
|
+
*/
|
|
462
|
+
get headers(): Headers;
|
|
463
|
+
/** Backing store for {@link Res.cookies}, created on first access. */
|
|
464
|
+
private _cookies;
|
|
465
|
+
/**
|
|
466
|
+
* The cookies to send, as a mutable map.
|
|
467
|
+
*
|
|
468
|
+
* This is the authoritative view: the map is serialized into `Set-Cookie`
|
|
469
|
+
* whenever {@link Res.headers} is read, so deleting a cookie here removes its
|
|
470
|
+
* header. Values are percent-encoded on serialization, which is what keeps a
|
|
471
|
+
* CRLF in a cookie value from splitting the response.
|
|
472
|
+
*
|
|
473
|
+
* @returns The {@link Cookies} map, created on first access.
|
|
474
|
+
*/
|
|
475
|
+
get cookies(): Cookies;
|
|
476
|
+
/**
|
|
477
|
+
* Serializes everything into a native `Response`.
|
|
478
|
+
*
|
|
479
|
+
* The content type inferred from the body is applied only when none was set
|
|
480
|
+
* explicitly, so a handler's own choice always wins. `X-Content-Type-Options:
|
|
481
|
+
* nosniff` is set unconditionally — without it a browser will sniff a
|
|
482
|
+
* `text/plain` body that looks like markup and render it as HTML, turning any
|
|
483
|
+
* reflected value into XSS.
|
|
484
|
+
*
|
|
485
|
+
* @returns The response to send over the wire. Called by
|
|
486
|
+
* {@link App.respond}.
|
|
487
|
+
*/
|
|
488
|
+
toNativeResponse(): Response;
|
|
489
|
+
/**
|
|
490
|
+
* Turns the response into a server-sent event stream.
|
|
491
|
+
*
|
|
492
|
+
* Sets the body to a stream and the headers browsers require for `EventSource`
|
|
493
|
+
* to work — the event stream type, no caching, and a kept-alive connection.
|
|
494
|
+
*
|
|
495
|
+
* @param source - The {@link SseSource} producing events. Return a cleanup
|
|
496
|
+
* function from it to keep the stream open indefinitely.
|
|
497
|
+
* @param retry - Reconnection delay in milliseconds, sent with every event to
|
|
498
|
+
* tell the client how long to wait before reconnecting.
|
|
499
|
+
* @returns This response, for chaining.
|
|
500
|
+
*/
|
|
501
|
+
sse(source: SseSource, retry?: number): this;
|
|
502
|
+
/**
|
|
503
|
+
* Turns the response into a newline-delimited JSON stream.
|
|
504
|
+
*
|
|
505
|
+
* Each item is serialized onto its own line, so a client can parse results as
|
|
506
|
+
* they arrive instead of waiting for a whole array. Useful for large result
|
|
507
|
+
* sets and progressive output where the event semantics of {@link Res.sse} are
|
|
508
|
+
* not needed.
|
|
509
|
+
*
|
|
510
|
+
* @param source - The {@link NdjsonSource} producing items. Return a cleanup
|
|
511
|
+
* function from it to keep the stream open indefinitely.
|
|
512
|
+
* @returns This response, for chaining.
|
|
513
|
+
*/
|
|
514
|
+
ndjson(source: NdjsonSource): this;
|
|
515
|
+
/**
|
|
516
|
+
* Streams a file as the response body, without reading it into memory. Prefer
|
|
517
|
+
* this over {@link Res.file} for anything large.
|
|
518
|
+
*
|
|
519
|
+
* @param fileOrPath - An {@link XFile} or a path to one.
|
|
520
|
+
* @param disposition - `"inline"` to display in the browser, `"attachment"` to
|
|
521
|
+
* prompt a download under the file's own name.
|
|
522
|
+
* @returns This response, for chaining.
|
|
523
|
+
* @throws {@link Exception} with {@link Status.NOT_FOUND} when the file does
|
|
524
|
+
* not exist.
|
|
525
|
+
*/
|
|
526
|
+
streamFile(fileOrPath: XFile | string, disposition: ContentDispositionDefinition["disposition"]): this;
|
|
527
|
+
/**
|
|
528
|
+
* Sends a file as the response body, read into memory so it can carry an exact
|
|
529
|
+
* `Content-Length`. Use {@link Res.streamFile} instead for large files.
|
|
530
|
+
*
|
|
531
|
+
* @param fileOrPath - An {@link XFile} or a path to one.
|
|
532
|
+
* @returns This response, for chaining.
|
|
533
|
+
* @throws {@link Exception} with {@link Status.NOT_FOUND} when the file does
|
|
534
|
+
* not exist.
|
|
535
|
+
*/
|
|
536
|
+
file(fileOrPath: XFile | string): this;
|
|
537
|
+
/**
|
|
538
|
+
* Redirects the client to another URL.
|
|
539
|
+
*
|
|
540
|
+
* @param url - Where to send the client, absolute or relative.
|
|
541
|
+
* @param status - Which redirect to use. Defaults to {@link Status.FOUND}, a
|
|
542
|
+
* temporary redirect that browsers do not cache. See
|
|
543
|
+
* {@link Res.permanentRedirect}, {@link Res.temporaryRedirect} and
|
|
544
|
+
* {@link Res.seeOther} for the named alternatives.
|
|
545
|
+
* @returns This response, for chaining.
|
|
546
|
+
*/
|
|
547
|
+
redirect(url: string | URL, status?: 301 | 302 | 303 | 307 | 308): this;
|
|
548
|
+
/**
|
|
549
|
+
* Redirects with {@link Status.MOVED_PERMANENTLY}, which browsers and search
|
|
550
|
+
* engines cache indefinitely. Use it only when the resource has really moved
|
|
551
|
+
* for good.
|
|
552
|
+
*
|
|
553
|
+
* @param url - Where to send the client.
|
|
554
|
+
* @returns This response, for chaining.
|
|
555
|
+
*/
|
|
556
|
+
permanentRedirect(url: string | URL): this;
|
|
557
|
+
/**
|
|
558
|
+
* Redirects with {@link Status.TEMPORARY_REDIRECT}, which preserves the
|
|
559
|
+
* original method and body — unlike {@link Status.FOUND}, which clients
|
|
560
|
+
* commonly turn into a GET.
|
|
561
|
+
*
|
|
562
|
+
* @param url - Where to send the client.
|
|
563
|
+
* @returns This response, for chaining.
|
|
564
|
+
*/
|
|
565
|
+
temporaryRedirect(url: string | URL): this;
|
|
566
|
+
/**
|
|
567
|
+
* Redirects with {@link Status.SEE_OTHER}, which explicitly switches the
|
|
568
|
+
* client to a GET. This is the correct redirect after a successful POST, since
|
|
569
|
+
* it stops a refresh from resubmitting the form.
|
|
570
|
+
*
|
|
571
|
+
* @param url - Where to send the client.
|
|
572
|
+
* @returns This response, for chaining.
|
|
573
|
+
*/
|
|
574
|
+
seeOther(url: string | URL): this;
|
|
575
|
+
}
|
|
576
|
+
//#endregion
|
|
577
|
+
//#region ../corpus/dist/Request/index.d.ts
|
|
578
|
+
/** Commonly used HTTP verbs. See [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods) for the full spec. */
|
|
579
|
+
declare const Method: {
|
|
580
|
+
/** Retrieve a resource from the server. */
|
|
581
|
+
readonly GET: "GET";
|
|
582
|
+
/** Submit data to create a new resource. */
|
|
583
|
+
readonly POST: "POST";
|
|
584
|
+
/** Replace an entire resource with new data. */
|
|
585
|
+
readonly PUT: "PUT";
|
|
586
|
+
/** Apply partial modifications to a resource. */
|
|
587
|
+
readonly PATCH: "PATCH";
|
|
588
|
+
/** Remove a resource from the server. */
|
|
589
|
+
readonly DELETE: "DELETE";
|
|
590
|
+
/** Get response headers without body. */
|
|
591
|
+
readonly HEAD: "HEAD";
|
|
592
|
+
/** Discover communication options. */
|
|
593
|
+
readonly OPTIONS: "OPTIONS";
|
|
594
|
+
/** Establish tunnel to server. */
|
|
595
|
+
readonly CONNECT: "CONNECT";
|
|
596
|
+
/** Echo back received request. */
|
|
597
|
+
readonly TRACE: "TRACE";
|
|
598
|
+
};
|
|
599
|
+
/**
|
|
600
|
+
* An HTTP method. The {@link Method} constants are suggested, but
|
|
601
|
+
* {@link OrString} keeps any custom verb assignable.
|
|
602
|
+
*/
|
|
603
|
+
type Method = OrString$1<ValueOf<typeof Method>>;
|
|
604
|
+
declare global {
|
|
605
|
+
interface RequestInit {
|
|
606
|
+
/**
|
|
607
|
+
* Cookies to seed the request with. Anything in the `Cookie` header is
|
|
608
|
+
* layered on top of these.
|
|
609
|
+
*/
|
|
610
|
+
cookies?: Cookies;
|
|
611
|
+
}
|
|
612
|
+
/** The `Request` surface after {@link patchGlobalRequest} has run. */
|
|
613
|
+
interface Request {
|
|
614
|
+
/**
|
|
615
|
+
* The raw path parameters matched by the route, populated by Bun's router.
|
|
616
|
+
* {@link Context.params} holds the parsed, validated version.
|
|
617
|
+
*/
|
|
618
|
+
params: {
|
|
619
|
+
[x: string]: string;
|
|
620
|
+
};
|
|
621
|
+
/** The request's cookies, parsed from the `Cookie` header on first access. */
|
|
622
|
+
cookies: Cookies;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
//#endregion
|
|
626
|
+
//#region ../corpus/dist/ParserBase/SchemaParser/index.d.ts
|
|
627
|
+
/**
|
|
628
|
+
* Any Standard Schema validator producing `T`. This is the type
|
|
629
|
+
* {@link RouteConfig} fields accept.
|
|
630
|
+
*
|
|
631
|
+
* @typeParam T - What the schema validates to.
|
|
632
|
+
*/
|
|
633
|
+
type Schema<T = unknown> = StandardSchemaV1<unknown, T>;
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region ../corpus/dist/RouteBase/index.d.ts
|
|
636
|
+
/**
|
|
637
|
+
* What kind of route this is. {@link App.composeRoutes} branches on it — a
|
|
638
|
+
* `websocket` route upgrades instead of responding, and a `bundle` route is
|
|
639
|
+
* excluded from {@link RateLimiter} by default.
|
|
640
|
+
*/
|
|
641
|
+
declare const RouteVariant: {
|
|
642
|
+
/** A file whose contents feed a handler. See {@link StaticRoute}. */
|
|
643
|
+
readonly static: "static";
|
|
644
|
+
/** A single file served as-is. See {@link FileRoute}. */
|
|
645
|
+
readonly file: "file";
|
|
646
|
+
/** A handler function. See {@link Route}. */
|
|
647
|
+
readonly dynamic: "dynamic";
|
|
648
|
+
/** A connection upgrade. See {@link WebSocketRoute}. */
|
|
649
|
+
readonly websocket: "websocket";
|
|
650
|
+
/** A directory of built files. See {@link BundleRoute}. */
|
|
651
|
+
readonly bundle: "bundle";
|
|
652
|
+
};
|
|
653
|
+
/** One of the {@link RouteVariant} values. */
|
|
654
|
+
type RouteVariant = ValueOf<typeof RouteVariant>;
|
|
655
|
+
/**
|
|
656
|
+
* The request to simulate when calling a route directly through
|
|
657
|
+
* {@link RouteBase.handle}. Every field is optional — supply only what the
|
|
658
|
+
* handler reads.
|
|
659
|
+
*
|
|
660
|
+
* @typeParam B - Body type.
|
|
661
|
+
* @typeParam S - Search type.
|
|
662
|
+
* @typeParam P - Params type.
|
|
663
|
+
*/
|
|
664
|
+
type RouteHandleInput<B, S, P> = {
|
|
665
|
+
/** The request body, already in parsed form. */
|
|
666
|
+
body?: B;
|
|
667
|
+
/** The query values, already in parsed form. */
|
|
668
|
+
search?: S;
|
|
669
|
+
/** The path parameters, which are also substituted into the endpoint. */
|
|
670
|
+
params?: P;
|
|
671
|
+
/** Headers for the synthesized request. */
|
|
672
|
+
headers?: HeadersInit;
|
|
673
|
+
};
|
|
674
|
+
/**
|
|
675
|
+
* A route's schemas and per-route limits.
|
|
676
|
+
*
|
|
677
|
+
* The schemas do double duty: {@link SchemaParser} validates against them at
|
|
678
|
+
* request time, and their inferred output types become the {@link Context}
|
|
679
|
+
* types the handler sees. {@link getContextAccess} also reads this to decide
|
|
680
|
+
* what to parse — a surface with a schema is always parsed, since it must be
|
|
681
|
+
* validated.
|
|
682
|
+
*
|
|
683
|
+
* @typeParam B - Body type.
|
|
684
|
+
* @typeParam S - Search type.
|
|
685
|
+
* @typeParam P - Params type.
|
|
686
|
+
* @typeParam R - Response type.
|
|
687
|
+
*/
|
|
688
|
+
type RouteConfig<B = unknown, S = unknown, P = unknown, R = unknown> = {
|
|
689
|
+
/**
|
|
690
|
+
* Body size ceiling in bytes for this route, enforced by
|
|
691
|
+
* {@link enforceBodyLimit}. Tightens {@link App.maxRequestBodySize} for a
|
|
692
|
+
* single endpoint — an upload route and a JSON route rarely want the same
|
|
693
|
+
* limit.
|
|
694
|
+
*/
|
|
695
|
+
maxRequestBodySize?: number;
|
|
696
|
+
/** Schema for the response body. Types the handler's return value. */
|
|
697
|
+
response?: Schema<R>;
|
|
698
|
+
/** Schema for the request body. Validated before the handler runs. */
|
|
699
|
+
body?: Schema<B>;
|
|
700
|
+
/** Schema for the query string. Validated before the handler runs. */
|
|
701
|
+
search?: Schema<S>;
|
|
702
|
+
/** Schema for the path parameters. Validated before the handler runs. */
|
|
703
|
+
params?: Schema<P>;
|
|
704
|
+
};
|
|
705
|
+
/**
|
|
706
|
+
* The contract every route kind implements.
|
|
707
|
+
*
|
|
708
|
+
* Subclasses declare what they are and how they answer; this class supplies
|
|
709
|
+
* {@link RouteBase.id}, registration, and the direct-invocation helpers.
|
|
710
|
+
*
|
|
711
|
+
* The abstract members exist because {@link App} reads them while compiling —
|
|
712
|
+
* {@link RouteBase.variant} decides the pipeline shape,
|
|
713
|
+
* {@link RouteBase.config} decides what gets parsed and validated, and the rest
|
|
714
|
+
* decide where the route sits in the route map.
|
|
715
|
+
*
|
|
716
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
717
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
718
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
719
|
+
* @typeParam R - Response body type.
|
|
720
|
+
* @typeParam E - The literal endpoint type.
|
|
721
|
+
*/
|
|
722
|
+
declare abstract class RouteBase<B = any, S = any, P = any, R = any, E extends string = string> {
|
|
723
|
+
/** Which kind of route this is. */
|
|
724
|
+
abstract readonly variant: RouteVariant;
|
|
725
|
+
/** The HTTP method this route answers. */
|
|
726
|
+
abstract readonly method: Method;
|
|
727
|
+
/** The path this route answers, before {@link App.prefix} is applied. */
|
|
728
|
+
abstract readonly endpoint: E;
|
|
729
|
+
/** Schemas and limits for this route, if any. */
|
|
730
|
+
abstract readonly config?: RouteConfig<B, S, P, R>;
|
|
731
|
+
/**
|
|
732
|
+
* Answers the request. Declared as a method rather than a property so
|
|
733
|
+
* subclasses can narrow its parameter types — a property declaration would
|
|
734
|
+
* make the variance error out on routes that take `never` for their inputs.
|
|
735
|
+
*
|
|
736
|
+
* @param args - The {@link ContextHandler} arguments: the {@link Context} for
|
|
737
|
+
* the request.
|
|
738
|
+
* @returns The response body, a {@link Res}, or nothing.
|
|
739
|
+
*/
|
|
740
|
+
abstract handler(...args: Parameters<ContextHandler<B, S, P, R>>): ReturnType<ContextHandler<B, S, P, R>>;
|
|
741
|
+
/**
|
|
742
|
+
* The route's identity, as `"METHOD /endpoint"`.
|
|
743
|
+
*
|
|
744
|
+
* This is what {@link Middleware.useOn} targets and what
|
|
745
|
+
* {@link Controller.routeIds} collects, so two routes sharing a method and
|
|
746
|
+
* endpoint share middlewares as well.
|
|
747
|
+
*
|
|
748
|
+
* @returns The id.
|
|
749
|
+
*/
|
|
750
|
+
get id(): string;
|
|
751
|
+
/**
|
|
752
|
+
* Appends this route to the nearest {@link App}. Called by every concrete
|
|
753
|
+
* route's constructor; a subclass that declares its members as class fields
|
|
754
|
+
* must call it itself, after those fields are initialized.
|
|
755
|
+
*/
|
|
756
|
+
register(): void;
|
|
757
|
+
/**
|
|
758
|
+
* Invokes the route's handler directly, with no server and no HTTP.
|
|
759
|
+
*
|
|
760
|
+
* The inputs are taken as already-parsed values, so nothing is decoded or
|
|
761
|
+
* validated — and no {@link Middleware} runs, since middlewares are folded in
|
|
762
|
+
* by {@link App} at compile time, not by the route. What this exercises is the
|
|
763
|
+
* handler itself, which is what makes it useful for unit tests and for calling
|
|
764
|
+
* one route's logic from another.
|
|
765
|
+
*
|
|
766
|
+
* @param data - The {@link RouteHandleInput} to build the {@link Context}
|
|
767
|
+
* from.
|
|
768
|
+
* @returns Whatever the handler returns.
|
|
769
|
+
*/
|
|
770
|
+
handle(data: RouteHandleInput<B, S, P>): MaybePromise<R>;
|
|
771
|
+
/**
|
|
772
|
+
* Builds the request a {@link RouteHandleInput} describes, so the
|
|
773
|
+
* {@link Context} that {@link RouteBase.handle} creates has a real request
|
|
774
|
+
* behind it — a handler reading {@link Context.url} or a header gets what it
|
|
775
|
+
* would have got over the wire.
|
|
776
|
+
*
|
|
777
|
+
* Params are substituted into the endpoint, so `/users/:id` becomes a concrete
|
|
778
|
+
* URL. A `FormData` body is passed through untouched, since the runtime sets
|
|
779
|
+
* its own multipart content type with the boundary; anything else is
|
|
780
|
+
* JSON-encoded.
|
|
781
|
+
*
|
|
782
|
+
* @param data - The {@link RouteHandleInput} to build from.
|
|
783
|
+
* @returns The synthesized request, addressed against {@link App.baseUrl}.
|
|
784
|
+
*/
|
|
785
|
+
request(data: RouteHandleInput<B, S, P>): Request;
|
|
786
|
+
}
|
|
787
|
+
//#endregion
|
|
788
|
+
//#region ../corpus/dist/RouteBase/WebSocketRoute/index.d.ts
|
|
789
|
+
/**
|
|
790
|
+
* Runs once a connection has been upgraded and is ready.
|
|
791
|
+
*
|
|
792
|
+
* @param ws - The newly opened {@link ServerWebSocket}.
|
|
793
|
+
*/
|
|
794
|
+
type WebSocketOnOpen = (ws: ServerWebSocket) => MaybePromise<void>;
|
|
795
|
+
/**
|
|
796
|
+
* Runs when a connection closes, whichever side ended it.
|
|
797
|
+
*
|
|
798
|
+
* @param ws - The closing {@link ServerWebSocket}.
|
|
799
|
+
* @param code - The WebSocket close code, when one was sent.
|
|
800
|
+
* @param reason - The accompanying reason, when one was sent.
|
|
801
|
+
*/
|
|
802
|
+
type WebSocketOnClose = (ws: ServerWebSocket, code?: number, reason?: string) => MaybePromise<void>;
|
|
803
|
+
/**
|
|
804
|
+
* Runs for each message a client sends.
|
|
805
|
+
*
|
|
806
|
+
* @param ws - The {@link ServerWebSocket} the message arrived on.
|
|
807
|
+
* @param message - The payload: a string for text frames, a `Buffer` for binary
|
|
808
|
+
* ones.
|
|
809
|
+
*/
|
|
810
|
+
type WebSocketOnMessage = (ws: ServerWebSocket, message: string | Buffer) => MaybePromise<void>;
|
|
811
|
+
/** The socket lifecycle callbacks a {@link WebSocketRoute} is built from. */
|
|
812
|
+
interface WebSocketRouteDefinition {
|
|
813
|
+
/** Called once per connection, after the upgrade succeeds. */
|
|
814
|
+
onOpen?: WebSocketOnOpen;
|
|
815
|
+
/** Called once per connection, when it closes. */
|
|
816
|
+
onClose?: WebSocketOnClose;
|
|
817
|
+
/** Called for every message received. The only required callback — a socket that never reads has nothing to do. */
|
|
818
|
+
onMessage: WebSocketOnMessage;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* A WebSocket endpoint.
|
|
822
|
+
*
|
|
823
|
+
* Constructing one registers it on the nearest {@link App}, which upgrades
|
|
824
|
+
* matching requests rather than responding to them. The callbacks are shared by
|
|
825
|
+
* every connection to the endpoint, and each event receives the socket it
|
|
826
|
+
* concerns.
|
|
827
|
+
*
|
|
828
|
+
* @typeParam E - The literal endpoint type, carried so the endpoint stays
|
|
829
|
+
* narrowly typed at the call site.
|
|
830
|
+
*/
|
|
831
|
+
declare class WebSocketRoute<E extends string = string> extends RouteBase<never, never, never, WebSocketRoute, E> {
|
|
832
|
+
/**
|
|
833
|
+
* Creates a websocket route for subclasses, which declare
|
|
834
|
+
* {@link WebSocketRoute.endpoint} and the callbacks as class fields and call
|
|
835
|
+
* {@link RouteBase.register} themselves.
|
|
836
|
+
*/
|
|
837
|
+
constructor();
|
|
838
|
+
/**
|
|
839
|
+
* Creates a websocket route and registers it on the nearest {@link App}.
|
|
840
|
+
*
|
|
841
|
+
* @param endpoint - The path clients connect to.
|
|
842
|
+
* @param definition - The {@link WebSocketRouteDefinition} holding the socket
|
|
843
|
+
* lifecycle callbacks.
|
|
844
|
+
*/
|
|
845
|
+
constructor(endpoint: E, definition: WebSocketRouteDefinition);
|
|
846
|
+
/**
|
|
847
|
+
* Marks this route as {@link RouteVariant.websocket}, which is what tells
|
|
848
|
+
* {@link App.composeRoutes} to upgrade rather than respond.
|
|
849
|
+
*/
|
|
850
|
+
readonly variant: RouteVariant;
|
|
851
|
+
/** Always {@link Method.GET} — an upgrade handshake is a GET request. */
|
|
852
|
+
readonly method: Method;
|
|
853
|
+
/** The path clients connect to. */
|
|
854
|
+
endpoint: E;
|
|
855
|
+
/** No schemas apply: an upgrade request carries no body, search or params to validate. */
|
|
856
|
+
readonly config?: RouteConfig<never, never, never, WebSocketRoute<string>> | undefined;
|
|
857
|
+
/**
|
|
858
|
+
* Returns the route itself, which {@link App.composeRoutes} attaches to the
|
|
859
|
+
* socket as its data — that is how a message arriving minutes later finds its
|
|
860
|
+
* way back to {@link WebSocketRoute.onMessage}.
|
|
861
|
+
*
|
|
862
|
+
* The upgrade itself still happens in {@link App}; this handler only supplies
|
|
863
|
+
* what the socket carries.
|
|
864
|
+
*
|
|
865
|
+
* @returns This route.
|
|
866
|
+
*/
|
|
867
|
+
readonly handler: ContextHandler<never, never, never, WebSocketRoute<string>>;
|
|
868
|
+
/** Called once per connection, after the upgrade succeeds. */
|
|
869
|
+
onOpen?: WebSocketOnOpen | undefined;
|
|
870
|
+
/** Called once per connection, when it closes. */
|
|
871
|
+
onClose?: WebSocketOnClose | undefined;
|
|
872
|
+
/** Called for every message received. */
|
|
873
|
+
onMessage: WebSocketOnMessage;
|
|
874
|
+
}
|
|
875
|
+
//#endregion
|
|
876
|
+
//#region ../corpus/dist/Server/index.d.ts
|
|
877
|
+
/**
|
|
878
|
+
* A live WebSocket connection. Its `data` is the {@link WebSocketRoute} that
|
|
879
|
+
* accepted the upgrade, which is what {@link App.createServer} dispatches the
|
|
880
|
+
* open, message and close events through.
|
|
881
|
+
*/
|
|
882
|
+
type ServerWebSocket = Bun.ServerWebSocket<WebSocketRoute>;
|
|
883
|
+
/** The running Bun server, as held by {@link App.server}. */
|
|
884
|
+
type Server = Bun.Server<WebSocketRoute>;
|
|
885
|
+
//#endregion
|
|
886
|
+
//#region ../corpus/dist/Context/index.d.ts
|
|
887
|
+
/**
|
|
888
|
+
* Declaration target for {@link Context.data}, the request-scoped state shared
|
|
889
|
+
* between {@link Middleware} and route handlers.
|
|
890
|
+
*
|
|
891
|
+
* Empty by design. Augment it from your own code so everything a middleware sets
|
|
892
|
+
* is typed where a handler reads it:
|
|
893
|
+
*
|
|
894
|
+
* ```ts
|
|
895
|
+
* declare module "@ozanarslan/corpus" {
|
|
896
|
+
* interface ContextDataInterface {
|
|
897
|
+
* user: User;
|
|
898
|
+
* }
|
|
899
|
+
* }
|
|
900
|
+
* ```
|
|
901
|
+
*/
|
|
902
|
+
interface ContextDataInterface {}
|
|
903
|
+
/**
|
|
904
|
+
* A function that handles a request given its {@link Context}. This is the shape
|
|
905
|
+
* of a {@link RouteBase} handler and of the app-level hooks
|
|
906
|
+
* {@link App.handleNotFound} and {@link App.handlePreflight}.
|
|
907
|
+
*
|
|
908
|
+
* A {@link Middleware} handler is a {@link MiddlewareHandler} instead, since it
|
|
909
|
+
* additionally receives `next`.
|
|
910
|
+
*
|
|
911
|
+
* @param context - The {@link Context} for the request.
|
|
912
|
+
* @returns The response body, a {@link Res}, or a promise of either. Returning
|
|
913
|
+
* `undefined` leaves {@link Context.res} as the handler mutated it.
|
|
914
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
915
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
916
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
917
|
+
* @typeParam R - Response body type.
|
|
918
|
+
*/
|
|
919
|
+
type ContextHandler<B = unknown, S = unknown, P = unknown, R = unknown> = (context: Context<B, S, P, R>) => MaybePromise<R>;
|
|
920
|
+
/**
|
|
921
|
+
* Everything a handler needs to know about one request, and everything it uses
|
|
922
|
+
* to answer it.
|
|
923
|
+
*
|
|
924
|
+
* The type parameters are supplied by the route the context belongs to, so a
|
|
925
|
+
* handler sees its own validated shapes rather than `unknown`.
|
|
926
|
+
*
|
|
927
|
+
* {@link Context.res} and {@link Context.url} are lazy: neither the response
|
|
928
|
+
* object nor the parsed URL is constructed until something reads it, so a
|
|
929
|
+
* handler that returns a body without touching either pays for neither.
|
|
930
|
+
*
|
|
931
|
+
* The parsed containers are created with {@link createSafeObject}, so a payload
|
|
932
|
+
* carrying a `__proto__` key cannot reach `Object.prototype` through them.
|
|
933
|
+
*
|
|
934
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
935
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
936
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
937
|
+
* @typeParam R - Response body type carried by {@link Context.res}.
|
|
938
|
+
*/
|
|
939
|
+
declare class Context<B = unknown, S = unknown, P = unknown, R = unknown> {
|
|
940
|
+
/**
|
|
941
|
+
* Creates a context with empty parsed containers; {@link App} fills them
|
|
942
|
+
* during the request lifecycle.
|
|
943
|
+
*
|
|
944
|
+
* @param req - The incoming request.
|
|
945
|
+
* @param server - The {@link Server} that accepted it. Absent when the request
|
|
946
|
+
* was dispatched without one, which is why {@link Context.server} is optional
|
|
947
|
+
* at every use site — including the WebSocket upgrade.
|
|
948
|
+
*/
|
|
949
|
+
constructor(req: Request, server: Maybe<Server>);
|
|
950
|
+
/**
|
|
951
|
+
* The parsed request body, decoded by {@link BodyParser} and validated against
|
|
952
|
+
* the route's {@link RouteConfig} body schema.
|
|
953
|
+
*
|
|
954
|
+
* Empty for {@link Method.GET} and {@link Method.HEAD} requests, and for any
|
|
955
|
+
* route whose handlers never read it.
|
|
956
|
+
*/
|
|
957
|
+
body: B;
|
|
958
|
+
/**
|
|
959
|
+
* The path parameters matched by the route, parsed by
|
|
960
|
+
* {@link ParsersRegistry.urlParamsParser} and validated against the route's
|
|
961
|
+
* params schema. A wildcard segment is available under the `*` key.
|
|
962
|
+
*/
|
|
963
|
+
params: P;
|
|
964
|
+
/**
|
|
965
|
+
* The query string, parsed by {@link ParsersRegistry.searchParamsParser} and
|
|
966
|
+
* validated against the route's search schema. Empty when the request carried
|
|
967
|
+
* no query string.
|
|
968
|
+
*/
|
|
969
|
+
search: S;
|
|
970
|
+
/**
|
|
971
|
+
* Free-form request-scoped state, shared across the whole
|
|
972
|
+
* {@link Middleware} chain and the route handler. This is how a middleware
|
|
973
|
+
* hands something — an authenticated user, a request id — to what runs after
|
|
974
|
+
* it. Type it by augmenting {@link ContextDataInterface}.
|
|
975
|
+
*/
|
|
976
|
+
data: ContextDataInterface;
|
|
977
|
+
/**
|
|
978
|
+
* The {@link Server} that accepted the request. Needed to upgrade a connection
|
|
979
|
+
* to a {@link WebSocketRoute}; absent when the request was dispatched without
|
|
980
|
+
* a server.
|
|
981
|
+
*/
|
|
982
|
+
readonly server: Maybe<Server>;
|
|
983
|
+
/**
|
|
984
|
+
* The untouched incoming request. Read it for headers and for the raw body;
|
|
985
|
+
* the parsed views live on {@link Context.body} and its siblings.
|
|
986
|
+
*/
|
|
987
|
+
readonly req: Request;
|
|
988
|
+
/** Backing store for {@link Context.res}, constructed on first access. */
|
|
989
|
+
private _res;
|
|
990
|
+
/**
|
|
991
|
+
* The response under construction. Mutate it to set status, headers or body
|
|
992
|
+
* before returning, or assign a whole new {@link Res} to replace it.
|
|
993
|
+
*
|
|
994
|
+
* A {@link Middleware} that replaces this after `next()` resolves wins over
|
|
995
|
+
* whatever the downstream handler returned — see {@link composeHandlerChain}.
|
|
996
|
+
*
|
|
997
|
+
* @returns The response object, created on first access.
|
|
998
|
+
*/
|
|
999
|
+
get res(): Res<R>;
|
|
1000
|
+
set res(value: Res<R>);
|
|
1001
|
+
/** Backing store for {@link Context.url}, parsed on first access. */
|
|
1002
|
+
private _url;
|
|
1003
|
+
/**
|
|
1004
|
+
* The request URL, parsed once and reused.
|
|
1005
|
+
*
|
|
1006
|
+
* @returns The parsed `URL`. Prefer {@link Context.params} and
|
|
1007
|
+
* {@link Context.search} for path and query values; reach for this when you
|
|
1008
|
+
* need the pathname or origin itself, as {@link BundleRoute} does.
|
|
1009
|
+
*/
|
|
1010
|
+
get url(): URL;
|
|
1011
|
+
}
|
|
1012
|
+
//#endregion
|
|
1013
|
+
//#region ../utils/is.d.ts
|
|
1014
|
+
type OrString<T> = T | (string & {});
|
|
1015
|
+
//#endregion
|
|
1016
|
+
//#region src/Importable/index.d.ts
|
|
1017
|
+
type ImportableKind = OrString<"model" | "service" | "controller" | "route" | "exception">;
|
|
1018
|
+
//#endregion
|
|
1019
|
+
//#region src/Config/Config.d.ts
|
|
1020
|
+
interface ApiClientConfig {
|
|
1021
|
+
/**
|
|
1022
|
+
* Disables api client generation.
|
|
1023
|
+
* Types and models are still generated.
|
|
1024
|
+
*
|
|
1025
|
+
* @default false
|
|
1026
|
+
*/
|
|
1027
|
+
disabled: boolean;
|
|
1028
|
+
/**
|
|
1029
|
+
* Controls how the API Client is exported.
|
|
1030
|
+
* Set to false if you don't want the api client.
|
|
1031
|
+
*
|
|
1032
|
+
* @default "CorpusApi"
|
|
1033
|
+
*/
|
|
1034
|
+
exportAs: OrString<"CorpusApi">;
|
|
1035
|
+
/**
|
|
1036
|
+
* Makes all API Client methods and properties static.
|
|
1037
|
+
*
|
|
1038
|
+
* @default false
|
|
1039
|
+
*/
|
|
1040
|
+
useStaticClass: boolean;
|
|
1041
|
+
}
|
|
1042
|
+
interface DefaultMethodsConfig {
|
|
1043
|
+
get: {
|
|
1044
|
+
propertyKey: OrString<"get">;
|
|
1045
|
+
address: `${Method} /${string}`;
|
|
1046
|
+
};
|
|
1047
|
+
getByParams: {
|
|
1048
|
+
propertyKey: OrString<"getByParams">;
|
|
1049
|
+
address: `${Method} /${string}`;
|
|
1050
|
+
};
|
|
1051
|
+
create: {
|
|
1052
|
+
propertyKey: OrString<"create">;
|
|
1053
|
+
address: `${Method} /${string}`;
|
|
1054
|
+
};
|
|
1055
|
+
update: {
|
|
1056
|
+
propertyKey: OrString<"update">;
|
|
1057
|
+
address: `${Method} /${string}`;
|
|
1058
|
+
};
|
|
1059
|
+
remove: {
|
|
1060
|
+
propertyKey: OrString<"remove">;
|
|
1061
|
+
address: `${Method} /${string}`;
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
interface Config {
|
|
1065
|
+
/**
|
|
1066
|
+
* Suppress console logs.
|
|
1067
|
+
*
|
|
1068
|
+
* @default false
|
|
1069
|
+
*/
|
|
1070
|
+
silent: boolean;
|
|
1071
|
+
/**
|
|
1072
|
+
* The server entrypoint file path.
|
|
1073
|
+
* This file should contain your instances and the listen call.
|
|
1074
|
+
*
|
|
1075
|
+
* @default "./src/main.ts"
|
|
1076
|
+
*/
|
|
1077
|
+
main: string;
|
|
1078
|
+
/**
|
|
1079
|
+
* The corpus package path.
|
|
1080
|
+
*
|
|
1081
|
+
* @default "@ozanarslan/corpus"
|
|
1082
|
+
*/
|
|
1083
|
+
pkgPath: string;
|
|
1084
|
+
/**
|
|
1085
|
+
* Casing for file and directory names,
|
|
1086
|
+
*
|
|
1087
|
+
* @default "pascal"
|
|
1088
|
+
*/
|
|
1089
|
+
casing: "pascal" | "camel" | "kebab";
|
|
1090
|
+
/**
|
|
1091
|
+
* Validation Library to generate models using.
|
|
1092
|
+
* Append version number with @ if you need a specific version.
|
|
1093
|
+
*
|
|
1094
|
+
* Default versions:
|
|
1095
|
+
* arktype: "2.2.0"
|
|
1096
|
+
* yup: "1.7.1"
|
|
1097
|
+
* zod: "4.3.6"
|
|
1098
|
+
*
|
|
1099
|
+
* @default null
|
|
1100
|
+
*/
|
|
1101
|
+
validationLibrary: "arktype" | "zod" | "yup" | null;
|
|
1102
|
+
/**
|
|
1103
|
+
* The file path where the generated output will be written.
|
|
1104
|
+
*
|
|
1105
|
+
* @default "./src/corpus.gen.ts"
|
|
1106
|
+
*/
|
|
1107
|
+
output: string;
|
|
1108
|
+
/**
|
|
1109
|
+
* Api Client specific configuration
|
|
1110
|
+
*/
|
|
1111
|
+
apiClient: ApiClientConfig;
|
|
1112
|
+
/**
|
|
1113
|
+
* Collects all models to a namespace.
|
|
1114
|
+
*
|
|
1115
|
+
* @default true
|
|
1116
|
+
*/
|
|
1117
|
+
exportModelsNamespace: boolean;
|
|
1118
|
+
/**
|
|
1119
|
+
* Collects all args to a namespace.
|
|
1120
|
+
* Args are models without the response.
|
|
1121
|
+
*
|
|
1122
|
+
* @default true
|
|
1123
|
+
*/
|
|
1124
|
+
exportArgsNamespace: boolean;
|
|
1125
|
+
/**
|
|
1126
|
+
* Generated method/type names ignore the global prefix by default,
|
|
1127
|
+
* you can optionally include it.
|
|
1128
|
+
*
|
|
1129
|
+
* @default true
|
|
1130
|
+
*/
|
|
1131
|
+
ignoreGlobalPrefix: boolean;
|
|
1132
|
+
/**
|
|
1133
|
+
* Default method names for the add modules.
|
|
1134
|
+
* Used for model, service, and controllers.
|
|
1135
|
+
* Map the default name to your custom one.
|
|
1136
|
+
*/
|
|
1137
|
+
defaultMethods: DefaultMethodsConfig;
|
|
1138
|
+
/**
|
|
1139
|
+
* Custom output path templates per file kind, letting you control your own folder structure.
|
|
1140
|
+
*
|
|
1141
|
+
* Each template is a relative path string that supports the following placeholders:
|
|
1142
|
+
* - `{resource}` — the resource name (e.g. `"user"`), cased per the `casing` option.
|
|
1143
|
+
* - `{kind}` — the file kind (e.g. `"service"`, `"model"`, `"controller"`, `"route"`), cased per the `casing` option.
|
|
1144
|
+
*
|
|
1145
|
+
* Kinds without a matching entry fall back to the default template.
|
|
1146
|
+
* The file extension is preserved as-is and not affected by casing.
|
|
1147
|
+
*
|
|
1148
|
+
* @default "{resource}/{resource}-{kind}.ts" (applied per kind when no override is set)*
|
|
1149
|
+
*
|
|
1150
|
+
*
|
|
1151
|
+
* @example
|
|
1152
|
+
* // group files by kind instead of by resource
|
|
1153
|
+
* {
|
|
1154
|
+
* model: "models/{resource}-model.ts",
|
|
1155
|
+
* service: "services/{resource}-service.ts",
|
|
1156
|
+
* controller: "controllers/{resource}-controller.ts",
|
|
1157
|
+
* }
|
|
1158
|
+
*/
|
|
1159
|
+
folderStructure: Partial<Record<ImportableKind, `${string}.ts`>>;
|
|
1160
|
+
}
|
|
1161
|
+
//#endregion
|
|
1162
|
+
//#region ../utils/object.d.ts
|
|
1163
|
+
type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]>; } : T;
|
|
1164
|
+
declare global {
|
|
1165
|
+
interface ObjectConstructor {
|
|
1166
|
+
keys<O extends object>(o: O): Array<keyof O>;
|
|
1167
|
+
values<O extends object>(o: O): Array<O[keyof O]>;
|
|
1168
|
+
entries<O extends object>(o: O): Array<[keyof O, O[keyof O]]>;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
//#endregion
|
|
1172
|
+
//#region src/Config/defineConfig.d.ts
|
|
1173
|
+
declare function defineConfig(config: DeepPartial<Config>): Config;
|
|
1174
|
+
//#endregion
|
|
1175
|
+
//#region src/exports/generateApiClient.d.ts
|
|
1176
|
+
declare function generateApiClient(prefix: string, routesArr: Array<RouteBase>, config: Config): void;
|
|
1177
|
+
//#endregion
|
|
1178
|
+
export { Config, DefaultMethodsConfig, defineConfig, generateApiClient };
|