diff --git a/src/automation-framework/index.js b/src/automation-framework/index.js deleted file mode 100644 index 2d65b6d..0000000 --- a/src/automation-framework/index.js +++ /dev/null @@ -1,85 +0,0 @@ -const WindsurfAdapter = require('./sites/windsurf-adapter'); -const logger = require('../shared/logger'); -const BrowserManager = require('../tools/account-register/utils/browser-manager'); - -/** - * 自动化工厂 - 统一入口 - */ -class AutomationFactory { - /** - * 使用 AdsPower 注册(主要方法) - */ - static async registerWithAdsPower(siteName, adspowerUserId) { - logger.info('AutomationFactory', `========================================`); - logger.info('AutomationFactory', `开始 ${siteName} 注册流程`); - logger.info('AutomationFactory', `AdsPower Profile: ${adspowerUserId}`); - logger.info('AutomationFactory', `========================================`); - - const browserManager = new BrowserManager({ - profileId: adspowerUserId, - siteName: 'AutomationFactory' - }); - - try { - // 1. 启动并连接到 AdsPower 浏览器 - await browserManager.launch(); - - const browser = browserManager.browser; - const page = browserManager.page; - - // 4. 创建上下文 - const context = { - page, - browser, - logger, - data: {}, - adspowerUserId - }; - - // 5. 创建适配器 - let adapter; - - switch (siteName.toLowerCase()) { - case 'windsurf': - adapter = new WindsurfAdapter(context); - break; - - default: - throw new Error(`不支持的站点: ${siteName}`); - } - - // 6. 执行自动化流程 - logger.info('AutomationFactory', '开始执行自动化流程...'); - const result = await adapter.execute(); - - // 7. 返回结果 - return { - success: true, - siteName, - accountData: context.data.account, - cardInfo: context.data.card, - result - }; - - } catch (error) { - logger.error('AutomationFactory', `注册失败: ${error.message}`); - console.error(error); - - return { - success: false, - error: error.message - }; - - } finally { - // 8. 关闭浏览器 - try { - await browserManager.close(); - } catch (e) { - logger.warn('AutomationFactory', `关闭浏览器失败: ${e.message}`); - } - } - } -} - - -module.exports = AutomationFactory; diff --git a/src/cli.js b/src/cli.js index ab0148c..ae41bc2 100644 --- a/src/cli.js +++ b/src/cli.js @@ -92,6 +92,37 @@ if (registerTool) { }); } +// 注册automation-framework命令(新框架) +const autoTool = registry.get('automation-framework'); +if (autoTool) { + const autoCommand = program + .command('auto') + .description('基于配置的自动化注册(新框架)') + .option('-s, --site ', '网站名称 (windsurf, etc)') + .option('-p, --profile-id ', 'AdsPower Profile ID') + .option('-o, --output ', '保存结果到文件') + .option('--no-validate-config', '跳过配置验证', false) + .option('--no-performance-report', '跳过性能报告', false) + .action(async (options) => { + await autoTool.execute(options); + }); + + // 添加子命令 + autoCommand + .command('list') + .description('列出所有支持的网站') + .action(() => { + autoTool.listSites(); + }); + + autoCommand + .command('validate ') + .description('验证站点配置文件') + .action((site) => { + autoTool.validateConfig(site); + }); +} + // 列出所有工具 program .command('list') @@ -116,12 +147,17 @@ program.on('--help', () => { console.log(' $ aam card -t unionpay -n 10 # 生成10张银联卡'); console.log(' $ aam card list-types # 查看支持的卡类型'); console.log(''); - console.log(' # 账号注册工具'); + console.log(' # 账号注册工具(旧框架)'); console.log(' $ aam register -s windsurf --dry-run # 生成Windsurf账号数据'); console.log(' $ aam register -s windsurf # 执行Windsurf注册'); console.log(' $ aam register list # 列出支持的网站'); console.log(' $ aam register generate # 生成通用账号数据'); console.log(''); + console.log(' # 自动化框架(新框架 - 推荐)'); + console.log(' $ aam auto -s windsurf -p k7g4ia4 # 使用新框架注册Windsurf'); + console.log(' $ aam auto list # 列出支持的网站'); + console.log(' $ aam auto validate windsurf # 验证配置文件'); + console.log(''); console.log(' # 其他'); console.log(' $ aam list # 列出所有工具'); console.log(''); diff --git a/src/shared/errors/index.js b/src/shared/errors/index.js new file mode 100644 index 0000000..1a40bc2 --- /dev/null +++ b/src/shared/errors/index.js @@ -0,0 +1,24 @@ +/** + * Shared Errors - 通用错误类 + */ + +class ValidationError extends Error { + constructor(module, message) { + super(`[${module}] ${message}`); + this.name = 'ValidationError'; + this.module = module; + } +} + +class ConfigurationError extends Error { + constructor(module, message) { + super(`[${module}] ${message}`); + this.name = 'ConfigurationError'; + this.module = module; + } +} + +module.exports = { + ValidationError, + ConfigurationError +}; diff --git a/src/tools/account-register/generators/email-generator.js b/src/shared/libs/account-generator/email-generator.js similarity index 96% rename from src/tools/account-register/generators/email-generator.js rename to src/shared/libs/account-generator/email-generator.js index 4bf96ec..b8b58e2 100644 --- a/src/tools/account-register/generators/email-generator.js +++ b/src/shared/libs/account-generator/email-generator.js @@ -2,7 +2,7 @@ * Email Generator - 邮箱生成器 */ -const { randomInt } = require('../../../shared/utils'); +const { randomInt } = require('../../utils'); class EmailGenerator { constructor() { diff --git a/src/tools/account-register/generator.js b/src/shared/libs/account-generator/index.js similarity index 88% rename from src/tools/account-register/generator.js rename to src/shared/libs/account-generator/index.js index e19b764..67d75ac 100644 --- a/src/tools/account-register/generator.js +++ b/src/shared/libs/account-generator/index.js @@ -3,12 +3,12 @@ * 统一的数据生成接口 */ -const EmailGenerator = require('./generators/email-generator'); -const UsernameGenerator = require('./generators/username-generator'); -const PasswordGenerator = require('./generators/password-generator'); -const PhoneGenerator = require('./generators/phone-generator'); -const NameGenerator = require('./generators/name-generator'); -const CardGenerator = require('../card-generator/generator'); +const EmailGenerator = require('./email-generator'); +const UsernameGenerator = require('./username-generator'); +const PasswordGenerator = require('./password-generator'); +const PhoneGenerator = require('./phone-generator'); +const NameGenerator = require('./name-generator'); +const CardGenerator = require('../card-generator'); class AccountDataGenerator { constructor() { diff --git a/src/tools/account-register/generators/name-generator.js b/src/shared/libs/account-generator/name-generator.js similarity index 98% rename from src/tools/account-register/generators/name-generator.js rename to src/shared/libs/account-generator/name-generator.js index e9fcf1a..e16cd17 100644 --- a/src/tools/account-register/generators/name-generator.js +++ b/src/shared/libs/account-generator/name-generator.js @@ -2,7 +2,7 @@ * Name Generator - 姓名生成器 */ -const { randomInt } = require('../../../shared/utils'); +const { randomInt } = require('../../utils'); class NameGenerator { constructor() { diff --git a/src/tools/account-register/generators/password-generator.js b/src/shared/libs/account-generator/password-generator.js similarity index 98% rename from src/tools/account-register/generators/password-generator.js rename to src/shared/libs/account-generator/password-generator.js index 6fe7ddf..18c8c84 100644 --- a/src/tools/account-register/generators/password-generator.js +++ b/src/shared/libs/account-generator/password-generator.js @@ -2,7 +2,7 @@ * Password Generator - 密码生成器 */ -const { randomInt } = require('../../../shared/utils'); +const { randomInt } = require('../../utils'); class PasswordGenerator { constructor() { diff --git a/src/tools/account-register/generators/phone-generator.js b/src/shared/libs/account-generator/phone-generator.js similarity index 98% rename from src/tools/account-register/generators/phone-generator.js rename to src/shared/libs/account-generator/phone-generator.js index ee1c4ca..12634de 100644 --- a/src/tools/account-register/generators/phone-generator.js +++ b/src/shared/libs/account-generator/phone-generator.js @@ -2,7 +2,7 @@ * Phone Generator - 手机号生成器 */ -const { randomInt, padZero } = require('../../../shared/utils'); +const { randomInt, padZero } = require('../../utils'); class PhoneGenerator { constructor() { diff --git a/src/tools/account-register/generators/username-generator.js b/src/shared/libs/account-generator/username-generator.js similarity index 98% rename from src/tools/account-register/generators/username-generator.js rename to src/shared/libs/account-generator/username-generator.js index 10bce37..57f14cc 100644 --- a/src/tools/account-register/generators/username-generator.js +++ b/src/shared/libs/account-generator/username-generator.js @@ -2,7 +2,7 @@ * Username Generator - 用户名生成器 */ -const { randomInt } = require('../../../shared/utils'); +const { randomInt } = require('../../utils'); class UsernameGenerator { constructor() { diff --git a/src/shared/libs/base/base-lib.js b/src/shared/libs/base/base-lib.js new file mode 100644 index 0000000..31f5e92 --- /dev/null +++ b/src/shared/libs/base/base-lib.js @@ -0,0 +1,118 @@ +/** + * BaseLib - 所有共享库的基类 + * 提供统一的接口、日志、配置管理 + */ + +const logger = require('../../logger'); + +class BaseLib { + /** + * @param {Object} config - 库配置 + * @param {string} config.name - 库名称 + * @param {string} config.version - 版本号 + * @param {Object} config.options - 可选配置 + */ + constructor(config = {}) { + // 验证必需配置 + if (!config.name) { + throw new Error('Lib must have a name'); + } + + this.name = config.name; + this.version = config.version || '1.0.0'; + this.options = config.options || {}; + this.initialized = false; + + // 注册到全局注册表 + if (global.__libRegistry) { + global.__libRegistry.register(this); + } + } + + /** + * 初始化库(子类可重写) + */ + async initialize() { + if (this.initialized) { + return; + } + + this.log('info', `Initializing ${this.name} v${this.version}...`); + + // 子类实现具体初始化逻辑 + await this.onInitialize(); + + this.initialized = true; + this.log('info', `${this.name} initialized successfully`); + } + + /** + * 子类重写此方法实现初始化逻辑 + */ + async onInitialize() { + // 子类实现 + } + + /** + * 清理资源(子类可重写) + */ + async cleanup() { + this.log('info', `Cleaning up ${this.name}...`); + await this.onCleanup(); + this.initialized = false; + } + + /** + * 子类重写此方法实现清理逻辑 + */ + async onCleanup() { + // 子类实现 + } + + /** + * 统一的日志方法 + */ + log(level, message) { + const prefix = `[${this.name}]`; + logger[level](prefix, message); + } + + /** + * 验证配置 + */ + validateConfig(required = []) { + for (const key of required) { + if (!this.options[key]) { + throw new Error(`${this.name}: Missing required config: ${key}`); + } + } + } + + /** + * 获取配置项 + */ + getConfig(key, defaultValue = null) { + return this.options[key] !== undefined ? this.options[key] : defaultValue; + } + + /** + * 设置配置项 + */ + setConfig(key, value) { + this.options[key] = value; + } + + /** + * 获取库信息 + */ + getInfo() { + return { + name: this.name, + version: this.version, + initialized: this.initialized, + options: this.options + }; + } +} + +module.exports = BaseLib; diff --git a/src/shared/libs/base/lib-config.js b/src/shared/libs/base/lib-config.js new file mode 100644 index 0000000..a529636 --- /dev/null +++ b/src/shared/libs/base/lib-config.js @@ -0,0 +1,91 @@ +/** + * LibConfig - 库配置规范 + * 定义所有库的标准配置接口 + */ + +/** + * 配置模式定义 + */ +const CONFIG_SCHEMA = { + // 基础配置 + base: { + name: { type: 'string', required: true }, + version: { type: 'string', required: false, default: '1.0.0' }, + description: { type: 'string', required: false }, + author: { type: 'string', required: false } + }, + + // 运行时配置 + runtime: { + logLevel: { type: 'string', required: false, default: 'info' }, + timeout: { type: 'number', required: false, default: 30000 }, + retries: { type: 'number', required: false, default: 3 } + } +}; + +/** + * 验证配置 + */ +function validateLibConfig(config, schema = CONFIG_SCHEMA.base) { + const errors = []; + + for (const [key, spec] of Object.entries(schema)) { + // 检查必需字段 + if (spec.required && config[key] === undefined) { + errors.push(`Missing required field: ${key}`); + } + + // 检查类型 + if (config[key] !== undefined && typeof config[key] !== spec.type) { + errors.push(`Invalid type for ${key}: expected ${spec.type}, got ${typeof config[key]}`); + } + } + + return { + valid: errors.length === 0, + errors + }; +} + +/** + * 应用默认配置 + */ +function applyDefaults(config, schema = CONFIG_SCHEMA.base) { + const result = { ...config }; + + for (const [key, spec] of Object.entries(schema)) { + if (result[key] === undefined && spec.default !== undefined) { + result[key] = spec.default; + } + } + + return result; +} + +/** + * 创建库配置 + */ +function createLibConfig(name, options = {}) { + const baseConfig = { + name, + ...options + }; + + // 应用默认值 + const config = applyDefaults(baseConfig); + + // 验证配置 + const validation = validateLibConfig(config); + if (!validation.valid) { + throw new Error(`Invalid lib config: ${validation.errors.join(', ')}`); + } + + return config; +} + +module.exports = { + CONFIG_SCHEMA, + validateLibConfig, + applyDefaults, + createLibConfig +}; diff --git a/src/shared/libs/base/lib-registry.js b/src/shared/libs/base/lib-registry.js new file mode 100644 index 0000000..273b232 --- /dev/null +++ b/src/shared/libs/base/lib-registry.js @@ -0,0 +1,79 @@ +/** + * LibRegistry - 全局库注册表 + * 管理所有共享库的实例 + */ + +class LibRegistry { + constructor() { + this.libs = new Map(); + } + + /** + * 注册库 + */ + register(lib) { + if (this.libs.has(lib.name)) { + console.warn(`[LibRegistry] Library ${lib.name} already registered, replacing...`); + } + this.libs.set(lib.name, lib); + } + + /** + * 获取库实例 + */ + get(name) { + return this.libs.get(name); + } + + /** + * 检查库是否已注册 + */ + has(name) { + return this.libs.has(name); + } + + /** + * 获取所有库 + */ + getAll() { + return Array.from(this.libs.values()); + } + + /** + * 获取所有库的信息 + */ + getAllInfo() { + return this.getAll().map(lib => lib.getInfo()); + } + + /** + * 初始化所有库 + */ + async initializeAll() { + const libs = this.getAll(); + for (const lib of libs) { + if (!lib.initialized) { + await lib.initialize(); + } + } + } + + /** + * 清理所有库 + */ + async cleanupAll() { + const libs = this.getAll(); + for (const lib of libs) { + if (lib.initialized) { + await lib.cleanup(); + } + } + } +} + +// 创建全局单例 +if (!global.__libRegistry) { + global.__libRegistry = new LibRegistry(); +} + +module.exports = global.__libRegistry; diff --git a/src/tools/account-register/utils/browser-manager.js b/src/shared/libs/browser/browser-manager.js similarity index 99% rename from src/tools/account-register/utils/browser-manager.js rename to src/shared/libs/browser/browser-manager.js index b7cfb31..2366777 100644 --- a/src/tools/account-register/utils/browser-manager.js +++ b/src/shared/libs/browser/browser-manager.js @@ -5,7 +5,7 @@ const puppeteer = require('puppeteer'); const axios = require('axios'); -const logger = require('../../../shared/logger'); +const logger = require('../../logger'); class BrowserManager { constructor(options = {}) { diff --git a/src/tools/account-register/utils/capsolver-api.js b/src/shared/libs/browser/capsolver-api.js similarity index 99% rename from src/tools/account-register/utils/capsolver-api.js rename to src/shared/libs/browser/capsolver-api.js index a8e636c..b916d8a 100644 --- a/src/tools/account-register/utils/capsolver-api.js +++ b/src/shared/libs/browser/capsolver-api.js @@ -4,7 +4,7 @@ */ const axios = require('axios'); -const logger = require('../../../shared/logger'); +const logger = require('../../logger'); class CapSolverAPI { constructor(apiKey) { diff --git a/src/tools/account-register/utils/cloudflare-handler.js b/src/shared/libs/browser/cloudflare-handler.js similarity index 99% rename from src/tools/account-register/utils/cloudflare-handler.js rename to src/shared/libs/browser/cloudflare-handler.js index 6952972..b2f8aa0 100644 --- a/src/tools/account-register/utils/cloudflare-handler.js +++ b/src/shared/libs/browser/cloudflare-handler.js @@ -3,7 +3,7 @@ * 通用的Cloudflare人机验证处理,支持全自动和半自动模式 */ -const logger = require('../../../shared/logger'); +const logger = require('../../logger'); class CloudflareHandler { /** diff --git a/src/tools/account-register/utils/hcaptcha-solver.js b/src/shared/libs/browser/hcaptcha-solver.js similarity index 99% rename from src/tools/account-register/utils/hcaptcha-solver.js rename to src/shared/libs/browser/hcaptcha-solver.js index 83ca8e5..f819e01 100644 --- a/src/tools/account-register/utils/hcaptcha-solver.js +++ b/src/shared/libs/browser/hcaptcha-solver.js @@ -24,7 +24,7 @@ * }); */ -const logger = require('../../../shared/logger'); +const logger = require('../../logger'); class HCaptchaSolver { constructor(options = {}) { diff --git a/src/tools/account-register/utils/human-behavior.js b/src/shared/libs/browser/human-behavior.js similarity index 99% rename from src/tools/account-register/utils/human-behavior.js rename to src/shared/libs/browser/human-behavior.js index d5e1136..ae7cb3a 100644 --- a/src/tools/account-register/utils/human-behavior.js +++ b/src/shared/libs/browser/human-behavior.js @@ -3,7 +3,7 @@ * 用于使自动化操作更像真实用户 */ -const { randomInt } = require('../../../shared/utils'); +const { randomInt } = require('../../utils'); class HumanBehavior { /** diff --git a/src/tools/account-register/utils/yescaptcha-api.js b/src/shared/libs/browser/yescaptcha-api.js similarity index 98% rename from src/tools/account-register/utils/yescaptcha-api.js rename to src/shared/libs/browser/yescaptcha-api.js index 19f9ef4..5824ed3 100644 --- a/src/tools/account-register/utils/yescaptcha-api.js +++ b/src/shared/libs/browser/yescaptcha-api.js @@ -1,5 +1,5 @@ const axios = require('axios'); -const logger = require('../../../shared/logger'); +const logger = require('../../logger'); /** * YesCaptcha API 封装 diff --git a/src/tools/card-generator/config.js b/src/shared/libs/card-generator/config.js similarity index 100% rename from src/tools/card-generator/config.js rename to src/shared/libs/card-generator/config.js diff --git a/src/tools/card-generator/formatter.js b/src/shared/libs/card-generator/formatter.js similarity index 100% rename from src/tools/card-generator/formatter.js rename to src/shared/libs/card-generator/formatter.js diff --git a/src/tools/card-generator/generator.js b/src/shared/libs/card-generator/generator.js similarity index 96% rename from src/tools/card-generator/generator.js rename to src/shared/libs/card-generator/generator.js index af798c8..e088406 100644 --- a/src/tools/card-generator/generator.js +++ b/src/shared/libs/card-generator/generator.js @@ -2,9 +2,9 @@ * Card Generator - 核心生成逻辑 */ -const { randomInt, randomDigits, padZero, generateLuhnNumber } = require('../../shared/utils'); +const { randomInt, randomDigits, padZero, generateLuhnNumber } = require('../../utils'); const { CARD_TYPES, EXPIRY_CONFIG } = require('./config'); -const { ValidationError } = require('../../shared/errors'); +const { ValidationError } = require('../../errors'); class CardGenerator { constructor() { diff --git a/src/shared/libs/card-generator/index.js b/src/shared/libs/card-generator/index.js new file mode 100644 index 0000000..47ad767 --- /dev/null +++ b/src/shared/libs/card-generator/index.js @@ -0,0 +1,7 @@ +/** + * Card Generator Lib - 导出接口 + */ + +const CardGenerator = require('./generator'); + +module.exports = CardGenerator; diff --git a/src/tools/database/account-repository.js b/src/shared/libs/database/account-repository.js similarity index 99% rename from src/tools/database/account-repository.js rename to src/shared/libs/database/account-repository.js index ddf7f7e..6d581c7 100644 --- a/src/tools/database/account-repository.js +++ b/src/shared/libs/database/account-repository.js @@ -2,7 +2,7 @@ * Account Repository - 账号数据访问层(Repository 模式) */ -const logger = require('../../shared/logger'); +const logger = require('../../logger'); class AccountRepository { constructor(connection) { diff --git a/src/tools/database/config.js b/src/shared/libs/database/config.js similarity index 100% rename from src/tools/database/config.js rename to src/shared/libs/database/config.js diff --git a/src/tools/database/connection.js b/src/shared/libs/database/connection.js similarity index 97% rename from src/tools/database/connection.js rename to src/shared/libs/database/connection.js index 3e56337..cdba2cb 100644 --- a/src/tools/database/connection.js +++ b/src/shared/libs/database/connection.js @@ -3,7 +3,7 @@ */ const mysql = require('mysql2/promise'); -const logger = require('../../shared/logger'); +const logger = require('../../logger'); const { connection: defaultConfig } = require('./config'); class DatabaseConnection { diff --git a/src/shared/libs/database/index.js b/src/shared/libs/database/index.js new file mode 100644 index 0000000..44db4ad --- /dev/null +++ b/src/shared/libs/database/index.js @@ -0,0 +1,44 @@ +/** + * Database Lib - 数据库核心库 + */ + +const connection = require('./connection'); +const AccountRepository = require('./account-repository'); + +module.exports = { + /** + * 初始化数据库连接 + */ + async initialize(config) { + return await connection.initialize(config); + }, + + /** + * 获取连接 + */ + getConnection() { + return connection; + }, + + /** + * 获取 Repository + */ + getRepository(name) { + const repositories = { + account: new AccountRepository(connection) + }; + + return repositories[name]; + }, + + /** + * 关闭数据库连接 + */ + async close() { + return await connection.close(); + }, + + // 直接导出以便使用 + connection, + AccountRepository +}; diff --git a/src/shared/utils.js b/src/shared/utils/index.js similarity index 100% rename from src/shared/utils.js rename to src/shared/utils/index.js diff --git a/src/tools/account-register/index.js b/src/tools/account-register/index.js index eb36608..2615b39 100644 --- a/src/tools/account-register/index.js +++ b/src/tools/account-register/index.js @@ -4,7 +4,7 @@ const fs = require('fs'); const path = require('path'); -const AccountDataGenerator = require('./generator'); +const AccountDataGenerator = require('../../shared/libs/account-generator'); const logger = require('../../shared/logger'); const { OUTPUT_FORMATS } = require('./config'); diff --git a/src/tools/account-register/sites/windsurf.js b/src/tools/account-register/sites/windsurf.js index 16f53cf..121731c 100644 --- a/src/tools/account-register/sites/windsurf.js +++ b/src/tools/account-register/sites/windsurf.js @@ -10,17 +10,17 @@ * ... 根据实际情况继续添加步骤 */ -const AccountDataGenerator = require('../generator'); -const HumanBehavior = require('../utils/human-behavior'); -const CloudflareHandler = require('../utils/cloudflare-handler'); +const AccountDataGenerator = require('../../../shared/libs/account-generator'); +const HumanBehavior = require('../../../shared/libs/browser/human-behavior'); +const CloudflareHandler = require('../../../shared/libs/browser/cloudflare-handler'); const logger = require('../../../shared/logger'); const EmailVerificationService = require('../email-verification'); const { DEFAULT_CONFIG } = require('../config'); -const CardGenerator = require('../../card-generator/generator'); -const database = require('../../database'); -const CapSolverAPI = require('../utils/capsolver-api'); -const YesCaptchaAPI = require('../utils/yescaptcha-api'); -const BrowserManager = require('../utils/browser-manager'); +const CardGenerator = require('../../../shared/libs/card-generator'); +const database = require('../../../shared/libs/database'); +const CapSolverAPI = require('../../../shared/libs/browser/capsolver-api'); +const YesCaptchaAPI = require('../../../shared/libs/browser/yescaptcha-api'); +const BrowserManager = require('../../../shared/libs/browser/browser-manager'); const { Solver } = require('2captcha-ts'); class WindsurfRegister { diff --git a/src/automation-framework/README.md b/src/tools/automation-framework/README.md similarity index 100% rename from src/automation-framework/README.md rename to src/tools/automation-framework/README.md diff --git a/src/automation-framework/actions/click-action.js b/src/tools/automation-framework/actions/click-action.js similarity index 100% rename from src/automation-framework/actions/click-action.js rename to src/tools/automation-framework/actions/click-action.js diff --git a/src/automation-framework/actions/custom-action.js b/src/tools/automation-framework/actions/custom-action.js similarity index 100% rename from src/automation-framework/actions/custom-action.js rename to src/tools/automation-framework/actions/custom-action.js diff --git a/src/automation-framework/actions/extract-action.js b/src/tools/automation-framework/actions/extract-action.js similarity index 100% rename from src/automation-framework/actions/extract-action.js rename to src/tools/automation-framework/actions/extract-action.js diff --git a/src/automation-framework/actions/fill-form-action.js b/src/tools/automation-framework/actions/fill-form-action.js similarity index 100% rename from src/automation-framework/actions/fill-form-action.js rename to src/tools/automation-framework/actions/fill-form-action.js diff --git a/src/automation-framework/actions/navigate-action.js b/src/tools/automation-framework/actions/navigate-action.js similarity index 100% rename from src/automation-framework/actions/navigate-action.js rename to src/tools/automation-framework/actions/navigate-action.js diff --git a/src/automation-framework/actions/retry-block-action.js b/src/tools/automation-framework/actions/retry-block-action.js similarity index 100% rename from src/automation-framework/actions/retry-block-action.js rename to src/tools/automation-framework/actions/retry-block-action.js diff --git a/src/automation-framework/actions/verify-action.js b/src/tools/automation-framework/actions/verify-action.js similarity index 100% rename from src/automation-framework/actions/verify-action.js rename to src/tools/automation-framework/actions/verify-action.js diff --git a/src/automation-framework/actions/wait-action.js b/src/tools/automation-framework/actions/wait-action.js similarity index 100% rename from src/automation-framework/actions/wait-action.js rename to src/tools/automation-framework/actions/wait-action.js diff --git a/src/automation-framework/configs/sites/windsurf.yaml b/src/tools/automation-framework/configs/sites/windsurf.yaml similarity index 100% rename from src/automation-framework/configs/sites/windsurf.yaml rename to src/tools/automation-framework/configs/sites/windsurf.yaml diff --git a/src/automation-framework/core/action-registry.js b/src/tools/automation-framework/core/action-registry.js similarity index 100% rename from src/automation-framework/core/action-registry.js rename to src/tools/automation-framework/core/action-registry.js diff --git a/src/automation-framework/core/base-action.js b/src/tools/automation-framework/core/base-action.js similarity index 100% rename from src/automation-framework/core/base-action.js rename to src/tools/automation-framework/core/base-action.js diff --git a/src/automation-framework/core/config-validator.js b/src/tools/automation-framework/core/config-validator.js similarity index 100% rename from src/automation-framework/core/config-validator.js rename to src/tools/automation-framework/core/config-validator.js diff --git a/src/automation-framework/core/errors.js b/src/tools/automation-framework/core/errors.js similarity index 100% rename from src/automation-framework/core/errors.js rename to src/tools/automation-framework/core/errors.js diff --git a/src/automation-framework/core/performance-tracker.js b/src/tools/automation-framework/core/performance-tracker.js similarity index 100% rename from src/automation-framework/core/performance-tracker.js rename to src/tools/automation-framework/core/performance-tracker.js diff --git a/src/automation-framework/core/site-adapter.js b/src/tools/automation-framework/core/site-adapter.js similarity index 100% rename from src/automation-framework/core/site-adapter.js rename to src/tools/automation-framework/core/site-adapter.js diff --git a/src/automation-framework/core/smart-selector.js b/src/tools/automation-framework/core/smart-selector.js similarity index 100% rename from src/automation-framework/core/smart-selector.js rename to src/tools/automation-framework/core/smart-selector.js diff --git a/src/automation-framework/core/workflow-engine.js b/src/tools/automation-framework/core/workflow-engine.js similarity index 100% rename from src/automation-framework/core/workflow-engine.js rename to src/tools/automation-framework/core/workflow-engine.js diff --git a/src/tools/automation-framework/index.js b/src/tools/automation-framework/index.js new file mode 100644 index 0000000..731bfc3 --- /dev/null +++ b/src/tools/automation-framework/index.js @@ -0,0 +1,234 @@ +/** + * Automation Framework Tool - 基于配置的自动化注册工具 + */ + +const fs = require('fs'); +const path = require('path'); +const logger = require('../../shared/logger'); +const BrowserManager = require('../../shared/libs/browser/browser-manager'); + +const TOOL_NAME = 'automation-framework'; + +class AutomationFramework { + constructor() { + this.sites = new Map(); + this.loadSites(); + } + + /** + * 加载所有站点适配器 + */ + loadSites() { + const sitesDir = path.join(__dirname, 'sites'); + + try { + const files = fs.readdirSync(sitesDir); + + files.forEach(file => { + if (file.endsWith('-adapter.js')) { + const siteName = file.replace('-adapter.js', ''); + try { + const AdapterClass = require(path.join(sitesDir, file)); + this.sites.set(siteName, AdapterClass); + logger.debug(TOOL_NAME, `Loaded site: ${siteName}`); + } catch (error) { + logger.warn(TOOL_NAME, `Failed to load site ${siteName}: ${error.message}`); + } + } + }); + } catch (error) { + logger.warn(TOOL_NAME, `Failed to load sites: ${error.message}`); + } + } + + /** + * 执行注册 + */ + async execute(options) { + const { site, profileId } = options; + + try { + if (!site) { + logger.error(TOOL_NAME, '请指定网站名称'); + this.listSites(); + process.exit(1); + } + + if (!profileId) { + logger.error(TOOL_NAME, '请指定 AdsPower Profile ID'); + process.exit(1); + } + + const AdapterClass = this.sites.get(site); + if (!AdapterClass) { + logger.error(TOOL_NAME, `未知的网站: ${site}`); + this.listSites(); + process.exit(1); + } + + logger.info(TOOL_NAME, `========================================`); + logger.info(TOOL_NAME, `开始 ${site} 注册流程`); + logger.info(TOOL_NAME, `AdsPower Profile: ${profileId}`); + logger.info(TOOL_NAME, `========================================`); + + // 启动浏览器 + const browserManager = new BrowserManager({ + profileId: profileId, + siteName: TOOL_NAME + }); + + await browserManager.launch(); + + const browser = browserManager.browser; + const page = browserManager.page; + + // 创建上下文 + const context = { + page, + browser, + logger, + data: {}, + profileId, + validateConfig: options.validateConfig !== false, + performanceReport: options.performanceReport !== false + }; + + // 创建适配器并执行 + const adapter = new AdapterClass(context); + const result = await adapter.execute(); + + // 关闭浏览器 + await browserManager.close(); + + if (result.success) { + logger.success(TOOL_NAME, '注册流程完成'); + + // 保存结果 + if (options.output) { + const outputData = { + site, + account: context.data.account, + card: context.data.card, + subscription: context.data.subscription, + timestamp: new Date().toISOString() + }; + + fs.writeFileSync( + options.output, + JSON.stringify(outputData, null, 2) + ); + logger.success(TOOL_NAME, `结果已保存到: ${options.output}`); + } + } + + // 返回兼容格式 + return { + success: result.success, + siteName: site, + accountData: context.data.account, + cardInfo: context.data.card, + subscription: context.data.subscription, + result, + performance: result.performance + }; + + } catch (error) { + logger.error(TOOL_NAME, error.message); + console.error(error); + process.exit(1); + } + } + + /** + * 列出支持的网站 + */ + listSites() { + const sites = Array.from(this.sites.keys()); + + if (sites.length === 0) { + console.log('\n暂无可用网站\n'); + return; + } + + console.log('\n支持的网站:\n'); + sites.forEach(site => { + console.log(` ${site}`); + }); + console.log(''); + } + + /** + * 验证配置文件 + */ + validateConfig(siteName) { + const ConfigValidator = require('./core/config-validator'); + const yaml = require('js-yaml'); + + try { + const configPath = path.join(__dirname, 'configs/sites', `${siteName}.yaml`); + + if (!fs.existsSync(configPath)) { + logger.error(TOOL_NAME, `配置文件不存在: ${siteName}.yaml`); + return; + } + + const configContent = fs.readFileSync(configPath, 'utf8'); + const config = yaml.load(configContent); + + const validator = new ConfigValidator(); + const result = validator.validate(config); + + if (result.valid) { + logger.success(TOOL_NAME, `✓ 配置验证通过: ${siteName}`); + logger.info(TOOL_NAME, ` - 步骤数: ${config.workflow.length}`); + } else { + logger.error(TOOL_NAME, `✗ 配置验证失败: ${siteName}`); + result.errors.forEach(err => { + logger.error(TOOL_NAME, ` - ${err}`); + }); + } + + } catch (error) { + logger.error(TOOL_NAME, `验证失败: ${error.message}`); + } + } +} + +/** + * 兼容旧接口:静态方法 + */ +class AutomationFactory { + /** + * 使用 AdsPower 注册(兼容旧接口) + */ + static async registerWithAdsPower(siteName, profileId, options = {}) { + const tool = new AutomationFramework(); + return await tool.execute({ + site: siteName, + profileId: profileId, + ...options + }); + } +} + +module.exports = { + name: TOOL_NAME, + alias: 'auto', + description: '基于配置的自动化注册工具(新框架)', + execute: async (options) => { + const tool = new AutomationFramework(); + await tool.execute(options); + }, + listSites: () => { + const tool = new AutomationFramework(); + tool.listSites(); + }, + validateConfig: (siteName) => { + const tool = new AutomationFramework(); + tool.validateConfig(siteName); + }, + // 导出类以支持旧接口 + AutomationFactory, + // 兼容旧的直接调用方式 + registerWithAdsPower: AutomationFactory.registerWithAdsPower +}; diff --git a/src/automation-framework/sites/windsurf-adapter.js b/src/tools/automation-framework/sites/windsurf-adapter.js similarity index 98% rename from src/automation-framework/sites/windsurf-adapter.js rename to src/tools/automation-framework/sites/windsurf-adapter.js index af077aa..bc0964f 100644 --- a/src/automation-framework/sites/windsurf-adapter.js +++ b/src/tools/automation-framework/sites/windsurf-adapter.js @@ -1,6 +1,6 @@ const SiteAdapter = require('../core/site-adapter'); -const AccountDataGenerator = require('../../tools/account-register/generator'); -const CardGenerator = require('../../tools/card-generator/generator'); +const AccountDataGenerator = require('../../../shared/libs/account-generator'); +const CardGenerator = require('../../../shared/libs/card-generator'); /** * Windsurf 站点适配器 @@ -177,7 +177,7 @@ class WindsurfAdapter extends SiteAdapter { this.log('info', '开始邮箱验证'); // 导入邮箱服务 - const EmailVerificationService = require('../../tools/account-register/email-verification'); + const EmailVerificationService = require('../../account-register/email-verification'); if (!this.emailService) { this.emailService = new EmailVerificationService(); } @@ -468,7 +468,7 @@ class WindsurfAdapter extends SiteAdapter { try { // 导入数据库模块 - const database = require('../../tools/account-register/database'); + const database = require('../../../shared/libs/database'); // 初始化数据库连接 this.log('info', '连接数据库...'); diff --git a/src/tools/card-generator/index.js b/src/tools/card-generator/index.js index d02fc2b..92e63b2 100644 --- a/src/tools/card-generator/index.js +++ b/src/tools/card-generator/index.js @@ -2,8 +2,8 @@ * Card Generator Tool - 工具入口 */ -const CardGenerator = require('./generator'); -const Formatter = require('./formatter'); +const CardGenerator = require('../../shared/libs/card-generator'); +const Formatter = require('../../shared/libs/card-generator/formatter'); const logger = require('../../shared/logger'); const TOOL_NAME = 'card-generator'; diff --git a/src/tools/database/index.js b/src/tools/database/index.js index 9badfb5..bfd521c 100644 --- a/src/tools/database/index.js +++ b/src/tools/database/index.js @@ -1,37 +1,27 @@ /** * Database Tool - 数据库工具入口 + * 直接导出 shared/libs/database 并添加工具元信息 */ -const connection = require('./connection'); -const AccountRepository = require('./account-repository'); +const database = require('../../shared/libs/database'); module.exports = { name: 'database', alias: 'db', description: 'MySQL数据库工具', - /** - * 初始化数据库连接 - */ - async initialize(config) { - return await connection.initialize(config); - }, + // 导出所有数据库功能 + ...database, /** - * 获取 Repository + * 执行数据库命令(CLI 入口) */ - getRepository(name) { - const repositories = { - account: new AccountRepository(connection) - }; - - return repositories[name]; - }, - - /** - * 关闭数据库连接 - */ - async close() { - return await connection.close(); + execute: async (options) => { + // 未来可以添加 CLI 命令,如: + // aam db init - 初始化数据库 + // aam db migrate - 运行迁移 + // aam db seed - 填充测试数据 + console.log('Database tool - 功能开发中'); + console.log('使用 database.initialize() 初始化连接'); } }; diff --git a/test-new-framework.js b/test-new-framework.js index 87ffc38..5a85466 100644 --- a/test-new-framework.js +++ b/test-new-framework.js @@ -3,7 +3,7 @@ * 测试新框架 */ require('dotenv').config(); -const AutomationFactory = require('./src/automation-framework'); +const { AutomationFactory } = require('./src/tools/automation-framework'); const logger = require('./src/shared/logger'); async function test() {