mirror of
https://github.com/certd/certd.git
synced 2026-07-13 00:37:36 +08:00
156 lines
4.2 KiB
JavaScript
156 lines
4.2 KiB
JavaScript
// 转换单个插件为 YAML 配置的技能脚本
|
||
|
||
import path from 'path';
|
||
import fs from 'fs';
|
||
import { pathToFileURL } from 'node:url';
|
||
import * as yaml from 'js-yaml';
|
||
import { AbstractTaskPlugin, BaseAccess, BaseNotification } from '@certd/pipeline';
|
||
import { BaseAddon } from '@certd/lib-server';
|
||
|
||
/**
|
||
* 检查对象是否是指定类的原型
|
||
*/
|
||
function isPrototypeOf(value, cls) {
|
||
return cls.prototype.isPrototypeOf(value.prototype);
|
||
}
|
||
|
||
/**
|
||
* 加载单个插件模块
|
||
*/
|
||
async function loadSingleModule(filePath) {
|
||
try {
|
||
// 转换为 file:// URL(Windows 必需)
|
||
const moduleUrl = pathToFileURL(filePath).href;
|
||
const module = await import(moduleUrl);
|
||
return module.default || module;
|
||
} catch (err) {
|
||
console.error(`加载模块 ${filePath} 失败:`, err);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 分析单个插件并生成 YAML 配置
|
||
*/
|
||
async function convertSinglePlugin(pluginPath) {
|
||
console.log(`开始转换插件: ${pluginPath}`);
|
||
|
||
// 加载插件模块
|
||
const module = await loadSingleModule(pluginPath);
|
||
if (!module) {
|
||
console.error('加载插件失败,退出');
|
||
return;
|
||
}
|
||
|
||
// 处理模块中的所有导出
|
||
const entry = Object.entries(module);
|
||
if (entry.length === 0) {
|
||
console.error('插件模块没有导出任何内容');
|
||
return;
|
||
}
|
||
|
||
console.log(`插件模块导出了 ${entry.length} 个对象: ${entry.map(([name]) => name).join(', ')}`);
|
||
|
||
// 处理每个导出的对象
|
||
for (const [name, value] of entry) {
|
||
// 检查是否是插件(有 define 属性)
|
||
if (!value.define) {
|
||
console.log(`跳过非插件对象: ${name}`);
|
||
continue;
|
||
}
|
||
|
||
console.log(`处理插件: ${name}`);
|
||
|
||
// 构建插件定义
|
||
const pluginDefine = {
|
||
...value.define,
|
||
};
|
||
|
||
let subType = '';
|
||
|
||
// 确定插件类型
|
||
if (pluginDefine.accessType) {
|
||
pluginDefine.pluginType = 'dnsProvider';
|
||
} else if (isPrototypeOf(value, AbstractTaskPlugin)) {
|
||
pluginDefine.pluginType = 'deploy';
|
||
} else if (isPrototypeOf(value, BaseNotification)) {
|
||
pluginDefine.pluginType = 'notification';
|
||
} else if (isPrototypeOf(value, BaseAccess)) {
|
||
pluginDefine.pluginType = 'access';
|
||
} else if (isPrototypeOf(value, BaseAddon)) {
|
||
pluginDefine.pluginType = 'addon';
|
||
subType = '_' + (pluginDefine.addonType || '');
|
||
} else {
|
||
console.log(`[warning] 未知的插件类型:${pluginDefine.name}`);
|
||
continue;
|
||
}
|
||
|
||
pluginDefine.type = 'builtIn';
|
||
|
||
// 计算脚本文件路径
|
||
const relativePath = path.relative(process.cwd(), pluginPath);
|
||
const scriptFilePath = relativePath.replace(/\\/g, '/').replace(/\.js$/, '.js');
|
||
pluginDefine.scriptFilePath = scriptFilePath;
|
||
|
||
console.log(`插件类型: ${pluginDefine.pluginType}`);
|
||
console.log(`脚本路径: ${scriptFilePath}`);
|
||
|
||
// 生成 YAML 配置
|
||
const yamlContent = yaml.dump(pluginDefine);
|
||
console.log('\n生成的 YAML 配置:');
|
||
console.log(yamlContent);
|
||
|
||
// 可选:保存到文件
|
||
const outputDir = './metadata';
|
||
if (!fs.existsSync(outputDir)) {
|
||
fs.mkdirSync(outputDir, { recursive: true });
|
||
}
|
||
|
||
const outputFileName = `${pluginDefine.pluginType}${subType}_${pluginDefine.name}.yaml`;
|
||
const outputPath = path.join(outputDir, outputFileName);
|
||
|
||
fs.writeFileSync(outputPath, yamlContent, 'utf8');
|
||
console.log(`\nYAML 配置已保存到: ${outputPath}`);
|
||
|
||
return pluginDefine;
|
||
}
|
||
|
||
console.error('未找到有效的插件定义');
|
||
}
|
||
|
||
/**
|
||
* 主函数
|
||
*/
|
||
async function main() {
|
||
const args = process.argv.slice(2);
|
||
|
||
if (args.length === 0) {
|
||
console.error('请指定插件文件路径');
|
||
console.log('用法: node convert-plugin-to-yaml.js <插件文件路径>');
|
||
process.exit(1);
|
||
}
|
||
|
||
const pluginPath = args[0];
|
||
|
||
if (!fs.existsSync(pluginPath)) {
|
||
console.error(`插件文件不存在: ${pluginPath}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
try {
|
||
await convertSinglePlugin(pluginPath);
|
||
console.log('\n插件转换完成!');
|
||
} catch (error) {
|
||
console.error('转换过程中出错:', error);
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// 如果直接运行此脚本
|
||
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||
main();
|
||
}
|
||
|
||
// 导出函数,以便其他模块使用
|
||
export { convertSinglePlugin, loadSingleModule, isPrototypeOf };
|