mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-04 06:31:13 +00:00
Add napcat-schema package for OpenAPI generation
Introduces the napcat-schema package with scripts and configuration to auto-generate OpenAPI schemas for NapCat OneBot 11 actions. Refactors action handler export in napcat-onebot to support schema extraction.
This commit is contained in:
parent
20398af648
commit
8f1dc3fdde
@ -156,7 +156,7 @@ import { ReceiveOnlineFile } from './file/online/ReceiveOnlineFile';
|
||||
import { RefuseOnlineFile } from './file/online/RefuseOnlineFile';
|
||||
import { GetFilesetId } from './file/flash/GetFilesetIdByCode';
|
||||
|
||||
export function createActionMap (obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
||||
export function getAllHandlers (obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
||||
const actionHandlers = [
|
||||
new CleanStreamTempFile(obContext, core),
|
||||
new DownloadFileStream(obContext, core),
|
||||
@ -324,7 +324,11 @@ export function createActionMap (obContext: NapCatOneBot11Adapter, core: NapCatC
|
||||
new DownloadFileset(obContext, core),
|
||||
new GetFilesetId(obContext, core),
|
||||
];
|
||||
return actionHandlers;
|
||||
}
|
||||
|
||||
export function createActionMap (obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
||||
const actionHandlers = getAllHandlers(obContext, core);
|
||||
type HandlerUnion = typeof actionHandlers[number];
|
||||
type MapType = {
|
||||
[H in HandlerUnion as H['actionName']]: H;
|
||||
|
||||
85
packages/napcat-schema/index.ts
Normal file
85
packages/napcat-schema/index.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { getAllHandlers } from '@/napcat-onebot/action/index';
|
||||
import { AutoRegisterRouter } from '@/napcat-onebot/action/auto-register';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { resolve, dirname } from 'node:path';
|
||||
import { TSchema } from '@sinclair/typebox';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export const actionSchemas: Record<string, { payload?: TSchema, return?: TSchema; }> = {};
|
||||
|
||||
|
||||
export function initSchemas () {
|
||||
const handlers = getAllHandlers(null as any, null as any);
|
||||
handlers.forEach(handler => {
|
||||
if (handler.actionName && (handler.actionName as string) !== 'unknown') {
|
||||
actionSchemas[handler.actionName] = {
|
||||
payload: handler.payloadSchema,
|
||||
return: handler.returnSchema
|
||||
};
|
||||
}
|
||||
});
|
||||
AutoRegisterRouter.forEach((ActionClass) => {
|
||||
const handler = new ActionClass(null as any, null as any);
|
||||
if (handler.actionName && (handler.actionName as string) !== 'unknown') {
|
||||
actionSchemas[handler.actionName] = {
|
||||
payload: handler.payloadSchema,
|
||||
return: handler.returnSchema
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function generateOpenAPI () {
|
||||
try {
|
||||
initSchemas();
|
||||
} catch (e) {
|
||||
console.warn('Init schemas partial failure (expected due to complex imports), proceeding with collected data...');
|
||||
}
|
||||
|
||||
const openapi: any = {
|
||||
openapi: '3.1.0',
|
||||
info: {
|
||||
title: 'NapCat OneBot 11 API',
|
||||
description: 'Auto-generated OpenAPI schema for NapCat OneBot 11 actions',
|
||||
version: '1.0.0'
|
||||
},
|
||||
paths: {}
|
||||
};
|
||||
|
||||
for (const [actionName, schemas] of Object.entries(actionSchemas)) {
|
||||
if (!schemas.payload) continue;
|
||||
const path = `/${actionName}`;
|
||||
|
||||
const cleanPayload = JSON.parse(JSON.stringify(schemas.payload || { type: 'object', properties: {} }));
|
||||
const cleanReturn = JSON.parse(JSON.stringify(schemas.return || { type: 'object', properties: {} }));
|
||||
|
||||
openapi.paths[path] = {
|
||||
post: {
|
||||
summary: actionName,
|
||||
requestBody: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: cleanPayload
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: '成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: cleanReturn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
const outputPath = resolve(__dirname, 'openapi.json');
|
||||
writeFileSync(outputPath, JSON.stringify(openapi, null, 2));
|
||||
console.log(`OpenAPI schema generated at: ${outputPath}`);
|
||||
}
|
||||
generateOpenAPI();
|
||||
19
packages/napcat-schema/package.json
Normal file
19
packages/napcat-schema/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "napcat-schema",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"generate:openapi": "node ./dist/schemas.mjs",
|
||||
"build:schema": "vite build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "^0.34.38",
|
||||
"napcat-onebot": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsx": "^4.7.1",
|
||||
"vite": "^6.0.0"
|
||||
}
|
||||
}
|
||||
11
packages/napcat-schema/tsconfig.json
Normal file
11
packages/napcat-schema/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"include": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
46
packages/napcat-schema/vite.config.ts
Normal file
46
packages/napcat-schema/vite.config.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import path, { resolve } from 'path';
|
||||
import { builtinModules } from 'module';
|
||||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||||
|
||||
// 依赖排除
|
||||
const external = [
|
||||
'ws',
|
||||
'express',
|
||||
'electron'
|
||||
];
|
||||
const nodeModules = [...builtinModules, builtinModules.map((m) => `node:${m}`)].flat();
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
conditions: ['node', 'default'],
|
||||
alias: {
|
||||
'@/napcat-core': resolve(__dirname, '../napcat-core'),
|
||||
'@/napcat-common': resolve(__dirname, '../napcat-common'),
|
||||
'@/napcat-onebot': resolve(__dirname, '../napcat-onebot'),
|
||||
'@/napcat-pty': resolve(__dirname, '../napcat-pty'),
|
||||
'@/napcat-webui-backend': resolve(__dirname, '../napcat-webui-backend'),
|
||||
'@/image-size': resolve(__dirname, '../image-size'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
],
|
||||
build: {
|
||||
target: 'esnext',
|
||||
minify: false,
|
||||
emptyOutDir: true,
|
||||
outDir: 'dist',
|
||||
lib: {
|
||||
entry: path.resolve(__dirname, './index.ts'),
|
||||
formats: ['es'],
|
||||
fileName: () => 'schemas.mjs',
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [
|
||||
...nodeModules,
|
||||
...external
|
||||
]
|
||||
},
|
||||
},
|
||||
});
|
||||
772
pnpm-lock.yaml
772
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user