@veloxts/router 0.6.57 → 0.6.59
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 +18 -0
- package/GUIDE.md +237 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +11 -0
- package/dist/openapi/generator.d.ts +52 -0
- package/dist/openapi/generator.js +442 -0
- package/dist/openapi/index.d.ts +37 -0
- package/dist/openapi/index.js +51 -0
- package/dist/openapi/path-extractor.d.ts +212 -0
- package/dist/openapi/path-extractor.js +256 -0
- package/dist/openapi/plugin.d.ts +101 -0
- package/dist/openapi/plugin.js +228 -0
- package/dist/openapi/schema-converter.d.ts +119 -0
- package/dist/openapi/schema-converter.js +246 -0
- package/dist/openapi/security-mapper.d.ts +131 -0
- package/dist/openapi/security-mapper.js +226 -0
- package/dist/openapi/types.d.ts +437 -0
- package/dist/openapi/types.js +8 -0
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @veloxts/router
|
|
2
2
|
|
|
3
|
+
## 0.6.59
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- refactor(ecosystem): Laravel-style API refinements & added missing unit tests
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @veloxts/core@0.6.59
|
|
10
|
+
- @veloxts/validation@0.6.59
|
|
11
|
+
|
|
12
|
+
## 0.6.58
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- feat(router): add OpenAPI 3.0.3 specification generator
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @veloxts/core@0.6.58
|
|
19
|
+
- @veloxts/validation@0.6.58
|
|
20
|
+
|
|
3
21
|
## 0.6.57
|
|
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
|
@@ -81,3 +81,25 @@ export { serve } from './expose.js';
|
|
|
81
81
|
export { appRouterProvider, registerRouterProviders, trpcInstanceProvider, trpcPluginOptionsProvider, } from './providers.js';
|
|
82
82
|
export type { RestAdapterConfig, RouterConfig } from './tokens.js';
|
|
83
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
|
@@ -86,3 +86,14 @@ export { serve } from './expose.js';
|
|
|
86
86
|
// Provider exports - factory functions for registering services
|
|
87
87
|
export { appRouterProvider, registerRouterProviders, trpcInstanceProvider, trpcPluginOptionsProvider, } from './providers.js';
|
|
88
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[];
|