@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.
Files changed (87) hide show
  1. package/LICENSE.txt +20 -0
  2. package/README.md +337 -0
  3. package/dist/App/index.d.ts +377 -0
  4. package/dist/App/index.d.ts.map +1 -0
  5. package/dist/C.namespace.d.ts +27 -0
  6. package/dist/C.namespace.d.ts.map +1 -0
  7. package/dist/Config/index.d.ts +163 -0
  8. package/dist/Config/index.d.ts.map +1 -0
  9. package/dist/Context/ContextAccess/index.d.ts +50 -0
  10. package/dist/Context/ContextAccess/index.d.ts.map +1 -0
  11. package/dist/Context/index.d.ts +162 -0
  12. package/dist/Context/index.d.ts.map +1 -0
  13. package/dist/Controller/index.d.ts +164 -0
  14. package/dist/Controller/index.d.ts.map +1 -0
  15. package/dist/Cookies/index.d.ts +81 -0
  16. package/dist/Cookies/index.d.ts.map +1 -0
  17. package/dist/Cors/index.d.ts +135 -0
  18. package/dist/Cors/index.d.ts.map +1 -0
  19. package/dist/Exception/index.d.ts +85 -0
  20. package/dist/Exception/index.d.ts.map +1 -0
  21. package/dist/Globals/AppsRegistry/index.d.ts +48 -0
  22. package/dist/Globals/AppsRegistry/index.d.ts.map +1 -0
  23. package/dist/Globals/ParsersRegistry/index.d.ts +93 -0
  24. package/dist/Globals/ParsersRegistry/index.d.ts.map +1 -0
  25. package/dist/Globals/index.d.ts +109 -0
  26. package/dist/Globals/index.d.ts.map +1 -0
  27. package/dist/Headers/index.d.ts +208 -0
  28. package/dist/Headers/index.d.ts.map +1 -0
  29. package/dist/Middleware/index.d.ts +125 -0
  30. package/dist/Middleware/index.d.ts.map +1 -0
  31. package/dist/ParserBase/BodyParser/index.d.ts +138 -0
  32. package/dist/ParserBase/BodyParser/index.d.ts.map +1 -0
  33. package/dist/ParserBase/FormDataParser/index.d.ts +57 -0
  34. package/dist/ParserBase/FormDataParser/index.d.ts.map +1 -0
  35. package/dist/ParserBase/SchemaParser/index.d.ts +143 -0
  36. package/dist/ParserBase/SchemaParser/index.d.ts.map +1 -0
  37. package/dist/ParserBase/SearchParamsParser/index.d.ts +61 -0
  38. package/dist/ParserBase/SearchParamsParser/index.d.ts.map +1 -0
  39. package/dist/ParserBase/URLParamsParser/index.d.ts +32 -0
  40. package/dist/ParserBase/URLParamsParser/index.d.ts.map +1 -0
  41. package/dist/ParserBase/index.d.ts +92 -0
  42. package/dist/ParserBase/index.d.ts.map +1 -0
  43. package/dist/RateLimiter/index.d.ts +321 -0
  44. package/dist/RateLimiter/index.d.ts.map +1 -0
  45. package/dist/Request/index.d.ts +81 -0
  46. package/dist/Request/index.d.ts.map +1 -0
  47. package/dist/Res/index.d.ts +353 -0
  48. package/dist/Res/index.d.ts.map +1 -0
  49. package/dist/RouteBase/BundleRoute/index.d.ts +268 -0
  50. package/dist/RouteBase/BundleRoute/index.d.ts.map +1 -0
  51. package/dist/RouteBase/FileRoute/index.d.ts +121 -0
  52. package/dist/RouteBase/FileRoute/index.d.ts.map +1 -0
  53. package/dist/RouteBase/Route/index.d.ts +83 -0
  54. package/dist/RouteBase/Route/index.d.ts.map +1 -0
  55. package/dist/RouteBase/StaticRoute/index.d.ts +149 -0
  56. package/dist/RouteBase/StaticRoute/index.d.ts.map +1 -0
  57. package/dist/RouteBase/WebSocketRoute/index.d.ts +117 -0
  58. package/dist/RouteBase/WebSocketRoute/index.d.ts.map +1 -0
  59. package/dist/RouteBase/index.d.ts +206 -0
  60. package/dist/RouteBase/index.d.ts.map +1 -0
  61. package/dist/Server/index.d.ts +44 -0
  62. package/dist/Server/index.d.ts.map +1 -0
  63. package/dist/XFile/index.d.ts +202 -0
  64. package/dist/XFile/index.d.ts.map +1 -0
  65. package/dist/exports.d.ts +11 -0
  66. package/dist/exports.d.ts.map +1 -0
  67. package/dist/index.d.ts +5 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +12 -0
  70. package/dist/index.js.map +47 -0
  71. package/dist/initialize.d.ts +22 -0
  72. package/dist/initialize.d.ts.map +1 -0
  73. package/dist/utils/assert.d.ts +7 -0
  74. package/dist/utils/assert.d.ts.map +1 -0
  75. package/dist/utils/is.d.ts +17 -0
  76. package/dist/utils/is.d.ts.map +1 -0
  77. package/dist/utils/lazy.d.ts +27 -0
  78. package/dist/utils/lazy.d.ts.map +1 -0
  79. package/dist/utils/logger.d.ts +31 -0
  80. package/dist/utils/logger.d.ts.map +1 -0
  81. package/dist/utils/object.d.ts +20 -0
  82. package/dist/utils/object.d.ts.map +1 -0
  83. package/dist/utils/path.d.ts +6 -0
  84. package/dist/utils/path.d.ts.map +1 -0
  85. package/dist/utils/tuple.d.ts +3 -0
  86. package/dist/utils/tuple.d.ts.map +1 -0
  87. package/package.json +57 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Process-wide registry of every {@link AppInterface} instance that has been
3
+ * constructed.
4
+ *
5
+ * The registry is what lets {@link RouteBase} implementations and
6
+ * {@link Middleware} attach themselves without being handed an app: they call
7
+ * {@link getNearestApp} and find the most recently constructed one. The array
8
+ * lives on {@link Globals}, so it survives module re-evaluation and is shared
9
+ * across the whole process.
10
+ *
11
+ * @module AppsRegistry
12
+ */
13
+ import type { AppInterface } from "../../App";
14
+ /**
15
+ * The registry itself: every {@link AppInterface} in construction order, oldest
16
+ * first. The last entry is the one {@link getNearestApp} resolves to.
17
+ */
18
+ type AppsRegistry = Array<AppInterface>;
19
+ /**
20
+ * Reads the registry from {@link Globals}, creating an empty one on first
21
+ * access.
22
+ *
23
+ * @returns The shared {@link AppsRegistry}. The array is live — mutating it
24
+ * mutates the registry.
25
+ */
26
+ declare function getOrInitAppsRegistry(): AppsRegistry;
27
+ /**
28
+ * Resolves the {@link AppInterface} that newly constructed routes and
29
+ * middlewares should attach to: the most recently registered one.
30
+ *
31
+ * With a single app — the common case — this is simply that app. With several,
32
+ * "nearest" means last constructed, so an app must be instantiated before the
33
+ * routes belonging to it.
34
+ *
35
+ * @returns The most recently registered {@link AppInterface}.
36
+ * @throws {@link Error} when no app has been constructed yet.
37
+ */
38
+ declare function getNearestApp(): AppInterface;
39
+ /**
40
+ * Appends an app to the registry, making it the one {@link getNearestApp}
41
+ * returns. Called by the {@link App} constructor; there is no reason to call it
42
+ * by hand.
43
+ *
44
+ * @param app - The {@link AppInterface} to register.
45
+ */
46
+ declare function registerApp(app: AppInterface): void;
47
+ export { type AppsRegistry, getOrInitAppsRegistry, getNearestApp, registerApp };
48
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Globals/AppsRegistry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C;;;GAGG;AACH,KAAK,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;AAExC;;;;;;GAMG;AACH,iBAAS,qBAAqB,IAAI,YAAY,CAM7C;AAED;;;;;;;;;;GAUG;AACH,iBAAS,aAAa,IAAI,YAAY,CAKrC;AAED;;;;;;GAMG;AACH,iBAAS,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAG5C;AAED,OAAO,EAAE,KAAK,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * The single place every parsing decision in the framework is resolved from —
3
+ * and the single place to replace them.
4
+ *
5
+ * Nothing in corpus constructs a parser inline. {@link App} resolves the
6
+ * registry while compiling routes, and {@link BodyParser} reaches back into it
7
+ * for {@link FormDataParser} and {@link SearchParamsParser} rather than owning
8
+ * instances of its own. Replacing an entry therefore changes how the whole
9
+ * framework parses that surface, across every {@link RouteBase} on every
10
+ * {@link App}, without touching a single route definition.
11
+ *
12
+ * Every slot is plug and play. Each is typed as an interface
13
+ * ({@link ParserBaseInterface}, {@link BodyParserInterface},
14
+ * {@link SchemaParserInterface}), never as a concrete class, so a replacement
15
+ * only has to satisfy the contract — subclassing the default is optional.
16
+ *
17
+ * ```ts
18
+ * // Replace one parser; the rest keep their defaults.
19
+ * setParsersRegistry({ bodyParser: new MyBodyParser() });
20
+ *
21
+ * await app.listen();
22
+ * ```
23
+ *
24
+ * Overrides must be in place before {@link App.listen}: routes read the registry
25
+ * as they are compiled, so anything swapped in afterwards is never reached.
26
+ *
27
+ * The registry lives on {@link Globals}, so it is created once per process and
28
+ * shared by every {@link App}.
29
+ *
30
+ * @module ParsersRegistry
31
+ */
32
+ import type { ParserBaseInterface } from "../../ParserBase";
33
+ import { type BodyParserInterface } from "../../ParserBase/BodyParser";
34
+ import { type SchemaParserInterface } from "../../ParserBase/SchemaParser";
35
+ /**
36
+ * The set of parsers the framework resolves at request time. Every field is an
37
+ * interface, so each one can be replaced independently through
38
+ * {@link setParsersRegistry}.
39
+ */
40
+ interface ParsersRegistry {
41
+ /**
42
+ * Turns the raw path parameters matched by a {@link RouteBase} into
43
+ * {@link Context.params}. Defaults to {@link URLParamsParser}.
44
+ */
45
+ urlParamsParser: ParserBaseInterface<Record<string, string>>;
46
+ /**
47
+ * Turns a query string into {@link Context.search}. Defaults to
48
+ * {@link SearchParamsParser}, which {@link BodyParser} also reuses for
49
+ * `application/x-www-form-urlencoded` bodies.
50
+ */
51
+ searchParamsParser: ParserBaseInterface<URLSearchParams>;
52
+ /**
53
+ * Turns `multipart/form-data` into an object. Defaults to
54
+ * {@link FormDataParser} and is reached through {@link BodyParser} rather than
55
+ * called directly.
56
+ */
57
+ formDataParser: ParserBaseInterface<FormData>;
58
+ /**
59
+ * Reads and decodes request and response bodies by content type. Defaults to
60
+ * {@link BodyParser}.
61
+ */
62
+ bodyParser: BodyParserInterface;
63
+ /**
64
+ * Validates already-parsed params, search and body against the schemas
65
+ * declared in a route's {@link Config}. Defaults to {@link SchemaParser},
66
+ * which supports Zod and ArkType.
67
+ */
68
+ schemaParser: SchemaParserInterface;
69
+ }
70
+ /**
71
+ * Reads the registry from {@link Globals}, constructing the defaults on first
72
+ * access.
73
+ *
74
+ * Called by {@link App} during route compilation and by {@link BodyParser} when
75
+ * it needs a sibling parser.
76
+ *
77
+ * @returns The shared {@link ParsersRegistry}.
78
+ */
79
+ declare function getOrInitParsersRegistry(): ParsersRegistry;
80
+ /**
81
+ * Overrides one or more parsers. Only the provided keys are replaced;
82
+ * unspecified parsers keep their current implementation.
83
+ *
84
+ * Must be called before {@link App.listen} — routes resolve their parsers as
85
+ * they are compiled, so a later override has no effect on an already-listening
86
+ * app.
87
+ *
88
+ * @param overrides - The {@link ParsersRegistry} entries to swap in. Each value
89
+ * need only satisfy its interface; it does not have to extend the default class.
90
+ */
91
+ declare function setParsersRegistry(overrides: Partial<ParsersRegistry>): void;
92
+ export { type ParsersRegistry, getOrInitParsersRegistry, setParsersRegistry };
93
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Globals/ParsersRegistry/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,KAAK,mBAAmB,EAAc,MAAM,yBAAyB,CAAC;AAE/E,OAAO,EAAE,KAAK,qBAAqB,EAAgB,MAAM,2BAA2B,CAAC;AAIrF;;;;GAIG;AACH,UAAU,eAAe;IACxB;;;OAGG;IACH,eAAe,EAAE,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D;;;;OAIG;IACH,kBAAkB,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACzD;;;;OAIG;IACH,cAAc,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC9C;;;OAGG;IACH,UAAU,EAAE,mBAAmB,CAAC;IAChC;;;;OAIG;IACH,YAAY,EAAE,qBAAqB,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,iBAAS,wBAAwB,IAAI,eAAe,CAanD;AAED;;;;;;;;;;GAUG;AACH,iBAAS,kBAAkB,CAAC,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAErE;AAED,OAAO,EAAE,KAAK,eAAe,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Typed process-wide state, stored on `globalThis` under package-namespaced
3
+ * symbols.
4
+ *
5
+ * Two things in the framework must be singletons regardless of how many times
6
+ * the module is evaluated: the {@link AppsRegistry} that {@link getNearestApp}
7
+ * resolves against, and the {@link ParsersRegistry} that every route reads while
8
+ * compiling. Module-level variables cannot guarantee that — a duplicated
9
+ * dependency, a re-import under a different resolution, or a test runner
10
+ * reloading modules each produces a second copy, and two apps registries means
11
+ * routes registering onto an app that is never served.
12
+ *
13
+ * The keys are `Symbol.for("@ozanarslan/corpus:<key>")`, so they are shared
14
+ * across every copy of the package in the process and cannot collide with
15
+ * another library's globals.
16
+ *
17
+ * @module Globals
18
+ */
19
+ import type { AppsRegistry } from "./AppsRegistry";
20
+ import type { ParsersRegistry } from "./ParsersRegistry";
21
+ /**
22
+ * What lives in the global store, and the type of each entry. Adding a key here
23
+ * requires a matching entry in {@link GLOBAL_SYMBOLS}, which the `satisfies`
24
+ * clause enforces.
25
+ */
26
+ interface GlobalRegistry {
27
+ /** Whether one-time framework setup has run. */
28
+ initialized: boolean;
29
+ /** The shared {@link AppsRegistry} — every {@link App} constructed in this process. */
30
+ apps: AppsRegistry;
31
+ /** The shared {@link ParsersRegistry} — the parsers routes resolve at compile time. */
32
+ parsers: ParsersRegistry;
33
+ }
34
+ /**
35
+ * The symbol for each {@link GlobalRegistry} entry.
36
+ *
37
+ * Registered through `Symbol.for`, so every copy of the package in the process
38
+ * resolves to the same symbol and therefore to the same stored value.
39
+ */
40
+ declare const GLOBAL_SYMBOLS: {
41
+ readonly initialized: symbol;
42
+ readonly apps: symbol;
43
+ readonly parsers: symbol;
44
+ };
45
+ /**
46
+ * Typed accessor for the global store.
47
+ *
48
+ * Keys are constrained to {@link GlobalRegistry}, so every read and write is
49
+ * checked against the type declared for that entry.
50
+ */
51
+ declare class Globals {
52
+ /** The backing store: `globalThis`, typed for symbol access. */
53
+ private static readonly store;
54
+ /**
55
+ * Returns the symbol an entry is stored under.
56
+ *
57
+ * Useful for inspecting or clearing global state directly — in a test that
58
+ * needs a clean process, for instance.
59
+ *
60
+ * @param key - The {@link GlobalRegistry} entry.
61
+ * @returns Its symbol from {@link GLOBAL_SYMBOLS}.
62
+ */
63
+ static getSymbol<K extends keyof GlobalRegistry>(key: K): (typeof GLOBAL_SYMBOLS)[K];
64
+ /**
65
+ * Reads an entry, creating it on first access.
66
+ *
67
+ * The initialiser runs only when the entry is absent, which is what makes this
68
+ * safe to call from anywhere: the first caller creates the value and every
69
+ * later one gets that same instance. This is how
70
+ * {@link getOrInitAppsRegistry} and {@link getOrInitParsersRegistry} work.
71
+ *
72
+ * @param key - The {@link GlobalRegistry} entry.
73
+ * @param init - Builds the initial value. Not called if the entry exists.
74
+ * @returns The stored value.
75
+ */
76
+ static create<K extends keyof GlobalRegistry>(key: K, init: () => GlobalRegistry[K]): GlobalRegistry[K];
77
+ /**
78
+ * Reads an entry that is expected to exist.
79
+ *
80
+ * @param key - The {@link GlobalRegistry} entry.
81
+ * @returns The stored value.
82
+ * @throws {@link Error} when the entry has not been created. Use
83
+ * {@link Globals.create} when the caller may be the first.
84
+ */
85
+ static get<K extends keyof GlobalRegistry>(key: K): GlobalRegistry[K];
86
+ /**
87
+ * Writes an entry, replacing any existing value.
88
+ *
89
+ * @param key - The {@link GlobalRegistry} entry.
90
+ * @param value - The value to store.
91
+ */
92
+ static set<K extends keyof GlobalRegistry>(key: K, value: GlobalRegistry[K]): void;
93
+ /**
94
+ * Reports whether an entry has been created, without creating it or throwing.
95
+ *
96
+ * @param key - The {@link GlobalRegistry} entry.
97
+ * @returns `true` when the entry exists.
98
+ */
99
+ static has<K extends keyof GlobalRegistry>(key: K): boolean;
100
+ /**
101
+ * Removes an entry, so the next {@link Globals.create} rebuilds it from
102
+ * scratch. Mainly useful for resetting state between tests.
103
+ *
104
+ * @param key - The {@link GlobalRegistry} entry.
105
+ */
106
+ static delete<K extends keyof GlobalRegistry>(key: K): void;
107
+ }
108
+ export { type GlobalRegistry, Globals, GLOBAL_SYMBOLS };
109
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Globals/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAKjE;;;;GAIG;AACH,UAAU,cAAc;IAEvB,gDAAgD;IAChD,WAAW,EAAE,OAAO,CAAC;IACrB,uFAAuF;IACvF,IAAI,EAAE,YAAY,CAAC;IACnB,uFAAuF;IACvF,OAAO,EAAE,eAAe,CAAC;CACzB;AAWD;;;;;GAKG;AACH,QAAA,MAAM,cAAc;;;;CAIqC,CAAC;AAE1D;;;;;GAKG;AACH,cAAM,OAAO;IACZ,gEAAgE;IAChE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAyC;IAEtE;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC;IAIpF;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,cAAc,EAC3C,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,GAC3B,cAAc,CAAC,CAAC,CAAC;IAMpB;;;;;;;OAOG;IACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAOrE;;;;;OAKG;IACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IAKlF;;;;;OAKG;IACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO;IAK3D;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI;CAI3D;AAED,OAAO,EAAE,KAAK,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Header names, header-value builders, and the `Headers` extensions the
3
+ * framework relies on.
4
+ *
5
+ * Two things happen here. {@link HeaderKey} gives the common header names as
6
+ * documented constants, so header access is autocompleted and typo-free rather
7
+ * than stringly typed. {@link patchGlobalHeaders} then extends the global
8
+ * `Headers` class with conveniences the native API lacks: non-string values,
9
+ * bulk assignment through {@link Headers.setMany}, and structured builders for
10
+ * `Cache-Control` and `Content-Disposition`.
11
+ *
12
+ * The patch is what lets {@link Res}, {@link FileRoute} and {@link BundleRoute}
13
+ * write headers without stringifying every value by hand. It applies to the
14
+ * process's own `Headers`, so it must be installed once at startup, before any
15
+ * request is served.
16
+ *
17
+ * @module Headers
18
+ */
19
+ import type { MaybeArray, Nullable, Optional, OrString } from "../utils/is";
20
+ import type { ValueOf } from "../utils/object";
21
+ /**
22
+ * A value accepted by the patched header setters. Numbers and booleans are
23
+ * stringified on the way in, so a byte length or a flag can be passed as-is.
24
+ */
25
+ type HeadersInitValue = string | number | boolean;
26
+ /**
27
+ * What {@link Headers.setMany} accepts: entry pairs, a plain object, or another
28
+ * `Headers` instance.
29
+ */
30
+ type CustomHeadersInit = [string, HeadersInitValue][] | Record<string, HeadersInitValue> | Headers;
31
+ /** Just some common headers. See [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers) for the full spec. */
32
+ declare const HeaderKey: {
33
+ /** Controls caching mechanisms for requests and responses. */
34
+ readonly CacheControl: "Cache-Control";
35
+ /** Specifies the media type of the resource or data. */
36
+ readonly ContentType: "Content-Type";
37
+ /** Indicates the size of the entity-body in bytes. */
38
+ readonly ContentLength: "Content-Length";
39
+ /** Whether to display payload inline within the page or prompt the user to download it as an attachment. */
40
+ readonly ContentDisposition: "Content-Disposition";
41
+ /** Specifies the character encodings that are acceptable. */
42
+ readonly AcceptEncoding: "Accept-Encoding";
43
+ /** Informs the server about the types of data that can be sent back. */
44
+ readonly Accept: "Accept";
45
+ /** Contains the credentials to authenticate with the server. */
46
+ readonly Authorization: "Authorization";
47
+ /** The user agent string of the client software. */
48
+ readonly UserAgent: "User-Agent";
49
+ /** The domain name of the server and port number. */
50
+ readonly Host: "Host";
51
+ /** The address of the previous web page from which the current request originated. */
52
+ readonly Referer: "Referer";
53
+ /** Indicates whether the connection should be kept alive. */
54
+ readonly Connection: "Connection";
55
+ /** Requests that the server switch to a different protocol (e.g. WebSocket). */
56
+ readonly Upgrade: "Upgrade";
57
+ /** Used to specify directives that must be obeyed by caching mechanisms. */
58
+ readonly Pragma: "Pragma";
59
+ /** The date and time at which the message was sent. */
60
+ readonly Date: "Date";
61
+ /** Makes the request conditional based on the ETag of the resource. */
62
+ readonly IfNoneMatch: "If-None-Match";
63
+ /** Makes the request conditional based on the last modification date. */
64
+ readonly IfModifiedSince: "If-Modified-Since";
65
+ /** An identifier for a specific version of a resource. */
66
+ readonly ETag: "ETag";
67
+ /** The date and time after which the response is considered stale. */
68
+ readonly Expires: "Expires";
69
+ /** The last modification date of the resource. */
70
+ readonly LastModified: "Last-Modified";
71
+ /** Indicates the URL to redirect a page to. */
72
+ readonly Location: "Location";
73
+ /** Defines the authentication method that should be used. */
74
+ readonly WWWAuthenticate: "WWW-Authenticate";
75
+ /** Determines how long the results of a preflight request can be cached. */
76
+ readonly AccessControlMaxAge: "Access-Control-Max-Age";
77
+ /** Indicates whether the response can be shared with resources with credentials. */
78
+ readonly AccessControlAllowCredentials: "Access-Control-Allow-Credentials";
79
+ /** Indicates which HTTP method will be used in the actual CORS request. */
80
+ readonly AccessControlRequestMethod: "Access-Control-Request-Method";
81
+ /** Indicates which headers can be exposed to the browser in a CORS response. */
82
+ readonly AccessControlExposeHeaders: "Access-Control-Expose-Headers";
83
+ /** Indicates which origins are allowed to access the resource. */
84
+ readonly AccessControlAllowOrigin: "Access-Control-Allow-Origin";
85
+ /** Specifies the HTTP methods allowed when accessing the resource in a CORS request. */
86
+ readonly AccessControlAllowMethods: "Access-Control-Allow-Methods";
87
+ /** Specifies the HTTP headers allowed in a CORS request. */
88
+ readonly AccessControlAllowHeaders: "Access-Control-Allow-Headers";
89
+ /** Sends cookies from the server to the client. */
90
+ readonly SetCookie: "Set-Cookie";
91
+ /** Sends cookies from the client to the server. */
92
+ readonly Cookie: "Cookie";
93
+ /** Determines which headers should be used to select a response from cache when content negotiation is in use. */
94
+ readonly Vary: "Vary";
95
+ /** Set to "nosniff" by default in {@link Res}. */
96
+ readonly XContentTypeOptions: "X-Content-Type-Options";
97
+ };
98
+ /**
99
+ * A header name. The {@link HeaderKey} constants are suggested, but
100
+ * {@link OrString} keeps any custom header name assignable — the enum is a
101
+ * convenience, not a restriction.
102
+ */
103
+ type HeaderKey = OrString<ValueOf<typeof HeaderKey>>;
104
+ /**
105
+ * A caching policy, rendered into a `Cache-Control` value by
106
+ * {@link createCacheControlHeader}. Used by {@link FileRoute.cache} and by each
107
+ * entry of a {@link BundleRouteDefinition}.
108
+ */
109
+ interface CacheControlDefinition {
110
+ /** Allows shared caches — proxies and CDNs — to store the response, not just the browser. */
111
+ public?: boolean;
112
+ /** How long the response stays fresh, in seconds. */
113
+ maxAge?: number;
114
+ /** Promises the response will never change, so the browser skips revalidation entirely. Only meaningful with a content hash in the URL. */
115
+ immutable?: boolean;
116
+ /** Caches the response but revalidates before every use. Overrides the other directives except `noStore`. */
117
+ noCache?: boolean;
118
+ /** Forbids storing the response anywhere. Overrides every other directive. */
119
+ noStore?: boolean;
120
+ }
121
+ /**
122
+ * Renders a {@link CacheControlDefinition} into a `Cache-Control` header value.
123
+ *
124
+ * The two prohibitive directives take precedence and are emitted alone, since
125
+ * combining them with freshness directives is contradictory: `noStore` wins over
126
+ * everything, then `noCache`. Otherwise the remaining directives are joined in
127
+ * order.
128
+ *
129
+ * @param def - The caching policy to render.
130
+ * @returns The header value, or an empty string when the definition sets
131
+ * nothing.
132
+ */
133
+ declare function createCacheControlHeader(def: CacheControlDefinition): string;
134
+ /**
135
+ * How a response body should be presented, rendered by
136
+ * {@link createContentDispositionHeader}.
137
+ */
138
+ interface ContentDispositionDefinition {
139
+ /** `"inline"` to display in the browser, `"attachment"` to prompt a download. */
140
+ disposition: "attachment" | "inline";
141
+ /** The name to save the file under. Omit it to let the client decide. */
142
+ filename?: string;
143
+ }
144
+ /**
145
+ * Renders a {@link ContentDispositionDefinition} into a `Content-Disposition`
146
+ * header value.
147
+ *
148
+ * @param def - The disposition to render.
149
+ * @returns The header value, with a quoted `filename` parameter when one is
150
+ * given.
151
+ */
152
+ declare function createContentDispositionHeader(def: ContentDispositionDefinition): string;
153
+ /**
154
+ * Reads a header from any `HeadersInit` shape, without constructing a `Headers`.
155
+ *
156
+ * Header names are case-insensitive, so every shape is matched case-insensitively:
157
+ * a `Headers` instance is probed with both casings, and the array and object
158
+ * forms are scanned with lowercased comparison.
159
+ *
160
+ * @param headers - The headers to read, in any accepted form. `undefined` and
161
+ * `null` are allowed and yield `null`.
162
+ * @param name - The header to look for.
163
+ * @returns The value, or `null` when absent.
164
+ */
165
+ declare function readHeader(headers: Optional<HeadersInit>, name: HeaderKey): Nullable<string>;
166
+ /**
167
+ * Installs the extended `Headers` behaviour declared above onto the global
168
+ * class. Call it once at startup, before any request is served.
169
+ *
170
+ * The patch is applied twice over, deliberately. The prototype methods are
171
+ * replaced so headers *the runtime* created — those on an incoming `Request`, or
172
+ * on a `Response` built elsewhere — gain the same behaviour. The global class is
173
+ * then also replaced with a subclass, so instances constructed after the patch
174
+ * carry the methods as own class members rather than only as prototype
175
+ * assignments.
176
+ *
177
+ * The subclass overrides `Symbol.hasInstance` to defer to the native class, so
178
+ * `instanceof Headers` stays true for objects the runtime created before or
179
+ * outside the patch. Without it, the swap would silently break every
180
+ * `instanceof` check against headers the framework did not construct.
181
+ */
182
+ declare function patchGlobalHeaders(): void;
183
+ declare global {
184
+ /**
185
+ * The `Headers` surface after {@link patchGlobalHeaders} has run.
186
+ *
187
+ * The existing methods are re-declared to accept a {@link HeaderKey} and a
188
+ * {@link HeadersInitValue}; the rest are additions.
189
+ */
190
+ interface Headers {
191
+ /** Adds a value without replacing existing ones. An array appends each item as its own header line. */
192
+ append(name: HeaderKey, value: MaybeArray<HeadersInitValue>): void;
193
+ /** Sets a header, replacing any existing value. Numbers and booleans are stringified. */
194
+ set(name: HeaderKey, value: HeadersInitValue): void;
195
+ /** Reads a header, falling back to the lowercased name. */
196
+ get(name: HeaderKey): Nullable<string>;
197
+ /** Reports whether a header is present, falling back to the lowercased name. */
198
+ has(name: HeaderKey): boolean;
199
+ /** Sets many headers at once. See {@link CustomHeadersInit}. */
200
+ setMany(init: CustomHeadersInit): void;
201
+ /** Sets `Cache-Control` from a {@link CacheControlDefinition}. */
202
+ setCacheControl(def: CacheControlDefinition): void;
203
+ /** Sets `Content-Disposition` from a {@link ContentDispositionDefinition}. */
204
+ setContentDisposition(def: ContentDispositionDefinition): void;
205
+ }
206
+ }
207
+ export { patchGlobalHeaders, createCacheControlHeader, createContentDispositionHeader, readHeader, HeaderKey, type ContentDispositionDefinition, type CacheControlDefinition, };
208
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Headers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Logic that runs around a route handler — before it, after it, or instead of
3
+ * it.
4
+ *
5
+ * A {@link Middleware} receives the {@link Context} and a `next` function. What
6
+ * runs before `await next()` happens on the way in; what runs after it happens
7
+ * on the way out, with the downstream result in hand. Returning early instead of
8
+ * calling `next()` short-circuits the chain, which is how authentication rejects
9
+ * a request without the route handler ever running.
10
+ *
11
+ * Constructing one registers it on the nearest {@link App}, which folds it into
12
+ * each targeted route's chain at compile time via {@link composeHandlerChain}.
13
+ * Targeting is by route id, but {@link Middleware.useOn} accepts routes and
14
+ * {@link Controller} instances directly and resolves the ids itself.
15
+ *
16
+ * ```ts
17
+ * import { Middleware } from "@ozanarslan/corpus";
18
+ *
19
+ * new Middleware({
20
+ * useOn: usersController,
21
+ * handler: async (c, next) => {
22
+ * const started = performance.now();
23
+ * const result = await next();
24
+ * c.res.headers.set("X-Response-Time", performance.now() - started);
25
+ * return result;
26
+ * },
27
+ * });
28
+ * ```
29
+ *
30
+ * @module Middleware
31
+ */
32
+ import type { Context } from "../Context";
33
+ import type { Controller } from "../Controller";
34
+ import type { RouteBase } from "../RouteBase";
35
+ import type { MaybePromise, OrString } from "../utils/is";
36
+ /**
37
+ * A middleware's handler function. Like a {@link ContextHandler}, but with the
38
+ * rest of the chain passed in.
39
+ *
40
+ * What the return value means is resolved by {@link composeHandlerChain}: a
41
+ * returned value short-circuits the chain, `undefined` after calling `next()`
42
+ * passes the downstream result through, and `undefined` without calling `next()`
43
+ * lets the chain continue anyway.
44
+ *
45
+ * @param context - The {@link Context} for the request, shared with every other
46
+ * handler in the chain. Use {@link Context.data} to pass state downstream.
47
+ * @param next - Runs the rest of the chain and resolves to its result. Calling
48
+ * it more than once throws.
49
+ * @returns The response value, or `undefined` to defer to the chain.
50
+ * @typeParam R - The result type passed along the chain.
51
+ */
52
+ type MiddlewareHandler<R = unknown> = (context: Context, next: () => MaybePromise<R>) => MaybePromise<R>;
53
+ /**
54
+ * What a middleware applies to.
55
+ *
56
+ * A {@link RouteBase} targets that route, a {@link Controller} targets every
57
+ * route registered through it, a string targets a route id directly, and an
58
+ * array combines any of these. The literal `"*"` targets every route on the app,
59
+ * including requests that match none — global middlewares also run ahead of
60
+ * {@link App.handleNotFound}.
61
+ */
62
+ type MiddlewareUseOn = Array<RouteBase | Controller | string> | RouteBase | Controller | OrString<"*">;
63
+ /** Construction arguments for a {@link Middleware}. */
64
+ type MiddlewareDefinition = {
65
+ /** What the middleware applies to. Defaults to `"*"` — every route. */
66
+ useOn?: MiddlewareUseOn;
67
+ /** The {@link MiddlewareHandler} to run. */
68
+ handler: MiddlewareHandler;
69
+ };
70
+ /**
71
+ * A handler registered to run around some or all of an app's routes.
72
+ *
73
+ * Middlewares execute in the order {@link App.findMiddlewares} returns them:
74
+ * global ones first, then route-specific ones, then the route handler. Since the
75
+ * chain nests, a global middleware wraps everything after it — its post-`next()`
76
+ * code runs last.
77
+ *
78
+ * Targeting a route id that no route claims is not an error, but the middleware
79
+ * will never run; {@link App.warnUnmatchedMiddlewares} logs a warning at startup
80
+ * when that happens.
81
+ */
82
+ declare class Middleware {
83
+ /**
84
+ * Creates a middleware for subclasses, which declare
85
+ * {@link Middleware.handler} and {@link Middleware.useOn} as class fields and
86
+ * call {@link Middleware.register} themselves.
87
+ */
88
+ constructor();
89
+ /**
90
+ * Creates a middleware and registers it on the nearest {@link App}.
91
+ *
92
+ * @param definition - The {@link MiddlewareDefinition}: the handler, and
93
+ * optionally what it applies to.
94
+ */
95
+ constructor(definition: MiddlewareDefinition);
96
+ /**
97
+ * Registers this middleware on the nearest {@link App} through
98
+ * {@link App.addMiddleware}. Called by the constructor.
99
+ *
100
+ * Registration order relative to routes does not matter — targets are resolved
101
+ * to ids here, and the app only matches them when it compiles routes.
102
+ */
103
+ register(): void;
104
+ /**
105
+ * What this middleware applies to. Defaults to `"*"`, meaning every route on
106
+ * the app.
107
+ */
108
+ useOn: MiddlewareUseOn;
109
+ /** The function that runs when a targeted route is hit. */
110
+ handler: MiddlewareHandler;
111
+ /**
112
+ * The route ids resolved from {@link Middleware.useOn}, which
113
+ * {@link App.addMiddleware} indexes the middleware under.
114
+ *
115
+ * Each target contributes its ids: a route its own, a {@link Controller} all
116
+ * of {@link Controller.routeIds}, and a string itself. Duplicates are
117
+ * collapsed, so a route listed both directly and through its controller is
118
+ * still wrapped once.
119
+ *
120
+ * @returns The ids, or `["*"]` for a global middleware.
121
+ */
122
+ get routeIds(): Array<string>;
123
+ }
124
+ export { Middleware, type MiddlewareDefinition, type MiddlewareUseOn, type MiddlewareHandler };
125
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Middleware/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;;;;;GAeG;AACH,KAAK,iBAAiB,CAAC,CAAC,GAAG,OAAO,IAAI,CACrC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,YAAY,CAAC,CAAC,CAAC,KACvB,YAAY,CAAC,CAAC,CAAC,CAAC;AAErB;;;;;;;;GAQG;AACH,KAAK,eAAe,GACjB,KAAK,CAAC,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC,GACtC,SAAS,GACT,UAAU,GACV,QAAQ,CAAC,GAAG,CAAC,CAAC;AAEjB,uDAAuD;AACvD,KAAK,oBAAoB,GAAG;IAC3B,uEAAuE;IACvE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,OAAO,EAAE,iBAAiB,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,cAAM,UAAU;IACf;;;;OAIG;;IAEH;;;;;OAKG;gBACS,UAAU,EAAE,oBAAoB;IAS5C;;;;;;OAMG;IACH,QAAQ,IAAI,IAAI;IAIhB;;;OAGG;IACH,KAAK,EAAE,eAAe,CAAO;IAE7B,2DAA2D;IAC3D,OAAO,EAAG,iBAAiB,CAAC;IAE5B;;;;;;;;;;OAUG;IACH,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,CAc5B;CACD;AAED,OAAO,EAAE,UAAU,EAAE,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,CAAC"}