ts-class-to-openapi 1.0.0 → 1.0.2
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 +166 -0
- package/dist/index.d.ts +2 -1
- package/package.json +17 -17
package/README.md
CHANGED
|
@@ -382,6 +382,172 @@ app.listen(3000, () => {
|
|
|
382
382
|
})
|
|
383
383
|
```
|
|
384
384
|
|
|
385
|
+
#### Complete POST API Example with Schema Validation
|
|
386
|
+
|
|
387
|
+
Here's a complete example of a POST endpoint that uses the generated schemas for both request validation and response structure:
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import express from 'express'
|
|
391
|
+
import swaggerUi from 'swagger-ui-express'
|
|
392
|
+
import { transform } from 'ts-class-to-openapi'
|
|
393
|
+
import {
|
|
394
|
+
IsString,
|
|
395
|
+
IsEmail,
|
|
396
|
+
IsNotEmpty,
|
|
397
|
+
IsInt,
|
|
398
|
+
Min,
|
|
399
|
+
Max,
|
|
400
|
+
IsOptional,
|
|
401
|
+
} from 'class-validator'
|
|
402
|
+
|
|
403
|
+
// Define your entities
|
|
404
|
+
class User {
|
|
405
|
+
@IsInt()
|
|
406
|
+
@Min(1)
|
|
407
|
+
id: number
|
|
408
|
+
|
|
409
|
+
@IsString()
|
|
410
|
+
@IsNotEmpty()
|
|
411
|
+
name: string
|
|
412
|
+
|
|
413
|
+
@IsEmail()
|
|
414
|
+
email: string
|
|
415
|
+
|
|
416
|
+
@IsInt()
|
|
417
|
+
@Min(18)
|
|
418
|
+
@Max(100)
|
|
419
|
+
age: number
|
|
420
|
+
|
|
421
|
+
@IsOptional()
|
|
422
|
+
@IsString()
|
|
423
|
+
phone?: string
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// DTO for creating a user
|
|
427
|
+
class CreateUserDto {
|
|
428
|
+
@IsString()
|
|
429
|
+
@IsNotEmpty()
|
|
430
|
+
name: string
|
|
431
|
+
|
|
432
|
+
@IsEmail()
|
|
433
|
+
email: string
|
|
434
|
+
|
|
435
|
+
@IsInt()
|
|
436
|
+
@Min(18)
|
|
437
|
+
@Max(100)
|
|
438
|
+
age: number
|
|
439
|
+
|
|
440
|
+
@IsOptional()
|
|
441
|
+
@IsString()
|
|
442
|
+
phone?: string
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Response wrapper (not transformed, defined manually in OpenAPI spec)
|
|
446
|
+
interface ApiResponse<T> {
|
|
447
|
+
data: T
|
|
448
|
+
success: boolean
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const app = express()
|
|
452
|
+
app.use(express.json())
|
|
453
|
+
|
|
454
|
+
// Generate schemas only for your entities
|
|
455
|
+
const userSchema = transform(User)
|
|
456
|
+
const createUserSchema = transform(CreateUserDto)
|
|
457
|
+
|
|
458
|
+
// Create OpenAPI specification with POST endpoint
|
|
459
|
+
const swaggerSpec = {
|
|
460
|
+
openapi: '3.1.0',
|
|
461
|
+
info: { title: 'User Management API', version: '1.0.0' },
|
|
462
|
+
components: {
|
|
463
|
+
schemas: {
|
|
464
|
+
[userSchema.name]: userSchema.schema,
|
|
465
|
+
[createUserSchema.name]: createUserSchema.schema,
|
|
466
|
+
// ApiResponse schema defined manually
|
|
467
|
+
UserApiResponse: {
|
|
468
|
+
type: 'object',
|
|
469
|
+
properties: {
|
|
470
|
+
data: { $ref: `#/components/schemas/${userSchema.name}` },
|
|
471
|
+
success: { type: 'boolean' },
|
|
472
|
+
},
|
|
473
|
+
required: ['data', 'success'],
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
paths: {
|
|
478
|
+
'/users': {
|
|
479
|
+
post: {
|
|
480
|
+
summary: 'Create a new user',
|
|
481
|
+
requestBody: {
|
|
482
|
+
required: true,
|
|
483
|
+
content: {
|
|
484
|
+
'application/json': {
|
|
485
|
+
schema: { $ref: `#/components/schemas/${createUserSchema.name}` },
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
responses: {
|
|
490
|
+
'201': {
|
|
491
|
+
description: 'User created successfully',
|
|
492
|
+
content: {
|
|
493
|
+
'application/json': {
|
|
494
|
+
schema: { $ref: '#/components/schemas/UserApiResponse' },
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
},
|
|
498
|
+
'400': {
|
|
499
|
+
description: 'Invalid input data',
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Implement the POST endpoint
|
|
508
|
+
app.post('/users', (req, res) => {
|
|
509
|
+
try {
|
|
510
|
+
// In a real application, you would validate the request body
|
|
511
|
+
// and save to database
|
|
512
|
+
const userData = req.body as CreateUserDto
|
|
513
|
+
|
|
514
|
+
// Mock user creation (replace with actual database logic)
|
|
515
|
+
const newUser: User = {
|
|
516
|
+
id: Math.floor(Math.random() * 1000) + 1,
|
|
517
|
+
...userData,
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Return response matching the schema
|
|
521
|
+
const response: ApiResponse<User> = {
|
|
522
|
+
data: newUser,
|
|
523
|
+
success: true,
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
res.status(201).json(response)
|
|
527
|
+
} catch (error) {
|
|
528
|
+
res.status(400).json({
|
|
529
|
+
data: null,
|
|
530
|
+
success: false,
|
|
531
|
+
error: 'Invalid input data',
|
|
532
|
+
})
|
|
533
|
+
}
|
|
534
|
+
})
|
|
535
|
+
|
|
536
|
+
// Setup Swagger UI
|
|
537
|
+
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec))
|
|
538
|
+
|
|
539
|
+
app.listen(3000, () => {
|
|
540
|
+
console.log('API docs available at http://localhost:3000/api-docs')
|
|
541
|
+
})
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
This example demonstrates:
|
|
545
|
+
|
|
546
|
+
- **Request Schema**: Uses `CreateUserDto` schema for POST body validation
|
|
547
|
+
- **Response Schema**: Returns data in `{ data: User, success: boolean }` format
|
|
548
|
+
- **OpenAPI Documentation**: Complete Swagger specification with request/response schemas
|
|
549
|
+
- **Type Safety**: Full TypeScript support for request and response types
|
|
550
|
+
|
|
385
551
|
### File Upload Example
|
|
386
552
|
|
|
387
553
|
```typescript
|
package/dist/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-class-to-openapi",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Transform TypeScript classes into OpenAPI 3.1.0 schema objects, which support class-validator decorators",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.esm.js",
|
|
@@ -18,6 +18,18 @@
|
|
|
18
18
|
"README.md",
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "npm run build:test && node --test dist/test.js",
|
|
23
|
+
"test:watch": "npm run build:test && node --test --watch dist/**/*.test.js",
|
|
24
|
+
"test:coverage": "npm run build:test && node --test --experimental-test-coverage dist/**/*.test.js",
|
|
25
|
+
"build": "rm -rf dist && rollup -c",
|
|
26
|
+
"build:test": "rm -rf dist && BUILD_TARGET=test rollup -c",
|
|
27
|
+
"build:watch": "rm -rf dist && rollup -c -w",
|
|
28
|
+
"dev": "node --trace-deprecation --watch dist/run.js",
|
|
29
|
+
"format": "prettier --write .",
|
|
30
|
+
"format:check": "prettier --check .",
|
|
31
|
+
"prepublish": "pnpm run build"
|
|
32
|
+
},
|
|
21
33
|
"repository": {
|
|
22
34
|
"type": "git",
|
|
23
35
|
"url": "git+https://github.com/julioolivares/ts-class-to-openapi.git"
|
|
@@ -48,8 +60,8 @@
|
|
|
48
60
|
},
|
|
49
61
|
"license": "MIT",
|
|
50
62
|
"engines": {
|
|
51
|
-
"node": ">=
|
|
52
|
-
"npm": ">=
|
|
63
|
+
"node": ">=14.21.3",
|
|
64
|
+
"npm": ">=6.14.18"
|
|
53
65
|
},
|
|
54
66
|
"engineStrict": true,
|
|
55
67
|
"peerDependencies": {
|
|
@@ -72,17 +84,5 @@
|
|
|
72
84
|
"rollup": "4.46.2",
|
|
73
85
|
"tslib": "2.8.1"
|
|
74
86
|
},
|
|
75
|
-
"package": "./package-dist.json"
|
|
76
|
-
|
|
77
|
-
"test": "npm run build:test && node --test dist/test.js",
|
|
78
|
-
"test:watch": "npm run build:test && node --test --watch dist/**/*.test.js",
|
|
79
|
-
"test:coverage": "npm run build:test && node --test --experimental-test-coverage dist/**/*.test.js",
|
|
80
|
-
"build": "rm -rf dist && rollup -c",
|
|
81
|
-
"build:test": "rm -rf dist && BUILD_TARGET=test rollup -c",
|
|
82
|
-
"build:watch": "rm -rf dist && rollup -c -w",
|
|
83
|
-
"dev": "node --trace-deprecation --watch dist/run.js",
|
|
84
|
-
"format": "prettier --write .",
|
|
85
|
-
"format:check": "prettier --check .",
|
|
86
|
-
"prepublish": "pnpm run build"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
87
|
+
"package": "./package-dist.json"
|
|
88
|
+
}
|