@nubase/backend 0.1.0 → 0.1.4
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.mts +503 -15
- package/dist/index.d.ts +503 -15
- package/dist/index.js +196 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +183 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -8
package/dist/index.d.mts
CHANGED
|
@@ -1,23 +1,382 @@
|
|
|
1
1
|
import * as hono from 'hono';
|
|
2
|
-
import { Context } from 'hono';
|
|
2
|
+
import { Context, Hono } from 'hono';
|
|
3
3
|
import { RequestSchema, InferRequestParams, InferRequestBody, InferResponseBody } from '@nubase/core';
|
|
4
|
+
import { ContentfulStatusCode } from 'hono/utils/http-status';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Represents an authenticated user on the backend.
|
|
8
|
+
* Generic type allows applications to define their own user shape.
|
|
9
|
+
*/
|
|
10
|
+
interface BackendUser {
|
|
11
|
+
id: number | string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Token payload that can be embedded in JWTs.
|
|
15
|
+
* Applications can extend this with additional claims.
|
|
16
|
+
*/
|
|
17
|
+
interface TokenPayload {
|
|
18
|
+
/** User identifier */
|
|
19
|
+
userId: number | string;
|
|
20
|
+
/** Token issued at timestamp */
|
|
21
|
+
iat?: number;
|
|
22
|
+
/** Token expiration timestamp */
|
|
23
|
+
exp?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result of token verification.
|
|
27
|
+
*/
|
|
28
|
+
type VerifyTokenResult<TUser extends BackendUser> = {
|
|
29
|
+
valid: true;
|
|
30
|
+
user: TUser;
|
|
31
|
+
} | {
|
|
32
|
+
valid: false;
|
|
33
|
+
error: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Authentication level for routes.
|
|
37
|
+
*/
|
|
38
|
+
type AuthLevel = "required" | "optional" | "none";
|
|
39
|
+
/**
|
|
40
|
+
* BackendAuthController interface.
|
|
41
|
+
*
|
|
42
|
+
* This is the core abstraction for backend authentication in Nubase applications.
|
|
43
|
+
* Applications implement this interface to provide their own authentication logic.
|
|
44
|
+
*
|
|
45
|
+
* The controller handles:
|
|
46
|
+
* - Token extraction from requests (cookies, headers)
|
|
47
|
+
* - Token verification and user lookup
|
|
48
|
+
* - Token creation for login flows
|
|
49
|
+
*
|
|
50
|
+
* Future extensibility:
|
|
51
|
+
* - Token refresh
|
|
52
|
+
* - Token revocation (logout, security)
|
|
53
|
+
* - Two-factor authentication verification
|
|
54
|
+
* - Social login / SSO token validation
|
|
55
|
+
* - Session management
|
|
56
|
+
*
|
|
57
|
+
* @template TUser - The user type returned after authentication
|
|
58
|
+
* @template TTokenPayload - Additional claims to include in tokens
|
|
59
|
+
*/
|
|
60
|
+
interface BackendAuthController<TUser extends BackendUser = BackendUser, TTokenPayload extends TokenPayload = TokenPayload> {
|
|
61
|
+
/**
|
|
62
|
+
* Extract the authentication token from a request.
|
|
63
|
+
* Typically looks in cookies or Authorization header.
|
|
64
|
+
*
|
|
65
|
+
* @param ctx - Hono context
|
|
66
|
+
* @returns The token string or null if not present
|
|
67
|
+
*/
|
|
68
|
+
extractToken(ctx: Context): string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Verify a token and return the authenticated user.
|
|
71
|
+
*
|
|
72
|
+
* @param token - The token to verify
|
|
73
|
+
* @returns Verification result with user or error
|
|
74
|
+
*/
|
|
75
|
+
verifyToken(token: string): Promise<VerifyTokenResult<TUser>>;
|
|
76
|
+
/**
|
|
77
|
+
* Create a new authentication token for a user.
|
|
78
|
+
* Used during login to generate the JWT.
|
|
79
|
+
*
|
|
80
|
+
* @param user - The user to create a token for
|
|
81
|
+
* @param additionalPayload - Optional additional claims
|
|
82
|
+
* @returns The signed token string
|
|
83
|
+
*/
|
|
84
|
+
createToken(user: TUser, additionalPayload?: Partial<TTokenPayload>): Promise<string>;
|
|
85
|
+
/**
|
|
86
|
+
* Set the authentication token in the response.
|
|
87
|
+
* Typically sets an HttpOnly cookie.
|
|
88
|
+
*
|
|
89
|
+
* @param ctx - Hono context
|
|
90
|
+
* @param token - The token to set
|
|
91
|
+
*/
|
|
92
|
+
setTokenInResponse(ctx: Context, token: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Clear the authentication token from the response.
|
|
95
|
+
* Used during logout.
|
|
96
|
+
*
|
|
97
|
+
* @param ctx - Hono context
|
|
98
|
+
*/
|
|
99
|
+
clearTokenFromResponse(ctx: Context): void;
|
|
100
|
+
/**
|
|
101
|
+
* Validate user credentials during login.
|
|
102
|
+
* Looks up the user by username and verifies the password.
|
|
103
|
+
*
|
|
104
|
+
* @param username - The username to look up
|
|
105
|
+
* @param password - The plain text password to verify
|
|
106
|
+
* @returns The user if credentials are valid, null otherwise
|
|
107
|
+
*/
|
|
108
|
+
validateCredentials(username: string, password: string): Promise<TUser | null>;
|
|
109
|
+
/**
|
|
110
|
+
* Refresh an existing token.
|
|
111
|
+
* Returns a new token if the old one is valid but near expiration.
|
|
112
|
+
*
|
|
113
|
+
* @param token - The current token
|
|
114
|
+
* @returns New token or null if refresh not possible
|
|
115
|
+
*/
|
|
116
|
+
refreshToken?(token: string): Promise<string | null>;
|
|
117
|
+
/**
|
|
118
|
+
* Revoke a token (e.g., for logout or security).
|
|
119
|
+
* Implementations may track revoked tokens in a blacklist.
|
|
120
|
+
*
|
|
121
|
+
* @param token - The token to revoke
|
|
122
|
+
*/
|
|
123
|
+
revokeToken?(token: string): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Verify a two-factor authentication code.
|
|
126
|
+
*
|
|
127
|
+
* @param userId - The user's ID
|
|
128
|
+
* @param code - The 2FA code to verify
|
|
129
|
+
* @returns Whether the code is valid
|
|
130
|
+
*/
|
|
131
|
+
verify2FA?(userId: number | string, code: string): Promise<boolean>;
|
|
132
|
+
/**
|
|
133
|
+
* Check if a user requires 2FA.
|
|
134
|
+
*
|
|
135
|
+
* @param user - The user to check
|
|
136
|
+
* @returns Whether 2FA is required
|
|
137
|
+
*/
|
|
138
|
+
requires2FA?(user: TUser): boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Validate an external OAuth/SSO token.
|
|
141
|
+
*
|
|
142
|
+
* @param provider - The OAuth provider (google, github, etc.)
|
|
143
|
+
* @param token - The external token
|
|
144
|
+
* @returns The user if valid, null otherwise
|
|
145
|
+
*/
|
|
146
|
+
validateExternalToken?(provider: string, token: string): Promise<TUser | null>;
|
|
147
|
+
/**
|
|
148
|
+
* Link an external OAuth provider to a user account.
|
|
149
|
+
*
|
|
150
|
+
* @param userId - The user's ID
|
|
151
|
+
* @param provider - The OAuth provider
|
|
152
|
+
* @param externalId - The external provider's user ID
|
|
153
|
+
*/
|
|
154
|
+
linkExternalProvider?(userId: number | string, provider: string, externalId: string): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Create a server-side session (for SSO session sync).
|
|
157
|
+
*
|
|
158
|
+
* @param user - The user to create a session for
|
|
159
|
+
* @returns The session ID
|
|
160
|
+
*/
|
|
161
|
+
createSession?(user: TUser): Promise<string>;
|
|
162
|
+
/**
|
|
163
|
+
* Invalidate a session.
|
|
164
|
+
*
|
|
165
|
+
* @param sessionId - The session to invalidate
|
|
166
|
+
*/
|
|
167
|
+
invalidateSession?(sessionId: string): Promise<void>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Options for creating auth handlers.
|
|
172
|
+
*/
|
|
173
|
+
interface CreateAuthHandlersOptions<TUser extends BackendUser = BackendUser> {
|
|
174
|
+
/**
|
|
175
|
+
* The auth controller instance.
|
|
176
|
+
*/
|
|
177
|
+
controller: BackendAuthController<TUser>;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Auth handlers returned by createAuthHandlers.
|
|
181
|
+
*/
|
|
182
|
+
interface AuthHandlers {
|
|
183
|
+
/**
|
|
184
|
+
* Login handler - validates credentials and sets auth cookie.
|
|
185
|
+
* Expects JSON body: { username: string, password: string }
|
|
186
|
+
* Returns: { user: { id, email, username } }
|
|
187
|
+
*/
|
|
188
|
+
login: (ctx: Context) => Promise<Response>;
|
|
189
|
+
/**
|
|
190
|
+
* Logout handler - clears the auth cookie.
|
|
191
|
+
* Returns: { success: true }
|
|
192
|
+
*/
|
|
193
|
+
logout: (ctx: Context) => Promise<Response>;
|
|
194
|
+
/**
|
|
195
|
+
* Get current user handler - returns the authenticated user or undefined.
|
|
196
|
+
* Returns: { user?: { id, email, username } }
|
|
197
|
+
*/
|
|
198
|
+
getMe: (ctx: Context) => Promise<Response>;
|
|
199
|
+
/**
|
|
200
|
+
* Pre-configured Hono router with all auth routes.
|
|
201
|
+
* Mount this at /auth to get /auth/login, /auth/logout, /auth/me
|
|
202
|
+
*/
|
|
203
|
+
routes: Hono;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create standard authentication handlers from a BackendAuthController.
|
|
207
|
+
*
|
|
208
|
+
* This utility reduces boilerplate by providing pre-built handlers for
|
|
209
|
+
* login, logout, and get-current-user endpoints.
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* import { createAuthHandlers, createAuthMiddleware } from "@nubase/backend";
|
|
214
|
+
*
|
|
215
|
+
* const authController = new MyBackendAuthController();
|
|
216
|
+
* const authHandlers = createAuthHandlers({ controller: authController });
|
|
217
|
+
*
|
|
218
|
+
* const app = new Hono();
|
|
219
|
+
* app.use("*", createAuthMiddleware({ controller: authController }));
|
|
220
|
+
*
|
|
221
|
+
* // Option 1: Register routes individually
|
|
222
|
+
* app.post("/auth/login", authHandlers.login);
|
|
223
|
+
* app.post("/auth/logout", authHandlers.logout);
|
|
224
|
+
* app.get("/auth/me", authHandlers.getMe);
|
|
225
|
+
*
|
|
226
|
+
* // Option 2: Mount the pre-configured router
|
|
227
|
+
* app.route("/auth", authHandlers.routes);
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
declare function createAuthHandlers<TUser extends BackendUser = BackendUser>(options: CreateAuthHandlersOptions<TUser>): AuthHandlers;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Context key for storing the authenticated user.
|
|
234
|
+
* Use `c.get('user')` to retrieve the user in handlers.
|
|
235
|
+
*/
|
|
236
|
+
declare const AUTH_USER_KEY = "user";
|
|
237
|
+
/**
|
|
238
|
+
* Context key for storing the auth controller instance.
|
|
239
|
+
*/
|
|
240
|
+
declare const AUTH_CONTROLLER_KEY = "authController";
|
|
241
|
+
/**
|
|
242
|
+
* Variables added to Hono context by auth middleware.
|
|
243
|
+
*/
|
|
244
|
+
interface AuthVariables<TUser extends BackendUser = BackendUser> {
|
|
245
|
+
user: TUser | null;
|
|
246
|
+
authController: BackendAuthController<TUser>;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Options for the auth middleware.
|
|
250
|
+
*/
|
|
251
|
+
interface AuthMiddlewareOptions<TUser extends BackendUser = BackendUser> {
|
|
252
|
+
/**
|
|
253
|
+
* The auth controller instance to use for token verification.
|
|
254
|
+
*/
|
|
255
|
+
controller: BackendAuthController<TUser>;
|
|
256
|
+
/**
|
|
257
|
+
* Default auth level for all routes.
|
|
258
|
+
* Can be overridden per-route using createHttpHandler's auth option.
|
|
259
|
+
* @default "none"
|
|
260
|
+
*/
|
|
261
|
+
defaultAuthLevel?: AuthLevel;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Create an authentication middleware for Hono.
|
|
265
|
+
*
|
|
266
|
+
* This middleware:
|
|
267
|
+
* 1. Extracts the token from the request
|
|
268
|
+
* 2. Verifies the token using the provided controller
|
|
269
|
+
* 3. Sets the user in the context (or null if not authenticated)
|
|
270
|
+
* 4. Makes the controller available in context for handlers
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```typescript
|
|
274
|
+
* const authController = new QuestlogBackendAuthController();
|
|
275
|
+
* const app = new Hono();
|
|
276
|
+
*
|
|
277
|
+
* // Apply to all routes
|
|
278
|
+
* app.use('*', createAuthMiddleware({ controller: authController }));
|
|
279
|
+
*
|
|
280
|
+
* // Access user in handlers
|
|
281
|
+
* app.get('/me', (c) => {
|
|
282
|
+
* const user = c.get('user');
|
|
283
|
+
* if (!user) return c.json({ error: 'Unauthorized' }, 401);
|
|
284
|
+
* return c.json({ user });
|
|
285
|
+
* });
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
declare function createAuthMiddleware<TUser extends BackendUser = BackendUser>(options: AuthMiddlewareOptions<TUser>): hono.MiddlewareHandler<{
|
|
289
|
+
Variables: AuthVariables<TUser>;
|
|
290
|
+
}, string, {}, Response>;
|
|
291
|
+
/**
|
|
292
|
+
* Middleware to require authentication.
|
|
293
|
+
* Returns 401 if user is not authenticated.
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* // Protect a single route
|
|
298
|
+
* app.get('/protected', requireAuth(), (c) => {
|
|
299
|
+
* const user = c.get('user')!; // User is guaranteed to exist
|
|
300
|
+
* return c.json({ message: `Hello ${user.username}` });
|
|
301
|
+
* });
|
|
302
|
+
*
|
|
303
|
+
* // Protect a group of routes
|
|
304
|
+
* const protected = app.basePath('/api/admin');
|
|
305
|
+
* protected.use('*', requireAuth());
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
declare function requireAuth<TUser extends BackendUser = BackendUser>(): hono.MiddlewareHandler<{
|
|
309
|
+
Variables: AuthVariables<TUser>;
|
|
310
|
+
}, string, {}, Response>;
|
|
311
|
+
/**
|
|
312
|
+
* Helper to get the authenticated user from context.
|
|
313
|
+
* Returns null if not authenticated.
|
|
314
|
+
*/
|
|
315
|
+
declare function getUser<TUser extends BackendUser = BackendUser>(c: Context): TUser | null;
|
|
316
|
+
/**
|
|
317
|
+
* Helper to get the auth controller from context.
|
|
318
|
+
*/
|
|
319
|
+
declare function getAuthController<TUser extends BackendUser = BackendUser>(c: Context): BackendAuthController<TUser>;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Custom HTTP error class that allows handlers to throw errors with specific status codes.
|
|
323
|
+
* Use this to return proper HTTP error responses instead of generic 500 errors.
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* throw new HttpError(401, "Invalid username or password");
|
|
327
|
+
* throw new HttpError(404, "Resource not found");
|
|
328
|
+
* throw new HttpError(403, "Access denied");
|
|
329
|
+
*/
|
|
330
|
+
declare class HttpError extends Error {
|
|
331
|
+
statusCode: ContentfulStatusCode;
|
|
332
|
+
constructor(statusCode: ContentfulStatusCode, message: string);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* URL Parameter Coercion System (Backend)
|
|
336
|
+
*
|
|
337
|
+
* **The Problem:**
|
|
338
|
+
* URL path parameters always arrive as strings from HTTP requests,
|
|
339
|
+
* but schemas expect typed values (numbers, booleans).
|
|
340
|
+
*
|
|
341
|
+
* **The Solution:**
|
|
342
|
+
* We use the schema's `toZodWithCoercion()` method which leverages Zod's
|
|
343
|
+
* built-in coercion to automatically convert string values to expected types.
|
|
344
|
+
*
|
|
345
|
+
* **Example:**
|
|
346
|
+
* - URL: `/tickets/37` → params: { id: "37" }
|
|
347
|
+
* - Schema expects: { id: number }
|
|
348
|
+
* - toZodWithCoercion() converts: { id: 37 }
|
|
349
|
+
*/
|
|
350
|
+
/**
|
|
351
|
+
* Context provided to typed handlers.
|
|
352
|
+
*
|
|
353
|
+
* @template T - The request schema type
|
|
354
|
+
* @template TUser - The user type (when auth is required/optional)
|
|
355
|
+
*/
|
|
356
|
+
type TypedHandlerContext<T extends RequestSchema, TUser extends BackendUser | null = null> = {
|
|
6
357
|
params: InferRequestParams<T>;
|
|
7
358
|
body: InferRequestBody<T>;
|
|
8
359
|
ctx: Context;
|
|
360
|
+
/**
|
|
361
|
+
* The authenticated user.
|
|
362
|
+
* - When auth is 'required': TUser (guaranteed to exist)
|
|
363
|
+
* - When auth is 'optional': TUser | null
|
|
364
|
+
* - When auth is 'none': not present (null)
|
|
365
|
+
*/
|
|
366
|
+
user: TUser;
|
|
9
367
|
};
|
|
10
|
-
|
|
368
|
+
/**
|
|
369
|
+
* Handler function type for typed HTTP handlers.
|
|
370
|
+
*/
|
|
371
|
+
type TypedHandler<T extends RequestSchema, TUser extends BackendUser | null = null> = (context: TypedHandlerContext<T, TUser>) => Promise<InferResponseBody<T>>;
|
|
11
372
|
declare function createTypedHandler<T extends RequestSchema>(schema: T, handler: TypedHandler<T>): ReturnType<typeof createTypedHandlerInternal>;
|
|
12
373
|
declare function createTypedHandler<T extends RequestSchema>(endpointRef: T, // Can be apiEndpoints.ticketsGetTickets
|
|
13
374
|
handler: TypedHandler<T>): ReturnType<typeof createTypedHandlerInternal>;
|
|
14
|
-
declare function createTypedHandlerInternal<T extends RequestSchema>(schema: T, handler: TypedHandler<T
|
|
375
|
+
declare function createTypedHandlerInternal<T extends RequestSchema, TUser extends BackendUser | null = null>(schema: T, handler: TypedHandler<T, TUser>, options?: {
|
|
376
|
+
auth?: AuthLevel;
|
|
377
|
+
}): (c: Context) => Promise<(Response & hono.TypedResponse<any, 200 | 201, "json">) | (Response & hono.TypedResponse<{
|
|
15
378
|
error: string;
|
|
16
|
-
|
|
17
|
-
}, 400, "json">) | (Response & hono.TypedResponse<any, 200 | 201, "json">) | (Response & hono.TypedResponse<{
|
|
18
|
-
error: string;
|
|
19
|
-
details: string;
|
|
20
|
-
}, 500, "json">)>;
|
|
379
|
+
}, 401 | 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1, "json">)>;
|
|
21
380
|
type TypedRouteDefinition<T extends RequestSchema> = {
|
|
22
381
|
schema: T;
|
|
23
382
|
handler: TypedHandler<T>;
|
|
@@ -25,10 +384,139 @@ type TypedRouteDefinition<T extends RequestSchema> = {
|
|
|
25
384
|
type TypedRoutes = Record<string, TypedRouteDefinition<any>>;
|
|
26
385
|
declare function createTypedRoutes<T extends TypedRoutes>(routes: T): Record<string, (c: Context) => Promise<(Response & hono.TypedResponse<any, 200 | 201, "json">) | (Response & hono.TypedResponse<{
|
|
27
386
|
error: string;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
387
|
+
}, 401 | 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | -1, "json">)>>;
|
|
388
|
+
/**
|
|
389
|
+
* A handler created by createHttpHandler with endpoint metadata attached.
|
|
390
|
+
* This allows registerHandlers to auto-register routes based on the endpoint's path and method.
|
|
391
|
+
*/
|
|
392
|
+
type HttpHandler = ((c: Context) => Promise<Response>) & {
|
|
393
|
+
__endpoint: RequestSchema;
|
|
394
|
+
};
|
|
395
|
+
/**
|
|
396
|
+
* Options for createHttpHandler.
|
|
397
|
+
*/
|
|
398
|
+
type CreateHttpHandlerOptions<T extends RequestSchema, TAuth extends AuthLevel = "none", TUser extends BackendUser = BackendUser> = {
|
|
399
|
+
/**
|
|
400
|
+
* The endpoint schema defining request/response types.
|
|
401
|
+
*/
|
|
402
|
+
endpoint: T;
|
|
403
|
+
/**
|
|
404
|
+
* Authentication level for this route.
|
|
405
|
+
* - 'required': Request must be authenticated. Returns 401 if not. User is guaranteed in handler.
|
|
406
|
+
* - 'optional': Authentication is optional. User may be null in handler.
|
|
407
|
+
* - 'none': No authentication check. User is always null. (default)
|
|
408
|
+
*/
|
|
409
|
+
auth?: TAuth;
|
|
410
|
+
/**
|
|
411
|
+
* The handler function.
|
|
412
|
+
* When auth is 'required', user is guaranteed to be non-null.
|
|
413
|
+
* When auth is 'optional', user may be null.
|
|
414
|
+
* When auth is 'none', user is null.
|
|
415
|
+
*/
|
|
416
|
+
handler: TypedHandler<T, TAuth extends "required" ? TUser : TAuth extends "optional" ? TUser | null : null>;
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* Create a typed HTTP handler with optional authentication.
|
|
420
|
+
*
|
|
421
|
+
* @example
|
|
422
|
+
* ```typescript
|
|
423
|
+
* // No auth (default)
|
|
424
|
+
* export const handleGetPublicData = createHttpHandler({
|
|
425
|
+
* endpoint: apiEndpoints.getPublicData,
|
|
426
|
+
* handler: async ({ body }) => {
|
|
427
|
+
* return { data: 'public' };
|
|
428
|
+
* },
|
|
429
|
+
* });
|
|
430
|
+
*
|
|
431
|
+
* // Required auth - user is guaranteed
|
|
432
|
+
* export const handleGetProfile = createHttpHandler({
|
|
433
|
+
* endpoint: apiEndpoints.getProfile,
|
|
434
|
+
* auth: 'required',
|
|
435
|
+
* handler: async ({ body, user }) => {
|
|
436
|
+
* // user is guaranteed to exist here
|
|
437
|
+
* return { userId: user.id };
|
|
438
|
+
* },
|
|
439
|
+
* });
|
|
440
|
+
*
|
|
441
|
+
* // Optional auth - user may be null
|
|
442
|
+
* export const handleGetContent = createHttpHandler({
|
|
443
|
+
* endpoint: apiEndpoints.getContent,
|
|
444
|
+
* auth: 'optional',
|
|
445
|
+
* handler: async ({ body, user }) => {
|
|
446
|
+
* if (user) {
|
|
447
|
+
* return { content: 'personalized', userId: user.id };
|
|
448
|
+
* }
|
|
449
|
+
* return { content: 'generic' };
|
|
450
|
+
* },
|
|
451
|
+
* });
|
|
452
|
+
* ```
|
|
453
|
+
*/
|
|
454
|
+
declare function createHttpHandler<T extends RequestSchema, TAuth extends AuthLevel = "none", TUser extends BackendUser = BackendUser>(options: CreateHttpHandlerOptions<T, TAuth, TUser>): HttpHandler;
|
|
455
|
+
/**
|
|
456
|
+
* A record of handlers to be registered with registerHandlers.
|
|
457
|
+
*/
|
|
458
|
+
type HttpHandlers = Record<string, HttpHandler>;
|
|
459
|
+
/**
|
|
460
|
+
* Register multiple HTTP handlers with a Hono app.
|
|
461
|
+
* Automatically extracts path and method from each handler's endpoint metadata.
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* ```typescript
|
|
465
|
+
* // In dashboard.ts
|
|
466
|
+
* export const dashboardHandlers = {
|
|
467
|
+
* getRevenueChart: createHttpHandler({
|
|
468
|
+
* endpoint: apiEndpoints.getRevenueChart,
|
|
469
|
+
* auth: "required",
|
|
470
|
+
* handler: async () => ({ ... }),
|
|
471
|
+
* }),
|
|
472
|
+
* getBrowserStats: createHttpHandler({
|
|
473
|
+
* endpoint: apiEndpoints.getBrowserStats,
|
|
474
|
+
* auth: "required",
|
|
475
|
+
* handler: async () => ({ ... }),
|
|
476
|
+
* }),
|
|
477
|
+
* };
|
|
478
|
+
*
|
|
479
|
+
* // In index.ts
|
|
480
|
+
* registerHandlers(app, dashboardHandlers);
|
|
481
|
+
* // Automatically registers:
|
|
482
|
+
* // app.get("/dashboard/revenue-chart", handler)
|
|
483
|
+
* // app.get("/dashboard/browser-stats", handler)
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function registerHandlers<TApp extends {
|
|
487
|
+
get: any;
|
|
488
|
+
post: any;
|
|
489
|
+
put: any;
|
|
490
|
+
patch: any;
|
|
491
|
+
delete: any;
|
|
492
|
+
}>(app: TApp, handlers: HttpHandlers): void;
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Parse a cookie header string into a key-value object.
|
|
496
|
+
*
|
|
497
|
+
* @param cookieHeader - The Cookie header string (e.g., "name=value; other=123")
|
|
498
|
+
* @returns An object mapping cookie names to their values
|
|
499
|
+
*
|
|
500
|
+
* @example
|
|
501
|
+
* ```typescript
|
|
502
|
+
* const cookies = parseCookies("session=abc123; theme=dark");
|
|
503
|
+
* // { session: "abc123", theme: "dark" }
|
|
504
|
+
* ```
|
|
505
|
+
*/
|
|
506
|
+
declare function parseCookies(cookieHeader: string): Record<string, string>;
|
|
507
|
+
/**
|
|
508
|
+
* Get a specific cookie value from a cookie header string.
|
|
509
|
+
*
|
|
510
|
+
* @param cookieHeader - The Cookie header string
|
|
511
|
+
* @param name - The cookie name to retrieve
|
|
512
|
+
* @returns The cookie value or null if not found
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* const session = getCookie("session=abc123; theme=dark", "session");
|
|
517
|
+
* // "abc123"
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
declare function getCookie(cookieHeader: string, name: string): string | null;
|
|
33
521
|
|
|
34
|
-
export { type TypedHandler, type TypedHandlerContext, type TypedRouteDefinition, type TypedRoutes, createTypedHandler, createTypedRoutes };
|
|
522
|
+
export { AUTH_CONTROLLER_KEY, AUTH_USER_KEY, type AuthHandlers, type AuthLevel, type AuthMiddlewareOptions, type AuthVariables, type BackendAuthController, type BackendUser, type CreateAuthHandlersOptions, type CreateHttpHandlerOptions, HttpError, type HttpHandler, type HttpHandlers, type TokenPayload, type TypedHandler, type TypedHandlerContext, type TypedRouteDefinition, type TypedRoutes, type VerifyTokenResult, createAuthHandlers, createAuthMiddleware, createHttpHandler, createTypedHandler, createTypedRoutes, getAuthController, getCookie, getUser, parseCookies, registerHandlers, requireAuth };
|