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.
- package/README.md +22 -43
- package/dist/config/config-service.d.ts +101 -0
- package/dist/config/config-service.d.ts.map +1 -0
- package/dist/config/config-service.js +164 -0
- package/dist/config/config-service.js.map +1 -0
- package/dist/config/helpers.d.ts +101 -0
- package/dist/config/helpers.d.ts.map +1 -0
- package/dist/config/helpers.js +122 -0
- package/dist/config/helpers.js.map +1 -0
- package/dist/config/index.d.ts +39 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +41 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/providers.d.ts +163 -0
- package/dist/config/providers.d.ts.map +1 -0
- package/dist/config/providers.js +188 -0
- package/dist/config/providers.js.map +1 -0
- package/dist/config/types.d.ts +98 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +7 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/bootstrap.js +9 -3
- package/dist/core/bootstrap.js.map +1 -1
- package/dist/core/types.d.ts +2 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/http/error-response.dto.d.ts +76 -0
- package/dist/http/error-response.dto.d.ts.map +1 -0
- package/dist/http/error-response.dto.js +67 -0
- package/dist/http/error-response.dto.js.map +1 -0
- package/dist/http/errors.d.ts +39 -0
- package/dist/http/errors.d.ts.map +1 -1
- package/dist/http/errors.js +78 -0
- package/dist/http/errors.js.map +1 -1
- package/dist/http/route-helpers.d.ts +13 -6
- package/dist/http/route-helpers.d.ts.map +1 -1
- package/dist/http/route-helpers.js +29 -1
- package/dist/http/route-helpers.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/middleware/rate-limit.d.ts.map +1 -1
- package/dist/middleware/rate-limit.js +2 -16
- package/dist/middleware/rate-limit.js.map +1 -1
- package/dist/openapi/defaults.d.ts.map +1 -1
- package/dist/openapi/defaults.js +6 -38
- package/dist/openapi/defaults.js.map +1 -1
- package/dist/openapi/openapi.d.ts +1 -1
- package/dist/openapi/openapi.d.ts.map +1 -1
- package/dist/openapi/openapi.js +21 -3
- package/dist/openapi/openapi.js.map +1 -1
- package/package.json +25 -2
- package/dist/bootstrap.d.ts +0 -55
- package/dist/bootstrap.d.ts.map +0 -1
- package/dist/bootstrap.js +0 -359
- package/dist/bootstrap.js.map +0 -1
- package/dist/environment.d.ts +0 -21
- package/dist/environment.d.ts.map +0 -1
- package/dist/environment.js +0 -29
- package/dist/environment.js.map +0 -1
- package/dist/error-handler.d.ts +0 -33
- package/dist/error-handler.d.ts.map +0 -1
- package/dist/error-handler.js +0 -53
- package/dist/error-handler.js.map +0 -1
- package/dist/errors.d.ts +0 -36
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -65
- package/dist/errors.js.map +0 -1
- package/dist/get-client-ip.d.ts +0 -24
- package/dist/get-client-ip.d.ts.map +0 -1
- package/dist/get-client-ip.js +0 -49
- package/dist/get-client-ip.js.map +0 -1
- package/dist/logger.d.ts +0 -37
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -52
- package/dist/logger.js.map +0 -1
- package/dist/module.d.ts +0 -21
- package/dist/module.d.ts.map +0 -1
- package/dist/module.js +0 -85
- package/dist/module.js.map +0 -1
- package/dist/omit.d.ts +0 -20
- package/dist/omit.d.ts.map +0 -1
- package/dist/omit.js +0 -28
- package/dist/omit.js.map +0 -1
- package/dist/openapi-defaults.d.ts +0 -11
- package/dist/openapi-defaults.d.ts.map +0 -1
- package/dist/openapi-defaults.js +0 -127
- package/dist/openapi-defaults.js.map +0 -1
- package/dist/openapi-hooks.d.ts +0 -14
- package/dist/openapi-hooks.d.ts.map +0 -1
- package/dist/openapi-hooks.js +0 -80
- package/dist/openapi-hooks.js.map +0 -1
- package/dist/openapi.d.ts +0 -24
- package/dist/openapi.d.ts.map +0 -1
- package/dist/openapi.js +0 -106
- package/dist/openapi.js.map +0 -1
- package/dist/pagination.d.ts +0 -48
- package/dist/pagination.d.ts.map +0 -1
- package/dist/pagination.js +0 -43
- package/dist/pagination.js.map +0 -1
- package/dist/pick.d.ts +0 -20
- package/dist/pick.d.ts.map +0 -1
- package/dist/pick.js +0 -28
- package/dist/pick.js.map +0 -1
- package/dist/rate-limit.d.ts +0 -7
- package/dist/rate-limit.d.ts.map +0 -1
- package/dist/rate-limit.js +0 -180
- package/dist/rate-limit.js.map +0 -1
- package/dist/route-helpers.d.ts +0 -172
- package/dist/route-helpers.d.ts.map +0 -1
- package/dist/route-helpers.js +0 -249
- package/dist/route-helpers.js.map +0 -1
- package/dist/serialize-dates.d.ts +0 -27
- package/dist/serialize-dates.d.ts.map +0 -1
- package/dist/serialize-dates.js +0 -39
- package/dist/serialize-dates.js.map +0 -1
- package/dist/testing.d.ts +0 -87
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -94
- package/dist/testing.js.map +0 -1
- package/dist/types.d.ts +0 -273
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -9
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -31
- package/dist/utils.js.map +0 -1
package/dist/rate-limit.js
DELETED
|
@@ -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
|
package/dist/rate-limit.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
|
package/dist/route-helpers.d.ts
DELETED
|
@@ -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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"}
|
package/dist/route-helpers.js
DELETED
|
@@ -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"}
|