55 lines
3.2 KiB
JavaScript
55 lines
3.2 KiB
JavaScript
import { execFileSync } from 'node:child_process';
|
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
import path from 'node:path';
|
|
|
|
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const openApiUrl = process.env.OPENAPI_URL || 'http://localhost:5090/openapi/v1.json';
|
|
const response = await fetch(openApiUrl);
|
|
if (!response.ok) throw new Error(`OpenAPI 下载失败:${response.status} ${response.statusText}`);
|
|
const document = await response.json();
|
|
|
|
const generatedDir = path.join(projectRoot, '.generated');
|
|
const apiDir = path.join(projectRoot, 'src', 'api');
|
|
mkdirSync(generatedDir, { recursive: true });
|
|
mkdirSync(apiDir, { recursive: true });
|
|
const snapshotPath = path.join(generatedDir, 'openapi.json');
|
|
writeFileSync(snapshotPath, `${JSON.stringify(document)}\n`);
|
|
|
|
const cli = path.join(projectRoot, 'node_modules', '.bin', process.platform === 'win32' ? 'openapi-typescript.cmd' : 'openapi-typescript');
|
|
execFileSync(cli, [snapshotPath, '-o', path.join(apiDir, 'schema.generated.d.ts')], { stdio: 'inherit' });
|
|
|
|
const methods = new Set(['get', 'post', 'put', 'patch', 'delete']);
|
|
const operations = [];
|
|
for (const [route, pathItem] of Object.entries(document.paths || {})) {
|
|
for (const [method, operation] of Object.entries(pathItem || {})) {
|
|
if (!methods.has(method)) continue;
|
|
const tags = operation.tags || [];
|
|
const isPlatform = route.startsWith('/api/platform-admin/') || route === '/api/platform-admin' || route.startsWith('/api/backoffice/platform/');
|
|
if (!isPlatform) continue;
|
|
const requestSchema = operation.requestBody?.content?.['application/json']?.schema || null;
|
|
const responseEntry = Object.entries(operation.responses || {}).find(([status]) => /^2/.test(status));
|
|
const responseSchema = responseEntry?.[1]?.content?.['application/json']?.schema || null;
|
|
operations.push({
|
|
id: `${method.toUpperCase()} ${route}`,
|
|
method: method.toUpperCase(),
|
|
path: route,
|
|
tag: tags[0] || '平台端',
|
|
summary: operation.summary || `${method.toUpperCase()} ${route}`,
|
|
description: operation.description || '',
|
|
parameters: [...(pathItem.parameters || []), ...(operation.parameters || [])],
|
|
requestSchema,
|
|
responseSchema,
|
|
requiredPermission: operation['x-tiku-required-permission'] || null,
|
|
riskLevel: operation['x-tiku-risk-level'] || (method === 'get' ? 'low' : 'medium'),
|
|
approvalPolicyCode: operation['x-tiku-approval-policy-code'] || null,
|
|
});
|
|
}
|
|
}
|
|
|
|
operations.sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
|
|
const schemas = document.components?.schemas || {};
|
|
const source = `/* eslint-disable */\n// 由 scripts/generate-platform-operations.mjs 根据后端 OpenAPI 自动生成,请勿手改。\nimport type { PlatformOperation } from './types';\n\nexport const platformOperations = ${JSON.stringify(operations, null, 2)} as const satisfies readonly PlatformOperation[];\nexport const openApiSchemas = ${JSON.stringify(schemas, null, 2)} as const;\n`;
|
|
writeFileSync(path.join(apiDir, 'platform-operations.generated.ts'), source);
|
|
console.log(`已生成 ${operations.length} 个平台接口契约,来源:${openApiUrl}`);
|