@stacksjs/bun-router 0.0.12 → 0.0.14
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/CHANGELOG.md +770 -0
- package/README.md +584 -261
- package/package.json +43 -48
- package/bin/cli.ts +0 -9
- package/dist/auth.d.ts +0 -134
- package/dist/cache/lru-cache.d.ts +0 -139
- package/dist/cache/middleware-memoization.d.ts +0 -151
- package/dist/cache/route-cache-warmer.d.ts +0 -161
- package/dist/cache/sqlite-cache.d.ts +0 -209
- package/dist/cache/streaming-cache.d.ts +0 -132
- package/dist/chunk-1mvtv6jw.js +0 -13012
- package/dist/cli/colors.d.ts +0 -15
- package/dist/cli/index.d.ts +0 -10
- package/dist/cli/middleware.d.ts +0 -31
- package/dist/cli/openapi.d.ts +0 -17
- package/dist/cli/router.d.ts +0 -15
- package/dist/cli/routes.d.ts +0 -29
- package/dist/cli/utils.d.ts +0 -74
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +0 -3195
- package/dist/config.d.ts +0 -7
- package/dist/container/container.d.ts +0 -273
- package/dist/container/contextual-binding.d.ts +0 -240
- package/dist/container/decorators.d.ts +0 -141
- package/dist/container/service-provider.d.ts +0 -285
- package/dist/development/hot-reload.d.ts +0 -187
- package/dist/development/index.d.ts +0 -167
- package/dist/development/performance-profiler.d.ts +0 -217
- package/dist/development/route-debugger.d.ts +0 -154
- package/dist/development/route-inspector.d.ts +0 -211
- package/dist/development/typescript-utilities.d.ts +0 -209
- package/dist/docs.d.ts +0 -11
- package/dist/errors/circuit-breaker.d.ts +0 -195
- package/dist/errors/error-handler.d.ts +0 -88
- package/dist/errors/error-reporting.d.ts +0 -144
- package/dist/errors/exceptions.d.ts +0 -184
- package/dist/errors/graceful-degradation.d.ts +0 -154
- package/dist/errors/index.d.ts +0 -9
- package/dist/errors/router-errors.d.ts +0 -110
- package/dist/file-serving/static-files.d.ts +0 -143
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -13933
- package/dist/middleware/auth.d.ts +0 -63
- package/dist/middleware/content_security_policy.d.ts +0 -53
- package/dist/middleware/cors.d.ts +0 -5
- package/dist/middleware/csrf.d.ts +0 -7
- package/dist/middleware/ddos_protection.d.ts +0 -39
- package/dist/middleware/file_security.d.ts +0 -26
- package/dist/middleware/file_upload.d.ts +0 -38
- package/dist/middleware/helmet.d.ts +0 -54
- package/dist/middleware/index.d.ts +0 -44
- package/dist/middleware/input_validation.d.ts +0 -45
- package/dist/middleware/json_body.d.ts +0 -4
- package/dist/middleware/performance_alerting.d.ts +0 -87
- package/dist/middleware/performance_dashboard.d.ts +0 -87
- package/dist/middleware/performance_monitor.d.ts +0 -209
- package/dist/middleware/pipeline.d.ts +0 -131
- package/dist/middleware/rate_limit.d.ts +0 -36
- package/dist/middleware/request_id.d.ts +0 -4
- package/dist/middleware/request_signing.d.ts +0 -153
- package/dist/middleware/request_tracer.d.ts +0 -72
- package/dist/middleware/response_cache.d.ts +0 -97
- package/dist/middleware/security.d.ts +0 -69
- package/dist/middleware/security_suite.d.ts +0 -46
- package/dist/middleware/session.d.ts +0 -23
- package/dist/model-binding/index.d.ts +0 -2
- package/dist/model-binding/model-middleware.d.ts +0 -118
- package/dist/model-binding/model-registry.d.ts +0 -164
- package/dist/model-binding.d.ts +0 -185
- package/dist/model-resolver-factory.d.ts +0 -31
- package/dist/observability/correlation.d.ts +0 -187
- package/dist/observability/health-checks.d.ts +0 -186
- package/dist/observability/index.d.ts +0 -60
- package/dist/observability/integration.d.ts +0 -147
- package/dist/observability/metrics.d.ts +0 -184
- package/dist/observability/tracing.d.ts +0 -187
- package/dist/optimization/bun-utilities.d.ts +0 -224
- package/dist/query-builder-integration.d.ts +0 -36
- package/dist/request/context.d.ts +0 -34
- package/dist/request/enhanced-request.d.ts +0 -213
- package/dist/request/macros.d.ts +0 -300
- package/dist/response/macros.d.ts +0 -245
- package/dist/response/response-factory.d.ts +0 -133
- package/dist/router/api-routes.d.ts +0 -5
- package/dist/router/file-based-routing.d.ts +0 -118
- package/dist/router/file-streaming.d.ts +0 -5
- package/dist/router/fluent-router.d.ts +0 -315
- package/dist/router/fluent-routing.d.ts +0 -271
- package/dist/router/group-organization.d.ts +0 -5
- package/dist/router/handler-resolver.d.ts +0 -24
- package/dist/router/http-methods.d.ts +0 -10
- package/dist/router/index.d.ts +0 -114
- package/dist/router/middleware-groups.d.ts +0 -94
- package/dist/router/middleware-integration.d.ts +0 -112
- package/dist/router/middleware.d.ts +0 -5
- package/dist/router/model-binding.d.ts +0 -5
- package/dist/router/optimized-route-matching.d.ts +0 -6
- package/dist/router/route-building.d.ts +0 -5
- package/dist/router/route-compiler.d.ts +0 -153
- package/dist/router/route-matching.d.ts +0 -5
- package/dist/router/route-trie.d.ts +0 -114
- package/dist/router/router.d.ts +0 -294
- package/dist/router/server.d.ts +0 -5
- package/dist/router/validation-integration.d.ts +0 -170
- package/dist/router/view-rendering.d.ts +0 -5
- package/dist/router/websocket.d.ts +0 -5
- package/dist/routing/route-caching.d.ts +0 -129
- package/dist/routing/route-throttling.d.ts +0 -150
- package/dist/routing/subdomain-routing.d.ts +0 -206
- package/dist/session/database-store.d.ts +0 -51
- package/dist/session/file-store.d.ts +0 -22
- package/dist/session/index.d.ts +0 -106
- package/dist/session/memory-store.d.ts +0 -21
- package/dist/session/redis-store.d.ts +0 -31
- package/dist/streaming/index.d.ts +0 -3
- package/dist/streaming/sse-handler.d.ts +0 -138
- package/dist/streaming/stream-handler.d.ts +0 -114
- package/dist/testing/auth-testing.d.ts +0 -156
- package/dist/testing/file-upload-testing.d.ts +0 -190
- package/dist/testing/index.d.ts +0 -10
- package/dist/testing/middleware-testing.d.ts +0 -138
- package/dist/testing/model-binding-testing.d.ts +0 -186
- package/dist/testing/performance-testing.d.ts +0 -235
- package/dist/testing/test-client.d.ts +0 -117
- package/dist/testing/test-request.d.ts +0 -85
- package/dist/testing/test-response.d.ts +0 -90
- package/dist/testing/types.d.ts +0 -207
- package/dist/testing/websocket-testing.d.ts +0 -227
- package/dist/types/controller-types.d.ts +0 -208
- package/dist/types/core.d.ts +0 -543
- package/dist/types/middleware-types.d.ts +0 -227
- package/dist/types/request-response-augmentation.d.ts +0 -261
- package/dist/types/route-inference.d.ts +0 -168
- package/dist/types.d.ts +0 -1782
- package/dist/url.d.ts +0 -56
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/query-preservation.d.ts +0 -48
- package/dist/utils.d.ts +0 -69
- package/dist/validation/validator.d.ts +0 -140
- package/dist/websocket/clustering.d.ts +0 -185
- package/src/auth.ts +0 -469
- package/src/cache/lru-cache.ts +0 -457
- package/src/cache/middleware-memoization.ts +0 -531
- package/src/cache/route-cache-warmer.ts +0 -486
- package/src/cache/sqlite-cache.ts +0 -783
- package/src/cache/streaming-cache.ts +0 -572
- package/src/cli/colors.ts +0 -29
- package/src/cli/index.ts +0 -287
- package/src/cli/middleware.ts +0 -291
- package/src/cli/openapi.ts +0 -407
- package/src/cli/router.ts +0 -188
- package/src/cli/routes.ts +0 -265
- package/src/cli/utils.ts +0 -531
- package/src/cli.ts +0 -5
- package/src/config.ts +0 -322
- package/src/container/container.ts +0 -740
- package/src/container/contextual-binding.ts +0 -603
- package/src/container/decorators.ts +0 -359
- package/src/container/service-provider.ts +0 -596
- package/src/development/hot-reload.ts +0 -673
- package/src/development/index.ts +0 -499
- package/src/development/performance-profiler.ts +0 -717
- package/src/development/route-debugger.ts +0 -527
- package/src/development/route-inspector.ts +0 -749
- package/src/development/typescript-utilities.ts +0 -682
- package/src/docs.ts +0 -397
- package/src/errors/circuit-breaker.ts +0 -732
- package/src/errors/error-handler.ts +0 -569
- package/src/errors/error-reporting.ts +0 -672
- package/src/errors/exceptions.ts +0 -536
- package/src/errors/graceful-degradation.ts +0 -621
- package/src/errors/index.ts +0 -21
- package/src/errors/router-errors.ts +0 -632
- package/src/file-serving/static-files.ts +0 -581
- package/src/index.ts +0 -14
- package/src/middleware/auth.ts +0 -219
- package/src/middleware/content_security_policy.ts +0 -215
- package/src/middleware/cors.ts +0 -74
- package/src/middleware/csrf.ts +0 -108
- package/src/middleware/ddos_protection.ts +0 -255
- package/src/middleware/file_security.ts +0 -191
- package/src/middleware/file_upload.ts +0 -264
- package/src/middleware/helmet.ts +0 -268
- package/src/middleware/index.ts +0 -117
- package/src/middleware/input_validation.ts +0 -449
- package/src/middleware/json_body.ts +0 -37
- package/src/middleware/performance_alerting.ts +0 -538
- package/src/middleware/performance_dashboard.ts +0 -661
- package/src/middleware/performance_monitor.ts +0 -943
- package/src/middleware/pipeline.ts +0 -489
- package/src/middleware/rate_limit.ts +0 -245
- package/src/middleware/request_id.ts +0 -36
- package/src/middleware/request_signing.ts +0 -636
- package/src/middleware/request_tracer.ts +0 -636
- package/src/middleware/response_cache.ts +0 -743
- package/src/middleware/security.ts +0 -482
- package/src/middleware/security_suite.ts +0 -257
- package/src/middleware/session.ts +0 -91
- package/src/model-binding/index.ts +0 -18
- package/src/model-binding/model-middleware.ts +0 -425
- package/src/model-binding/model-registry.ts +0 -550
- package/src/model-binding.ts +0 -370
- package/src/model-resolver-factory.ts +0 -106
- package/src/observability/correlation.ts +0 -691
- package/src/observability/health-checks.ts +0 -729
- package/src/observability/index.ts +0 -184
- package/src/observability/integration.ts +0 -548
- package/src/observability/metrics.ts +0 -753
- package/src/observability/tracing.ts +0 -638
- package/src/optimization/bun-utilities.ts +0 -778
- package/src/query-builder-integration.ts +0 -137
- package/src/request/context.ts +0 -62
- package/src/request/enhanced-request.ts +0 -857
- package/src/request/macros.ts +0 -688
- package/src/response/macros.ts +0 -612
- package/src/response/response-factory.ts +0 -596
- package/src/router/api-routes.ts +0 -243
- package/src/router/file-based-routing.ts +0 -670
- package/src/router/file-streaming.ts +0 -372
- package/src/router/fluent-router.ts +0 -927
- package/src/router/fluent-routing.ts +0 -797
- package/src/router/group-organization.ts +0 -213
- package/src/router/handler-resolver.ts +0 -291
- package/src/router/http-methods.ts +0 -377
- package/src/router/index.ts +0 -187
- package/src/router/middleware-groups.ts +0 -222
- package/src/router/middleware-integration.ts +0 -399
- package/src/router/middleware.ts +0 -231
- package/src/router/model-binding.ts +0 -215
- package/src/router/optimized-route-matching.ts +0 -253
- package/src/router/route-building.ts +0 -212
- package/src/router/route-compiler.ts +0 -702
- package/src/router/route-matching.ts +0 -349
- package/src/router/route-trie.ts +0 -464
- package/src/router/router.ts +0 -1581
- package/src/router/server.ts +0 -462
- package/src/router/validation-integration.ts +0 -443
- package/src/router/view-rendering.ts +0 -233
- package/src/router/websocket.ts +0 -100
- package/src/routing/route-caching.ts +0 -402
- package/src/routing/route-throttling.ts +0 -469
- package/src/routing/subdomain-routing.ts +0 -492
- package/src/session/database-store.ts +0 -109
- package/src/session/file-store.ts +0 -148
- package/src/session/index.ts +0 -244
- package/src/session/memory-store.ts +0 -88
- package/src/session/redis-store.ts +0 -93
- package/src/streaming/index.ts +0 -17
- package/src/streaming/sse-handler.ts +0 -482
- package/src/streaming/stream-handler.ts +0 -552
- package/src/testing/auth-testing.ts +0 -446
- package/src/testing/file-upload-testing.ts +0 -543
- package/src/testing/index.ts +0 -10
- package/src/testing/middleware-testing.ts +0 -322
- package/src/testing/model-binding-testing.ts +0 -645
- package/src/testing/performance-testing.ts +0 -738
- package/src/testing/test-client.ts +0 -310
- package/src/testing/test-request.ts +0 -315
- package/src/testing/test-response.ts +0 -332
- package/src/testing/types.ts +0 -224
- package/src/testing/websocket-testing.ts +0 -590
- package/src/types/controller-types.ts +0 -385
- package/src/types/core.ts +0 -683
- package/src/types/middleware-types.ts +0 -419
- package/src/types/request-response-augmentation.ts +0 -489
- package/src/types/route-inference.ts +0 -357
- package/src/types.ts +0 -2055
- package/src/url.ts +0 -126
- package/src/utils/index.ts +0 -1
- package/src/utils/query-preservation.ts +0 -201
- package/src/utils.ts +0 -327
- package/src/validation/validator.ts +0 -685
- package/src/websocket/clustering.ts +0 -762
|
@@ -1,682 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Development Tools - TypeScript Utilities
|
|
3
|
-
*
|
|
4
|
-
* TypeScript development utilities, type checking, and code generation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { EnhancedRequest } from '../types'
|
|
8
|
-
|
|
9
|
-
export interface TypeScriptConfig {
|
|
10
|
-
strictMode?: boolean
|
|
11
|
-
generateTypes?: boolean
|
|
12
|
-
validateTypes?: boolean
|
|
13
|
-
outputDir?: string
|
|
14
|
-
includeComments?: boolean
|
|
15
|
-
generateSchemas?: boolean
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface RouteTypeInfo {
|
|
19
|
-
method: string
|
|
20
|
-
pattern: string
|
|
21
|
-
requestType: string
|
|
22
|
-
responseType: string
|
|
23
|
-
paramsType: string
|
|
24
|
-
queryType: string
|
|
25
|
-
bodyType: string
|
|
26
|
-
middlewareTypes: string[]
|
|
27
|
-
handlerSignature: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface TypeDefinition {
|
|
31
|
-
name: string
|
|
32
|
-
type: 'interface' | 'type' | 'enum' | 'class'
|
|
33
|
-
definition: string
|
|
34
|
-
imports: string[]
|
|
35
|
-
exports: string[]
|
|
36
|
-
documentation?: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface ValidationSchema {
|
|
40
|
-
type: 'object' | 'array' | 'string' | 'number' | 'boolean'
|
|
41
|
-
properties?: Record<string, ValidationSchema>
|
|
42
|
-
items?: ValidationSchema
|
|
43
|
-
required?: string[]
|
|
44
|
-
pattern?: string
|
|
45
|
-
minimum?: number
|
|
46
|
-
maximum?: number
|
|
47
|
-
enum?: any[]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* TypeScript utilities for development
|
|
52
|
-
*/
|
|
53
|
-
export class TypeScriptUtilities {
|
|
54
|
-
private config: TypeScriptConfig
|
|
55
|
-
private routeTypes = new Map<string, RouteTypeInfo>()
|
|
56
|
-
private typeDefinitions = new Map<string, TypeDefinition>()
|
|
57
|
-
|
|
58
|
-
constructor(config: TypeScriptConfig = {}) {
|
|
59
|
-
this.config = {
|
|
60
|
-
strictMode: true,
|
|
61
|
-
generateTypes: true,
|
|
62
|
-
validateTypes: true,
|
|
63
|
-
outputDir: './types',
|
|
64
|
-
includeComments: true,
|
|
65
|
-
generateSchemas: true,
|
|
66
|
-
...config,
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Register route type information
|
|
72
|
-
*/
|
|
73
|
-
registerRouteTypes(
|
|
74
|
-
method: string,
|
|
75
|
-
pattern: string,
|
|
76
|
-
options: {
|
|
77
|
-
requestType?: string
|
|
78
|
-
responseType?: string
|
|
79
|
-
paramsType?: string
|
|
80
|
-
queryType?: string
|
|
81
|
-
bodyType?: string
|
|
82
|
-
middlewareTypes?: string[]
|
|
83
|
-
handlerSignature?: string
|
|
84
|
-
} = {},
|
|
85
|
-
): void {
|
|
86
|
-
const routeKey = `${method.toUpperCase()}:${pattern}`
|
|
87
|
-
|
|
88
|
-
const typeInfo: RouteTypeInfo = {
|
|
89
|
-
method: method.toUpperCase(),
|
|
90
|
-
pattern,
|
|
91
|
-
requestType: options.requestType || 'EnhancedRequest',
|
|
92
|
-
responseType: options.responseType || 'Response',
|
|
93
|
-
paramsType: options.paramsType || this.inferParamsType(pattern),
|
|
94
|
-
queryType: options.queryType || 'Record<string, string>',
|
|
95
|
-
bodyType: options.bodyType || 'unknown',
|
|
96
|
-
middlewareTypes: options.middlewareTypes || [],
|
|
97
|
-
handlerSignature: options.handlerSignature || this.generateHandlerSignature(options),
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
this.routeTypes.set(routeKey, typeInfo)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Generate TypeScript definitions for all routes
|
|
105
|
-
*/
|
|
106
|
-
generateRouteTypes(): string {
|
|
107
|
-
const routes = Array.from(this.routeTypes.values())
|
|
108
|
-
let output = ''
|
|
109
|
-
|
|
110
|
-
// Add imports
|
|
111
|
-
output += this.generateImports()
|
|
112
|
-
output += '\n\n'
|
|
113
|
-
|
|
114
|
-
// Generate parameter types
|
|
115
|
-
output += this.generateParamTypes(routes)
|
|
116
|
-
output += '\n\n'
|
|
117
|
-
|
|
118
|
-
// Generate handler types
|
|
119
|
-
output += this.generateHandlerTypes(routes)
|
|
120
|
-
output += '\n\n'
|
|
121
|
-
|
|
122
|
-
// Generate route registry type
|
|
123
|
-
output += this.generateRouteRegistryType(routes)
|
|
124
|
-
output += '\n\n'
|
|
125
|
-
|
|
126
|
-
// Generate utility types
|
|
127
|
-
output += this.generateUtilityTypes()
|
|
128
|
-
|
|
129
|
-
return output
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Generate validation schemas from TypeScript types
|
|
134
|
-
*/
|
|
135
|
-
generateValidationSchemas(): Record<string, ValidationSchema> {
|
|
136
|
-
const schemas: Record<string, ValidationSchema> = {}
|
|
137
|
-
|
|
138
|
-
this.routeTypes.forEach((typeInfo, routeKey) => {
|
|
139
|
-
// Generate schema for request body
|
|
140
|
-
if (typeInfo.bodyType && typeInfo.bodyType !== 'unknown') {
|
|
141
|
-
schemas[`${routeKey}_body`] = this.typeToSchema(typeInfo.bodyType)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Generate schema for query parameters
|
|
145
|
-
if (typeInfo.queryType && typeInfo.queryType !== 'Record<string, string>') {
|
|
146
|
-
schemas[`${routeKey}_query`] = this.typeToSchema(typeInfo.queryType)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Generate schema for route parameters
|
|
150
|
-
if (typeInfo.paramsType && typeInfo.paramsType !== 'Record<string, string>') {
|
|
151
|
-
schemas[`${routeKey}_params`] = this.typeToSchema(typeInfo.paramsType)
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
return schemas
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Generate OpenAPI schema from route types
|
|
160
|
-
*/
|
|
161
|
-
generateOpenAPISchema(): any {
|
|
162
|
-
const routes = Array.from(this.routeTypes.values())
|
|
163
|
-
const openapi = {
|
|
164
|
-
openapi: '3.0.0',
|
|
165
|
-
info: {
|
|
166
|
-
title: 'API Documentation',
|
|
167
|
-
version: '1.0.0',
|
|
168
|
-
},
|
|
169
|
-
paths: {} as Record<string, any>,
|
|
170
|
-
components: {
|
|
171
|
-
schemas: {} as Record<string, any>,
|
|
172
|
-
},
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
routes.forEach((route) => {
|
|
176
|
-
const path = route.pattern.replace(/\{([^}:]+)(?::[^}]+)?\}/g, '{$1}')
|
|
177
|
-
const method = route.method.toLowerCase()
|
|
178
|
-
|
|
179
|
-
if (!openapi.paths[path]) {
|
|
180
|
-
openapi.paths[path] = {}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const operation: any = {
|
|
184
|
-
summary: `${route.method} ${route.pattern}`,
|
|
185
|
-
operationId: `${method}${this.pathToOperationId(path)}`,
|
|
186
|
-
responses: {
|
|
187
|
-
200: {
|
|
188
|
-
description: 'Success',
|
|
189
|
-
content: {
|
|
190
|
-
'application/json': {
|
|
191
|
-
schema: this.typeToOpenAPISchema(route.responseType),
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Add parameters
|
|
199
|
-
const params = this.extractPathParameters(route.pattern)
|
|
200
|
-
if (params.length > 0) {
|
|
201
|
-
operation.parameters = params.map(param => ({
|
|
202
|
-
name: param.name,
|
|
203
|
-
in: 'path',
|
|
204
|
-
required: true,
|
|
205
|
-
schema: { type: param.type === 'number' ? 'integer' : 'string' },
|
|
206
|
-
}))
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Add request body for POST/PUT/PATCH
|
|
210
|
-
if (['post', 'put', 'patch'].includes(method) && route.bodyType !== 'unknown') {
|
|
211
|
-
operation.requestBody = {
|
|
212
|
-
required: true,
|
|
213
|
-
content: {
|
|
214
|
-
'application/json': {
|
|
215
|
-
schema: this.typeToOpenAPISchema(route.bodyType),
|
|
216
|
-
},
|
|
217
|
-
},
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
openapi.paths[path][method] = operation
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
return openapi
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Validate request against TypeScript types
|
|
229
|
-
*/
|
|
230
|
-
validateRequest(req: EnhancedRequest, routeKey: string): {
|
|
231
|
-
valid: boolean
|
|
232
|
-
errors: string[]
|
|
233
|
-
warnings: string[]
|
|
234
|
-
} {
|
|
235
|
-
const typeInfo = this.routeTypes.get(routeKey)
|
|
236
|
-
if (!typeInfo) {
|
|
237
|
-
return { valid: false, errors: ['Route type information not found'], warnings: [] }
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const errors: string[] = []
|
|
241
|
-
const warnings: string[] = []
|
|
242
|
-
|
|
243
|
-
// Validate parameters
|
|
244
|
-
if (typeInfo.paramsType !== 'Record<string, string>') {
|
|
245
|
-
const paramErrors = this.validateParams(req, typeInfo.paramsType)
|
|
246
|
-
errors.push(...paramErrors)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Validate query parameters
|
|
250
|
-
if (typeInfo.queryType !== 'Record<string, string>') {
|
|
251
|
-
const queryErrors = this.validateQuery(req, typeInfo.queryType)
|
|
252
|
-
errors.push(...queryErrors)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Validate request body
|
|
256
|
-
if (typeInfo.bodyType !== 'unknown' && req.body) {
|
|
257
|
-
const bodyErrors = this.validateBody(req, typeInfo.bodyType)
|
|
258
|
-
errors.push(...bodyErrors)
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
valid: errors.length === 0,
|
|
263
|
-
errors,
|
|
264
|
-
warnings,
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Generate type-safe route builder
|
|
270
|
-
*/
|
|
271
|
-
generateRouteBuilder(): string {
|
|
272
|
-
const routes = Array.from(this.routeTypes.values())
|
|
273
|
-
|
|
274
|
-
let output = `/**
|
|
275
|
-
* Type-safe route builder
|
|
276
|
-
* Generated automatically from route definitions
|
|
277
|
-
*/
|
|
278
|
-
|
|
279
|
-
import type { EnhancedRequest } from '../types'
|
|
280
|
-
|
|
281
|
-
export class TypeSafeRouteBuilder {
|
|
282
|
-
`
|
|
283
|
-
|
|
284
|
-
routes.forEach((route) => {
|
|
285
|
-
const methodName = `${route.method.toLowerCase()}${this.pathToMethodName(route.pattern)}`
|
|
286
|
-
|
|
287
|
-
output += ` /**
|
|
288
|
-
* ${route.method} ${route.pattern}
|
|
289
|
-
*/
|
|
290
|
-
${methodName}(
|
|
291
|
-
handler: (req: ${route.requestType} & { params: ${route.paramsType} }) => Promise<${route.responseType}>
|
|
292
|
-
): void {
|
|
293
|
-
// Implementation would register the route with proper typing
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
`
|
|
297
|
-
})
|
|
298
|
-
|
|
299
|
-
output += '}\n'
|
|
300
|
-
return output
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Generate middleware type definitions
|
|
305
|
-
*/
|
|
306
|
-
generateMiddlewareTypes(): string {
|
|
307
|
-
const middlewareTypes = new Set<string>()
|
|
308
|
-
|
|
309
|
-
this.routeTypes.forEach((route) => {
|
|
310
|
-
route.middlewareTypes.forEach(type => middlewareTypes.add(type))
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
let output = `/**
|
|
314
|
-
* Middleware type definitions
|
|
315
|
-
*/
|
|
316
|
-
|
|
317
|
-
export type MiddlewareFunction<T = any> = (
|
|
318
|
-
req: EnhancedRequest,
|
|
319
|
-
next: () => Promise<Response>
|
|
320
|
-
) => Promise<Response>
|
|
321
|
-
|
|
322
|
-
export type MiddlewareWithConfig<T> = (config: T) => MiddlewareFunction
|
|
323
|
-
|
|
324
|
-
`
|
|
325
|
-
|
|
326
|
-
middlewareTypes.forEach((type) => {
|
|
327
|
-
output += `export type ${type}Middleware = MiddlewareFunction\n`
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
return output
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Get route type information
|
|
335
|
-
*/
|
|
336
|
-
getRouteTypes(): RouteTypeInfo[] {
|
|
337
|
-
return Array.from(this.routeTypes.values())
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Get type definition
|
|
342
|
-
*/
|
|
343
|
-
getTypeDefinition(name: string): TypeDefinition | undefined {
|
|
344
|
-
return this.typeDefinitions.get(name)
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Register custom type definition
|
|
349
|
-
*/
|
|
350
|
-
registerTypeDefinition(definition: TypeDefinition): void {
|
|
351
|
-
this.typeDefinitions.set(definition.name, definition)
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Clear all type information
|
|
356
|
-
*/
|
|
357
|
-
clear(): void {
|
|
358
|
-
this.routeTypes.clear()
|
|
359
|
-
this.typeDefinitions.clear()
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Infer parameter types from route pattern
|
|
364
|
-
*/
|
|
365
|
-
private inferParamsType(pattern: string): string {
|
|
366
|
-
const params = this.extractPathParameters(pattern)
|
|
367
|
-
|
|
368
|
-
if (params.length === 0) {
|
|
369
|
-
return 'Record<string, never>'
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const properties = params.map((param) => {
|
|
373
|
-
const type = param.type === 'number' ? 'number' : 'string'
|
|
374
|
-
return ` ${param.name}: ${type}`
|
|
375
|
-
}).join('\n')
|
|
376
|
-
|
|
377
|
-
return `{\n${properties}\n}`
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Extract path parameters from pattern
|
|
382
|
-
*/
|
|
383
|
-
private extractPathParameters(pattern: string): Array<{ name: string, type: string, optional: boolean }> {
|
|
384
|
-
const params: Array<{ name: string, type: string, optional: boolean }> = []
|
|
385
|
-
const paramRegex = /\{([^}]+)\}/g
|
|
386
|
-
|
|
387
|
-
for (const match of pattern.matchAll(paramRegex)) {
|
|
388
|
-
const paramDef = match[1]
|
|
389
|
-
const [name, constraint] = paramDef.split(':')
|
|
390
|
-
|
|
391
|
-
params.push({
|
|
392
|
-
name: name.trim(),
|
|
393
|
-
type: this.inferParamType(constraint),
|
|
394
|
-
optional: paramDef.includes('?'),
|
|
395
|
-
})
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return params
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Infer parameter type from constraint
|
|
403
|
-
*/
|
|
404
|
-
private inferParamType(constraint?: string): string {
|
|
405
|
-
if (!constraint)
|
|
406
|
-
return 'string'
|
|
407
|
-
|
|
408
|
-
if (constraint.includes('number') || constraint.includes('int'))
|
|
409
|
-
return 'number'
|
|
410
|
-
if (constraint.includes('uuid'))
|
|
411
|
-
return 'string'
|
|
412
|
-
if (constraint.includes('slug'))
|
|
413
|
-
return 'string'
|
|
414
|
-
|
|
415
|
-
return 'string'
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Generate handler signature
|
|
420
|
-
*/
|
|
421
|
-
private generateHandlerSignature(options: any): string {
|
|
422
|
-
const requestType = options.requestType || 'EnhancedRequest'
|
|
423
|
-
const responseType = options.responseType || 'Response'
|
|
424
|
-
const paramsType = options.paramsType || 'Record<string, string>'
|
|
425
|
-
|
|
426
|
-
// pickier mis-parses the embedded `req:` token in this template literal
|
|
427
|
-
// as a real unused function parameter — disable on the next line so a
|
|
428
|
-
// pre-existing rule false positive doesn't block CI.
|
|
429
|
-
// eslint-disable-next-line pickier/no-unused-vars
|
|
430
|
-
return `(req: ${requestType} & { params: ${paramsType} }) => Promise<${responseType}>`
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Generate imports section
|
|
435
|
-
*/
|
|
436
|
-
private generateImports(): string {
|
|
437
|
-
return `import type { EnhancedRequest } from '../types'
|
|
438
|
-
|
|
439
|
-
// Generated route types`
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Generate parameter types
|
|
444
|
-
*/
|
|
445
|
-
private generateParamTypes(routes: RouteTypeInfo[]): string {
|
|
446
|
-
const paramTypes = new Set<string>()
|
|
447
|
-
|
|
448
|
-
routes.forEach((route) => {
|
|
449
|
-
if (route.paramsType !== 'Record<string, string>' && !route.paramsType.startsWith('{')) {
|
|
450
|
-
paramTypes.add(route.paramsType)
|
|
451
|
-
}
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
let output = '// Route parameter types\n'
|
|
455
|
-
|
|
456
|
-
routes.forEach((route) => {
|
|
457
|
-
if (route.paramsType.startsWith('{')) {
|
|
458
|
-
const typeName = `${route.method}${this.pathToTypeName(route.pattern)}Params`
|
|
459
|
-
output += `export interface ${typeName} ${route.paramsType}\n\n`
|
|
460
|
-
}
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
return output
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* Generate handler types
|
|
468
|
-
*/
|
|
469
|
-
private generateHandlerTypes(routes: RouteTypeInfo[]): string {
|
|
470
|
-
let output = '// Route handler types\n'
|
|
471
|
-
|
|
472
|
-
routes.forEach((route) => {
|
|
473
|
-
const handlerName = `${route.method}${this.pathToTypeName(route.pattern)}Handler`
|
|
474
|
-
output += `export type ${handlerName} = ${route.handlerSignature}\n\n`
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
return output
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
/**
|
|
481
|
-
* Generate route registry type
|
|
482
|
-
*/
|
|
483
|
-
private generateRouteRegistryType(routes: RouteTypeInfo[]): string {
|
|
484
|
-
let output = '// Route registry type\nexport interface RouteRegistry {\n'
|
|
485
|
-
|
|
486
|
-
routes.forEach((route) => {
|
|
487
|
-
const key = `'${route.method} ${route.pattern}'`
|
|
488
|
-
const handlerType = `${route.method}${this.pathToTypeName(route.pattern)}Handler`
|
|
489
|
-
output += ` ${key}: ${handlerType}\n`
|
|
490
|
-
})
|
|
491
|
-
|
|
492
|
-
output += '}\n'
|
|
493
|
-
return output
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Generate utility types
|
|
498
|
-
*/
|
|
499
|
-
private generateUtilityTypes(): string {
|
|
500
|
-
return `// Utility types
|
|
501
|
-
export type RouteMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'
|
|
502
|
-
|
|
503
|
-
export type RoutePattern = keyof RouteRegistry
|
|
504
|
-
|
|
505
|
-
export type HandlerForRoute<T extends RoutePattern> = RouteRegistry[T]
|
|
506
|
-
|
|
507
|
-
export type ExtractParams<T extends string> =
|
|
508
|
-
T extends \`\${string}{\${infer Param}}\${infer Rest}\`
|
|
509
|
-
? { [K in Param]: string } & ExtractParams<Rest>
|
|
510
|
-
: {}
|
|
511
|
-
|
|
512
|
-
export type TypedRequest<T extends RoutePattern> = EnhancedRequest & {
|
|
513
|
-
params: ExtractParams<T>
|
|
514
|
-
}
|
|
515
|
-
`
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Convert path to type name
|
|
520
|
-
*/
|
|
521
|
-
private pathToTypeName(path: string): string {
|
|
522
|
-
return path
|
|
523
|
-
.replace(/[{}]/g, '')
|
|
524
|
-
.replace(/[^a-z0-9]/gi, '_')
|
|
525
|
-
.replace(/_+/g, '_')
|
|
526
|
-
.replace(/^_|_$/g, '')
|
|
527
|
-
.split('_')
|
|
528
|
-
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
529
|
-
.join('')
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Convert path to method name
|
|
534
|
-
*/
|
|
535
|
-
private pathToMethodName(path: string): string {
|
|
536
|
-
const typeName = this.pathToTypeName(path)
|
|
537
|
-
return typeName.charAt(0).toLowerCase() + typeName.slice(1)
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
/**
|
|
541
|
-
* Convert path to operation ID
|
|
542
|
-
*/
|
|
543
|
-
private pathToOperationId(path: string): string {
|
|
544
|
-
return this.pathToTypeName(path)
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/**
|
|
548
|
-
* Convert TypeScript type to validation schema
|
|
549
|
-
*/
|
|
550
|
-
private typeToSchema(type: string): ValidationSchema {
|
|
551
|
-
// Simplified type to schema conversion
|
|
552
|
-
if (type.includes('string')) {
|
|
553
|
-
return { type: 'string' }
|
|
554
|
-
}
|
|
555
|
-
else if (type.includes('number')) {
|
|
556
|
-
return { type: 'number' }
|
|
557
|
-
}
|
|
558
|
-
else if (type.includes('boolean')) {
|
|
559
|
-
return { type: 'boolean' }
|
|
560
|
-
}
|
|
561
|
-
else if (type.includes('[]')) {
|
|
562
|
-
return { type: 'array', items: { type: 'string' } }
|
|
563
|
-
}
|
|
564
|
-
else {
|
|
565
|
-
return { type: 'object' }
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/**
|
|
570
|
-
* Convert TypeScript type to OpenAPI schema
|
|
571
|
-
*/
|
|
572
|
-
private typeToOpenAPISchema(type: string): any {
|
|
573
|
-
if (type.includes('string')) {
|
|
574
|
-
return { type: 'string' }
|
|
575
|
-
}
|
|
576
|
-
else if (type.includes('number')) {
|
|
577
|
-
return { type: 'number' }
|
|
578
|
-
}
|
|
579
|
-
else if (type.includes('boolean')) {
|
|
580
|
-
return { type: 'boolean' }
|
|
581
|
-
}
|
|
582
|
-
else if (type.includes('[]')) {
|
|
583
|
-
return { type: 'array', items: { type: 'string' } }
|
|
584
|
-
}
|
|
585
|
-
else {
|
|
586
|
-
return { type: 'object' }
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
/**
|
|
591
|
-
* Validate request parameters
|
|
592
|
-
*/
|
|
593
|
-
private validateParams(_req: EnhancedRequest, _expectedType: string): string[] {
|
|
594
|
-
// Simplified validation - in a real implementation, this would use a proper type checker
|
|
595
|
-
return []
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
/**
|
|
599
|
-
* Validate query parameters
|
|
600
|
-
*/
|
|
601
|
-
private validateQuery(_req: EnhancedRequest, _expectedType: string): string[] {
|
|
602
|
-
// Simplified validation
|
|
603
|
-
return []
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
/**
|
|
607
|
-
* Validate request body
|
|
608
|
-
*/
|
|
609
|
-
private validateBody(_req: EnhancedRequest, _expectedType: string): string[] {
|
|
610
|
-
// Simplified validation
|
|
611
|
-
return []
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
/**
|
|
616
|
-
* Global TypeScript utilities instance
|
|
617
|
-
*/
|
|
618
|
-
let globalTsUtils: TypeScriptUtilities | null = null
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* Initialize global TypeScript utilities
|
|
622
|
-
*/
|
|
623
|
-
export function initializeTypeScriptUtilities(config?: TypeScriptConfig): TypeScriptUtilities {
|
|
624
|
-
globalTsUtils = new TypeScriptUtilities(config)
|
|
625
|
-
return globalTsUtils
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
/**
|
|
629
|
-
* Get global TypeScript utilities
|
|
630
|
-
*/
|
|
631
|
-
export function getTypeScriptUtilities(): TypeScriptUtilities | null {
|
|
632
|
-
return globalTsUtils
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* TypeScript development helpers
|
|
637
|
-
*/
|
|
638
|
-
export const TypeScriptHelpers = {
|
|
639
|
-
/**
|
|
640
|
-
* Generate types for current routes
|
|
641
|
-
*/
|
|
642
|
-
generateTypes: (): string => {
|
|
643
|
-
const tsUtils = getTypeScriptUtilities()
|
|
644
|
-
if (!tsUtils) {
|
|
645
|
-
throw new Error('TypeScript utilities not initialized')
|
|
646
|
-
}
|
|
647
|
-
return tsUtils.generateRouteTypes()
|
|
648
|
-
},
|
|
649
|
-
|
|
650
|
-
/**
|
|
651
|
-
* Generate validation schemas
|
|
652
|
-
*/
|
|
653
|
-
generateSchemas: (): Record<string, ValidationSchema> => {
|
|
654
|
-
const tsUtils = getTypeScriptUtilities()
|
|
655
|
-
if (!tsUtils) {
|
|
656
|
-
throw new Error('TypeScript utilities not initialized')
|
|
657
|
-
}
|
|
658
|
-
return tsUtils.generateValidationSchemas()
|
|
659
|
-
},
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* Generate OpenAPI documentation
|
|
663
|
-
*/
|
|
664
|
-
generateOpenAPI: (): any => {
|
|
665
|
-
const tsUtils = getTypeScriptUtilities()
|
|
666
|
-
if (!tsUtils) {
|
|
667
|
-
throw new Error('TypeScript utilities not initialized')
|
|
668
|
-
}
|
|
669
|
-
return tsUtils.generateOpenAPISchema()
|
|
670
|
-
},
|
|
671
|
-
|
|
672
|
-
/**
|
|
673
|
-
* Validate request types
|
|
674
|
-
*/
|
|
675
|
-
validateRequest: (req: EnhancedRequest, routeKey: string): { valid: boolean, errors: string[], warnings: string[] } => {
|
|
676
|
-
const tsUtils = getTypeScriptUtilities()
|
|
677
|
-
if (!tsUtils) {
|
|
678
|
-
return { valid: true, errors: [], warnings: ['TypeScript utilities not initialized'] }
|
|
679
|
-
}
|
|
680
|
-
return tsUtils.validateRequest(req, routeKey)
|
|
681
|
-
},
|
|
682
|
-
}
|