glasswork 0.1.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/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/bootstrap.d.ts +55 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +359 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/core/bootstrap.d.ts +55 -0
- package/dist/core/bootstrap.d.ts.map +1 -0
- package/dist/core/bootstrap.js +329 -0
- package/dist/core/bootstrap.js.map +1 -0
- package/dist/core/module.d.ts +21 -0
- package/dist/core/module.d.ts.map +1 -0
- package/dist/core/module.js +85 -0
- package/dist/core/module.js.map +1 -0
- package/dist/core/types.d.ts +273 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/environment.d.ts +21 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +29 -0
- package/dist/environment.js.map +1 -0
- package/dist/error-handler.d.ts +33 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +53 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +65 -0
- package/dist/errors.js.map +1 -0
- package/dist/get-client-ip.d.ts +24 -0
- package/dist/get-client-ip.d.ts.map +1 -0
- package/dist/get-client-ip.js +49 -0
- package/dist/get-client-ip.js.map +1 -0
- package/dist/http/error-handler.d.ts +33 -0
- package/dist/http/error-handler.d.ts.map +1 -0
- package/dist/http/error-handler.js +55 -0
- package/dist/http/error-handler.js.map +1 -0
- package/dist/http/errors.d.ts +36 -0
- package/dist/http/errors.d.ts.map +1 -0
- package/dist/http/errors.js +65 -0
- package/dist/http/errors.js.map +1 -0
- package/dist/http/route-helpers.d.ts +172 -0
- package/dist/http/route-helpers.d.ts.map +1 -0
- package/dist/http/route-helpers.js +249 -0
- package/dist/http/route-helpers.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +37 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +52 -0
- package/dist/logger.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +7 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +182 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/module.d.ts +21 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +85 -0
- package/dist/module.js.map +1 -0
- package/dist/omit.d.ts +20 -0
- package/dist/omit.d.ts.map +1 -0
- package/dist/omit.js +28 -0
- package/dist/omit.js.map +1 -0
- package/dist/openapi/defaults.d.ts +11 -0
- package/dist/openapi/defaults.d.ts.map +1 -0
- package/dist/openapi/defaults.js +127 -0
- package/dist/openapi/defaults.js.map +1 -0
- package/dist/openapi/hooks.d.ts +14 -0
- package/dist/openapi/hooks.d.ts.map +1 -0
- package/dist/openapi/hooks.js +80 -0
- package/dist/openapi/hooks.js.map +1 -0
- package/dist/openapi/openapi.d.ts +24 -0
- package/dist/openapi/openapi.d.ts.map +1 -0
- package/dist/openapi/openapi.js +108 -0
- package/dist/openapi/openapi.js.map +1 -0
- package/dist/openapi-defaults.d.ts +11 -0
- package/dist/openapi-defaults.d.ts.map +1 -0
- package/dist/openapi-defaults.js +127 -0
- package/dist/openapi-defaults.js.map +1 -0
- package/dist/openapi-hooks.d.ts +14 -0
- package/dist/openapi-hooks.d.ts.map +1 -0
- package/dist/openapi-hooks.js +80 -0
- package/dist/openapi-hooks.js.map +1 -0
- package/dist/openapi.d.ts +24 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +106 -0
- package/dist/openapi.js.map +1 -0
- package/dist/pagination.d.ts +48 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +43 -0
- package/dist/pagination.js.map +1 -0
- package/dist/pick.d.ts +20 -0
- package/dist/pick.d.ts.map +1 -0
- package/dist/pick.js +28 -0
- package/dist/pick.js.map +1 -0
- package/dist/rate-limit.d.ts +7 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +180 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/route-helpers.d.ts +172 -0
- package/dist/route-helpers.d.ts.map +1 -0
- package/dist/route-helpers.js +249 -0
- package/dist/route-helpers.js.map +1 -0
- package/dist/serialize-dates.d.ts +27 -0
- package/dist/serialize-dates.d.ts.map +1 -0
- package/dist/serialize-dates.js +39 -0
- package/dist/serialize-dates.js.map +1 -0
- package/dist/testing.d.ts +87 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +94 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +273 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/deep-merge.d.ts +5 -0
- package/dist/utils/deep-merge.d.ts.map +1 -0
- package/dist/utils/deep-merge.js +21 -0
- package/dist/utils/deep-merge.js.map +1 -0
- package/dist/utils/environment.d.ts +21 -0
- package/dist/utils/environment.d.ts.map +1 -0
- package/dist/utils/environment.js +29 -0
- package/dist/utils/environment.js.map +1 -0
- package/dist/utils/get-client-ip.d.ts +24 -0
- package/dist/utils/get-client-ip.d.ts.map +1 -0
- package/dist/utils/get-client-ip.js +49 -0
- package/dist/utils/get-client-ip.js.map +1 -0
- package/dist/utils/logger.d.ts +37 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/omit.d.ts +20 -0
- package/dist/utils/omit.d.ts.map +1 -0
- package/dist/utils/omit.js +28 -0
- package/dist/utils/omit.js.map +1 -0
- package/dist/utils/pagination.d.ts +48 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +42 -0
- package/dist/utils/pagination.js.map +1 -0
- package/dist/utils/pick.d.ts +20 -0
- package/dist/utils/pick.d.ts.map +1 -0
- package/dist/utils/pick.js +28 -0
- package/dist/utils/pick.js.map +1 -0
- package/dist/utils/serialize-dates.d.ts +27 -0
- package/dist/utils/serialize-dates.d.ts.map +1 -0
- package/dist/utils/serialize-dates.js +39 -0
- package/dist/utils/serialize-dates.js.map +1 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +31 -0
- package/dist/utils.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import type { AwilixContainer } from 'awilix';
|
|
2
|
+
import type { ErrorHandler, Hono } from 'hono';
|
|
3
|
+
/**
|
|
4
|
+
* Service lifetime scope for dependency injection
|
|
5
|
+
*/
|
|
6
|
+
export type ServiceScope = 'SINGLETON' | 'SCOPED' | 'TRANSIENT';
|
|
7
|
+
/**
|
|
8
|
+
* Constructor type for class providers
|
|
9
|
+
*
|
|
10
|
+
* We use `any[]` for constructor arguments because in dependency injection,
|
|
11
|
+
* we can't know at compile time what arguments will be injected - that's
|
|
12
|
+
* determined by the DI container at runtime. This is a legitimate use of `any`.
|
|
13
|
+
*/
|
|
14
|
+
export type Constructor<T = unknown> = new (...args: any[]) => T;
|
|
15
|
+
/**
|
|
16
|
+
* Provider configuration for dependency injection
|
|
17
|
+
*/
|
|
18
|
+
export type ProviderConfig = Constructor | {
|
|
19
|
+
provide: string | Constructor;
|
|
20
|
+
useClass: Constructor;
|
|
21
|
+
scope?: ServiceScope;
|
|
22
|
+
} | {
|
|
23
|
+
provide: string;
|
|
24
|
+
useValue: unknown;
|
|
25
|
+
} | {
|
|
26
|
+
provide: string;
|
|
27
|
+
useFactory: (container: unknown) => unknown;
|
|
28
|
+
inject?: string[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Route factory function that receives Hono router and services
|
|
32
|
+
*/
|
|
33
|
+
export type RouteFactory = (router: Hono, services: Record<string, unknown>) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Module configuration
|
|
36
|
+
*/
|
|
37
|
+
export interface ModuleConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Unique module name
|
|
40
|
+
*/
|
|
41
|
+
name: string;
|
|
42
|
+
/**
|
|
43
|
+
* Base path for routes (e.g., 'auth' becomes /api/auth)
|
|
44
|
+
*/
|
|
45
|
+
basePath?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Service providers to register
|
|
48
|
+
*/
|
|
49
|
+
providers?: ProviderConfig[];
|
|
50
|
+
/**
|
|
51
|
+
* Modules to import (access their exported providers)
|
|
52
|
+
*/
|
|
53
|
+
imports?: ModuleConfig[];
|
|
54
|
+
/**
|
|
55
|
+
* Providers to export (available to importing modules)
|
|
56
|
+
*/
|
|
57
|
+
exports?: (Constructor | string)[];
|
|
58
|
+
/**
|
|
59
|
+
* Route factory function
|
|
60
|
+
*/
|
|
61
|
+
routes?: RouteFactory;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Environment type for conditional behavior
|
|
65
|
+
*/
|
|
66
|
+
export type Environment = 'development' | 'production' | 'test';
|
|
67
|
+
/**
|
|
68
|
+
* OpenAPI documentation configuration
|
|
69
|
+
*/
|
|
70
|
+
export interface OpenAPIDocumentation {
|
|
71
|
+
info: {
|
|
72
|
+
title: string;
|
|
73
|
+
version: string;
|
|
74
|
+
description?: string;
|
|
75
|
+
contact?: {
|
|
76
|
+
name?: string;
|
|
77
|
+
email?: string;
|
|
78
|
+
url?: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
tags?: Array<{
|
|
82
|
+
name: string;
|
|
83
|
+
description?: string;
|
|
84
|
+
}>;
|
|
85
|
+
servers?: Array<{
|
|
86
|
+
url: string;
|
|
87
|
+
description?: string;
|
|
88
|
+
}>;
|
|
89
|
+
components?: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Hook function for customizing OpenAPI responses
|
|
93
|
+
*
|
|
94
|
+
* Receives the response object and context, returns modified response.
|
|
95
|
+
* This allows both framework and applications to add headers, modify
|
|
96
|
+
* descriptions, etc. globally across all routes.
|
|
97
|
+
*/
|
|
98
|
+
export type OpenAPIResponseHook = (response: {
|
|
99
|
+
description: string;
|
|
100
|
+
headers?: Record<string, {
|
|
101
|
+
$ref: string;
|
|
102
|
+
}>;
|
|
103
|
+
content?: Record<string, unknown>;
|
|
104
|
+
}, context: {
|
|
105
|
+
statusCode: string;
|
|
106
|
+
routeConfig: {
|
|
107
|
+
public?: boolean;
|
|
108
|
+
paginate?: boolean;
|
|
109
|
+
tags?: string[];
|
|
110
|
+
summary?: string;
|
|
111
|
+
};
|
|
112
|
+
}) => {
|
|
113
|
+
description: string;
|
|
114
|
+
headers?: Record<string, {
|
|
115
|
+
$ref: string;
|
|
116
|
+
}>;
|
|
117
|
+
content?: Record<string, unknown>;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* OpenAPI configuration options
|
|
121
|
+
*/
|
|
122
|
+
export interface OpenAPIOptions {
|
|
123
|
+
/**
|
|
124
|
+
* Whether to enable OpenAPI generation
|
|
125
|
+
*/
|
|
126
|
+
enabled?: boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Serve OpenAPI specs at /api/openapi.json (default: true in development)
|
|
129
|
+
*/
|
|
130
|
+
serveSpecs?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Serve Swagger UI at /api (default: true in development)
|
|
133
|
+
*/
|
|
134
|
+
serveUI?: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Write OpenAPI specs to file (path relative to cwd)
|
|
137
|
+
*/
|
|
138
|
+
writeToFile?: string;
|
|
139
|
+
/**
|
|
140
|
+
* OpenAPI documentation
|
|
141
|
+
*/
|
|
142
|
+
documentation?: OpenAPIDocumentation;
|
|
143
|
+
/**
|
|
144
|
+
* Response hooks for customizing OpenAPI responses
|
|
145
|
+
*
|
|
146
|
+
* Hooks are applied in order to each response object.
|
|
147
|
+
* Use this to add custom headers, modify descriptions, etc.
|
|
148
|
+
*/
|
|
149
|
+
responseHooks?: OpenAPIResponseHook[];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Rate limiting storage backend
|
|
153
|
+
*/
|
|
154
|
+
export type RateLimitStorage = 'memory' | 'dynamodb';
|
|
155
|
+
/**
|
|
156
|
+
* Rate limiting configuration
|
|
157
|
+
*/
|
|
158
|
+
export interface RateLimitOptions {
|
|
159
|
+
/**
|
|
160
|
+
* Whether rate limiting is enabled
|
|
161
|
+
*/
|
|
162
|
+
enabled: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Storage backend
|
|
165
|
+
*/
|
|
166
|
+
storage: RateLimitStorage;
|
|
167
|
+
/**
|
|
168
|
+
* Rate limit window in milliseconds (default: 60000 = 1 minute)
|
|
169
|
+
*/
|
|
170
|
+
windowMs?: number;
|
|
171
|
+
/**
|
|
172
|
+
* Maximum requests per window (default: 100)
|
|
173
|
+
*/
|
|
174
|
+
maxRequests?: number;
|
|
175
|
+
/**
|
|
176
|
+
* DynamoDB configuration (required if storage is 'dynamodb')
|
|
177
|
+
*/
|
|
178
|
+
dynamodb?: {
|
|
179
|
+
tableName: string;
|
|
180
|
+
region?: string;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Middleware configuration options
|
|
185
|
+
*/
|
|
186
|
+
export interface MiddlewareOptions {
|
|
187
|
+
/**
|
|
188
|
+
* Enable request ID middleware
|
|
189
|
+
* @default true
|
|
190
|
+
*/
|
|
191
|
+
requestId?: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Enable secure headers middleware
|
|
194
|
+
* @default true in production
|
|
195
|
+
*/
|
|
196
|
+
secureHeaders?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* CORS configuration
|
|
199
|
+
*/
|
|
200
|
+
cors?: {
|
|
201
|
+
origin: string | string[];
|
|
202
|
+
credentials?: boolean;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Logger configuration options
|
|
207
|
+
*/
|
|
208
|
+
export interface LoggerOptions {
|
|
209
|
+
/**
|
|
210
|
+
* Enable HTTP request logging
|
|
211
|
+
* @default true
|
|
212
|
+
*/
|
|
213
|
+
enabled?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Use plain logger (no ANSI colors) for Lambda/CloudWatch
|
|
216
|
+
* Auto-detected based on environment if not specified
|
|
217
|
+
*/
|
|
218
|
+
plain?: boolean;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Bootstrap options
|
|
222
|
+
*/
|
|
223
|
+
export interface BootstrapOptions {
|
|
224
|
+
/**
|
|
225
|
+
* Environment (auto-detected from NODE_ENV if not provided)
|
|
226
|
+
*/
|
|
227
|
+
environment?: Environment;
|
|
228
|
+
/**
|
|
229
|
+
* API base path (default: '/api')
|
|
230
|
+
*/
|
|
231
|
+
apiBasePath?: string;
|
|
232
|
+
/**
|
|
233
|
+
* Error handler middleware
|
|
234
|
+
* Set to false to disable default error handler
|
|
235
|
+
* Provide a custom ErrorHandler to override
|
|
236
|
+
* @default Glasswork's default error handler
|
|
237
|
+
*/
|
|
238
|
+
errorHandler?: ErrorHandler | false;
|
|
239
|
+
/**
|
|
240
|
+
* OpenAPI configuration
|
|
241
|
+
*/
|
|
242
|
+
openapi?: OpenAPIOptions;
|
|
243
|
+
/**
|
|
244
|
+
* Rate limiting configuration
|
|
245
|
+
*/
|
|
246
|
+
rateLimit?: RateLimitOptions;
|
|
247
|
+
/**
|
|
248
|
+
* Common middleware configuration
|
|
249
|
+
*/
|
|
250
|
+
middleware?: MiddlewareOptions;
|
|
251
|
+
/**
|
|
252
|
+
* Logger configuration
|
|
253
|
+
*/
|
|
254
|
+
logger?: LoggerOptions;
|
|
255
|
+
/**
|
|
256
|
+
* Enable debug logging
|
|
257
|
+
*/
|
|
258
|
+
debug?: boolean;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Bootstrap result
|
|
262
|
+
*/
|
|
263
|
+
export interface BootstrapResult {
|
|
264
|
+
/**
|
|
265
|
+
* Hono application instance
|
|
266
|
+
*/
|
|
267
|
+
app: Hono;
|
|
268
|
+
/**
|
|
269
|
+
* Awilix container (fully accessible)
|
|
270
|
+
*/
|
|
271
|
+
container: AwilixContainer;
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment detection utilities for serverless and local development.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if running in AWS Lambda environment
|
|
6
|
+
*/
|
|
7
|
+
export declare function isLambda(): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Check if running in production environment
|
|
10
|
+
* (either NODE_ENV=production or in Lambda)
|
|
11
|
+
*/
|
|
12
|
+
export declare function isProduction(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Check if running in test environment
|
|
15
|
+
*/
|
|
16
|
+
export declare function isTest(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if running in development environment
|
|
19
|
+
*/
|
|
20
|
+
export declare function isDevelopment(): boolean;
|
|
21
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;GAEG;AACH,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment detection utilities for serverless and local development.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if running in AWS Lambda environment
|
|
6
|
+
*/
|
|
7
|
+
export function isLambda() {
|
|
8
|
+
return !!(process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.LAMBDA_TASK_ROOT);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Check if running in production environment
|
|
12
|
+
* (either NODE_ENV=production or in Lambda)
|
|
13
|
+
*/
|
|
14
|
+
export function isProduction() {
|
|
15
|
+
return process.env.NODE_ENV === 'production' || isLambda();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if running in test environment
|
|
19
|
+
*/
|
|
20
|
+
export function isTest() {
|
|
21
|
+
return process.env.NODE_ENV === 'test';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if running in development environment
|
|
25
|
+
*/
|
|
26
|
+
export function isDevelopment() {
|
|
27
|
+
return !isProduction() && !isTest();
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,QAAQ,EAAE,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Context, ErrorHandler } from 'hono';
|
|
2
|
+
import type { ContentfulStatusCode } from 'hono/utils/http-status';
|
|
3
|
+
interface FormattedError {
|
|
4
|
+
message: string;
|
|
5
|
+
statusCode: ContentfulStatusCode;
|
|
6
|
+
}
|
|
7
|
+
interface ErrorHandlerOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Whether to log errors to console
|
|
10
|
+
* @default true in development, false in test
|
|
11
|
+
*/
|
|
12
|
+
logErrors?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Custom error response handler
|
|
15
|
+
*/
|
|
16
|
+
responseHandler?: (error: FormattedError, context: Context) => Response | Promise<Response>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create an error handler middleware for Hono
|
|
20
|
+
*
|
|
21
|
+
* Handles:
|
|
22
|
+
* - DomainException (custom business logic exceptions)
|
|
23
|
+
* - HTTPException (Hono's built-in HTTP exceptions)
|
|
24
|
+
* - Validation errors (returns 422)
|
|
25
|
+
* - Generic errors (returns 500)
|
|
26
|
+
*/
|
|
27
|
+
export declare function createErrorHandler(options?: ErrorHandlerOptions): ErrorHandler;
|
|
28
|
+
/**
|
|
29
|
+
* Default error handler instance
|
|
30
|
+
*/
|
|
31
|
+
export declare const defaultErrorHandler: ErrorHandler;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAElD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,UAAU,mBAAmB;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC7F;AAcD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,CA+BlF;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,cAAuB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { HTTPException } from 'hono/http-exception';
|
|
2
|
+
import { DomainException, getStatusCodeFromErrorCode } from './errors.js';
|
|
3
|
+
/**
|
|
4
|
+
* Default response handler - returns JSON error
|
|
5
|
+
*/
|
|
6
|
+
function defaultResponseHandler(error, context) {
|
|
7
|
+
return context.json({
|
|
8
|
+
error: error.message,
|
|
9
|
+
}, error.statusCode);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create an error handler middleware for Hono
|
|
13
|
+
*
|
|
14
|
+
* Handles:
|
|
15
|
+
* - DomainException (custom business logic exceptions)
|
|
16
|
+
* - HTTPException (Hono's built-in HTTP exceptions)
|
|
17
|
+
* - Validation errors (returns 422)
|
|
18
|
+
* - Generic errors (returns 500)
|
|
19
|
+
*/
|
|
20
|
+
export function createErrorHandler(options = {}) {
|
|
21
|
+
const { logErrors = process.env.NODE_ENV !== 'test', responseHandler = defaultResponseHandler } = options;
|
|
22
|
+
return (err, context) => {
|
|
23
|
+
let error;
|
|
24
|
+
if (err instanceof DomainException) {
|
|
25
|
+
const statusCode = getStatusCodeFromErrorCode(err.code);
|
|
26
|
+
error = { message: err.message, statusCode: statusCode };
|
|
27
|
+
if (logErrors && statusCode === 500) {
|
|
28
|
+
console.error('[Glasswork] DomainException with unknown code:', err);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (err instanceof HTTPException) {
|
|
32
|
+
error = {
|
|
33
|
+
message: err.message,
|
|
34
|
+
statusCode: err.status,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
if (logErrors) {
|
|
39
|
+
console.error('[Glasswork] Unhandled error:', err);
|
|
40
|
+
}
|
|
41
|
+
error = {
|
|
42
|
+
message: 'Internal server error',
|
|
43
|
+
statusCode: 500,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return responseHandler(error, context);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Default error handler instance
|
|
51
|
+
*/
|
|
52
|
+
export const defaultErrorHandler = createErrorHandler();
|
|
53
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAmB1E;;GAEG;AACH,SAAS,sBAAsB,CAAC,KAAqB,EAAE,OAAgB;IACrE,OAAO,OAAO,CAAC,IAAI,CACjB;QACE,KAAK,EAAE,KAAK,CAAC,OAAO;KACrB,EACD,KAAK,CAAC,UAAU,CACjB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAA+B,EAAE;IAClE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,eAAe,GAAG,sBAAsB,EAAE,GAC7F,OAAO,CAAC;IAEV,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;QACtB,IAAI,KAAqB,CAAC;QAE1B,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,0BAA0B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACxD,KAAK,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,UAAkC,EAAE,CAAC;YAEjF,IAAI,SAAS,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACxC,KAAK,GAAG;gBACN,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,UAAU,EAAE,GAAG,CAAC,MAAM;aACvB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;YACrD,CAAC;YACD,KAAK,GAAG;gBACN,OAAO,EAAE,uBAAuB;gBAChC,UAAU,EAAE,GAAG;aAChB,CAAC;QACJ,CAAC;QAED,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,EAAE,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base domain exception class for business logic errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class DomainException extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(message: string, code: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Standard HTTP exception classes
|
|
10
|
+
*/
|
|
11
|
+
export declare class ValidationException extends DomainException {
|
|
12
|
+
constructor(message?: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class UnauthorizedException extends DomainException {
|
|
15
|
+
constructor(message?: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class NotFoundException extends DomainException {
|
|
18
|
+
constructor(message?: string);
|
|
19
|
+
}
|
|
20
|
+
export declare class ConflictException extends DomainException {
|
|
21
|
+
constructor(message?: string);
|
|
22
|
+
}
|
|
23
|
+
export declare class ForbiddenException extends DomainException {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
export declare class BadRequestException extends DomainException {
|
|
27
|
+
constructor(message?: string);
|
|
28
|
+
}
|
|
29
|
+
export declare class TooManyRequestsException extends DomainException {
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Map error codes to HTTP status codes
|
|
34
|
+
*/
|
|
35
|
+
export declare function getStatusCodeFromErrorCode(code: string): number;
|
|
36
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAK/B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;gBAC1C,OAAO,SAAqB;CAGzC;AAED,qBAAa,qBAAsB,SAAQ,eAAe;gBAC5C,OAAO,SAAiB;CAGrC;AAED,qBAAa,iBAAkB,SAAQ,eAAe;gBACxC,OAAO,SAAc;CAGlC;AAED,qBAAa,iBAAkB,SAAQ,eAAe;gBACxC,OAAO,SAAa;CAGjC;AAED,qBAAa,kBAAmB,SAAQ,eAAe;gBACzC,OAAO,SAAc;CAGlC;AAED,qBAAa,mBAAoB,SAAQ,eAAe;gBAC1C,OAAO,SAAgB;CAGpC;AAED,qBAAa,wBAAyB,SAAQ,eAAe;gBAC/C,OAAO,SAAsB;CAG1C;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY/D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base domain exception class for business logic errors
|
|
3
|
+
*/
|
|
4
|
+
export class DomainException extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = this.constructor.name;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Standard HTTP exception classes
|
|
14
|
+
*/
|
|
15
|
+
export class ValidationException extends DomainException {
|
|
16
|
+
constructor(message = 'Validation error') {
|
|
17
|
+
super(message, 'VALIDATION_ERROR');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class UnauthorizedException extends DomainException {
|
|
21
|
+
constructor(message = 'Unauthorized') {
|
|
22
|
+
super(message, 'UNAUTHORIZED');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class NotFoundException extends DomainException {
|
|
26
|
+
constructor(message = 'Not found') {
|
|
27
|
+
super(message, 'NOT_FOUND');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class ConflictException extends DomainException {
|
|
31
|
+
constructor(message = 'Conflict') {
|
|
32
|
+
super(message, 'CONFLICT');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class ForbiddenException extends DomainException {
|
|
36
|
+
constructor(message = 'Forbidden') {
|
|
37
|
+
super(message, 'FORBIDDEN');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class BadRequestException extends DomainException {
|
|
41
|
+
constructor(message = 'Bad request') {
|
|
42
|
+
super(message, 'BAD_REQUEST');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class TooManyRequestsException extends DomainException {
|
|
46
|
+
constructor(message = 'Too many requests') {
|
|
47
|
+
super(message, 'TOO_MANY_REQUESTS');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Map error codes to HTTP status codes
|
|
52
|
+
*/
|
|
53
|
+
export function getStatusCodeFromErrorCode(code) {
|
|
54
|
+
const codeMap = {
|
|
55
|
+
BAD_REQUEST: 400,
|
|
56
|
+
UNAUTHORIZED: 401,
|
|
57
|
+
FORBIDDEN: 403,
|
|
58
|
+
NOT_FOUND: 404,
|
|
59
|
+
CONFLICT: 409,
|
|
60
|
+
VALIDATION_ERROR: 422,
|
|
61
|
+
TOO_MANY_REQUESTS: 429,
|
|
62
|
+
};
|
|
63
|
+
return codeMap[code] || 500;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAGtB;IAFlB,YACE,OAAe,EACC,IAAY;QAE5B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAQ;QAG5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;IACtD,YAAY,OAAO,GAAG,kBAAkB;QACtC,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,eAAe;IACxD,YAAY,OAAO,GAAG,cAAc;QAClC,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IACpD,YAAY,OAAO,GAAG,WAAW;QAC/B,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,eAAe;IACpD,YAAY,OAAO,GAAG,UAAU;QAC9B,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IACrD,YAAY,OAAO,GAAG,WAAW;QAC/B,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,eAAe;IACtD,YAAY,OAAO,GAAG,aAAa;QACjC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,eAAe;IAC3D,YAAY,OAAO,GAAG,mBAAmB;QACvC,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IACtC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,IAAY;IACrD,MAAM,OAAO,GAA2B;QACtC,WAAW,EAAE,GAAG;QAChB,YAAY,EAAE,GAAG;QACjB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;QACd,QAAQ,EAAE,GAAG;QACb,gBAAgB,EAAE,GAAG;QACrB,iBAAiB,EAAE,GAAG;KACvB,CAAC;IAEF,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Context } from 'hono';
|
|
2
|
+
/**
|
|
3
|
+
* Extract the client IP address from Hono context.
|
|
4
|
+
*
|
|
5
|
+
* Checks headers in order:
|
|
6
|
+
* 1. x-forwarded-for (proxy/load balancer)
|
|
7
|
+
* 2. x-real-ip (nginx)
|
|
8
|
+
* 3. Direct connection info (if available)
|
|
9
|
+
*
|
|
10
|
+
* @param c - Hono context
|
|
11
|
+
* @returns Client IP address or 'unknown' if not determinable
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* router.post('/login', route({
|
|
16
|
+
* handler: async ({ ip }) => {
|
|
17
|
+
* // ip is automatically populated
|
|
18
|
+
* await authService.logLoginAttempt(email, ip);
|
|
19
|
+
* }
|
|
20
|
+
* }));
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function getClientIp(c: Context): string;
|
|
24
|
+
//# sourceMappingURL=get-client-ip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-client-ip.d.ts","sourceRoot":"","sources":["../src/get-client-ip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CA0B9C"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the client IP address from Hono context.
|
|
3
|
+
*
|
|
4
|
+
* Checks headers in order:
|
|
5
|
+
* 1. x-forwarded-for (proxy/load balancer)
|
|
6
|
+
* 2. x-real-ip (nginx)
|
|
7
|
+
* 3. Direct connection info (if available)
|
|
8
|
+
*
|
|
9
|
+
* @param c - Hono context
|
|
10
|
+
* @returns Client IP address or 'unknown' if not determinable
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* router.post('/login', route({
|
|
15
|
+
* handler: async ({ ip }) => {
|
|
16
|
+
* // ip is automatically populated
|
|
17
|
+
* await authService.logLoginAttempt(email, ip);
|
|
18
|
+
* }
|
|
19
|
+
* }));
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function getClientIp(c) {
|
|
23
|
+
// Check x-forwarded-for header (proxy/load balancer)
|
|
24
|
+
const xForwardedFor = c.req.header('x-forwarded-for');
|
|
25
|
+
if (xForwardedFor) {
|
|
26
|
+
const ip = xForwardedFor.split(',')[0].trim();
|
|
27
|
+
if (ip)
|
|
28
|
+
return ip;
|
|
29
|
+
}
|
|
30
|
+
// Check x-real-ip header (nginx)
|
|
31
|
+
const xRealIp = c.req.header('x-real-ip');
|
|
32
|
+
if (xRealIp)
|
|
33
|
+
return xRealIp;
|
|
34
|
+
// Try to get connection info (Node.js server)
|
|
35
|
+
try {
|
|
36
|
+
// Dynamic import to avoid bundling @hono/node-server in Lambda
|
|
37
|
+
// This will throw in non-Node environments
|
|
38
|
+
const { getConnInfo } = require('@hono/node-server/conninfo');
|
|
39
|
+
const info = getConnInfo(c);
|
|
40
|
+
if (info?.remote?.address) {
|
|
41
|
+
return info.remote.address;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Not in Node.js environment or module not available
|
|
46
|
+
}
|
|
47
|
+
return 'unknown';
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=get-client-ip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-client-ip.js","sourceRoot":"","sources":["../src/get-client-ip.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,WAAW,CAAC,CAAU;IACpC,qDAAqD;IACrD,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACtD,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;IACpB,CAAC;IAED,iCAAiC;IACjC,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC1C,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,8CAA8C;IAC9C,IAAI,CAAC;QACH,+DAA+D;QAC/D,2CAA2C;QAC3C,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QAC7B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Context, ErrorHandler } from 'hono';
|
|
2
|
+
import type { ContentfulStatusCode } from 'hono/utils/http-status';
|
|
3
|
+
interface FormattedError {
|
|
4
|
+
message: string;
|
|
5
|
+
statusCode: ContentfulStatusCode;
|
|
6
|
+
}
|
|
7
|
+
interface ErrorHandlerOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Whether to log errors to console
|
|
10
|
+
* @default true in development, false in test
|
|
11
|
+
*/
|
|
12
|
+
logErrors?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Custom error response handler
|
|
15
|
+
*/
|
|
16
|
+
responseHandler?: (error: FormattedError, context: Context) => Response | Promise<Response>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create an error handler middleware for Hono
|
|
20
|
+
*
|
|
21
|
+
* Handles:
|
|
22
|
+
* - DomainException (custom business logic exceptions)
|
|
23
|
+
* - HTTPException (Hono's built-in HTTP exceptions)
|
|
24
|
+
* - Validation errors (returns 422)
|
|
25
|
+
* - Generic errors (returns 500)
|
|
26
|
+
*/
|
|
27
|
+
export declare function createErrorHandler(options?: ErrorHandlerOptions): ErrorHandler;
|
|
28
|
+
/**
|
|
29
|
+
* Default error handler instance
|
|
30
|
+
*/
|
|
31
|
+
export declare const defaultErrorHandler: ErrorHandler;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/http/error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAElD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAMnE,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,UAAU,mBAAmB;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC7F;AAcD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,CA+BlF;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,cAAuB,CAAC"}
|