@veloxts/router 0.6.56 → 0.6.58

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @veloxts/router
2
2
 
3
+ ## 0.6.58
4
+
5
+ ### Patch Changes
6
+
7
+ - feat(router): add OpenAPI 3.0.3 specification generator
8
+ - Updated dependencies
9
+ - @veloxts/core@0.6.58
10
+ - @veloxts/validation@0.6.58
11
+
12
+ ## 0.6.57
13
+
14
+ ### Patch Changes
15
+
16
+ - feat: add DI support to ecosystem packages and main packages
17
+ - Updated dependencies
18
+ - @veloxts/core@0.6.57
19
+ - @veloxts/validation@0.6.57
20
+
3
21
  ## 0.6.56
4
22
 
5
23
  ### Patch Changes
package/GUIDE.md CHANGED
@@ -72,6 +72,243 @@ await registerTRPCPlugin(app.server, { router, prefix: '/trpc' });
72
72
  export type AppRouter = typeof router;
73
73
  ```
74
74
 
75
+ ## OpenAPI Documentation
76
+
77
+ Auto-generate OpenAPI 3.0.3 specifications from your procedure definitions and serve interactive Swagger UI documentation.
78
+
79
+ ### Generating OpenAPI Specs
80
+
81
+ ```typescript
82
+ import { generateOpenApiSpec } from '@veloxts/router';
83
+
84
+ const spec = generateOpenApiSpec([userProcedures, postProcedures], {
85
+ info: {
86
+ title: 'My API',
87
+ version: '1.0.0',
88
+ description: 'A VeloxTS-powered API',
89
+ },
90
+ prefix: '/api',
91
+ servers: [
92
+ { url: 'http://localhost:3030', description: 'Development' },
93
+ { url: 'https://api.example.com', description: 'Production' },
94
+ ],
95
+ });
96
+
97
+ // Write to file
98
+ import fs from 'fs';
99
+ fs.writeFileSync('openapi.json', JSON.stringify(spec, null, 2));
100
+ ```
101
+
102
+ ### Swagger UI Plugin
103
+
104
+ Serve interactive API documentation with Swagger UI:
105
+
106
+ ```typescript
107
+ import { swaggerUIPlugin } from '@veloxts/router';
108
+
109
+ app.server.register(swaggerUIPlugin, {
110
+ routePrefix: '/docs',
111
+ collections: [userProcedures, postProcedures],
112
+ openapi: {
113
+ info: { title: 'My API', version: '1.0.0' },
114
+ prefix: '/api',
115
+ },
116
+ title: 'API Documentation',
117
+ });
118
+
119
+ // Available at:
120
+ // - /docs - Swagger UI interface
121
+ // - /docs/openapi.json - Raw OpenAPI spec
122
+ ```
123
+
124
+ ### Factory Functions
125
+
126
+ ```typescript
127
+ import { createSwaggerUI, getOpenApiSpec, registerDocs } from '@veloxts/router';
128
+
129
+ // Create pre-configured plugin
130
+ const docs = createSwaggerUI({
131
+ collections: [userProcedures],
132
+ openapi: { info: { title: 'My API', version: '1.0.0' } },
133
+ });
134
+ app.server.register(docs);
135
+
136
+ // Get spec without registering routes
137
+ const spec = getOpenApiSpec({
138
+ collections: [userProcedures],
139
+ openapi: { info: { title: 'My API', version: '1.0.0' } },
140
+ });
141
+
142
+ // Register docs with one call
143
+ await registerDocs(app.server, {
144
+ collections: [userProcedures],
145
+ openapi: { info: { title: 'My API', version: '1.0.0' } },
146
+ });
147
+ ```
148
+
149
+ ### CLI Command
150
+
151
+ Generate OpenAPI specs from the command line:
152
+
153
+ ```bash
154
+ # Basic generation
155
+ velox openapi generate --output ./openapi.json
156
+
157
+ # Full options
158
+ velox openapi generate \
159
+ --path ./src/procedures \
160
+ --output ./docs/openapi.json \
161
+ --title "My API" \
162
+ --version "1.0.0" \
163
+ --description "API documentation" \
164
+ --server http://localhost:3030 \
165
+ --server https://api.example.com \
166
+ --prefix /api
167
+
168
+ # Serve documentation locally
169
+ velox openapi serve --port 8080
170
+ ```
171
+
172
+ ### Security Schemes
173
+
174
+ Guards are automatically mapped to OpenAPI security requirements:
175
+
176
+ ```typescript
177
+ import { procedure, authenticated, hasRole } from '@veloxts/router';
178
+
179
+ const adminProcedures = procedures('admin', {
180
+ // 'authenticated' guard → bearerAuth security
181
+ listStats: procedure()
182
+ .guard(authenticated)
183
+ .query(handler),
184
+
185
+ // 'hasRole:admin' guard → bearerAuth security
186
+ deleteUser: procedure()
187
+ .input(z.object({ id: z.string().uuid() }))
188
+ .guard(hasRole('admin'))
189
+ .mutation(handler),
190
+ });
191
+ ```
192
+
193
+ Default guard mappings:
194
+
195
+ | Guard Name | Security Scheme |
196
+ |------------|-----------------|
197
+ | `authenticated` | `bearerAuth` |
198
+ | `hasRole:*` | `bearerAuth` |
199
+ | `hasPermission:*` | `bearerAuth` |
200
+ | `apiKey` | `apiKeyAuth` |
201
+
202
+ Custom security mappings:
203
+
204
+ ```typescript
205
+ const spec = generateOpenApiSpec([procedures], {
206
+ info: { title: 'API', version: '1.0.0' },
207
+ guardToSecurityMap: {
208
+ 'custom-guard': 'oauth2',
209
+ 'internal-only': 'apiKeyAuth',
210
+ },
211
+ securitySchemes: {
212
+ oauth2: {
213
+ type: 'oauth2',
214
+ flows: {
215
+ authorizationCode: {
216
+ authorizationUrl: 'https://auth.example.com/authorize',
217
+ tokenUrl: 'https://auth.example.com/token',
218
+ scopes: { read: 'Read access', write: 'Write access' },
219
+ },
220
+ },
221
+ },
222
+ },
223
+ });
224
+ ```
225
+
226
+ ### Generator Options
227
+
228
+ | Option | Type | Default | Description |
229
+ |--------|------|---------|-------------|
230
+ | `info` | `OpenAPIInfo` | required | API title, version, description |
231
+ | `prefix` | `string` | `'/api'` | Base path for all routes |
232
+ | `servers` | `OpenAPIServer[]` | `[]` | Server URLs |
233
+ | `tagDescriptions` | `Record<string, string>` | `{}` | Descriptions for namespace tags |
234
+ | `securitySchemes` | `Record<string, SecurityScheme>` | defaults | Custom security schemes |
235
+ | `guardToSecurityMap` | `Record<string, string>` | defaults | Guard → scheme mapping |
236
+ | `defaultSecurity` | `SecurityRequirement[]` | `[]` | Global security requirements |
237
+ | `externalDocs` | `ExternalDocs` | `undefined` | Link to external docs |
238
+ | `extensions` | `Record<string, unknown>` | `{}` | OpenAPI extensions (`x-*`) |
239
+
240
+ ### Swagger UI Options
241
+
242
+ | Option | Type | Default | Description |
243
+ |--------|------|---------|-------------|
244
+ | `routePrefix` | `string` | `'/docs'` | UI route path |
245
+ | `specRoute` | `string` | `'{prefix}/openapi.json'` | Spec JSON path |
246
+ | `title` | `string` | `'API Documentation'` | Page title |
247
+ | `favicon` | `string` | `undefined` | Favicon URL |
248
+ | `uiConfig.deepLinking` | `boolean` | `true` | Enable deep linking |
249
+ | `uiConfig.tryItOutEnabled` | `boolean` | `true` | Enable "Try it out" |
250
+ | `uiConfig.persistAuthorization` | `boolean` | `false` | Persist auth in localStorage |
251
+ | `uiConfig.docExpansion` | `string` | `'list'` | `'list'`, `'full'`, `'none'` |
252
+
253
+ ### Schema Conversion
254
+
255
+ Zod schemas are automatically converted to JSON Schema:
256
+
257
+ ```typescript
258
+ // Input
259
+ z.object({
260
+ id: z.string().uuid(),
261
+ email: z.string().email(),
262
+ age: z.number().min(0).max(150).optional(),
263
+ })
264
+
265
+ // Output (JSON Schema)
266
+ {
267
+ "type": "object",
268
+ "properties": {
269
+ "id": { "type": "string", "format": "uuid" },
270
+ "email": { "type": "string", "format": "email" },
271
+ "age": { "type": "number", "minimum": 0, "maximum": 150 }
272
+ },
273
+ "required": ["id", "email"]
274
+ }
275
+ ```
276
+
277
+ ### Validation
278
+
279
+ Validate generated specs for common issues:
280
+
281
+ ```typescript
282
+ import { validateOpenApiSpec } from '@veloxts/router';
283
+
284
+ const spec = generateOpenApiSpec([procedures], options);
285
+ const warnings = validateOpenApiSpec(spec);
286
+
287
+ if (warnings.length > 0) {
288
+ console.warn('OpenAPI warnings:', warnings);
289
+ }
290
+ // Possible warnings:
291
+ // - "OpenAPI spec has no paths defined"
292
+ // - "OpenAPI spec is missing info.title"
293
+ // - "Duplicate operationId: users_getUser"
294
+ ```
295
+
296
+ ### Route Summary
297
+
298
+ Get a summary of generated routes for debugging:
299
+
300
+ ```typescript
301
+ import { getOpenApiRouteSummary } from '@veloxts/router';
302
+
303
+ const routes = getOpenApiRouteSummary([userProcedures], '/api');
304
+ console.table(routes);
305
+ // [
306
+ // { method: 'GET', path: '/api/users/{id}', operationId: 'users_getUser', namespace: 'users' },
307
+ // { method: 'GET', path: '/api/users', operationId: 'users_listUsers', namespace: 'users' },
308
+ // { method: 'POST', path: '/api/users', operationId: 'users_createUser', namespace: 'users' },
309
+ // ]
310
+ ```
311
+
75
312
  ## Middleware
76
313
 
77
314
  ```typescript
package/dist/index.d.ts CHANGED
@@ -59,3 +59,47 @@ export type { ContractDefinition, ContractEntry, HttpMethodRoute, InferContract,
59
59
  export { defineContract, defineRoutes } from './contracts.js';
60
60
  export type { ServeOptions } from './expose.js';
61
61
  export { serve } from './expose.js';
62
+ /**
63
+ * DI tokens and providers for @veloxts/router
64
+ *
65
+ * Use these to integrate router services with the @veloxts/core DI container.
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * import { Container } from '@veloxts/core';
70
+ * import { registerRouterProviders, TRPC_INSTANCE, APP_ROUTER } from '@veloxts/router';
71
+ *
72
+ * const container = new Container();
73
+ * registerRouterProviders(container, {
74
+ * procedures: [userProcedures, postProcedures],
75
+ * });
76
+ *
77
+ * const t = container.resolve(TRPC_INSTANCE);
78
+ * const router = container.resolve(APP_ROUTER);
79
+ * ```
80
+ */
81
+ export { appRouterProvider, registerRouterProviders, trpcInstanceProvider, trpcPluginOptionsProvider, } from './providers.js';
82
+ export type { RestAdapterConfig, RouterConfig } from './tokens.js';
83
+ export { APP_ROUTER, PROCEDURE_COLLECTIONS, REST_ADAPTER_CONFIG, ROUTER_CONFIG, TRPC_INSTANCE, TRPC_PLUGIN_OPTIONS, } from './tokens.js';
84
+ /**
85
+ * OpenAPI 3.0.3 specification generation from procedure collections.
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * import { generateOpenApiSpec, swaggerUIPlugin } from '@veloxts/router';
90
+ *
91
+ * // Generate spec programmatically
92
+ * const spec = generateOpenApiSpec([userProcedures], {
93
+ * info: { title: 'My API', version: '1.0.0' },
94
+ * });
95
+ *
96
+ * // Or serve Swagger UI
97
+ * app.register(swaggerUIPlugin, {
98
+ * routePrefix: '/docs',
99
+ * collections: [userProcedures],
100
+ * openapi: { info: { title: 'My API', version: '1.0.0' } },
101
+ * });
102
+ * ```
103
+ */
104
+ export type { BuildParametersOptions, BuildParametersResult, GuardMappingOptions, JSONSchema, OpenAPIComponents, OpenAPIContact, OpenAPIEncoding, OpenAPIExample, OpenAPIExternalDocs, OpenAPIGeneratorOptions, OpenAPIHeader, OpenAPIHttpMethod, OpenAPIInfo, OpenAPILicense, OpenAPILink, OpenAPIMediaType, OpenAPIOAuthFlow, OpenAPIOAuthFlows, OpenAPIOperation, OpenAPIParameter, OpenAPIPathItem, OpenAPIRequestBody, OpenAPIResponse, OpenAPISecurityRequirement, OpenAPISecurityScheme, OpenAPIServer, OpenAPISpec, OpenAPITag, ParameterIn, QueryParamExtractionOptions, RouteInfo, SchemaConversionOptions, SecuritySchemeType, SwaggerUIConfig, SwaggerUIPluginOptions, } from './openapi/index.js';
105
+ export { buildParameters, convertFromOpenAPIPath, convertToOpenAPIPath, createSecurityRequirement, createStringSchema, createSwaggerUI, DEFAULT_GUARD_MAPPINGS, DEFAULT_SECURITY_SCHEMES, extractGuardScopes, extractPathParamNames, extractQueryParameters, extractResourceFromPath, extractSchemaProperties, extractUsedSecuritySchemes, filterUsedSecuritySchemes, generateOpenApiSpec, getOpenApiRouteSummary, getOpenApiSpec, guardsRequireAuth, guardsToSecurity, hasPathParameters, joinPaths, mapGuardToSecurity, mergeSchemas, mergeSecuritySchemes, normalizePath, parsePathParameters, registerDocs, removeSchemaProperties, schemaHasProperties, swaggerUIPlugin, validateOpenApiSpec, zodSchemaToJsonSchema, } from './openapi/index.js';
package/dist/index.js CHANGED
@@ -61,3 +61,39 @@ appRouter, buildTRPCRouter, createTRPCContextFactory, registerTRPCPlugin, trpc,
61
61
  export { DiscoveryError, DiscoveryErrorCode, directoryNotFound, discoverProcedures, discoverProceduresVerbose, fileLoadError, invalidExport, invalidFileType, isDiscoveryError, noProceduresFound, permissionDenied, } from './discovery/index.js';
62
62
  export { defineContract, defineRoutes } from './contracts.js';
63
63
  export { serve } from './expose.js';
64
+ // ============================================================================
65
+ // Dependency Injection
66
+ // ============================================================================
67
+ /**
68
+ * DI tokens and providers for @veloxts/router
69
+ *
70
+ * Use these to integrate router services with the @veloxts/core DI container.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { Container } from '@veloxts/core';
75
+ * import { registerRouterProviders, TRPC_INSTANCE, APP_ROUTER } from '@veloxts/router';
76
+ *
77
+ * const container = new Container();
78
+ * registerRouterProviders(container, {
79
+ * procedures: [userProcedures, postProcedures],
80
+ * });
81
+ *
82
+ * const t = container.resolve(TRPC_INSTANCE);
83
+ * const router = container.resolve(APP_ROUTER);
84
+ * ```
85
+ */
86
+ // Provider exports - factory functions for registering services
87
+ export { appRouterProvider, registerRouterProviders, trpcInstanceProvider, trpcPluginOptionsProvider, } from './providers.js';
88
+ export { APP_ROUTER, PROCEDURE_COLLECTIONS, REST_ADAPTER_CONFIG, ROUTER_CONFIG, TRPC_INSTANCE, TRPC_PLUGIN_OPTIONS, } from './tokens.js';
89
+ export {
90
+ // Path extractor
91
+ buildParameters, convertFromOpenAPIPath, convertToOpenAPIPath,
92
+ // Security mapper
93
+ createSecurityRequirement,
94
+ // Schema converter
95
+ createStringSchema,
96
+ // Plugin
97
+ createSwaggerUI, DEFAULT_GUARD_MAPPINGS, DEFAULT_SECURITY_SCHEMES, extractGuardScopes, extractPathParamNames, extractQueryParameters, extractResourceFromPath, extractSchemaProperties, extractUsedSecuritySchemes, filterUsedSecuritySchemes,
98
+ // Generator
99
+ generateOpenApiSpec, getOpenApiRouteSummary, getOpenApiSpec, guardsRequireAuth, guardsToSecurity, hasPathParameters, joinPaths, mapGuardToSecurity, mergeSchemas, mergeSecuritySchemes, normalizePath, parsePathParameters, registerDocs, removeSchemaProperties, schemaHasProperties, swaggerUIPlugin, validateOpenApiSpec, zodSchemaToJsonSchema, } from './openapi/index.js';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * OpenAPI Generator
3
+ *
4
+ * Generates OpenAPI 3.0.3 specifications from VeloxTS procedure collections.
5
+ *
6
+ * @module @veloxts/router/openapi/generator
7
+ */
8
+ import type { ProcedureCollection } from '../types.js';
9
+ import type { OpenAPIGeneratorOptions, OpenAPISpec } from './types.js';
10
+ /**
11
+ * Generates an OpenAPI 3.0.3 specification from procedure collections
12
+ *
13
+ * @param collections - Array of procedure collections to document
14
+ * @param options - Generator options
15
+ * @returns Complete OpenAPI specification
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { generateOpenApiSpec } from '@veloxts/router';
20
+ *
21
+ * const spec = generateOpenApiSpec([userProcedures, postProcedures], {
22
+ * info: {
23
+ * title: 'My API',
24
+ * version: '1.0.0',
25
+ * description: 'A VeloxTS-powered API',
26
+ * },
27
+ * prefix: '/api',
28
+ * servers: [{ url: 'http://localhost:3030' }],
29
+ * });
30
+ * ```
31
+ */
32
+ export declare function generateOpenApiSpec(collections: ProcedureCollection[], options: OpenAPIGeneratorOptions): OpenAPISpec;
33
+ /**
34
+ * Gets route summary information for debugging/logging
35
+ *
36
+ * @param collections - Procedure collections
37
+ * @param prefix - API prefix
38
+ * @returns Array of route summaries
39
+ */
40
+ export declare function getOpenApiRouteSummary(collections: ProcedureCollection[], prefix?: string): Array<{
41
+ method: string;
42
+ path: string;
43
+ operationId: string;
44
+ namespace: string;
45
+ }>;
46
+ /**
47
+ * Validates an OpenAPI spec for common issues
48
+ *
49
+ * @param spec - OpenAPI spec to validate
50
+ * @returns Array of validation warnings
51
+ */
52
+ export declare function validateOpenApiSpec(spec: OpenAPISpec): string[];