@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,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-request object every handler receives.
|
|
3
|
+
*
|
|
4
|
+
* A {@link Context} carries the incoming request alongside the parsed views of
|
|
5
|
+
* it — {@link Context.body}, {@link Context.params}, {@link Context.search} —
|
|
6
|
+
* and the {@link Res} being built up in reply. It is created once per request by
|
|
7
|
+
* the {@link ContextFactory} on {@link App.contextFactory} and threaded through
|
|
8
|
+
* the whole {@link Middleware} chain, so it is also the place to hang state that
|
|
9
|
+
* one handler produces and another consumes.
|
|
10
|
+
*
|
|
11
|
+
* The parsed fields start out empty and are filled by {@link App} during the
|
|
12
|
+
* request lifecycle, but only for the surfaces a route's handlers actually read
|
|
13
|
+
* — {@link getContextAccess} decides that, so an untouched body is never parsed.
|
|
14
|
+
*
|
|
15
|
+
* @module Context
|
|
16
|
+
*/
|
|
17
|
+
import { Res } from "../Res";
|
|
18
|
+
import type { Server } from "../Server";
|
|
19
|
+
import type { Maybe, MaybePromise } from "../utils/is";
|
|
20
|
+
/**
|
|
21
|
+
* Declaration target for {@link Context.data}, the request-scoped state shared
|
|
22
|
+
* between {@link Middleware} and route handlers.
|
|
23
|
+
*
|
|
24
|
+
* Empty by design. Augment it from your own code so everything a middleware sets
|
|
25
|
+
* is typed where a handler reads it:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* declare module "@ozanarslan/corpus" {
|
|
29
|
+
* interface ContextDataInterface {
|
|
30
|
+
* user: User;
|
|
31
|
+
* }
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
interface ContextDataInterface {
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Builds the {@link Context} for an incoming request. Assigned to
|
|
39
|
+
* {@link App.contextFactory}; replace it to have an app construct a
|
|
40
|
+
* {@link Context} subclass.
|
|
41
|
+
*
|
|
42
|
+
* @param request - The incoming request.
|
|
43
|
+
* @param server - The {@link Server} that accepted it, absent when the request
|
|
44
|
+
* was dispatched without one.
|
|
45
|
+
* @returns The context the request will be handled with.
|
|
46
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
47
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
48
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
49
|
+
* @typeParam R - Response body type carried by {@link Context.res}.
|
|
50
|
+
*/
|
|
51
|
+
type ContextFactory<B = unknown, S = unknown, P = unknown, R = unknown> = (request: Request, server: Maybe<Server>) => Context<B, S, P, R>;
|
|
52
|
+
/**
|
|
53
|
+
* A function that handles a request given its {@link Context}. This is the shape
|
|
54
|
+
* of a {@link RouteBase} handler and of the app-level hooks
|
|
55
|
+
* {@link App.handleNotFound} and {@link App.handlePreflight}.
|
|
56
|
+
*
|
|
57
|
+
* A {@link Middleware} handler is a {@link MiddlewareHandler} instead, since it
|
|
58
|
+
* additionally receives `next`.
|
|
59
|
+
*
|
|
60
|
+
* @param context - The {@link Context} for the request.
|
|
61
|
+
* @returns The response body, a {@link Res}, or a promise of either. Returning
|
|
62
|
+
* `undefined` leaves {@link Context.res} as the handler mutated it.
|
|
63
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
64
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
65
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
66
|
+
* @typeParam R - Response body type.
|
|
67
|
+
*/
|
|
68
|
+
type ContextHandler<B = unknown, S = unknown, P = unknown, R = unknown> = (context: Context<B, S, P, R>) => MaybePromise<R>;
|
|
69
|
+
/**
|
|
70
|
+
* Everything a handler needs to know about one request, and everything it uses
|
|
71
|
+
* to answer it.
|
|
72
|
+
*
|
|
73
|
+
* The type parameters are supplied by the route the context belongs to, so a
|
|
74
|
+
* handler sees its own validated shapes rather than `unknown`.
|
|
75
|
+
*
|
|
76
|
+
* {@link Context.res} and {@link Context.url} are lazy: neither the response
|
|
77
|
+
* object nor the parsed URL is constructed until something reads it, so a
|
|
78
|
+
* handler that returns a body without touching either pays for neither.
|
|
79
|
+
*
|
|
80
|
+
* The parsed containers are created with {@link createSafeObject}, so a payload
|
|
81
|
+
* carrying a `__proto__` key cannot reach `Object.prototype` through them.
|
|
82
|
+
*
|
|
83
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
84
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
85
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
86
|
+
* @typeParam R - Response body type carried by {@link Context.res}.
|
|
87
|
+
*/
|
|
88
|
+
declare class Context<B = unknown, S = unknown, P = unknown, R = unknown> {
|
|
89
|
+
/**
|
|
90
|
+
* Creates a context with empty parsed containers; {@link App} fills them
|
|
91
|
+
* during the request lifecycle.
|
|
92
|
+
*
|
|
93
|
+
* @param req - The incoming request.
|
|
94
|
+
* @param server - The {@link Server} that accepted it. Absent when the request
|
|
95
|
+
* was dispatched without one, which is why {@link Context.server} is optional
|
|
96
|
+
* at every use site — including the WebSocket upgrade.
|
|
97
|
+
*/
|
|
98
|
+
constructor(req: Request, server: Maybe<Server>);
|
|
99
|
+
/**
|
|
100
|
+
* The parsed request body, decoded by {@link BodyParser} and validated against
|
|
101
|
+
* the route's {@link RouteConfig} body schema.
|
|
102
|
+
*
|
|
103
|
+
* Empty for {@link Method.GET} and {@link Method.HEAD} requests, and for any
|
|
104
|
+
* route whose handlers never read it.
|
|
105
|
+
*/
|
|
106
|
+
body: B;
|
|
107
|
+
/**
|
|
108
|
+
* The path parameters matched by the route, parsed by
|
|
109
|
+
* {@link ParsersRegistry.urlParamsParser} and validated against the route's
|
|
110
|
+
* params schema. A wildcard segment is available under the `*` key.
|
|
111
|
+
*/
|
|
112
|
+
params: P;
|
|
113
|
+
/**
|
|
114
|
+
* The query string, parsed by {@link ParsersRegistry.searchParamsParser} and
|
|
115
|
+
* validated against the route's search schema. Empty when the request carried
|
|
116
|
+
* no query string.
|
|
117
|
+
*/
|
|
118
|
+
search: S;
|
|
119
|
+
/**
|
|
120
|
+
* Free-form request-scoped state, shared across the whole
|
|
121
|
+
* {@link Middleware} chain and the route handler. This is how a middleware
|
|
122
|
+
* hands something — an authenticated user, a request id — to what runs after
|
|
123
|
+
* it. Type it by augmenting {@link ContextDataInterface}.
|
|
124
|
+
*/
|
|
125
|
+
data: ContextDataInterface;
|
|
126
|
+
/**
|
|
127
|
+
* The {@link Server} that accepted the request. Needed to upgrade a connection
|
|
128
|
+
* to a {@link WebSocketRoute}; absent when the request was dispatched without
|
|
129
|
+
* a server.
|
|
130
|
+
*/
|
|
131
|
+
readonly server: Maybe<Server>;
|
|
132
|
+
/**
|
|
133
|
+
* The untouched incoming request. Read it for headers and for the raw body;
|
|
134
|
+
* the parsed views live on {@link Context.body} and its siblings.
|
|
135
|
+
*/
|
|
136
|
+
readonly req: Request;
|
|
137
|
+
/** Backing store for {@link Context.res}, constructed on first access. */
|
|
138
|
+
private _res;
|
|
139
|
+
/**
|
|
140
|
+
* The response under construction. Mutate it to set status, headers or body
|
|
141
|
+
* before returning, or assign a whole new {@link Res} to replace it.
|
|
142
|
+
*
|
|
143
|
+
* A {@link Middleware} that replaces this after `next()` resolves wins over
|
|
144
|
+
* whatever the downstream handler returned — see {@link composeHandlerChain}.
|
|
145
|
+
*
|
|
146
|
+
* @returns The response object, created on first access.
|
|
147
|
+
*/
|
|
148
|
+
get res(): Res<R>;
|
|
149
|
+
set res(value: Res<R>);
|
|
150
|
+
/** Backing store for {@link Context.url}, parsed on first access. */
|
|
151
|
+
private _url;
|
|
152
|
+
/**
|
|
153
|
+
* The request URL, parsed once and reused.
|
|
154
|
+
*
|
|
155
|
+
* @returns The parsed `URL`. Prefer {@link Context.params} and
|
|
156
|
+
* {@link Context.search} for path and query values; reach for this when you
|
|
157
|
+
* need the pathname or origin itself, as {@link BundleRoute} does.
|
|
158
|
+
*/
|
|
159
|
+
get url(): URL;
|
|
160
|
+
}
|
|
161
|
+
export { Context, type ContextDataInterface, type ContextFactory, type ContextHandler };
|
|
162
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Context/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAItD;;;;;;;;;;;;;;GAcG;AACH,UAAU,oBAAoB;CAAG;AAEjC;;;;;;;;;;;;;GAaG;AACH,KAAK,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,CACzE,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,KACjB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEzB;;;;;;;;;;;;;;;GAeG;AACH,KAAK,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,IAAI,CACzE,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KACxB,YAAY,CAAC,CAAC,CAAC,CAAC;AAErB;;;;;;;;;;;;;;;;;;GAkBG;AACH,cAAM,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IAC/D;;;;;;;;OAQG;gBACS,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IAW/C;;;;;;OAMG;IACH,IAAI,EAAE,CAAC,CAAC;IAER;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;;;OAIG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;;;;OAKG;IACH,IAAI,EAAE,oBAAoB,CAAC;IAE3B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAE/B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IAEtB,0EAA0E;IAC1E,OAAO,CAAC,IAAI,CAAkB;IAE9B;;;;;;;;OAQG;IACH,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAEhB;IAED,IAAI,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAEpB;IAED,qEAAqE;IACrE,OAAO,CAAC,IAAI,CAAY;IAExB;;;;;;OAMG;IACH,IAAI,GAAG,IAAI,GAAG,CAEb;CACD;AAED,OAAO,EAAE,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grouping for routes that share a path prefix and a common preamble.
|
|
3
|
+
*
|
|
4
|
+
* A {@link Controller} is a thin factory: each method constructs the
|
|
5
|
+
* corresponding {@link RouteBase} subclass with the prefix already joined on,
|
|
6
|
+
* records its id, and returns it. The routes are ordinary routes registered on
|
|
7
|
+
* the nearest {@link App} exactly as if they had been constructed directly —
|
|
8
|
+
* a controller adds no dispatch layer of its own.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { Controller } from "@ozanarslan/corpus";
|
|
12
|
+
*
|
|
13
|
+
* const users = new Controller("/users");
|
|
14
|
+
* users.beforeEach = (c) => authenticate(c);
|
|
15
|
+
*
|
|
16
|
+
* users.route("GET /:id", (c) => findUser(c.params.id));
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module Controller
|
|
20
|
+
*/
|
|
21
|
+
import type { ContextHandler } from "../Context";
|
|
22
|
+
import { BundleRoute } from "../RouteBase/BundleRoute";
|
|
23
|
+
import { FileRoute } from "../RouteBase/FileRoute";
|
|
24
|
+
import { Route } from "../RouteBase/Route";
|
|
25
|
+
import { StaticRoute } from "../RouteBase/StaticRoute";
|
|
26
|
+
import { WebSocketRoute } from "../RouteBase/WebSocketRoute";
|
|
27
|
+
import type { Optional } from "../utils/is";
|
|
28
|
+
import { type WithPrefix } from "../utils/path";
|
|
29
|
+
/**
|
|
30
|
+
* Registers routes under a shared path prefix.
|
|
31
|
+
*
|
|
32
|
+
* Every method mirrors the constructor of the route class it creates, so moving
|
|
33
|
+
* a route into a controller means changing the call site and nothing else. The
|
|
34
|
+
* prefix is folded into the endpoint at construction time and into the endpoint
|
|
35
|
+
* *type* through {@link WithPrefix}, so the returned route stays as narrowly
|
|
36
|
+
* typed as one written out by hand.
|
|
37
|
+
*
|
|
38
|
+
* {@link Controller.beforeEach} runs ahead of the handler for the route kinds
|
|
39
|
+
* that have a user-supplied handler — {@link Controller.route} and
|
|
40
|
+
* {@link Controller.staticRoute}. The other kinds resolve their responses
|
|
41
|
+
* internally and are unaffected.
|
|
42
|
+
*
|
|
43
|
+
* {@link Controller.routeIds} makes the group addressable afterwards, which is
|
|
44
|
+
* how a {@link Middleware} can be attached to every route in a controller at
|
|
45
|
+
* once.
|
|
46
|
+
*
|
|
47
|
+
* @typeParam Px - The literal prefix type, carried into every endpoint type the
|
|
48
|
+
* controller produces.
|
|
49
|
+
*/
|
|
50
|
+
declare class Controller<Px extends Optional<string> = Optional<string>> {
|
|
51
|
+
prefix?: Px | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Creates a controller.
|
|
54
|
+
*
|
|
55
|
+
* @param prefix - Path segment prepended to every endpoint registered through
|
|
56
|
+
* this controller. Omit it to group routes without changing their paths — the
|
|
57
|
+
* shared {@link Controller.beforeEach} and {@link Controller.routeIds} still
|
|
58
|
+
* apply.
|
|
59
|
+
*/
|
|
60
|
+
constructor(prefix?: Px | undefined);
|
|
61
|
+
/**
|
|
62
|
+
* Ids of every {@link RouteBase} registered through this controller, in the
|
|
63
|
+
* order they were created.
|
|
64
|
+
*
|
|
65
|
+
* Pass them to a {@link Middleware} to target the whole group:
|
|
66
|
+
*
|
|
67
|
+
* ```ts
|
|
68
|
+
* new Middleware([...users.routeIds], handler);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
readonly routeIds: Set<string>;
|
|
72
|
+
/**
|
|
73
|
+
* Runs before the handler of every {@link Controller.route} and
|
|
74
|
+
* {@link Controller.staticRoute} created by this controller.
|
|
75
|
+
*
|
|
76
|
+
* Its return value is discarded — this is for side effects on the
|
|
77
|
+
* {@link Context}, such as authenticating a request or populating
|
|
78
|
+
* {@link Context.data}. Throwing here aborts the request before the handler
|
|
79
|
+
* runs, which is the intended way to reject one.
|
|
80
|
+
*
|
|
81
|
+
* Assign it before registering routes: each route captures the controller, not
|
|
82
|
+
* the function, but a route registered while it is unset still checks it at
|
|
83
|
+
* request time. For behaviour that must wrap the response as well as precede
|
|
84
|
+
* it, use a {@link Middleware} targeting {@link Controller.routeIds} instead.
|
|
85
|
+
*/
|
|
86
|
+
beforeEach?: ContextHandler;
|
|
87
|
+
/**
|
|
88
|
+
* Registers a dynamic route under this controller. Behaves identically to {@link Route}
|
|
89
|
+
* but automatically prepends the controller prefix and runs `beforeEach` before the handler.
|
|
90
|
+
*
|
|
91
|
+
* @param args - The {@link Route} constructor arguments: the route address
|
|
92
|
+
* (a `"METHOD /endpoint"` string or a method/endpoint pair), the
|
|
93
|
+
* {@link ContextHandler}, and an optional {@link RouteConfig}.
|
|
94
|
+
* @returns The registered {@link Route}, its endpoint type prefixed.
|
|
95
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
96
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
97
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
98
|
+
* @typeParam R - Response body type.
|
|
99
|
+
* @typeParam E - The endpoint literal, before the prefix is applied.
|
|
100
|
+
*/
|
|
101
|
+
route<B = unknown, S = unknown, P = unknown, R = unknown, E extends string = string>(...args: ConstructorParameters<typeof Route<B, S, P, R, E>>): Route<B, S, P, R, WithPrefix<Px, E>>;
|
|
102
|
+
/**
|
|
103
|
+
* Registers a static route under this controller. Behaves identically to {@link StaticRoute}
|
|
104
|
+
* but automatically prepends the controller prefix.
|
|
105
|
+
*
|
|
106
|
+
* {@link Controller.beforeEach} runs only when a callback is supplied, since
|
|
107
|
+
* that is where the controller has a handler to wrap; a static route that just
|
|
108
|
+
* serves its file is left alone.
|
|
109
|
+
*
|
|
110
|
+
* @param args - The {@link StaticRoute} constructor arguments: the route
|
|
111
|
+
* address, the file path, an optional callback receiving the
|
|
112
|
+
* {@link Context} and the file contents, and an optional
|
|
113
|
+
* {@link RouteConfig}.
|
|
114
|
+
* @returns The registered {@link StaticRoute}, its endpoint type prefixed.
|
|
115
|
+
* @typeParam B - Parsed {@link Context.body} type.
|
|
116
|
+
* @typeParam S - Parsed {@link Context.search} type.
|
|
117
|
+
* @typeParam P - Parsed {@link Context.params} type.
|
|
118
|
+
* @typeParam E - The endpoint literal, before the prefix is applied.
|
|
119
|
+
*/
|
|
120
|
+
staticRoute<B = unknown, S = unknown, P = unknown, E extends string = string>(...args: ConstructorParameters<typeof StaticRoute<B, S, P, E>>): StaticRoute<B, S, P, WithPrefix<Px, E>>;
|
|
121
|
+
/**
|
|
122
|
+
* Registers a file route under this controller. Behaves identically to {@link FileRoute}
|
|
123
|
+
* but automatically prepends the controller prefix.
|
|
124
|
+
*
|
|
125
|
+
* {@link Controller.beforeEach} does not apply: a file route resolves its
|
|
126
|
+
* response internally and takes no handler to wrap.
|
|
127
|
+
*
|
|
128
|
+
* @param args - The {@link FileRoute} constructor arguments: the route address
|
|
129
|
+
* and the file definition.
|
|
130
|
+
* @returns The registered {@link FileRoute}, its endpoint type prefixed.
|
|
131
|
+
* @typeParam E - The endpoint literal, before the prefix is applied.
|
|
132
|
+
*/
|
|
133
|
+
fileRoute<E extends string = string>(...args: ConstructorParameters<typeof FileRoute<E>>): FileRoute<WithPrefix<Px, E>>;
|
|
134
|
+
/**
|
|
135
|
+
* Registers a websocket route under this controller. Behaves identically to {@link WebSocketRoute}
|
|
136
|
+
* but automatically prepends the controller prefix.
|
|
137
|
+
*
|
|
138
|
+
* The address is a plain endpoint rather than a method-and-endpoint pair, since
|
|
139
|
+
* an upgrade is always a {@link Method.GET}.
|
|
140
|
+
* {@link Controller.beforeEach} does not apply — the socket lifecycle
|
|
141
|
+
* callbacks are not a {@link ContextHandler}.
|
|
142
|
+
*
|
|
143
|
+
* @param args - The {@link WebSocketRoute} constructor arguments: the endpoint
|
|
144
|
+
* followed by the socket lifecycle callbacks.
|
|
145
|
+
* @returns The registered {@link WebSocketRoute}, its endpoint type prefixed.
|
|
146
|
+
* @typeParam E - The endpoint literal, before the prefix is applied.
|
|
147
|
+
*/
|
|
148
|
+
websocketRoute<E extends string = string>(...args: ConstructorParameters<typeof WebSocketRoute<E>>): WebSocketRoute<WithPrefix<Px, E>>;
|
|
149
|
+
/**
|
|
150
|
+
* Registers a bundle route under this controller. Behaves identically to {@link BundleRoute}
|
|
151
|
+
* but automatically prepends the controller prefix.
|
|
152
|
+
*
|
|
153
|
+
* {@link Controller.beforeEach} does not apply: a bundle route resolves files
|
|
154
|
+
* internally and takes no handler to wrap.
|
|
155
|
+
*
|
|
156
|
+
* @param args - The {@link BundleRoute} constructor arguments: the endpoint,
|
|
157
|
+
* the directory to serve, and an optional {@link BundleRouteDefinition}.
|
|
158
|
+
* @returns The registered {@link BundleRoute}, its endpoint type prefixed.
|
|
159
|
+
* @typeParam E - The endpoint literal, before the prefix is applied.
|
|
160
|
+
*/
|
|
161
|
+
bundleRoute<E extends string = string>(...args: ConstructorParameters<typeof BundleRoute<E>>): BundleRoute<WithPrefix<Px, E>>;
|
|
162
|
+
}
|
|
163
|
+
export { Controller };
|
|
164
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Controller/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAM,UAAU,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IAS3C,MAAM,CAAC,EAAE,EAAE;IAR9B;;;;;;;OAOG;gBACgB,MAAM,CAAC,EAAE,EAAE,YAAA;IAE9B;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAqB;IAEnD;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAE5B;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EAClF,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GACzD,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAiBvC;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EAC3E,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAC5D,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAoB1C;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAClC,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,GACjD,SAAS,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAU/B;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACvC,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,GACtD,cAAc,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAQpC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACpC,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,GACnD,WAAW,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;CAOjC;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookie reading and writing, built on Bun's native cookie primitives.
|
|
3
|
+
*
|
|
4
|
+
* {@link Cookies} extends `Bun.CookieMap`, so it keeps the whole native API —
|
|
5
|
+
* `get`, `set`, `delete`, iteration — and adds the two constructions the
|
|
6
|
+
* framework needs: parsing an inbound `Cookie` header and parsing outbound
|
|
7
|
+
* `Set-Cookie` headers back into a map.
|
|
8
|
+
*
|
|
9
|
+
* The two header formats are not interchangeable, which is why they get separate
|
|
10
|
+
* entry points: a `Cookie` header is a list of name/value pairs on one line with
|
|
11
|
+
* no attributes, while each `Set-Cookie` header is a single cookie carrying its
|
|
12
|
+
* own `Path`, `Max-Age`, `HttpOnly` and the rest.
|
|
13
|
+
*
|
|
14
|
+
* @module Cookies
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Parses an inbound `Cookie` header into individual cookies.
|
|
18
|
+
*
|
|
19
|
+
* The header is a semicolon-separated list of name/value pairs with no
|
|
20
|
+
* attributes, so each pair is re-serialised on its own before being handed to
|
|
21
|
+
* Bun's parser. Malformed fragments that yield no name are skipped rather than
|
|
22
|
+
* throwing — a single bad pair from a client should not fail the request.
|
|
23
|
+
*
|
|
24
|
+
* @param cookieHeader - The raw `Cookie` header value.
|
|
25
|
+
* @returns The parsed cookies, in header order. Values keep whatever encoding
|
|
26
|
+
* the client sent.
|
|
27
|
+
*/
|
|
28
|
+
declare function parseCookieHeader(cookieHeader: string): Array<Bun.Cookie>;
|
|
29
|
+
/**
|
|
30
|
+
* Parses `Set-Cookie` header values into individual cookies, attributes
|
|
31
|
+
* included.
|
|
32
|
+
*
|
|
33
|
+
* Each header carries exactly one cookie, so no splitting is needed — unlike
|
|
34
|
+
* {@link parseCookieHeader}, which has to break one header into many pairs.
|
|
35
|
+
*
|
|
36
|
+
* @param headers - The raw `Set-Cookie` header values, one per cookie. Use
|
|
37
|
+
* `Headers.getSetCookie()` to obtain them; a plain `get` collapses repeated
|
|
38
|
+
* headers into one string and loses the boundaries.
|
|
39
|
+
* @returns The parsed cookies, in the order given.
|
|
40
|
+
*/
|
|
41
|
+
declare function parseSetCookieHeaders(headers: string[]): Array<Bun.Cookie>;
|
|
42
|
+
/**
|
|
43
|
+
* A cookie map with header-parsing constructors.
|
|
44
|
+
*
|
|
45
|
+
* Everything `Bun.CookieMap` offers is available unchanged; the two static
|
|
46
|
+
* methods are the additions. Use {@link Cookies.fromHeader} for what a client
|
|
47
|
+
* sent and {@link Cookies.fromSetCookieHeaders} for what a server is sending
|
|
48
|
+
* back — reading a response's own cookies, or following them in a client.
|
|
49
|
+
*/
|
|
50
|
+
declare class Cookies extends Bun.CookieMap {
|
|
51
|
+
/**
|
|
52
|
+
* Creates a cookie map, forwarding to the native constructor.
|
|
53
|
+
*
|
|
54
|
+
* `Bun.CookieMap` is a native class that ignores `new.target`, so instances
|
|
55
|
+
* come back with the base prototype and none of the subclass members attached.
|
|
56
|
+
* The prototype is reattached here, which is what makes subclassing work at
|
|
57
|
+
* all.
|
|
58
|
+
*
|
|
59
|
+
* @param args - The native {@link Bun.CookieMap} constructor arguments.
|
|
60
|
+
*/
|
|
61
|
+
constructor(...args: ConstructorParameters<typeof Bun.CookieMap>);
|
|
62
|
+
/**
|
|
63
|
+
* Builds a map from an inbound `Cookie` header.
|
|
64
|
+
*
|
|
65
|
+
* @param cookieHeader - The raw `Cookie` header value, as sent by the client.
|
|
66
|
+
* @returns The cookies it carried. Repeated names resolve to the last
|
|
67
|
+
* occurrence.
|
|
68
|
+
*/
|
|
69
|
+
static fromHeader(cookieHeader: string): Cookies;
|
|
70
|
+
/**
|
|
71
|
+
* Builds a map from outbound `Set-Cookie` headers, preserving each cookie's
|
|
72
|
+
* attributes.
|
|
73
|
+
*
|
|
74
|
+
* @param headers - The raw `Set-Cookie` values, one per cookie.
|
|
75
|
+
* @returns The cookies they describe. Repeated names resolve to the last
|
|
76
|
+
* occurrence.
|
|
77
|
+
*/
|
|
78
|
+
static fromSetCookieHeaders(headers: string[]): Cookies;
|
|
79
|
+
}
|
|
80
|
+
export { Cookies, parseCookieHeader, parseSetCookieHeaders };
|
|
81
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Cookies/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;GAWG;AACH,iBAAS,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAQlE;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAMnE;AAED;;;;;;;GAOG;AACH,cAAM,OAAQ,SAAQ,GAAG,CAAC,SAAS;IAClC;;;;;;;;;OASG;gBACS,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,GAAG,CAAC,SAAS,CAAC;IAOhE;;;;;;OAMG;IACH,MAAM,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAMhD;;;;;;;OAOG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO;CAKvD;AAED,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-origin resource sharing.
|
|
3
|
+
*
|
|
4
|
+
* Constructing a {@link Cors} attaches it to the nearest {@link App}, which then
|
|
5
|
+
* calls it from two places: {@link App.respond} runs {@link Cors.handler} on
|
|
6
|
+
* every outgoing response, after the {@link Middleware} chain has finished, and
|
|
7
|
+
* {@link App.handlePreflight} delegates to {@link Cors.handlePreflight} for
|
|
8
|
+
* `OPTIONS` requests carrying
|
|
9
|
+
* {@link HeaderKey.AccessControlRequestMethod}. Running last is deliberate — a
|
|
10
|
+
* middleware that short-circuits the chain cannot drop the CORS headers.
|
|
11
|
+
*
|
|
12
|
+
* With no {@link Cors} attached, an app answers preflights with
|
|
13
|
+
* {@link Status.NO_CONTENT} and sends no CORS headers at all.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { Cors } from "@ozanarslan/corpus";
|
|
17
|
+
*
|
|
18
|
+
* new Cors({ allowedOrigins: ["https://example.com"], credentials: true });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module Cors
|
|
22
|
+
*/
|
|
23
|
+
import type { ContextHandler } from "../Context";
|
|
24
|
+
import { HeaderKey } from "../Headers";
|
|
25
|
+
/**
|
|
26
|
+
* The CORS policy. Every field is optional; an omitted field means the
|
|
27
|
+
* corresponding header is not sent, with the exception of the origin, which
|
|
28
|
+
* falls back to a wildcard.
|
|
29
|
+
*/
|
|
30
|
+
type CorsOptions = {
|
|
31
|
+
/** Which origins are allowed to access the resource. Use ["*"] for any origin, or specific domains. */
|
|
32
|
+
allowedOrigins?: string[];
|
|
33
|
+
/** Which HTTP methods are allowed (GET, POST, etc.) */
|
|
34
|
+
allowedMethods?: string[];
|
|
35
|
+
/** Which headers can be sent in the request */
|
|
36
|
+
allowedHeaders?: HeaderKey[];
|
|
37
|
+
/** Which headers should be exposed to the client/browser JavaScript
|
|
38
|
+
* These are response headers that the client can read
|
|
39
|
+
* @example ['RateLimit-Limit', 'RateLimit-Remaining', 'X-Custom-Header']
|
|
40
|
+
*/
|
|
41
|
+
exposedHeaders?: HeaderKey[];
|
|
42
|
+
/** Whether to expose cookies and auth headers to the client */
|
|
43
|
+
credentials?: boolean;
|
|
44
|
+
/** How long (in seconds) browsers can cache preflight results. Default: 86400 (24 hours) */
|
|
45
|
+
maxAge?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Whether {@link HeaderKey.AccessControlMaxAge} is sent on ordinary responses
|
|
48
|
+
* as well as on preflights. Preflights always carry it; browsers ignore it
|
|
49
|
+
* elsewhere.
|
|
50
|
+
*/
|
|
51
|
+
includeMaxAgeResponseHeader?: boolean;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* The public shape of a CORS policy, implemented by {@link Cors}. This is the
|
|
55
|
+
* type {@link App.cors} holds, so a custom policy only has to satisfy the
|
|
56
|
+
* contract.
|
|
57
|
+
*/
|
|
58
|
+
interface CorsInterface {
|
|
59
|
+
/** The configured {@link CorsOptions}. */
|
|
60
|
+
opts?: CorsOptions;
|
|
61
|
+
/** Preflight handler for OPTIONS requests. */
|
|
62
|
+
handlePreflight: ContextHandler;
|
|
63
|
+
/** Applies CORS headers to an outgoing response. */
|
|
64
|
+
handler: ContextHandler;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Default {@link CorsInterface} implementation.
|
|
68
|
+
*
|
|
69
|
+
* Both entry points share {@link Cors.applyHeaders}, so a preflight and a real
|
|
70
|
+
* response describe the same policy. The preflight builds a fresh
|
|
71
|
+
* {@link Status.NO_CONTENT} {@link Res} — it never reaches a route handler —
|
|
72
|
+
* while the response path writes onto the {@link Res} that is already being
|
|
73
|
+
* returned.
|
|
74
|
+
*/
|
|
75
|
+
declare class Cors implements CorsInterface {
|
|
76
|
+
opts?: CorsOptions | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Creates a policy and attaches it to the nearest {@link App}.
|
|
79
|
+
*
|
|
80
|
+
* @param opts - The {@link CorsOptions} to enforce. Omitting them yields a
|
|
81
|
+
* permissive wildcard origin with no method, header or exposure restrictions.
|
|
82
|
+
*/
|
|
83
|
+
constructor(opts?: CorsOptions | undefined);
|
|
84
|
+
/**
|
|
85
|
+
* Attaches this policy to the nearest {@link App}, replacing any policy
|
|
86
|
+
* already set. Called by the constructor; an app holds exactly one.
|
|
87
|
+
*/
|
|
88
|
+
register(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Adds the CORS headers to an outgoing response.
|
|
91
|
+
*
|
|
92
|
+
* Called by {@link App.respond} for every response, after the handler chain
|
|
93
|
+
* has produced its result.
|
|
94
|
+
*
|
|
95
|
+
* @param c - The {@link Context} for the request, read for its `Origin` header
|
|
96
|
+
* and written to through {@link Context.res}.
|
|
97
|
+
*/
|
|
98
|
+
handler: ContextHandler;
|
|
99
|
+
/**
|
|
100
|
+
* Preflight handler for OPTIONS requests.
|
|
101
|
+
*
|
|
102
|
+
* Answers with an empty {@link Status.NO_CONTENT} response carrying the full
|
|
103
|
+
* policy, including {@link HeaderKey.AccessControlMaxAge} so the browser can
|
|
104
|
+
* cache the result and skip the round trip on subsequent requests.
|
|
105
|
+
*
|
|
106
|
+
* @param c - The {@link Context} for the preflight request.
|
|
107
|
+
* @returns The preflight {@link Res}.
|
|
108
|
+
*/
|
|
109
|
+
handlePreflight: ContextHandler;
|
|
110
|
+
/**
|
|
111
|
+
* Applies CORS headers to a Headers object given the request origin.
|
|
112
|
+
*
|
|
113
|
+
* Origin resolution has three outcomes. A wildcard policy sends `*`. A policy
|
|
114
|
+
* listing origins sends the request's own origin when it is listed, and no
|
|
115
|
+
* origin header at all when it is not — an unlisted origin is rejected by
|
|
116
|
+
* omission rather than by an error status. A wildcard policy combined with
|
|
117
|
+
* `credentials` reflects the request origin instead of `*`, because the spec
|
|
118
|
+
* forbids the wildcard in credentialed mode. Whenever the origin is reflected,
|
|
119
|
+
* {@link HeaderKey.Vary} is appended so caches key on it.
|
|
120
|
+
*
|
|
121
|
+
* The remaining list headers are written only when their option is a non-empty
|
|
122
|
+
* array, so an unset method or header list leaves the browser's defaults
|
|
123
|
+
* alone.
|
|
124
|
+
*
|
|
125
|
+
* @param headers - The response headers to write into.
|
|
126
|
+
* @param reqOrigin - The request's `Origin` header, or an empty string when it
|
|
127
|
+
* sent none.
|
|
128
|
+
* @param includeMaxAge - Whether to send
|
|
129
|
+
* {@link HeaderKey.AccessControlMaxAge}. Set for preflights, where it governs
|
|
130
|
+
* how long the browser caches the result. Defaults to `false`.
|
|
131
|
+
*/
|
|
132
|
+
protected applyHeaders(headers: Headers, reqOrigin: string, includeMaxAge?: boolean): void;
|
|
133
|
+
}
|
|
134
|
+
export { Cors, type CorsInterface };
|
|
135
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Cors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC;;;;GAIG;AACH,KAAK,WAAW,GAAG;IAClB,uGAAuG;IACvG,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC;IAC7B;;;OAGG;IACH,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC;IAC7B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACtC,CAAC;AAEF;;;;GAIG;AACH,UAAU,aAAa;IACtB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8CAA8C;IAC9C,eAAe,EAAE,cAAc,CAAC;IAChC,oDAAoD;IACpD,OAAO,EAAE,cAAc,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,cAAM,IAAK,YAAW,aAAa;IAOf,IAAI,CAAC,EAAE,WAAW;IANrC;;;;;OAKG;gBACgB,IAAI,CAAC,EAAE,WAAW,YAAA;IAIrC;;;OAGG;IACH,QAAQ,IAAI,IAAI;IAIhB;;;;;;;;OAQG;IACH,OAAO,EAAE,cAAc,CAErB;IAEF;;;;;;;;;OASG;IACH,eAAe,EAAE,cAAc,CAI7B;IAEF;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,IAAI;CA2CxF;AAED,OAAO,EAAE,IAAI,EAAE,KAAK,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Throwing HTTP errors with a status attached.
|
|
3
|
+
*
|
|
4
|
+
* All errors are caught by {@link App.handleError}, whatever their type. What an
|
|
5
|
+
* {@link Exception} adds is the {@link Status} to answer with: it is rendered
|
|
6
|
+
* through {@link Exception.toRes}, message and detail intact, while an ordinary
|
|
7
|
+
* error becomes an opaque {@link Status.INTERNAL_SERVER_ERROR} so an accidental
|
|
8
|
+
* `TypeError` does not leak its message to the client.
|
|
9
|
+
*
|
|
10
|
+
* Throwing one is the intended way to end a request early:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { Exception, Status } from "@ozanarslan/corpus";
|
|
14
|
+
*
|
|
15
|
+
* if (!user) throw new Exception("User not found", Status.NOT_FOUND);
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Subclass it for errors you raise often, so the status and message live in one
|
|
19
|
+
* place rather than at every throw site.
|
|
20
|
+
*
|
|
21
|
+
* @module Exception
|
|
22
|
+
*/
|
|
23
|
+
import { Res, Status } from "../Res";
|
|
24
|
+
/**
|
|
25
|
+
* An error carrying the {@link Status} it should be answered with.
|
|
26
|
+
*
|
|
27
|
+
* Beyond a status, an exception can carry {@link Exception.data} — either
|
|
28
|
+
* arbitrary detail to include in the error body, or a fully formed {@link Res}
|
|
29
|
+
* when the error response needs its own headers or shape.
|
|
30
|
+
*/
|
|
31
|
+
declare class Exception extends Error {
|
|
32
|
+
/**
|
|
33
|
+
* Creates an exception for subclasses, which assign
|
|
34
|
+
* {@link Exception.message}, {@link Exception.status} and
|
|
35
|
+
* {@link Exception.data} themselves.
|
|
36
|
+
*/
|
|
37
|
+
constructor();
|
|
38
|
+
/**
|
|
39
|
+
* Creates an exception to throw from a handler.
|
|
40
|
+
*
|
|
41
|
+
* @param message - Human-readable description. It is sent to the client, so
|
|
42
|
+
* write it for whoever receives the response.
|
|
43
|
+
* @param status - The {@link Status} to answer with.
|
|
44
|
+
* @param data - Optional detail attached to the response body under `error`,
|
|
45
|
+
* such as validation failures. Pass a {@link Res} instead to control the whole
|
|
46
|
+
* error response — see {@link Exception.toRes}.
|
|
47
|
+
*/
|
|
48
|
+
constructor(message: string, status: Status, data?: unknown);
|
|
49
|
+
/** Human-readable description, sent to the client in the error body. */
|
|
50
|
+
message: string;
|
|
51
|
+
/** The {@link Status} the response is sent with. */
|
|
52
|
+
status: Status;
|
|
53
|
+
/**
|
|
54
|
+
* Optional detail. An arbitrary value is placed under `error` in the response
|
|
55
|
+
* body; a {@link Res} is used as the response itself.
|
|
56
|
+
*/
|
|
57
|
+
data?: unknown;
|
|
58
|
+
/**
|
|
59
|
+
* Renders the exception as the response to send.
|
|
60
|
+
*
|
|
61
|
+
* When {@link Exception.data} is a {@link Res}, that response is used directly:
|
|
62
|
+
* its status is overwritten with {@link Exception.status}, the Exception
|
|
63
|
+
* message gets discarded. Otherwise a fresh {@link Res} is built with the
|
|
64
|
+
* message and the detail under `error`.
|
|
65
|
+
*
|
|
66
|
+
* @returns The {@link Res} for this error. Called by
|
|
67
|
+
* {@link App.handleError}.
|
|
68
|
+
*/
|
|
69
|
+
toRes(): Res;
|
|
70
|
+
/**
|
|
71
|
+
* Checks the exception's status, by numeric value or by {@link Status} name.
|
|
72
|
+
*
|
|
73
|
+
* Useful when catching an exception to branch on what went wrong:
|
|
74
|
+
*
|
|
75
|
+
* ```ts
|
|
76
|
+
* if (err instanceof Exception && err.isStatusOf("NOT_FOUND")) { … }
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @param status - A {@link Status} value or one of its keys.
|
|
80
|
+
* @returns `true` when {@link Exception.status} matches.
|
|
81
|
+
*/
|
|
82
|
+
isStatusOf(status: Status | keyof typeof Status): boolean;
|
|
83
|
+
}
|
|
84
|
+
export { Exception };
|
|
85
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Exception/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAGpC;;;;;;GAMG;AACH,cAAM,SAAU,SAAQ,KAAK;IAC5B;;;;OAIG;;IAEH;;;;;;;;;OASG;gBACS,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAY3D,wEAAwE;IAC/D,OAAO,EAAG,MAAM,CAAC;IAE1B,oDAAoD;IACpD,MAAM,EAAG,MAAM,CAAC;IAEhB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;;;;;;;OAUG;IACH,KAAK,IAAI,GAAG;IAQZ;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,OAAO,MAAM,GAAG,OAAO;CAGzD;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|