serverstruct 1.0.0 → 1.2.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.
package/dist/index.d.cts CHANGED
@@ -1,16 +1,19 @@
1
- import { H3, serve } from "h3";
1
+ import * as h30 from "h3";
2
+ import { EventHandlerObject, EventHandlerRequest, H3, H3Event, Middleware, serve } from "h3";
2
3
  import { Box, Constructor } from "getbox";
3
4
 
4
5
  //#region src/index.d.ts
6
+ type MaybePromise<T = unknown> = T | Promise<T>;
7
+ type Server = ReturnType<typeof serve>;
5
8
  type ServeOptions = Parameters<typeof serve>[1];
6
9
  /**
7
- * Creates an h3 application with dependency injection support.
10
+ * Creates an h3 application.
8
11
  *
9
- * @param fn - Function that configures the app. Receives a fresh H3 instance
10
- * and Box instance. Can add routes to the provided app, or create
11
- * and return a new H3 instance.
12
+ * @param setup - Function that configures the app. Receives a fresh H3 instance
13
+ * and Box instance. Can add routes to the provided app, or create
14
+ * and return a new H3 instance.
12
15
  * @param box - Optional Box instance. If not provided, creates a new one.
13
- * @returns Object with `app` (H3 instance) and `serve` method.
16
+ * @returns Object with `app` (H3 instance), `box` (Box instance), and `serve` method.
14
17
  *
15
18
  * @example
16
19
  * ```typescript
@@ -31,24 +34,29 @@ type ServeOptions = Parameters<typeof serve>[1];
31
34
  * await app.serve({ port: 3000 });
32
35
  * ```
33
36
  */
34
- declare function application(fn: (app: H3, box: Box) => H3 | void, box?: Box): {
37
+ declare function application(setup: (app: H3, box: Box) => H3 | void, box?: Box): {
35
38
  app: H3;
36
- serve: (options?: ServeOptions) => ReturnType<typeof serve>;
39
+ box: Box;
40
+ serve: (options?: ServeOptions) => Server;
37
41
  };
38
42
  /**
39
- * Creates a Constructor that produces an h3 app when resolved.
43
+ * Creates an h3 app constructor.
40
44
  *
41
- * Use `box.new(controller)` to create fresh controller instances.
42
- * Controllers can use `box.get()` to access shared dependencies.
43
- *
44
- * @param fn - Function that configures the controller.
45
- * @returns A Constructor that can be resolved via `box.new(controller)`.
45
+ * @param setup - Function that configures the app.
46
+ * @returns A Constructor that produces an h3 app.
46
47
  *
47
48
  * @example
48
49
  * ```typescript
50
+ * import { application, controller } from "serverstruct";
51
+ *
52
+ * class Database {
53
+ * getUsers() { return ["Alice", "Bob"]; }
54
+ * }
55
+ *
49
56
  * // Define a controller
50
57
  * const usersController = controller((app, box) => {
51
- * app.get("/", () => ["Alice", "Bob"]);
58
+ * const db = box.get(Database);
59
+ * app.get("/", () => db.getUsers());
52
60
  * });
53
61
  *
54
62
  * // Use it in your app
@@ -56,20 +64,164 @@ declare function application(fn: (app: H3, box: Box) => H3 | void, box?: Box): {
56
64
  * app.mount("/users", box.new(usersController));
57
65
  * });
58
66
  * ```
67
+ */
68
+ declare function controller(setup: (app: H3, box: Box) => H3 | void): Constructor<H3>;
69
+ /**
70
+ * Creates a handler constructor.
71
+ *
72
+ * @param setup - Handler function that receives the event and Box instance.
73
+ * @returns A Constructor that produces an h3 handler.
59
74
  *
60
75
  * @example
61
76
  * ```typescript
62
- * // Controller with shared dependencies
63
- * class Database {
64
- * getUsers() { return ["Alice", "Bob"]; }
77
+ * import { application, handler } from "serverstruct";
78
+ *
79
+ * class UserService {
80
+ * getUser(id: string) { return { id, name: "Alice" }; }
65
81
  * }
66
82
  *
67
- * const usersController = controller((app, box) => {
68
- * const db = box.get(Database);
69
- * app.get("/", () => db.getUsers());
83
+ * // Define a handler
84
+ * const getUserHandler = handler((event, box) => {
85
+ * const userService = box.get(UserService);
86
+ * const id = event.context.params?.id;
87
+ * return userService.getUser(id);
88
+ * });
89
+ *
90
+ * // Use it in your app
91
+ * const app = application((app, box) => {
92
+ * app.get("/users/:id", box.get(getUserHandler));
93
+ * });
94
+ * ```
95
+ */
96
+ declare function handler<Res = unknown, Req extends EventHandlerRequest = EventHandlerRequest>(setup: (event: H3Event<Req>, box: Box) => Res): Constructor<h30.EventHandlerWithFetch<Req, Res>>;
97
+ /**
98
+ * Creates an event handler constructor from a setup function.
99
+ *
100
+ * @param setup - Function that receives Box instance and returns an event handler object.
101
+ * @returns A Constructor that produces an h3 event handler.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * import { application, eventHandler } from "serverstruct";
106
+ *
107
+ * class UserService {
108
+ * getUser(id: string) { return { id, name: "Alice" }; }
109
+ * }
110
+ *
111
+ * // Define an event handler
112
+ * const getUserHandler = eventHandler((box) => ({
113
+ * handler(event) {
114
+ * const userService = box.get(UserService);
115
+ * const id = event.context.params?.id;
116
+ * return userService.getUser(id);
117
+ * },
118
+ * meta: { auth: true }
119
+ * }));
120
+ *
121
+ * // Use it in your app
122
+ * const app = application((app, box) => {
123
+ * app.get("/users/:id", box.get(getUserHandler));
124
+ * });
125
+ * ```
126
+ */
127
+ declare function eventHandler<Res = unknown, Req extends EventHandlerRequest = EventHandlerRequest>(setup: (box: Box) => EventHandlerObject<Req, Res>): Constructor<h30.EventHandlerWithFetch<Req, Res>>;
128
+ /**
129
+ * Creates a middleware constructor.
130
+ *
131
+ * @param setup - Middleware function that receives the event, next function, and Box instance.
132
+ * @returns A Constructor that produces an h3 middleware.
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * import { application, middleware } from "serverstruct";
137
+ *
138
+ * class AuthService {
139
+ * validateToken(token: string) { return token === "valid"; }
140
+ * }
141
+ *
142
+ * // Define a middleware
143
+ * const authMiddleware = middleware((event, next, box) => {
144
+ * const authService = box.get(AuthService);
145
+ * const token = event.headers.get("authorization");
146
+ * if (!token || !authService.validateToken(token)) {
147
+ * throw new Error("Unauthorized");
148
+ * }
149
+ * });
150
+ *
151
+ * // Use it in your app
152
+ * const app = application((app, box) => {
153
+ * app.use(box.get(authMiddleware));
154
+ * app.get("/", () => "Hello world!");
155
+ * });
156
+ * ```
157
+ */
158
+ declare function middleware(setup: (event: H3Event, next: () => MaybePromise<unknown | undefined>, box: Box) => MaybePromise<unknown | undefined>): Constructor<Middleware>;
159
+ /**
160
+ * A request-scoped context store for associating values with H3 events.
161
+ *
162
+ * Each request gets its own isolated context that is automatically cleaned up
163
+ * when the request completes. Uses a WeakMap internally to ensure values are
164
+ * garbage collected with their events.
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * import { application, Context } from "serverstruct";
169
+ *
170
+ * const userContext = new Context<User>();
171
+ *
172
+ * const app = application((app) => {
173
+ * app.use((event) => {
174
+ * userContext.set(event, { id: "123", name: "Alice" });
175
+ * });
176
+ * app.get("/user", (event) => {
177
+ * const user = userContext.get(event);
178
+ * return user;
179
+ * });
180
+ * });
181
+ * ```
182
+ */
183
+ declare class Context<T> {
184
+ #private;
185
+ /**
186
+ * Sets a value for the given event.
187
+ */
188
+ set(event: H3Event<any>, value: T): void;
189
+ /**
190
+ * Gets the value for the given event.
191
+ * @throws Error if no value is set for the event.
192
+ */
193
+ get(event: H3Event<any>): T;
194
+ /**
195
+ * Gets the value for the given event, or undefined if not set.
196
+ */
197
+ lookup(event: H3Event<any>): T | undefined;
198
+ }
199
+ /**
200
+ * Creates a request-scoped context store for associating values with H3 events.
201
+ *
202
+ * Each request gets its own isolated context that is automatically cleaned up
203
+ * when the request completes. Uses a WeakMap internally to ensure values are
204
+ * garbage collected with their events.
205
+ *
206
+ * @returns A Context instance.
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * import { application, context } from "serverstruct";
211
+ *
212
+ * const userContext = context<User>();
213
+ *
214
+ * const app = application((app) => {
215
+ * app.use((event) => {
216
+ * userContext.set(event, { id: "123", name: "Alice" });
217
+ * });
218
+ * app.get("/user", (event) => {
219
+ * const user = userContext.get(event);
220
+ * return user;
221
+ * });
70
222
  * });
71
223
  * ```
72
224
  */
73
- declare function controller(fn: (app: H3, box: Box) => H3 | void): Constructor<H3>;
225
+ declare function context<T>(): Context<T>;
74
226
  //#endregion
75
- export { ServeOptions, application, controller };
227
+ export { Context, ServeOptions, Server, application, context, controller, eventHandler, handler, middleware };
package/dist/index.d.mts CHANGED
@@ -1,16 +1,19 @@
1
- import { H3, serve } from "h3";
2
1
  import { Box, Constructor } from "getbox";
2
+ import * as h30 from "h3";
3
+ import { EventHandlerObject, EventHandlerRequest, H3, H3Event, Middleware, serve } from "h3";
3
4
 
4
5
  //#region src/index.d.ts
6
+ type MaybePromise<T = unknown> = T | Promise<T>;
7
+ type Server = ReturnType<typeof serve>;
5
8
  type ServeOptions = Parameters<typeof serve>[1];
6
9
  /**
7
- * Creates an h3 application with dependency injection support.
10
+ * Creates an h3 application.
8
11
  *
9
- * @param fn - Function that configures the app. Receives a fresh H3 instance
10
- * and Box instance. Can add routes to the provided app, or create
11
- * and return a new H3 instance.
12
+ * @param setup - Function that configures the app. Receives a fresh H3 instance
13
+ * and Box instance. Can add routes to the provided app, or create
14
+ * and return a new H3 instance.
12
15
  * @param box - Optional Box instance. If not provided, creates a new one.
13
- * @returns Object with `app` (H3 instance) and `serve` method.
16
+ * @returns Object with `app` (H3 instance), `box` (Box instance), and `serve` method.
14
17
  *
15
18
  * @example
16
19
  * ```typescript
@@ -31,24 +34,29 @@ type ServeOptions = Parameters<typeof serve>[1];
31
34
  * await app.serve({ port: 3000 });
32
35
  * ```
33
36
  */
34
- declare function application(fn: (app: H3, box: Box) => H3 | void, box?: Box): {
37
+ declare function application(setup: (app: H3, box: Box) => H3 | void, box?: Box): {
35
38
  app: H3;
36
- serve: (options?: ServeOptions) => ReturnType<typeof serve>;
39
+ box: Box;
40
+ serve: (options?: ServeOptions) => Server;
37
41
  };
38
42
  /**
39
- * Creates a Constructor that produces an h3 app when resolved.
43
+ * Creates an h3 app constructor.
40
44
  *
41
- * Use `box.new(controller)` to create fresh controller instances.
42
- * Controllers can use `box.get()` to access shared dependencies.
43
- *
44
- * @param fn - Function that configures the controller.
45
- * @returns A Constructor that can be resolved via `box.new(controller)`.
45
+ * @param setup - Function that configures the app.
46
+ * @returns A Constructor that produces an h3 app.
46
47
  *
47
48
  * @example
48
49
  * ```typescript
50
+ * import { application, controller } from "serverstruct";
51
+ *
52
+ * class Database {
53
+ * getUsers() { return ["Alice", "Bob"]; }
54
+ * }
55
+ *
49
56
  * // Define a controller
50
57
  * const usersController = controller((app, box) => {
51
- * app.get("/", () => ["Alice", "Bob"]);
58
+ * const db = box.get(Database);
59
+ * app.get("/", () => db.getUsers());
52
60
  * });
53
61
  *
54
62
  * // Use it in your app
@@ -56,20 +64,164 @@ declare function application(fn: (app: H3, box: Box) => H3 | void, box?: Box): {
56
64
  * app.mount("/users", box.new(usersController));
57
65
  * });
58
66
  * ```
67
+ */
68
+ declare function controller(setup: (app: H3, box: Box) => H3 | void): Constructor<H3>;
69
+ /**
70
+ * Creates a handler constructor.
71
+ *
72
+ * @param setup - Handler function that receives the event and Box instance.
73
+ * @returns A Constructor that produces an h3 handler.
59
74
  *
60
75
  * @example
61
76
  * ```typescript
62
- * // Controller with shared dependencies
63
- * class Database {
64
- * getUsers() { return ["Alice", "Bob"]; }
77
+ * import { application, handler } from "serverstruct";
78
+ *
79
+ * class UserService {
80
+ * getUser(id: string) { return { id, name: "Alice" }; }
65
81
  * }
66
82
  *
67
- * const usersController = controller((app, box) => {
68
- * const db = box.get(Database);
69
- * app.get("/", () => db.getUsers());
83
+ * // Define a handler
84
+ * const getUserHandler = handler((event, box) => {
85
+ * const userService = box.get(UserService);
86
+ * const id = event.context.params?.id;
87
+ * return userService.getUser(id);
88
+ * });
89
+ *
90
+ * // Use it in your app
91
+ * const app = application((app, box) => {
92
+ * app.get("/users/:id", box.get(getUserHandler));
93
+ * });
94
+ * ```
95
+ */
96
+ declare function handler<Res = unknown, Req extends EventHandlerRequest = EventHandlerRequest>(setup: (event: H3Event<Req>, box: Box) => Res): Constructor<h30.EventHandlerWithFetch<Req, Res>>;
97
+ /**
98
+ * Creates an event handler constructor from a setup function.
99
+ *
100
+ * @param setup - Function that receives Box instance and returns an event handler object.
101
+ * @returns A Constructor that produces an h3 event handler.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * import { application, eventHandler } from "serverstruct";
106
+ *
107
+ * class UserService {
108
+ * getUser(id: string) { return { id, name: "Alice" }; }
109
+ * }
110
+ *
111
+ * // Define an event handler
112
+ * const getUserHandler = eventHandler((box) => ({
113
+ * handler(event) {
114
+ * const userService = box.get(UserService);
115
+ * const id = event.context.params?.id;
116
+ * return userService.getUser(id);
117
+ * },
118
+ * meta: { auth: true }
119
+ * }));
120
+ *
121
+ * // Use it in your app
122
+ * const app = application((app, box) => {
123
+ * app.get("/users/:id", box.get(getUserHandler));
124
+ * });
125
+ * ```
126
+ */
127
+ declare function eventHandler<Res = unknown, Req extends EventHandlerRequest = EventHandlerRequest>(setup: (box: Box) => EventHandlerObject<Req, Res>): Constructor<h30.EventHandlerWithFetch<Req, Res>>;
128
+ /**
129
+ * Creates a middleware constructor.
130
+ *
131
+ * @param setup - Middleware function that receives the event, next function, and Box instance.
132
+ * @returns A Constructor that produces an h3 middleware.
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * import { application, middleware } from "serverstruct";
137
+ *
138
+ * class AuthService {
139
+ * validateToken(token: string) { return token === "valid"; }
140
+ * }
141
+ *
142
+ * // Define a middleware
143
+ * const authMiddleware = middleware((event, next, box) => {
144
+ * const authService = box.get(AuthService);
145
+ * const token = event.headers.get("authorization");
146
+ * if (!token || !authService.validateToken(token)) {
147
+ * throw new Error("Unauthorized");
148
+ * }
149
+ * });
150
+ *
151
+ * // Use it in your app
152
+ * const app = application((app, box) => {
153
+ * app.use(box.get(authMiddleware));
154
+ * app.get("/", () => "Hello world!");
155
+ * });
156
+ * ```
157
+ */
158
+ declare function middleware(setup: (event: H3Event, next: () => MaybePromise<unknown | undefined>, box: Box) => MaybePromise<unknown | undefined>): Constructor<Middleware>;
159
+ /**
160
+ * A request-scoped context store for associating values with H3 events.
161
+ *
162
+ * Each request gets its own isolated context that is automatically cleaned up
163
+ * when the request completes. Uses a WeakMap internally to ensure values are
164
+ * garbage collected with their events.
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * import { application, Context } from "serverstruct";
169
+ *
170
+ * const userContext = new Context<User>();
171
+ *
172
+ * const app = application((app) => {
173
+ * app.use((event) => {
174
+ * userContext.set(event, { id: "123", name: "Alice" });
175
+ * });
176
+ * app.get("/user", (event) => {
177
+ * const user = userContext.get(event);
178
+ * return user;
179
+ * });
180
+ * });
181
+ * ```
182
+ */
183
+ declare class Context<T> {
184
+ #private;
185
+ /**
186
+ * Sets a value for the given event.
187
+ */
188
+ set(event: H3Event<any>, value: T): void;
189
+ /**
190
+ * Gets the value for the given event.
191
+ * @throws Error if no value is set for the event.
192
+ */
193
+ get(event: H3Event<any>): T;
194
+ /**
195
+ * Gets the value for the given event, or undefined if not set.
196
+ */
197
+ lookup(event: H3Event<any>): T | undefined;
198
+ }
199
+ /**
200
+ * Creates a request-scoped context store for associating values with H3 events.
201
+ *
202
+ * Each request gets its own isolated context that is automatically cleaned up
203
+ * when the request completes. Uses a WeakMap internally to ensure values are
204
+ * garbage collected with their events.
205
+ *
206
+ * @returns A Context instance.
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * import { application, context } from "serverstruct";
211
+ *
212
+ * const userContext = context<User>();
213
+ *
214
+ * const app = application((app) => {
215
+ * app.use((event) => {
216
+ * userContext.set(event, { id: "123", name: "Alice" });
217
+ * });
218
+ * app.get("/user", (event) => {
219
+ * const user = userContext.get(event);
220
+ * return user;
221
+ * });
70
222
  * });
71
223
  * ```
72
224
  */
73
- declare function controller(fn: (app: H3, box: Box) => H3 | void): Constructor<H3>;
225
+ declare function context<T>(): Context<T>;
74
226
  //#endregion
75
- export { ServeOptions, application, controller };
227
+ export { Context, ServeOptions, Server, application, context, controller, eventHandler, handler, middleware };