glasswork 0.1.0 → 0.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.
Files changed (128) hide show
  1. package/README.md +22 -43
  2. package/dist/config/config-service.d.ts +101 -0
  3. package/dist/config/config-service.d.ts.map +1 -0
  4. package/dist/config/config-service.js +164 -0
  5. package/dist/config/config-service.js.map +1 -0
  6. package/dist/config/helpers.d.ts +101 -0
  7. package/dist/config/helpers.d.ts.map +1 -0
  8. package/dist/config/helpers.js +122 -0
  9. package/dist/config/helpers.js.map +1 -0
  10. package/dist/config/index.d.ts +39 -0
  11. package/dist/config/index.d.ts.map +1 -0
  12. package/dist/config/index.js +41 -0
  13. package/dist/config/index.js.map +1 -0
  14. package/dist/config/providers.d.ts +163 -0
  15. package/dist/config/providers.d.ts.map +1 -0
  16. package/dist/config/providers.js +188 -0
  17. package/dist/config/providers.js.map +1 -0
  18. package/dist/config/types.d.ts +98 -0
  19. package/dist/config/types.d.ts.map +1 -0
  20. package/dist/config/types.js +7 -0
  21. package/dist/config/types.js.map +1 -0
  22. package/dist/core/bootstrap.js +9 -3
  23. package/dist/core/bootstrap.js.map +1 -1
  24. package/dist/core/types.d.ts +2 -1
  25. package/dist/core/types.d.ts.map +1 -1
  26. package/dist/http/error-response.dto.d.ts +76 -0
  27. package/dist/http/error-response.dto.d.ts.map +1 -0
  28. package/dist/http/error-response.dto.js +67 -0
  29. package/dist/http/error-response.dto.js.map +1 -0
  30. package/dist/http/errors.d.ts +39 -0
  31. package/dist/http/errors.d.ts.map +1 -1
  32. package/dist/http/errors.js +78 -0
  33. package/dist/http/errors.js.map +1 -1
  34. package/dist/http/route-helpers.d.ts +13 -6
  35. package/dist/http/route-helpers.d.ts.map +1 -1
  36. package/dist/http/route-helpers.js +29 -1
  37. package/dist/http/route-helpers.js.map +1 -1
  38. package/dist/index.d.ts +6 -3
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +10 -5
  41. package/dist/index.js.map +1 -1
  42. package/dist/middleware/rate-limit.d.ts.map +1 -1
  43. package/dist/middleware/rate-limit.js +2 -16
  44. package/dist/middleware/rate-limit.js.map +1 -1
  45. package/dist/openapi/defaults.d.ts.map +1 -1
  46. package/dist/openapi/defaults.js +6 -38
  47. package/dist/openapi/defaults.js.map +1 -1
  48. package/dist/openapi/openapi.d.ts +1 -1
  49. package/dist/openapi/openapi.d.ts.map +1 -1
  50. package/dist/openapi/openapi.js +21 -3
  51. package/dist/openapi/openapi.js.map +1 -1
  52. package/package.json +25 -2
  53. package/dist/bootstrap.d.ts +0 -55
  54. package/dist/bootstrap.d.ts.map +0 -1
  55. package/dist/bootstrap.js +0 -359
  56. package/dist/bootstrap.js.map +0 -1
  57. package/dist/environment.d.ts +0 -21
  58. package/dist/environment.d.ts.map +0 -1
  59. package/dist/environment.js +0 -29
  60. package/dist/environment.js.map +0 -1
  61. package/dist/error-handler.d.ts +0 -33
  62. package/dist/error-handler.d.ts.map +0 -1
  63. package/dist/error-handler.js +0 -53
  64. package/dist/error-handler.js.map +0 -1
  65. package/dist/errors.d.ts +0 -36
  66. package/dist/errors.d.ts.map +0 -1
  67. package/dist/errors.js +0 -65
  68. package/dist/errors.js.map +0 -1
  69. package/dist/get-client-ip.d.ts +0 -24
  70. package/dist/get-client-ip.d.ts.map +0 -1
  71. package/dist/get-client-ip.js +0 -49
  72. package/dist/get-client-ip.js.map +0 -1
  73. package/dist/logger.d.ts +0 -37
  74. package/dist/logger.d.ts.map +0 -1
  75. package/dist/logger.js +0 -52
  76. package/dist/logger.js.map +0 -1
  77. package/dist/module.d.ts +0 -21
  78. package/dist/module.d.ts.map +0 -1
  79. package/dist/module.js +0 -85
  80. package/dist/module.js.map +0 -1
  81. package/dist/omit.d.ts +0 -20
  82. package/dist/omit.d.ts.map +0 -1
  83. package/dist/omit.js +0 -28
  84. package/dist/omit.js.map +0 -1
  85. package/dist/openapi-defaults.d.ts +0 -11
  86. package/dist/openapi-defaults.d.ts.map +0 -1
  87. package/dist/openapi-defaults.js +0 -127
  88. package/dist/openapi-defaults.js.map +0 -1
  89. package/dist/openapi-hooks.d.ts +0 -14
  90. package/dist/openapi-hooks.d.ts.map +0 -1
  91. package/dist/openapi-hooks.js +0 -80
  92. package/dist/openapi-hooks.js.map +0 -1
  93. package/dist/openapi.d.ts +0 -24
  94. package/dist/openapi.d.ts.map +0 -1
  95. package/dist/openapi.js +0 -106
  96. package/dist/openapi.js.map +0 -1
  97. package/dist/pagination.d.ts +0 -48
  98. package/dist/pagination.d.ts.map +0 -1
  99. package/dist/pagination.js +0 -43
  100. package/dist/pagination.js.map +0 -1
  101. package/dist/pick.d.ts +0 -20
  102. package/dist/pick.d.ts.map +0 -1
  103. package/dist/pick.js +0 -28
  104. package/dist/pick.js.map +0 -1
  105. package/dist/rate-limit.d.ts +0 -7
  106. package/dist/rate-limit.d.ts.map +0 -1
  107. package/dist/rate-limit.js +0 -180
  108. package/dist/rate-limit.js.map +0 -1
  109. package/dist/route-helpers.d.ts +0 -172
  110. package/dist/route-helpers.d.ts.map +0 -1
  111. package/dist/route-helpers.js +0 -249
  112. package/dist/route-helpers.js.map +0 -1
  113. package/dist/serialize-dates.d.ts +0 -27
  114. package/dist/serialize-dates.d.ts.map +0 -1
  115. package/dist/serialize-dates.js +0 -39
  116. package/dist/serialize-dates.js.map +0 -1
  117. package/dist/testing.d.ts +0 -87
  118. package/dist/testing.d.ts.map +0 -1
  119. package/dist/testing.js +0 -94
  120. package/dist/testing.js.map +0 -1
  121. package/dist/types.d.ts +0 -273
  122. package/dist/types.d.ts.map +0 -1
  123. package/dist/types.js +0 -2
  124. package/dist/types.js.map +0 -1
  125. package/dist/utils.d.ts +0 -9
  126. package/dist/utils.d.ts.map +0 -1
  127. package/dist/utils.js +0 -31
  128. package/dist/utils.js.map +0 -1
@@ -1,180 +0,0 @@
1
- /**
2
- * In-memory rate limiter storage
3
- */
4
- class MemoryStore {
5
- store = new Map();
6
- async get(key) {
7
- const item = this.store.get(key);
8
- if (!item) {
9
- return null;
10
- }
11
- if (item.windowEnd < Date.now()) {
12
- this.store.delete(key);
13
- return null;
14
- }
15
- return item;
16
- }
17
- async set(key, value) {
18
- this.store.set(key, value);
19
- }
20
- async increment(key) {
21
- const item = this.store.get(key);
22
- if (item) {
23
- item.count += 1;
24
- }
25
- }
26
- // Cleanup expired entries periodically
27
- startCleanup(intervalMs = 60000) {
28
- setInterval(() => {
29
- const now = Date.now();
30
- for (const [key, item] of this.store.entries()) {
31
- if (item.windowEnd < now) {
32
- this.store.delete(key);
33
- }
34
- }
35
- }, intervalMs);
36
- }
37
- }
38
- /**
39
- * DynamoDB rate limiter storage
40
- */
41
- class DynamoDBStore {
42
- client;
43
- tableName;
44
- constructor(tableName, region) {
45
- this.tableName = tableName;
46
- // Lazy load AWS SDK only when needed
47
- this.initClient(region);
48
- }
49
- async initClient(region) {
50
- const { DynamoDBClient } = await import('@aws-sdk/client-dynamodb');
51
- const { DynamoDBDocumentClient } = await import('@aws-sdk/lib-dynamodb');
52
- const dynamoClient = new DynamoDBClient(region ? { region } : {});
53
- this.client = DynamoDBDocumentClient.from(dynamoClient);
54
- }
55
- async get(key) {
56
- const { GetCommand } = await import('@aws-sdk/lib-dynamodb');
57
- const client = this.client;
58
- try {
59
- // @ts-expect-error - client type is complex
60
- const { Item } = await client.send(new GetCommand({
61
- TableName: this.tableName,
62
- Key: { bucketId: key },
63
- }));
64
- if (!Item || Item.windowEnd < Date.now()) {
65
- return null;
66
- }
67
- return {
68
- count: Item.count,
69
- windowEnd: Item.windowEnd,
70
- };
71
- }
72
- catch {
73
- return null;
74
- }
75
- }
76
- async set(key, value) {
77
- const { PutCommand } = await import('@aws-sdk/lib-dynamodb');
78
- const client = this.client;
79
- const expiresAt = Math.floor(value.windowEnd / 1000);
80
- try {
81
- // @ts-expect-error - client type is complex
82
- await client.send(new PutCommand({
83
- TableName: this.tableName,
84
- Item: {
85
- bucketId: key,
86
- count: value.count,
87
- windowEnd: value.windowEnd,
88
- expiresAt,
89
- },
90
- }));
91
- }
92
- catch (error) {
93
- console.error('[Glasswork] DynamoDB rate limit set failed:', error);
94
- }
95
- }
96
- async increment(key) {
97
- const { UpdateCommand } = await import('@aws-sdk/lib-dynamodb');
98
- const client = this.client;
99
- try {
100
- // @ts-expect-error - client type is complex
101
- await client.send(new UpdateCommand({
102
- TableName: this.tableName,
103
- Key: { bucketId: key },
104
- UpdateExpression: 'SET #c = #c + :inc',
105
- ExpressionAttributeNames: { '#c': 'count' },
106
- ExpressionAttributeValues: { ':inc': 1 },
107
- }));
108
- }
109
- catch (error) {
110
- console.error('[Glasswork] DynamoDB rate limit increment failed:', error);
111
- }
112
- }
113
- }
114
- /**
115
- * Extract client IP from request context
116
- */
117
- function getClientIdentifier(context) {
118
- // Check various headers for client IP
119
- const forwarded = context.req.header('x-forwarded-for');
120
- if (forwarded) {
121
- return forwarded.split(',')[0].trim();
122
- }
123
- const realIp = context.req.header('x-real-ip');
124
- if (realIp) {
125
- return realIp;
126
- }
127
- return 'unknown';
128
- }
129
- /**
130
- * Create rate limiting middleware
131
- */
132
- export function createRateLimitMiddleware(options) {
133
- const { storage, windowMs = 60000, maxRequests = 100, dynamodb } = options;
134
- // Create appropriate storage backend
135
- const store = storage === 'dynamodb' && dynamodb
136
- ? new DynamoDBStore(dynamodb.tableName, dynamodb.region)
137
- : new MemoryStore();
138
- // Start cleanup for memory store
139
- if (store instanceof MemoryStore) {
140
- store.startCleanup();
141
- }
142
- return async (context, next) => {
143
- const clientId = getClientIdentifier(context);
144
- const now = Date.now();
145
- const windowEnd = now + windowMs;
146
- const setHeaders = (remaining, resetMs) => {
147
- context.header('RateLimit-Limit', String(maxRequests));
148
- context.header('RateLimit-Remaining', String(Math.max(0, remaining)));
149
- context.header('RateLimit-Reset', String(Math.ceil(resetMs / 1000)));
150
- };
151
- try {
152
- const item = await store.get(clientId);
153
- // New window or expired
154
- if (!item) {
155
- await store.set(clientId, { count: 1, windowEnd });
156
- setHeaders(maxRequests - 1, windowMs);
157
- await next();
158
- return;
159
- }
160
- // Rate limit exceeded
161
- if (item.count >= maxRequests) {
162
- const retryMs = item.windowEnd - now;
163
- setHeaders(0, retryMs);
164
- context.header('Retry-After', String(Math.ceil(retryMs / 1000)));
165
- return context.json({ error: 'Too Many Requests' }, 429);
166
- }
167
- // Increment counter
168
- await store.increment(clientId);
169
- setHeaders(maxRequests - (item.count + 1), item.windowEnd - now);
170
- await next();
171
- }
172
- catch (error) {
173
- console.error('[Glasswork] Rate limiter error:', error);
174
- // Fail open - allow request
175
- setHeaders(maxRequests, windowMs);
176
- await next();
177
- }
178
- };
179
- }
180
- //# sourceMappingURL=rate-limit.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
@@ -1,172 +0,0 @@
1
- import type { Context, Hono, MiddlewareHandler } from 'hono';
2
- import type { DescribeRouteOptions } from 'hono-openapi';
3
- import type { BaseIssue, BaseSchema, BaseSchemaAsync, InferOutput } from 'valibot';
4
- import type { OpenAPIResponseHook } from './types.js';
5
- /**
6
- * Set the global OpenAPI response hooks.
7
- * This is called during bootstrap and makes hooks available to route definitions.
8
- *
9
- * @internal
10
- */
11
- export declare function setGlobalResponseHooks(hooks: OpenAPIResponseHook[]): void;
12
- /**
13
- * Get the current global OpenAPI response hooks.
14
- *
15
- * @internal
16
- */
17
- export declare function getGlobalResponseHooks(): OpenAPIResponseHook[];
18
- /**
19
- * Valibot schema type (compatible with both sync and async schemas)
20
- */
21
- export type ValibotSchema = BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>;
22
- /**
23
- * Helper type to infer the output type from a Valibot schema
24
- */
25
- type InferSchemaType<T> = T extends ValibotSchema ? InferOutput<T> : never;
26
- /**
27
- * Helper type to infer the response type from the 200/201 status code schema
28
- *
29
- * Prisma client extension converts Date → string at the database layer,
30
- * so handlers return string-based entities that match the response schema output type.
31
- */
32
- type InferResponseType<T> = T extends {
33
- 200: infer TSchema;
34
- } ? TSchema extends ValibotSchema ? InferOutput<TSchema> : unknown : T extends {
35
- 201: infer TSchema;
36
- } ? TSchema extends ValibotSchema ? InferOutput<TSchema> : unknown : unknown;
37
- /**
38
- * HTTP status codes with descriptions
39
- */
40
- declare const STATUS_DESCRIPTIONS: {
41
- readonly 200: "Success";
42
- readonly 201: "Created";
43
- readonly 204: "No Content";
44
- readonly 400: "Bad Request";
45
- readonly 401: "Unauthorized";
46
- readonly 403: "Forbidden";
47
- readonly 404: "Not Found";
48
- readonly 409: "Conflict";
49
- readonly 422: "Unprocessable Entity";
50
- readonly 429: "Too Many Requests";
51
- readonly 500: "Internal Server Error";
52
- };
53
- /**
54
- * Route factory function type.
55
- * Receives a real Hono instance and services from DI container.
56
- */
57
- export type RouteFactory = (router: Hono, services: Record<string, unknown>) => void;
58
- /**
59
- * Create routes with typed service injection.
60
- *
61
- * @template TServices - The shape of services required by these routes
62
- *
63
- * @example
64
- * ```typescript
65
- * interface AuthRoutesServices {
66
- * authService: AuthService;
67
- * userService: UserService;
68
- * }
69
- *
70
- * export const authRoutes = createRoutes<AuthRoutesServices>((router, services) => {
71
- * // services.authService is typed as AuthService!
72
- * // services.userService is typed as UserService!
73
- * router.post('/login', ...);
74
- * });
75
- * ```
76
- */
77
- export declare function createRoutes<TServices = Record<string, unknown>>(factory: (router: Hono, services: TServices) => void): RouteFactory;
78
- /**
79
- * Route configuration with automatic type inference from Valibot schemas
80
- *
81
- * @template TBody - The body schema (automatically inferred)
82
- * @template TResponses - The responses object (automatically inferred)
83
- */
84
- export interface RouteConfig<TBody extends ValibotSchema | undefined = undefined, TResponses extends Partial<Record<keyof typeof STATUS_DESCRIPTIONS, ValibotSchema | undefined>> = Record<never, never>, TPublic extends boolean = false> {
85
- tags?: string[];
86
- summary?: string;
87
- description?: string;
88
- operationId?: string;
89
- /**
90
- * Whether this is a public route (no authentication required)
91
- * - false (default): Session is required and typed as non-nullable
92
- * - true: Session is optional and typed as nullable
93
- */
94
- public?: TPublic;
95
- body?: TBody;
96
- query?: ValibotSchema;
97
- params?: ValibotSchema;
98
- responses?: TResponses;
99
- openapi?: Partial<Omit<DescribeRouteOptions, 'responses' | 'operationId' | 'tags' | 'summary' | 'description'>>;
100
- /**
101
- * Custom middleware to apply before validation and handler
102
- */
103
- middleware?: MiddlewareHandler[];
104
- /**
105
- * Enable pagination - adds pagination query params and response headers to OpenAPI spec
106
- */
107
- paginate?: boolean;
108
- /**
109
- * Route handler - body and return types are automatically inferred from schemas
110
- * Session is required by default (unless public: true)
111
- *
112
- * Prisma client extension converts Date → string at the database layer,
113
- * so handler return types match the response schema output type.
114
- */
115
- handler: (context: RouteContext<TBody extends ValibotSchema ? InferSchemaType<TBody> : never, TPublic extends true ? false : true>) => Promise<InferResponseType<TResponses>> | InferResponseType<TResponses>;
116
- }
117
- /**
118
- * Route handler context with typed body
119
- *
120
- * Leverages Hono's ContextVariableMap for session typing.
121
- * If your middleware extends ContextVariableMap (e.g., auth middleware),
122
- * the session will be automatically typed in route handlers.
123
- *
124
- * @template TBody - The typed body (inferred from schema)
125
- * @template TSessionRequired - Whether session is guaranteed to exist (true by default, false for public routes)
126
- */
127
- export interface RouteContext<TBody = never, TSessionRequired extends boolean = true> {
128
- body: TBody;
129
- query: Record<string, string>;
130
- params: Record<string, string>;
131
- services: Record<string, unknown>;
132
- /**
133
- * Session from context variables (typed via Hono's ContextVariableMap)
134
- * - Required by default (for authenticated routes)
135
- * - Optional only for public routes (public: true)
136
- */
137
- session: TSessionRequired extends true ? NonNullable<Context['var']['session']> : Context['var']['session'];
138
- /**
139
- * Client IP address (extracted from headers and connection info)
140
- */
141
- ip: string;
142
- /**
143
- * User agent string from request headers
144
- */
145
- userAgent: string | undefined;
146
- /**
147
- * Original Hono context (for advanced use cases)
148
- */
149
- context: Context;
150
- }
151
- /**
152
- * Create a route handler with validation and OpenAPI metadata.
153
- *
154
- * Type inference works automatically:
155
- * - Body type is inferred from the `body` schema
156
- * - Return type is inferred from the `responses[200]` schema
157
- *
158
- * @example
159
- * ```typescript
160
- * route({
161
- * body: StartSessionDto,
162
- * responses: { 200: StartSessionResponseDto },
163
- * handler: async ({ body }) => {
164
- * // body is typed as InferOutput<typeof StartSessionDto>
165
- * return { email: body.email }; // Must match StartSessionResponseDto
166
- * }
167
- * })
168
- * ```
169
- */
170
- export declare function route<TBody extends ValibotSchema | undefined = undefined, TResponses extends Partial<Record<keyof typeof STATUS_DESCRIPTIONS, ValibotSchema | undefined>> = Record<never, never>, TPublic extends boolean = false>(config: RouteConfig<TBody, TResponses, TPublic>): MiddlewareHandler[];
171
- export {};
172
- //# sourceMappingURL=route-helpers.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../src/route-helpers.ts"],"names":[],"mappings":"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"}
@@ -1,249 +0,0 @@
1
- import { describeRoute as honoDescribeRoute } from 'hono-openapi';
2
- import { resolver, validator } from 'hono-openapi/valibot';
3
- import { getClientIp } from './get-client-ip.js';
4
- /**
5
- * Global storage for OpenAPI response hooks.
6
- * Set during bootstrap and used when defining routes.
7
- */
8
- let globalResponseHooks = [];
9
- /**
10
- * Set the global OpenAPI response hooks.
11
- * This is called during bootstrap and makes hooks available to route definitions.
12
- *
13
- * @internal
14
- */
15
- export function setGlobalResponseHooks(hooks) {
16
- globalResponseHooks = hooks;
17
- }
18
- /**
19
- * Get the current global OpenAPI response hooks.
20
- *
21
- * @internal
22
- */
23
- export function getGlobalResponseHooks() {
24
- return globalResponseHooks;
25
- }
26
- /**
27
- * HTTP status codes with descriptions
28
- */
29
- const STATUS_DESCRIPTIONS = {
30
- 200: 'Success',
31
- 201: 'Created',
32
- 204: 'No Content',
33
- 400: 'Bad Request',
34
- 401: 'Unauthorized',
35
- 403: 'Forbidden',
36
- 404: 'Not Found',
37
- 409: 'Conflict',
38
- 422: 'Unprocessable Entity',
39
- 429: 'Too Many Requests',
40
- 500: 'Internal Server Error',
41
- };
42
- /**
43
- * Create routes with typed service injection.
44
- *
45
- * @template TServices - The shape of services required by these routes
46
- *
47
- * @example
48
- * ```typescript
49
- * interface AuthRoutesServices {
50
- * authService: AuthService;
51
- * userService: UserService;
52
- * }
53
- *
54
- * export const authRoutes = createRoutes<AuthRoutesServices>((router, services) => {
55
- * // services.authService is typed as AuthService!
56
- * // services.userService is typed as UserService!
57
- * router.post('/login', ...);
58
- * });
59
- * ```
60
- */
61
- export function createRoutes(factory) {
62
- return factory;
63
- }
64
- /**
65
- * Create a route handler with validation and OpenAPI metadata.
66
- *
67
- * Type inference works automatically:
68
- * - Body type is inferred from the `body` schema
69
- * - Return type is inferred from the `responses[200]` schema
70
- *
71
- * @example
72
- * ```typescript
73
- * route({
74
- * body: StartSessionDto,
75
- * responses: { 200: StartSessionResponseDto },
76
- * handler: async ({ body }) => {
77
- * // body is typed as InferOutput<typeof StartSessionDto>
78
- * return { email: body.email }; // Must match StartSessionResponseDto
79
- * }
80
- * })
81
- * ```
82
- */
83
- export function route(config) {
84
- const middlewares = [];
85
- // Add OpenAPI metadata
86
- middlewares.push(buildOpenAPIMiddleware(config));
87
- // Add custom middleware (e.g., auth) before validation
88
- if (config.middleware) {
89
- middlewares.push(...config.middleware);
90
- }
91
- // Add validation middleware with custom error handler (returns 422 instead of 400)
92
- if (config.body) {
93
- middlewares.push(validator('json', config.body, (result, c) => {
94
- if (!result.success) {
95
- return c.json({ error: 'Validation failed', issues: result.issues }, 422);
96
- }
97
- }));
98
- }
99
- if (config.query) {
100
- middlewares.push(validator('query', config.query, (result, c) => {
101
- if (!result.success) {
102
- return c.json({ error: 'Validation failed', issues: result.issues }, 422);
103
- }
104
- }));
105
- }
106
- if (config.params) {
107
- middlewares.push(validator('param', config.params, (result, c) => {
108
- if (!result.success) {
109
- return c.json({ error: 'Validation failed', issues: result.issues }, 422);
110
- }
111
- }));
112
- }
113
- // Add handler wrapper
114
- middlewares.push(async (c) => {
115
- const routeContext = buildRouteContext(c);
116
- const result = await config.handler(
117
- // @ts-expect-error - Session typing issue to be resolved separately
118
- routeContext);
119
- // If handler returned a Response, return it directly (for custom responses like text)
120
- if (result instanceof Response) {
121
- return result;
122
- }
123
- // Return appropriate response
124
- if (result === null || result === undefined) {
125
- c.status(204);
126
- return c.body(null);
127
- }
128
- return c.json(result);
129
- });
130
- return middlewares;
131
- }
132
- function buildOpenAPIMiddleware(config) {
133
- const responses = buildOpenAPIResponses(config);
134
- const openApiConfig = {
135
- operationId: config.operationId || config.summary,
136
- tags: config.tags,
137
- summary: config.summary,
138
- description: config.description,
139
- responses: responses,
140
- security: config.public ? [] : [{ bearerAuth: [] }],
141
- ...(config.paginate && { parameters: buildPaginationParameters() }),
142
- ...config.openapi,
143
- };
144
- return honoDescribeRoute(openApiConfig);
145
- }
146
- /**
147
- * Build pagination parameters for OpenAPI spec
148
- */
149
- function buildPaginationParameters() {
150
- return [
151
- {
152
- name: 'page',
153
- in: 'query',
154
- required: false,
155
- schema: {
156
- type: 'integer',
157
- format: 'int32',
158
- minimum: 1,
159
- maximum: 2147483647, // Max int32
160
- default: 1,
161
- },
162
- description: 'Page number',
163
- },
164
- {
165
- name: 'limit',
166
- in: 'query',
167
- required: false,
168
- schema: {
169
- type: 'integer',
170
- format: 'int32',
171
- minimum: 1,
172
- maximum: 100,
173
- default: 50,
174
- },
175
- description: 'Number of items per page',
176
- },
177
- ];
178
- }
179
- function buildOpenAPIResponses(config) {
180
- const responses = {};
181
- // Add default error responses
182
- const defaultResponses = config.public
183
- ? { 400: undefined, 429: undefined, 500: undefined }
184
- : { 400: undefined, 401: undefined, 429: undefined, 500: undefined };
185
- const allResponses = { ...defaultResponses, ...(config.responses || {}) };
186
- // Get global hooks
187
- const hooks = getGlobalResponseHooks();
188
- for (const [statusCode, schema] of Object.entries(allResponses)) {
189
- const code = Number(statusCode);
190
- const description = STATUS_DESCRIPTIONS[code] || 'Response';
191
- // Determine if this is an error response that should use default error schema
192
- const isErrorResponse = code >= 400;
193
- const shouldUseDefaultErrorSchema = isErrorResponse && !schema;
194
- // Start with base response (no headers)
195
- let response = {
196
- description,
197
- ...(schema
198
- ? {
199
- content: {
200
- 'application/json': {
201
- // resolver type only supports BaseSchema, but works with BaseSchemaAsync at runtime
202
- // @ts-expect-error - resolver accepts both BaseSchema and BaseSchemaAsync
203
- schema: resolver(schema, { errorMode: 'ignore' }),
204
- },
205
- },
206
- }
207
- : shouldUseDefaultErrorSchema
208
- ? {
209
- content: {
210
- 'application/json': {
211
- schema: {
212
- $ref: '#/components/schemas/ErrorResponse',
213
- },
214
- },
215
- },
216
- }
217
- : {}),
218
- };
219
- // Apply hooks to build up headers
220
- for (const hook of hooks) {
221
- response = hook(response, {
222
- statusCode,
223
- routeConfig: {
224
- public: config.public,
225
- paginate: config.paginate,
226
- tags: config.tags,
227
- summary: config.summary,
228
- },
229
- });
230
- }
231
- responses[statusCode] = response;
232
- }
233
- return responses;
234
- }
235
- function buildRouteContext(c) {
236
- const req = c.req;
237
- return {
238
- body: req.valid('json'),
239
- query: req.valid('query'),
240
- params: req.valid('param'),
241
- services: c.get('services') || {},
242
- // @ts-expect-error - Session typing issue to be resolved separately
243
- session: c.get('session'),
244
- ip: getClientIp(c),
245
- userAgent: c.req.header('user-agent'),
246
- context: c,
247
- };
248
- }
249
- //# sourceMappingURL=route-helpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"route-helpers.js","sourceRoot":"","sources":["../src/route-helpers.ts"],"names":[],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- /**
2
- * Type helper to recursively convert Date fields to string in an object type
3
- */
4
- export type SerializedDates<T> = T extends Date ? string : T extends Array<infer U> ? Array<SerializedDates<U>> : T extends object ? {
5
- [K in keyof T]: SerializedDates<T[K]>;
6
- } : T;
7
- /**
8
- * Recursively converts all Date objects to ISO 8601 strings in an entity or array of entities.
9
- *
10
- * This utility handles the mismatch between Prisma's Date types and API response DTOs
11
- * that expect string timestamps. It preserves null values and handles nested objects and arrays.
12
- *
13
- * @template T - The type of data to transform
14
- * @param data - The data to transform (object, array, or primitive)
15
- * @returns The same structure with all Date objects converted to ISO strings
16
- *
17
- * @example
18
- * ```typescript
19
- * const ranger = await prisma.ranger.findUnique({
20
- * where: { id },
21
- * include: { category: true }
22
- * });
23
- * return serializeDates(ranger); // All Date fields → ISO strings
24
- * ```
25
- */
26
- export declare function serializeDates<T>(data: T): SerializedDates<T>;
27
- //# sourceMappingURL=serialize-dates.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serialize-dates.d.ts","sourceRoot":"","sources":["../src/serialize-dates.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,GAC3C,MAAM,GACN,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GACtB,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GACzB,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GACzC,CAAC,CAAC;AAEV;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAsB7D"}