add swagger

This commit is contained in:
liuyi 2025-06-14 23:32:15 +08:00
parent 5a5306b10d
commit 73e5a897c6
6 changed files with 2335 additions and 1616 deletions

View File

@ -5,6 +5,13 @@
"compilerOptions": {
"deleteOutDir": true,
"builder": "swc",
"typeCheck": true
"typeCheck": true,
"plugins": [{
"name": "@nestjs/swagger",
"options":{
"introspectComments": true,
"controllerKeyOfComment": "summary"
}
}]
}
}

View File

@ -22,10 +22,10 @@
},
"dependencies": {
"@fastify/static": "^8.2.0",
"@nestjs/common": "^10.0.3",
"@nestjs/core": "^10.0.3",
"@nestjs/common": "^11.1.3",
"@nestjs/core": "^11.1.3",
"@nestjs/platform-fastify": "^11.1.3",
"@nestjs/swagger": "^7.4.2",
"@nestjs/swagger": "^11.2.0",
"@nestjs/typeorm": "^11.0.0",
"chalk": "^5.4.1",
"class-transformer": "^0.5.1",
@ -35,50 +35,50 @@
"find-up": "^7.0.0",
"fs-extra": "^11.3.0",
"lodash": "^4.17.21",
"meilisearch": "^0.50.0",
"meilisearch": "^0.51.0",
"mysql2": "^3.14.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^5.0.1",
"rxjs": "^7.8.1",
"reflect-metadata": "^0.2.2",
"rimraf": "^6.0.1",
"rxjs": "^7.8.2",
"sanitize-html": "^2.17.0",
"typeorm": "^0.3.24",
"validator": "^13.15.0",
"validator": "^13.15.15",
"yaml": "^2.8.0"
},
"devDependencies": {
"@faker-js/faker": "^9.8.0",
"@nestjs/cli": "^10.0.3",
"@nestjs/schematics": "^10.0.1",
"@nestjs/testing": "^10.0.3",
"@swc/cli": "^0.1.62",
"@swc/core": "^1.3.66",
"@nestjs/cli": "^11.0.7",
"@nestjs/schematics": "^11.0.5",
"@nestjs/testing": "^11.1.3",
"@swc/cli": "^0.7.7",
"@swc/core": "^1.12.1",
"@types/fs-extra": "^11.0.4",
"@types/jest": "29.5.2",
"@types/lodash": "^4.17.16",
"@types/node": "^20.3.1",
"@types/jest": "29.5.14",
"@types/lodash": "^4.17.17",
"@types/node": "^24.0.1",
"@types/sanitize-html": "^2.16.0",
"@types/supertest": "^2.0.12",
"@types/supertest": "^6.0.3",
"@types/validator": "^13.15.1",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"cross-env": "^7.0.3",
"eslint": "^8.43.0",
"eslint": "^9.29.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.2.2",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-unused-imports": "^2.0.0",
"jest": "29.5.0",
"prettier": "^2.8.8",
"eslint-config-airbnb-typescript": "^18.0.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^28.13.5",
"eslint-plugin-prettier": "^5.4.1",
"eslint-plugin-unused-imports": "^4.1.4",
"jest": "30.0.0",
"prettier": "^3.5.3",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"supertest": "^7.1.1",
"ts-jest": "29.4.0",
"ts-loader": "^9.5.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "4.2.0",
"typescript": "~5.1.3"
"typescript": "~5.8.3"
},
"jest": {
"moduleFileExtensions": [

File diff suppressed because it is too large Load Diff

View File

@ -11,23 +11,33 @@ import {
SerializeOptions,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { Depends } from '@/modules/restful/decorators/depend.decorator';
import { ContentModule } from '../content.module';
import { CreateCategoryDto, QueryCategoryDto, UpdateCategoryDto } from '../dtos/category.dto';
import { CategoryService } from '../services';
@ApiTags('Category Operate')
@Depends(ContentModule)
@Controller('category')
export class CategoryController {
constructor(protected service: CategoryService) {}
/**
* Search category tree
*/
@Get('tree')
@SerializeOptions({ groups: ['category-tree'] })
async tree() {
return this.service.findTrees();
}
/**
*
* @param options
*/
@Get()
@SerializeOptions({ groups: ['category-list'] })
async list(
@ -37,6 +47,10 @@ export class CategoryController {
return this.service.paginate(options);
}
/**
*
* @param id
*/
@Get(':id')
@SerializeOptions({ groups: ['category-detail'] })
async detail(@Param('id', new ParseUUIDPipe()) id: string) {

View File

@ -2,7 +2,7 @@ import { INestApplication, Injectable, Type } from '@nestjs/common';
import { RouterModule } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { omit, trim } from 'lodash';
import { isNil, omit, trim } from 'lodash';
import { BaseRestful } from './base';
import {
@ -119,7 +119,10 @@ export class Restful extends BaseRestful {
this._docs.default = this.getDocOption(this._default, defaultVersion, true);
}
async factoryDocs<T extends INestApplication>(container: T) {
async factoryDocs<T extends INestApplication>(
container: T,
metadata?: () => Promise<RecordAny>,
) {
const docs = Object.values(this._docs)
.map((doc) => [doc.default, ...Object.values(doc.routes ?? [])])
.reduce((o, n) => [...o, ...n], [])
@ -146,6 +149,10 @@ export class Restful extends BaseRestful {
}
builder.setVersion(version);
if (!isNil(metadata)) {
await SwaggerModule.loadPluginMetadata(metadata);
}
const document = SwaggerModule.createDocument(container, builder.build(), {
include: include.length > 0 ? include : [() => undefined as any],
ignoreGlobalPrefix: true,

View File

@ -2,6 +2,9 @@ import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { existsSync } from 'fs-extra';
import { isNil } from 'lodash';
import * as configs from './config';
import { ContentModule } from './modules/content/content.module';
import { CreateOptions } from './modules/core/types';
@ -9,6 +12,8 @@ import { DatabaseModule } from './modules/database/database.module';
import { MeiliModule } from './modules/meilisearch/meili.module';
import { Restful } from './modules/restful/restful';
import { RestfulModule } from './modules/restful/restful.module';
import { ApiConfig } from './modules/restful/types';
import { join } from 'path';
export const createOptions: CreateOptions = {
config: { factories: configs as any, storage: { enable: true } },
@ -28,8 +33,18 @@ export const createOptions: CreateOptions = {
logger: ['error', 'warn'],
},
);
const restful = container.get(Restful);
await restful.factoryDocs(container);
if (!isNil(await configure.get<ApiConfig>('api', null))) {
const restful = container.get(Restful);
let metadata: () => Promise<RecordAny>;
if (existsSync(join(__dirname, 'metadata.js'))) {
metadata = (await import(join(__dirname, 'metadata.js'))).default;
}
if (existsSync(join(__dirname, 'metadata.ts'))) {
metadata = (await import(join(__dirname, 'metadata.ts'))).default;
}
await restful.factoryDocs(container, metadata);
}
return container;
},
};