alien-middleware 0.8.2 → 0.9.0

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.
@@ -0,0 +1,175 @@
1
+ // node_modules/.pnpm/radashi@12.5.0-beta.6d5c035/node_modules/radashi/dist/radashi.js
2
+ function noop() {
3
+ }
4
+ var isArray = /* @__PURE__ */ (() => Array.isArray)();
5
+ function isFunction(value) {
6
+ return typeof value === "function";
7
+ }
8
+
9
+ // src/url.ts
10
+ var urlDescriptor = {
11
+ configurable: true,
12
+ get() {
13
+ const url = new URL(this.request.url);
14
+ Object.defineProperty(this, "url", { value: url });
15
+ return url;
16
+ }
17
+ };
18
+ function defineParsedURL(context) {
19
+ if (!("url" in context)) {
20
+ Object.defineProperty(context, "url", urlDescriptor);
21
+ }
22
+ }
23
+
24
+ // src/index.ts
25
+ var kRequestChain = Symbol("requestChain");
26
+ var kResponseChain = Symbol("responseChain");
27
+ var kIgnoreNotFound = Symbol("ignoreNotFound");
28
+ var kMiddlewareCache = Symbol("middlewareCache");
29
+ var kResponseHeaders = Symbol("responseHeaders");
30
+ var MiddlewareChain = class _MiddlewareChain {
31
+ [kRequestChain] = [];
32
+ [kResponseChain] = [];
33
+ /**
34
+ * Attach a middleware. If the `response` parameter is declared, it will be
35
+ * treated as a response middleware. Otherwise, it will be treated as a
36
+ * request middleware.
37
+ *
38
+ * If a middleware chain is given, its middlewares will be executed after any
39
+ * existing middlewares in this chain.
40
+ *
41
+ * @returns a new `MiddlewareChain` instance
42
+ */
43
+ use(middleware) {
44
+ if (middleware instanceof _MiddlewareChain) {
45
+ return createHandler(
46
+ [...this[kRequestChain], ...middleware[kRequestChain]],
47
+ [...this[kResponseChain], ...middleware[kResponseChain]]
48
+ );
49
+ }
50
+ let requestChain = this[kRequestChain];
51
+ let responseChain = this[kResponseChain];
52
+ if (middleware.length < 2) {
53
+ requestChain = [...requestChain, middleware];
54
+ } else {
55
+ responseChain = [...responseChain, middleware];
56
+ }
57
+ return createHandler(requestChain, responseChain);
58
+ }
59
+ /**
60
+ * Create a middleware function that encapsulates this middleware chain, so
61
+ * any modifications it makes to the request context are not leaked.
62
+ */
63
+ isolate() {
64
+ return isFunction(this) ? (ctx) => this(ctx) : noop;
65
+ }
66
+ };
67
+ function createHandler(requestChain, responseChain) {
68
+ async function handler(parentContext) {
69
+ const context = Object.create(parentContext);
70
+ context[kIgnoreNotFound] = true;
71
+ defineParsedURL(context);
72
+ const { passThrough } = context;
73
+ let shouldPassThrough = false;
74
+ context.passThrough = () => {
75
+ shouldPassThrough = true;
76
+ };
77
+ context.setHeader = (name, value) => {
78
+ if (context[kResponseHeaders] === parentContext[kResponseHeaders]) {
79
+ context[kResponseHeaders] = new Headers(parentContext[kResponseHeaders]);
80
+ }
81
+ context[kResponseHeaders].set(name, value);
82
+ };
83
+ const cache = context[kMiddlewareCache] ||= /* @__PURE__ */ new Set();
84
+ let response;
85
+ let env;
86
+ for (const middleware of requestChain) {
87
+ if (cache.has(middleware)) {
88
+ continue;
89
+ }
90
+ cache.add(middleware);
91
+ let result = middleware(context);
92
+ if (result instanceof Promise) {
93
+ result = await result;
94
+ }
95
+ if (shouldPassThrough) {
96
+ break;
97
+ }
98
+ if (result) {
99
+ if (result instanceof Response) {
100
+ response = result;
101
+ break;
102
+ }
103
+ for (const key in result) {
104
+ if (key === "env") {
105
+ env ||= createExtendedEnv(context);
106
+ Object.defineProperties(
107
+ env,
108
+ Object.getOwnPropertyDescriptors(result.env)
109
+ );
110
+ } else {
111
+ const descriptor = Object.getOwnPropertyDescriptor(result, key);
112
+ descriptor.configurable = false;
113
+ Object.defineProperty(context, key, descriptor);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ if (!response) {
119
+ if (parentContext[kIgnoreNotFound]) {
120
+ return;
121
+ }
122
+ response = new Response("Not Found", { status: 404 });
123
+ if (shouldPassThrough) {
124
+ passThrough();
125
+ return response;
126
+ }
127
+ } else if (response.type !== "default") {
128
+ response = new Response(response.body, response);
129
+ }
130
+ context[kResponseHeaders]?.forEach((value, name) => {
131
+ response.headers.set(name, value);
132
+ });
133
+ context.setHeader = null;
134
+ for (const middleware of responseChain) {
135
+ if (cache.has(middleware)) {
136
+ continue;
137
+ }
138
+ cache.add(middleware);
139
+ let result = middleware(context, response);
140
+ if (result instanceof Promise) {
141
+ result = await result;
142
+ }
143
+ if (result && result instanceof Response) {
144
+ response = result;
145
+ continue;
146
+ }
147
+ }
148
+ return response;
149
+ }
150
+ Object.setPrototypeOf(handler, MiddlewareChain.prototype);
151
+ handler[kRequestChain] = requestChain;
152
+ handler[kResponseChain] = responseChain;
153
+ return handler;
154
+ }
155
+ function createExtendedEnv(context) {
156
+ const env = /* @__PURE__ */ Object.create(null);
157
+ const superEnv = context.env;
158
+ context.env = (key) => env[key] ?? superEnv(key);
159
+ return env;
160
+ }
161
+ function chain(middleware) {
162
+ if (middleware instanceof MiddlewareChain) {
163
+ return middleware;
164
+ }
165
+ const empty = new MiddlewareChain();
166
+ return middleware ? empty.use(middleware) : empty;
167
+ }
168
+
169
+ export {
170
+ isArray,
171
+ isFunction,
172
+ defineParsedURL,
173
+ MiddlewareChain,
174
+ chain
175
+ };
@@ -0,0 +1,212 @@
1
+ import { Any, noop } from 'radashi';
2
+ import { AdapterRequestContext, HattipHandler } from '@hattip/core';
3
+ import { InferParams } from 'pathic';
4
+
5
+ type Eval<T> = {} & {
6
+ [K in keyof T]: T[K] extends infer U ? U : never;
7
+ };
8
+ type Awaitable<T> = T | Promise<T>;
9
+ type OneOrMany<T> = T | readonly T[];
10
+ /**
11
+ * Converts a type `T` to something that can be intersected with an object.
12
+ */
13
+ type Intersectable<T extends object> = [T] extends [never] ? {} : [T] extends [Any] ? Record<PropertyKey, any> : T;
14
+
15
+ type Keys<T> = T extends any ? keyof T : never;
16
+ type IsOptional<T, K> = K extends keyof T ? T[K] extends Required<T>[K] ? false : true : true;
17
+ type PossiblyUndefined<T, K extends keyof T> = undefined extends Required<T>[K] ? true : false;
18
+ type MergeProperty<TSource, TOverrides, K> = (K extends keyof TOverrides ? PossiblyUndefined<TOverrides, K> extends true ? TOverrides[K] : Exclude<TOverrides[K], undefined> : never) | (IsOptional<TOverrides, K> extends true ? K extends keyof TSource ? TSource[K] : undefined : never) extends infer TProperty ? TProperty : never;
19
+ /**
20
+ * Merge a union of object types (possibly undefined) into a single object type.
21
+ *
22
+ * **FIXME:** Optional properties resolve as `foo: Foo | undefined` instead of `foo?: Foo`.
23
+ */
24
+ type Merge<TSource extends object, TOverrides extends object | undefined> = Eval<Omit<TSource, Keys<TOverrides>> & {
25
+ [K in Keys<TOverrides>]: TOverrides extends any ? MergeProperty<TSource, TOverrides, K> : never;
26
+ }>;
27
+
28
+ type RequestEnvPlugin = {
29
+ /**
30
+ * Add type-safe environment variables. These are accessed with the `env()`
31
+ * method on the request context.
32
+ */
33
+ env?: object;
34
+ };
35
+ /**
36
+ * The object returned by a request middleware that is merged into the request
37
+ * context. The same context property cannot be defined by two different
38
+ * plugins, or an error will be thrown at runtime.
39
+ *
40
+ * May contain special properties:
41
+ * - `env`: Add type-safe environment variables.
42
+ */
43
+ type RequestPlugin = Record<string, unknown> & RequestEnvPlugin;
44
+ type MiddlewareTypes = {
45
+ /** Values expected by the start of the chain. */
46
+ initial: {
47
+ env: object;
48
+ properties: object;
49
+ };
50
+ /** Values provided by the end of the chain. */
51
+ current: {
52
+ env: object;
53
+ properties: object;
54
+ };
55
+ /** Values from the host platform. */
56
+ platform: unknown;
57
+ };
58
+ type AnyMiddlewareTypes = {
59
+ initial: {
60
+ env: any;
61
+ properties: any;
62
+ };
63
+ current: {
64
+ env: any;
65
+ properties: any;
66
+ };
67
+ platform: any;
68
+ };
69
+ type AnyMiddlewareChain = MiddlewareChain<AnyMiddlewareTypes>;
70
+ type Inputs<T extends AnyMiddlewareChain> = T['$']['initial'];
71
+ type InputProperties<T extends AnyMiddlewareChain> = Inputs<T>['properties'];
72
+ type InputEnv<T extends AnyMiddlewareChain> = Inputs<T>['env'];
73
+ type Current<T extends AnyMiddlewareChain> = T['$']['current'];
74
+ type Properties<T extends AnyMiddlewareChain> = Current<T>['properties'];
75
+ type Env<T extends AnyMiddlewareChain> = Current<T>['env'];
76
+ type Platform<T extends AnyMiddlewareChain> = T['$']['platform'];
77
+ interface HattipContext<TPlatform, TEnv extends object> extends AdapterRequestContext<TPlatform> {
78
+ /**
79
+ * The `request.url` string parsed into a `URL` object. Parsing is performed
80
+ * on-demand and the result is cached.
81
+ */
82
+ url: URL;
83
+ env<K extends keyof TEnv>(key: Extract<K, string>): TEnv[K];
84
+ env(key: never): string | undefined;
85
+ /**
86
+ * Set a response header from a request middleware.
87
+ *
88
+ * Response middlewares should use `response.headers.set()` instead.
89
+ */
90
+ setHeader(name: string, value: string): void;
91
+ }
92
+ /**
93
+ * An extensible Hattip context object.
94
+ *
95
+ * NOTE: When using this type on the right side of an `extends` clause, you
96
+ * should prefer `RequestContext<any>` over `RequestContext` (no type
97
+ * parameters), as the default type is stricter.
98
+ */
99
+ type RequestContext<TEnv extends object = any, TProperties extends object = never, TPlatform = any> = HattipContext<TPlatform, TEnv> & Intersectable<TProperties>;
100
+ /**
101
+ * Extract a `RequestContext` type from a `MiddlewareChain` type.
102
+ *
103
+ * When type `T` is `never`, a default context is returned.
104
+ */
105
+ type MiddlewareContext<T extends MiddlewareChain> = [T] extends [never] ? RequestContext<{}, never, unknown> : RequestContext<Env<T>, Properties<T>, Platform<T>>;
106
+ type IsolatedContext<T extends MiddlewareChain> = RequestContext<InputProperties<T>, InputEnv<T>, Platform<T>>;
107
+ type RequestMiddleware<T extends MiddlewareChain = MiddlewareChain> = (context: RequestContext<InputProperties<T>, InputEnv<T>, Platform<T>>) => Awaitable<Response | RequestPlugin | void>;
108
+ type ResponseMiddleware<T extends MiddlewareChain = MiddlewareChain> = (context: RequestContext<InputProperties<T>, InputEnv<T>, Platform<T>>, response: Response) => Awaitable<Response | void>;
109
+ interface RequestHandler<T extends MiddlewareTypes = any> extends HattipHandler<T['platform']>, MiddlewareChain<T> {
110
+ }
111
+ /**
112
+ * Either a request middleware or a response middleware.
113
+ *
114
+ * If your middleware declares the `response` parameter, it's treated as a
115
+ * response middleware. This means it will run *after* a `Response` is generated
116
+ * by a request middleware.
117
+ */
118
+ type Middleware<TEnv extends object = any, TProperties extends object = any, TPlatform = any> = (context: RequestContext<TEnv, TProperties, TPlatform>, response: Response) => Awaitable<Response | RequestPlugin | void>;
119
+ /**
120
+ * Extract a `Middleware` type from a `MiddlewareChain` type.
121
+ */
122
+ type ExtractMiddleware<T extends MiddlewareChain> = Middleware<Env<T>, Properties<T>, Platform<T>>;
123
+ /**
124
+ * Merge a request plugin into a middleware chain.
125
+ */
126
+ type ApplyMiddlewareResult<TParent extends MiddlewareChain, TResult> = Eval<{
127
+ env: Merge<Env<TParent>, TResult extends {
128
+ env: infer TEnv extends object | undefined;
129
+ } ? TEnv : undefined>;
130
+ properties: Merge<Properties<TParent>, TResult extends RequestPlugin ? Omit<TResult, keyof RequestEnvPlugin> : undefined>;
131
+ }>;
132
+ /**
133
+ * This applies a middleware to a chain. If the type `TMiddleware` is itself a
134
+ * chain, it's treated as a nested chain, which won't leak its plugins into the
135
+ * parent chain.
136
+ */
137
+ type ApplyMiddleware<TFirst extends MiddlewareChain, TSecond extends Middleware<Env<TFirst>, Properties<TFirst>, Platform<TFirst>>> = (TSecond extends MiddlewareChain ? {
138
+ env: Merge<Env<TFirst>, Env<TSecond>>;
139
+ properties: Merge<Properties<TFirst>, Properties<TSecond>>;
140
+ } : TSecond extends (...args: any[]) => Awaitable<infer TResult> ? ApplyMiddlewareResult<TFirst, TResult> : Current<TFirst>) extends infer TOutputs extends MiddlewareTypes['current'] ? RequestHandler<{
141
+ initial: Inputs<TFirst>;
142
+ current: TOutputs;
143
+ platform: Platform<TFirst>;
144
+ }> : never;
145
+ type EmptyMiddlewareChain = MiddlewareChain<{
146
+ initial: {
147
+ env: {};
148
+ properties: {};
149
+ };
150
+ current: {
151
+ env: {};
152
+ properties: {};
153
+ };
154
+ platform: unknown;
155
+ }>;
156
+ type ApplyFirstMiddleware<T extends Middleware> = T extends MiddlewareChain ? T : ApplyMiddleware<EmptyMiddlewareChain, T>;
157
+ type RouteMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | (string & {});
158
+ type RouteContext<T extends RouterTypes = any, TPathParams extends object = any, TMethod extends RouteMethod = RouteMethod> = MiddlewareContext<ApplyMiddleware<MiddlewareChain<T['$']>, () => {
159
+ params: TPathParams;
160
+ method: TMethod;
161
+ }>>;
162
+ type RouteHandler<T extends RouterTypes = any, TPathParams extends object = any, TMethod extends RouteMethod = RouteMethod> = (context: RouteContext<T, TPathParams, TMethod>) => Awaitable<Response | void>;
163
+ declare class RouterTypes<T extends MiddlewareChain = any> extends Function {
164
+ /** This property won't exist at runtime. It contains type information for inference purposes. */
165
+ $: T['$'];
166
+ }
167
+ interface Router<T extends MiddlewareChain = any> extends RouterTypes<T> {
168
+ (context: AdapterRequestContext<Platform<T>>): Awaitable<void | Response>;
169
+ use<TPath extends string>(path: TPath, handler: RouteHandler<this, InferParams<TPath>>): Router;
170
+ use<TPath extends string, TMethod extends RouteMethod = RouteMethod>(method: OneOrMany<TMethod> | '*', path: TPath, handler: RouteHandler<this, InferParams<TPath>, TMethod>): Router;
171
+ }
172
+
173
+ declare const kRequestChain: unique symbol;
174
+ declare const kResponseChain: unique symbol;
175
+ declare class MiddlewareChain<T extends MiddlewareTypes = any> {
176
+ /** This property won't exist at runtime. It contains type information for inference purposes. */
177
+ $: T;
178
+ /** The number of parameters when called as a function. */
179
+ readonly length: 1;
180
+ protected [kRequestChain]: RequestMiddleware[];
181
+ protected [kResponseChain]: ResponseMiddleware[];
182
+ /**
183
+ * Attach a middleware. If the `response` parameter is declared, it will be
184
+ * treated as a response middleware. Otherwise, it will be treated as a
185
+ * request middleware.
186
+ *
187
+ * If a middleware chain is given, its middlewares will be executed after any
188
+ * existing middlewares in this chain.
189
+ *
190
+ * @returns a new `MiddlewareChain` instance
191
+ */
192
+ use<const TMiddleware extends ExtractMiddleware<this>>(middleware: TMiddleware): ApplyMiddleware<this, TMiddleware>;
193
+ /**
194
+ * Create a middleware function that encapsulates this middleware chain, so
195
+ * any modifications it makes to the request context are not leaked.
196
+ */
197
+ isolate(): ((ctx: IsolatedContext<this>) => Promise<Response | void>) | typeof noop;
198
+ }
199
+ declare function chain<TEnv extends object = {}, TProperties extends object = {}, TPlatform = unknown>(): MiddlewareChain<{
200
+ initial: {
201
+ env: TEnv;
202
+ properties: TProperties;
203
+ };
204
+ current: {
205
+ env: TEnv;
206
+ properties: TProperties;
207
+ };
208
+ platform: TPlatform;
209
+ }>;
210
+ declare function chain<const T extends Middleware = Middleware>(middleware: T): ApplyFirstMiddleware<T>;
211
+
212
+ export { type ApplyMiddleware as A, type EmptyMiddlewareChain as E, type MiddlewareContext as M, type Router as R, MiddlewareChain as a, type RouteContext as b, type RouteHandler as c, chain as d, type ExtractMiddleware as e, type Middleware as f, type RequestContext as g, type RequestHandler as h, type RequestMiddleware as i, type RequestPlugin as j, type ResponseMiddleware as k };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import 'radashi';
2
- export { A as ApplyMiddleware, e as ExtractMiddleware, f as Middleware, M as MiddlewareChain, a as MiddlewareContext, g as RequestContext, h as RequestHandler, i as RequestMiddleware, j as RequestPlugin, k as ResponseMiddleware, d as chain } from './index-Bpx2B6hx.js';
2
+ export { A as ApplyMiddleware, e as ExtractMiddleware, f as Middleware, a as MiddlewareChain, M as MiddlewareContext, g as RequestContext, h as RequestHandler, i as RequestMiddleware, j as RequestPlugin, k as ResponseMiddleware, d as chain } from './index-vRvlpUCy.js';
3
3
  import '@hattip/core';
4
+ import 'pathic';
package/dist/index.js CHANGED
@@ -1,142 +1,7 @@
1
1
  import {
2
- defineParsedURL,
3
- isFunction,
4
- noop
5
- } from "./chunk-HZDENULC.js";
6
-
7
- // src/index.ts
8
- var kRequestChain = Symbol("requestChain");
9
- var kResponseChain = Symbol("responseChain");
10
- var kIgnoreNotFound = Symbol("ignoreNotFound");
11
- var kMiddlewareCache = Symbol("middlewareCache");
12
- var MiddlewareChain = class _MiddlewareChain {
13
- [kRequestChain] = [];
14
- [kResponseChain] = [];
15
- /**
16
- * Attach a middleware. If the `response` parameter is declared, it will be
17
- * treated as a response middleware. Otherwise, it will be treated as a
18
- * request middleware.
19
- *
20
- * If a middleware chain is given, its middlewares will be executed after any
21
- * existing middlewares in this chain.
22
- *
23
- * @returns a new `MiddlewareChain` instance
24
- */
25
- use(middleware) {
26
- if (middleware instanceof _MiddlewareChain) {
27
- return createHandler(
28
- [...this[kRequestChain], ...middleware[kRequestChain]],
29
- [...this[kResponseChain], ...middleware[kResponseChain]]
30
- );
31
- }
32
- let requestChain = this[kRequestChain];
33
- let responseChain = this[kResponseChain];
34
- if (middleware.length < 2) {
35
- requestChain = [...requestChain, middleware];
36
- } else {
37
- responseChain = [...responseChain, middleware];
38
- }
39
- return createHandler(requestChain, responseChain);
40
- }
41
- /**
42
- * Create a middleware function that encapsulates this middleware chain, so
43
- * any modifications it makes to the request context are not leaked.
44
- */
45
- isolate() {
46
- return isFunction(this) ? (ctx) => this(ctx) : noop;
47
- }
48
- };
49
- function createHandler(requestChain, responseChain) {
50
- async function handler(parentContext) {
51
- const context = Object.create(parentContext);
52
- context[kIgnoreNotFound] = true;
53
- defineParsedURL(context);
54
- const { passThrough } = context;
55
- let shouldPassThrough = false;
56
- context.passThrough = () => {
57
- shouldPassThrough = true;
58
- };
59
- const cache = context[kMiddlewareCache] ||= /* @__PURE__ */ new Set();
60
- let response;
61
- let env;
62
- for (const middleware of requestChain) {
63
- if (cache.has(middleware)) {
64
- continue;
65
- }
66
- cache.add(middleware);
67
- let result = middleware(context);
68
- if (result instanceof Promise) {
69
- result = await result;
70
- }
71
- if (shouldPassThrough) {
72
- break;
73
- }
74
- if (result) {
75
- if (result instanceof Response) {
76
- response = result;
77
- break;
78
- }
79
- for (const key in result) {
80
- if (key === "env") {
81
- env ||= createExtendedEnv(context);
82
- Object.defineProperties(
83
- env,
84
- Object.getOwnPropertyDescriptors(result.env)
85
- );
86
- } else {
87
- const descriptor = Object.getOwnPropertyDescriptor(result, key);
88
- descriptor.configurable = false;
89
- Object.defineProperty(context, key, descriptor);
90
- }
91
- }
92
- }
93
- }
94
- if (!response) {
95
- if (parentContext[kIgnoreNotFound]) {
96
- return;
97
- }
98
- response = new Response("Not Found", { status: 404 });
99
- if (shouldPassThrough) {
100
- passThrough();
101
- return response;
102
- }
103
- } else if (response.type !== "default") {
104
- response = new Response(response.body, response);
105
- }
106
- for (const middleware of responseChain) {
107
- if (cache.has(middleware)) {
108
- continue;
109
- }
110
- cache.add(middleware);
111
- let result = middleware(context, response);
112
- if (result instanceof Promise) {
113
- result = await result;
114
- }
115
- if (result && result instanceof Response) {
116
- response = result;
117
- continue;
118
- }
119
- }
120
- return response;
121
- }
122
- Object.setPrototypeOf(handler, MiddlewareChain.prototype);
123
- handler[kRequestChain] = requestChain;
124
- handler[kResponseChain] = responseChain;
125
- return handler;
126
- }
127
- function createExtendedEnv(context) {
128
- const env = /* @__PURE__ */ Object.create(null);
129
- const superEnv = context.env;
130
- context.env = (key) => env[key] ?? superEnv(key);
131
- return env;
132
- }
133
- function chain(middleware) {
134
- if (middleware instanceof MiddlewareChain) {
135
- return middleware;
136
- }
137
- const empty = new MiddlewareChain();
138
- return middleware ? empty.use(middleware) : empty;
139
- }
2
+ MiddlewareChain,
3
+ chain
4
+ } from "./chunk-OH7VM54L.js";
140
5
  export {
141
6
  MiddlewareChain,
142
7
  chain
package/dist/router.d.ts CHANGED
@@ -1,17 +1,10 @@
1
- import { InferParams } from 'pathic';
2
- import { M as MiddlewareChain, E as EmptyMiddlewareChain, a as MiddlewareContext, R as RouteHandler, b as RouteMethod } from './index-Bpx2B6hx.js';
3
- export { c as RouterContext } from './index-Bpx2B6hx.js';
1
+ import { R as Router, M as MiddlewareContext, a as MiddlewareChain, E as EmptyMiddlewareChain } from './index-vRvlpUCy.js';
2
+ export { b as RouteContext, c as RouteHandler } from './index-vRvlpUCy.js';
4
3
  import 'radashi';
5
4
  import '@hattip/core';
5
+ import 'pathic';
6
6
 
7
- type OneOrMany<T> = T | readonly T[];
8
- type Router<T extends MiddlewareChain = any> = ReturnType<typeof routes<T>>;
9
- declare function routes<T extends MiddlewareChain = EmptyMiddlewareChain>(middlewares?: T): {
10
- (context: MiddlewareContext<T>): void | Response | Promise<void | Response> | undefined;
11
- use: {
12
- <TPath extends string>(path: TPath, handler: RouteHandler<T, InferParams<TPath>>): /*elided*/ any;
13
- <TPath extends string, TMethod extends RouteMethod = RouteMethod>(method: OneOrMany<TMethod> | "*", path: TPath, handler: RouteHandler<T, InferParams<TPath>, TMethod>): /*elided*/ any;
14
- };
15
- };
7
+ type RouterContext<TRouter extends Router> = TRouter extends Router<infer T> ? MiddlewareContext<T> : never;
8
+ declare function routes<T extends MiddlewareChain = EmptyMiddlewareChain>(middlewares?: T): Router<T>;
16
9
 
17
- export { RouteHandler, type Router, routes };
10
+ export { Router, type RouterContext, routes };
package/dist/router.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import {
2
+ chain,
2
3
  defineParsedURL,
3
4
  isArray,
4
5
  isFunction
5
- } from "./chunk-HZDENULC.js";
6
+ } from "./chunk-OH7VM54L.js";
6
7
 
7
8
  // src/router.ts
8
9
  import { compilePaths } from "pathic";
@@ -11,7 +12,23 @@ function routes(middlewares) {
11
12
  const filters = [];
12
13
  const handlers = [];
13
14
  let matcher;
14
- function use(method, path, handler) {
15
+ function handle(context) {
16
+ const method = context.request.method;
17
+ defineParsedURL(context);
18
+ matcher ||= compilePaths(paths);
19
+ return matcher(context.url.pathname, (index, params) => {
20
+ if (!filters[index] || filters[index](method)) {
21
+ context.method = method;
22
+ context.params = params;
23
+ return handlers[index](context);
24
+ }
25
+ });
26
+ }
27
+ const run = middlewares?.use(handle) ?? chain(handle);
28
+ function router(context) {
29
+ return run(context);
30
+ }
31
+ router.use = (method, path, handler) => {
15
32
  if (isFunction(path)) {
16
33
  paths.push(method);
17
34
  filters.push(null);
@@ -25,21 +42,7 @@ function routes(middlewares) {
25
42
  }
26
43
  matcher = void 0;
27
44
  return router;
28
- }
29
- function router(context) {
30
- defineParsedURL(context);
31
- const { request, url } = context;
32
- const method = request.method;
33
- matcher ||= compilePaths(paths);
34
- return matcher(url.pathname, (index, params) => {
35
- if (!filters[index] || filters[index](method)) {
36
- context.method = method;
37
- context.params = params;
38
- return middlewares ? middlewares.use(handlers[index])(context) : handlers[index](context);
39
- }
40
- });
41
- }
42
- router.use = use;
45
+ };
43
46
  return router;
44
47
  }
45
48
  export {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alien-middleware",
3
3
  "type": "module",
4
- "version": "0.8.2",
4
+ "version": "0.9.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -1,29 +0,0 @@
1
- // node_modules/.pnpm/radashi@12.5.0-beta.6d5c035/node_modules/radashi/dist/radashi.js
2
- function noop() {
3
- }
4
- var isArray = /* @__PURE__ */ (() => Array.isArray)();
5
- function isFunction(value) {
6
- return typeof value === "function";
7
- }
8
-
9
- // src/url.ts
10
- var urlDescriptor = {
11
- configurable: true,
12
- get() {
13
- const url = new URL(this.request.url);
14
- Object.defineProperty(this, "url", { value: url });
15
- return url;
16
- }
17
- };
18
- function defineParsedURL(context) {
19
- if (!("url" in context)) {
20
- Object.defineProperty(context, "url", urlDescriptor);
21
- }
22
- }
23
-
24
- export {
25
- noop,
26
- isArray,
27
- isFunction,
28
- defineParsedURL
29
- };
@@ -1,133 +0,0 @@
1
- import { Any, noop } from 'radashi';
2
- import { AdapterRequestContext, HattipHandler } from '@hattip/core';
3
-
4
- type RequestEnvPlugin = {
5
- /**
6
- * Add type-safe environment variables. These are accessed with the `env()`
7
- * method on the request context.
8
- */
9
- env?: object;
10
- };
11
- /**
12
- * The object returned by a request middleware that is merged into the request
13
- * context. The same context property cannot be defined by two different
14
- * plugins, or an error will be thrown at runtime.
15
- *
16
- * May contain special properties:
17
- * - `env`: Add type-safe environment variables.
18
- */
19
- type RequestPlugin = Record<string, unknown> & RequestEnvPlugin;
20
- type Inputs<T extends MiddlewareChain> = T['$']['input'];
21
- type Platform<T extends MiddlewareChain> = T['$']['platform'];
22
- type InputProperties<T extends MiddlewareChain> = Inputs<T>['properties'];
23
- type InputEnv<T extends MiddlewareChain> = Inputs<T>['env'];
24
- type Current<T extends MiddlewareChain> = T['$']['current'];
25
- type Properties<T extends MiddlewareChain> = Current<T>['properties'];
26
- type Env<T extends MiddlewareChain> = Current<T>['env'];
27
- type MiddlewareTypes<TEnv extends object = any, TProperties extends object = any> = {
28
- env: TEnv;
29
- properties: TProperties;
30
- };
31
- interface HattipContext<TPlatform, TEnv extends object> extends AdapterRequestContext<TPlatform> {
32
- /**
33
- * The `request.url` string parsed into a `URL` object. Parsing is performed
34
- * on-demand and the result is cached.
35
- */
36
- url: URL;
37
- env<K extends keyof TEnv>(key: Extract<K, string>): TEnv[K];
38
- env(key: never): string | undefined;
39
- }
40
- /**
41
- * Converts a type `T` to something that can be intersected with an object.
42
- */
43
- type Intersectable<T extends object> = [T] extends [never] ? {} : [T] extends [Any] ? Record<PropertyKey, any> : T;
44
- /**
45
- * An extensible Hattip context object.
46
- *
47
- * NOTE: When using this type on the right side of an `extends` clause, you
48
- * should prefer `RequestContext<any>` over `RequestContext` (no type
49
- * parameters), as the default type is stricter.
50
- */
51
- type RequestContext<TEnv extends object = any, TProperties extends object = never, TPlatform = any> = HattipContext<TPlatform, TEnv> & Intersectable<TProperties>;
52
- /**
53
- * Extract a `RequestContext` type from a `MiddlewareChain` type.
54
- *
55
- * When type `T` is `never`, a default context is returned.
56
- */
57
- type MiddlewareContext<T extends MiddlewareChain> = [T] extends [never] ? RequestContext<{}, never, unknown> : RequestContext<Env<T>, Properties<T>, Platform<T>>;
58
- type IsolatedContext<T extends MiddlewareChain> = RequestContext<InputProperties<T>, InputEnv<T>, Platform<T>>;
59
- type Awaitable<T> = T | Promise<T>;
60
- type RequestMiddleware<T extends MiddlewareChain = MiddlewareChain> = (context: RequestContext<InputProperties<T>, InputEnv<T>, Platform<T>>) => Awaitable<Response | RequestPlugin | void>;
61
- type ResponseMiddleware<T extends MiddlewareChain = MiddlewareChain> = (context: RequestContext<InputProperties<T>, InputEnv<T>, Platform<T>>, response: Response) => Awaitable<Response | void>;
62
- type RequestHandler<TInputs extends MiddlewareTypes = any, TCurrent extends MiddlewareTypes = any, TPlatform = any> = HattipHandler<TPlatform> & MiddlewareChain<TInputs, TCurrent, TPlatform>;
63
- /**
64
- * Either a request middleware or a response middleware.
65
- *
66
- * If your middleware declares the `response` parameter, it's treated as a
67
- * response middleware. This means it will run *after* a `Response` is generated
68
- * by a request middleware.
69
- */
70
- type Middleware<TEnv extends object = any, TProperties extends object = any, TPlatform = any> = (context: RequestContext<TEnv, TProperties, TPlatform>, response: Response) => Awaitable<Response | RequestPlugin | void>;
71
- /**
72
- * Extract a `Middleware` type from a `MiddlewareChain` type.
73
- */
74
- type ExtractMiddleware<T extends MiddlewareChain> = Middleware<Env<T>, Properties<T>, Platform<T>>;
75
- type Merge<TSource extends object, TOverrides extends object | undefined> = {} & (TOverrides extends object ? {
76
- [K in keyof TSource | keyof TOverrides]: K extends keyof TOverrides ? TOverrides[K] : K extends keyof TSource ? TSource[K] : never;
77
- } : TSource);
78
- type ApplyRequestPlugin<TParent extends MiddlewareChain, TPlugin extends RequestPlugin> = {} & MiddlewareTypes<Merge<Env<TParent>, TPlugin['env']>, Merge<Properties<TParent>, Omit<TPlugin, keyof RequestEnvPlugin>>>;
79
- /**
80
- * This applies a middleware to a chain. If the type `TMiddleware` is itself a
81
- * chain, it's treated as a nested chain, which won't leak its plugins into the
82
- * parent chain.
83
- */
84
- type ApplyMiddleware<TFirst extends MiddlewareChain, TSecond extends Middleware<Env<TFirst>, Properties<TFirst>, Platform<TFirst>>> = RequestHandler<Inputs<TFirst>, TSecond extends MiddlewareChain ? MiddlewareTypes<Merge<Env<TFirst>, Env<TSecond>>, Merge<Properties<TFirst>, Properties<TSecond>>> : TSecond extends (...args: any[]) => Awaitable<infer TResult> ? TResult extends RequestPlugin ? ApplyRequestPlugin<TFirst, TResult> : Current<TFirst> : Current<TFirst>, Platform<TFirst>>;
85
- type EmptyMiddlewareChain = MiddlewareChain<MiddlewareTypes<{}, {}>, MiddlewareTypes<{}, {}>, unknown>;
86
- type ApplyFirstMiddleware<T extends Middleware> = T extends MiddlewareChain ? T : ApplyMiddleware<EmptyMiddlewareChain, T>;
87
- type RouteMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
88
- type RouterContext<T extends MiddlewareChain = any, TPathParams extends object = any, TMethod extends RouteMethod = RouteMethod> = MiddlewareContext<T> & {
89
- params: TPathParams;
90
- method: TMethod;
91
- };
92
- type RouteHandler<T extends MiddlewareChain = any, TPathParams extends object = any, TMethod extends RouteMethod = RouteMethod> = (context: RouterContext<T, TPathParams, TMethod>) => Awaitable<Response | void>;
93
-
94
- declare const kRequestChain: unique symbol;
95
- declare const kResponseChain: unique symbol;
96
- declare class MiddlewareChain<
97
- /** Values expected by the start of the chain. */
98
- TInputs extends MiddlewareTypes = any,
99
- /** Values provided by the end of the chain. */
100
- TCurrent extends MiddlewareTypes = any,
101
- /** Values from the host platform. */
102
- TPlatform = any> {
103
- /** This property won't exist at runtime. It contains type information for inference purposes. */
104
- $: {
105
- input: TInputs;
106
- current: TCurrent;
107
- platform: TPlatform;
108
- };
109
- /** The number of parameters when called as a function. */
110
- readonly length: 1;
111
- protected [kRequestChain]: RequestMiddleware[];
112
- protected [kResponseChain]: ResponseMiddleware[];
113
- /**
114
- * Attach a middleware. If the `response` parameter is declared, it will be
115
- * treated as a response middleware. Otherwise, it will be treated as a
116
- * request middleware.
117
- *
118
- * If a middleware chain is given, its middlewares will be executed after any
119
- * existing middlewares in this chain.
120
- *
121
- * @returns a new `MiddlewareChain` instance
122
- */
123
- use<const TMiddleware extends ExtractMiddleware<this>>(middleware: TMiddleware): ApplyMiddleware<this, TMiddleware>;
124
- /**
125
- * Create a middleware function that encapsulates this middleware chain, so
126
- * any modifications it makes to the request context are not leaked.
127
- */
128
- isolate(): ((ctx: IsolatedContext<this>) => Promise<Response | void>) | typeof noop;
129
- }
130
- declare function chain<TEnv extends object = {}, TProperties extends object = {}, TPlatform = unknown>(): MiddlewareChain<MiddlewareTypes<TEnv, TProperties>, MiddlewareTypes<TEnv, TProperties>, TPlatform>;
131
- declare function chain<const T extends Middleware = Middleware>(middleware: T): ApplyFirstMiddleware<T>;
132
-
133
- export { type ApplyMiddleware as A, type EmptyMiddlewareChain as E, MiddlewareChain as M, type RouteHandler as R, type MiddlewareContext as a, type RouteMethod as b, type RouterContext as c, chain as d, type ExtractMiddleware as e, type Middleware as f, type RequestContext as g, type RequestHandler as h, type RequestMiddleware as i, type RequestPlugin as j, type ResponseMiddleware as k };