This commit is contained in:
2026-04-25 16:36:34 +08:00
commit db90e7579b
1876 changed files with 189777 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
{
"name": "tailchat-service-openapi-generator",
"private": true,
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": "./dist/index.js",
"scripts": {
"dev": "tsc --watch",
"prepare": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"msgbyte",
"moonrailgun",
"tailchat"
],
"author": "moonrailgun <moonrailgun@gmail.com>",
"license": "MIT",
"dependencies": {
"@apidevtools/swagger-parser": "^10.1.0",
"globby": "11.1.0",
"openapi3-ts": "^4.3.1",
"tailchat-server-sdk": "workspace:^",
"ts-node": "^10.9.1"
},
"devDependencies": {
"@types/node": "^18.11.18",
"typescript": "^4.9.4"
}
}

View File

@@ -0,0 +1,38 @@
import _ from 'lodash';
import type { TcService } from 'tailchat-server-sdk';
import type { PathsObject, SchemaObject } from 'openapi3-ts/oas31';
export function generateOpenapiPath(service: TcService): PathsObject {
const serviceName = service.serviceName;
const actions = service.getActionList();
const paths: PathsObject = {};
for (const action of actions) {
const pathName = '/' + serviceName + '/' + action.name;
paths[pathName] = {
post: {
requestBody: {
content: {
'application/json': {
schema: {
type: 'object',
properties: generateRequestBodyProperties(action.params),
},
},
},
},
},
};
}
return paths;
}
function generateRequestBodyProperties(params: {
[x: string]: any;
}): Record<string, SchemaObject> {
return _.mapValues(params, (type) => {
return type;
});
}

View File

@@ -0,0 +1,70 @@
import globby from 'globby';
import { TcBroker, TcService } from 'tailchat-server-sdk';
import { generateOpenapiPath } from './generateOpenapiPath';
import type { OpenAPIObject } from 'openapi3-ts/oas31';
import SwaggerParser from '@apidevtools/swagger-parser';
import fs from 'fs-extra';
import path from 'path';
import 'ts-node/register';
/**
* https://ts-morph.com/setup/
*/
/**
* 扫描服务
*/
async function scanServices(): Promise<OpenAPIObject> {
const packageJsonPath = path.resolve(__dirname, '../../../../package.json');
const version = (await fs.readJson(packageJsonPath)).verson || '0.0.0';
const serviceFiles = await globby(
['./services/**/*.service.ts', './plugins/**/*.service.ts'],
{
absolute: true,
}
);
console.log('Service List:', serviceFiles);
const openapiObj: OpenAPIObject = {
openapi: '3.1.0',
info: {
title: 'Tailchat Openapi',
version,
},
paths: {},
};
const broker = new TcBroker({
logger: false,
});
for (const servicePath of serviceFiles) {
const { default: serviceCls } = await import(servicePath);
if (TcService.prototype.isPrototypeOf(serviceCls.prototype)) {
const service: TcService = new serviceCls(broker);
openapiObj.paths = {
...openapiObj.paths,
...generateOpenapiPath(service),
};
}
}
broker.stop();
try {
await SwaggerParser.validate(openapiObj as any);
return openapiObj;
} catch (err) {
console.error(err);
}
}
scanServices().then(async (openapiObj) => {
await fs.writeJSON('./openapi.json', openapiObj, {
spaces: 2,
});
console.log(
'generate completed, if process not exist auto, you can exit it by yourself'
);
});

View File

@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"outDir": "./dist",
"paths": {}
},
"include": ["./src/**/*"],
"exclude": ["./node_modules/**/*", "./dist/**/*"]
}