2025-04-14 23:31:59 +08:00
|
|
|
|
// 扫描目录,列出文件,然后加载为模块
|
|
|
|
|
|
|
2025-04-28 23:34:08 +08:00
|
|
|
|
import path, { join } from "path";
|
|
|
|
|
|
import fs from "fs";
|
2025-04-14 23:31:59 +08:00
|
|
|
|
import { pathToFileURL } from "node:url";
|
2025-04-15 00:16:57 +08:00
|
|
|
|
import * as yaml from "js-yaml";
|
2025-04-28 23:34:08 +08:00
|
|
|
|
import { AbstractTaskPlugin, BaseAccess, BaseNotification } from "@certd/pipeline";
|
|
|
|
|
|
|
2025-04-14 23:31:59 +08:00
|
|
|
|
function scanDir(dir) {
|
|
|
|
|
|
const files = fs.readdirSync(dir);
|
|
|
|
|
|
const result = [];
|
|
|
|
|
|
// 扫描目录及子目录
|
|
|
|
|
|
for (const file of files) {
|
|
|
|
|
|
|
|
|
|
|
|
const filePath = join(dir, file);
|
|
|
|
|
|
const stat = fs.statSync(filePath);
|
|
|
|
|
|
if (stat.isDirectory()) {
|
|
|
|
|
|
result.push(...scanDir(filePath));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (!file.endsWith(".js")) {
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
result.push(filePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default async function loadModules(dir) {
|
|
|
|
|
|
const files = scanDir(dir);
|
|
|
|
|
|
const modules = {}
|
|
|
|
|
|
for (const file of files) {
|
2025-04-27 15:11:50 +08:00
|
|
|
|
if(file === "dist/plugins/index.js" || file === "dist\\plugins\\index.js"){
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2025-04-14 23:31:59 +08:00
|
|
|
|
try {
|
|
|
|
|
|
// 转换为 file:// URL(Windows 必需)
|
|
|
|
|
|
const moduleUrl = pathToFileURL(file).href
|
|
|
|
|
|
const module = await import(moduleUrl)
|
|
|
|
|
|
|
|
|
|
|
|
// 如果模块有默认导出,优先使用
|
|
|
|
|
|
modules[file] = module.default || module
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.error(`加载模块 ${file} 失败:`, err)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return modules;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-27 15:11:50 +08:00
|
|
|
|
function isPrototypeOf(value,cls){
|
|
|
|
|
|
return cls.prototype.isPrototypeOf(value.prototype)
|
|
|
|
|
|
}
|
2025-05-08 23:27:46 +08:00
|
|
|
|
async function genMetadata(){
|
|
|
|
|
|
const modules = await loadModules('./dist/plugins');
|
2025-04-27 15:11:50 +08:00
|
|
|
|
|
2025-05-08 23:27:46 +08:00
|
|
|
|
fs.rmSync("./metadata", { recursive: true });
|
|
|
|
|
|
fs.mkdirSync("./metadata", { recursive: true });
|
|
|
|
|
|
for (const key in modules) {
|
|
|
|
|
|
console.log(key)
|
|
|
|
|
|
const module = modules[key]
|
|
|
|
|
|
const entry = Object.entries(module)
|
|
|
|
|
|
for (const [name, value] of entry) {
|
|
|
|
|
|
//如果有define属性
|
|
|
|
|
|
if(value.define){
|
|
|
|
|
|
//那么就是插件
|
|
|
|
|
|
let location = key.substring(4)
|
|
|
|
|
|
location = location.substring(0, location.length - 3)
|
|
|
|
|
|
location = location.replaceAll("\\","/")
|
|
|
|
|
|
location += ".js"
|
|
|
|
|
|
location = `../../..${location}` // 从modules/plugin/plugin-service 加载 ../../plugins目录下的文件
|
2025-04-14 23:31:59 +08:00
|
|
|
|
|
2025-05-08 23:27:46 +08:00
|
|
|
|
const pluginDefine = {
|
|
|
|
|
|
...value.define
|
|
|
|
|
|
}
|
|
|
|
|
|
pluginDefine.type = "builtIn"
|
|
|
|
|
|
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{
|
|
|
|
|
|
console.log(`[warning] 未知的插件类型:${pluginDefine.name}`)
|
|
|
|
|
|
}
|
2025-04-15 00:16:57 +08:00
|
|
|
|
|
2025-05-08 23:27:46 +08:00
|
|
|
|
const filePath = path.join(`./metadata/${pluginDefine.pluginType}_${pluginDefine.name}.yaml`)
|
2025-04-15 00:16:57 +08:00
|
|
|
|
|
2025-05-08 23:27:46 +08:00
|
|
|
|
pluginDefine.scriptFilePath = location
|
|
|
|
|
|
const data = yaml.dump(pluginDefine)
|
|
|
|
|
|
fs.writeFileSync(filePath,data ,'utf8')
|
|
|
|
|
|
}
|
2025-04-15 00:16:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-08 23:27:46 +08:00
|
|
|
|
process.exit()
|
2025-04-14 23:31:59 +08:00
|
|
|
|
}
|
2025-04-28 23:34:08 +08:00
|
|
|
|
// import why from 'why-is-node-running'
|
|
|
|
|
|
// setTimeout(() => why(), 100); // 延迟打印原因
|
2025-05-08 23:27:46 +08:00
|
|
|
|
genMetadata()
|
2025-04-28 23:34:08 +08:00
|
|
|
|
|