wechat-md-publisher 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/default-wrapper.json +3 -3
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/renderer/ImageProcessor.d.ts.map +1 -1
- package/dist/core/renderer/ImageProcessor.js +9 -1
- package/dist/core/renderer/ImageProcessor.js.map +1 -1
- package/package.json +1 -1
- package/themes/builtin/lapis.css +184 -0
- package/themes/builtin/maize.css +193 -0
- package/themes/builtin/orangeheart.css +176 -0
- package/themes/builtin/phycat.css +302 -0
- package/themes/builtin/pie.css +231 -0
- package/themes/builtin/purple.css +174 -0
- package/themes/builtin/rainbow.css +165 -0
- package/themes/builtin/sport.css +223 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"enabled": true,
|
|
3
|
-
"header": "<div style=\"padding: 12px 15px; border:
|
|
4
|
-
"footer": "
|
|
5
|
-
}
|
|
3
|
+
"header": "<div style=\"padding: 12px 15px; border: 1px dashed currentColor; font-size:14px; background: transparent; color: inherit;\">\n点击左上关注,PingAI 品智助你智领未来\n</div>",
|
|
4
|
+
"footer": "<div style=\"padding: 12px 15px; border: 1px dashed currentColor; font-size:14px; background: transparent; color: inherit;\">\n免责声明:本文内容转载自互联网,仅供参考学习使用。文中观点不代表本公众号立场,内容准确性请读者自行判断。如有侵权或不当之处,请联系我们删除。转载请注明出处。\n</div>"
|
|
5
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -258,6 +258,9 @@ async function readImageFile(filePath) {
|
|
|
258
258
|
function isRemoteUrl(url) {
|
|
259
259
|
return url.startsWith("http://") || url.startsWith("https://");
|
|
260
260
|
}
|
|
261
|
+
function isWechatImageUrl(url) {
|
|
262
|
+
return url.startsWith("https://mmbiz.qpic.cn");
|
|
263
|
+
}
|
|
261
264
|
function getImageFilename(url) {
|
|
262
265
|
const urlWithoutQuery = url.split("?")[0];
|
|
263
266
|
const parts = urlWithoutQuery.split("/");
|
|
@@ -307,6 +310,9 @@ class ImageProcessor {
|
|
|
307
310
|
const uploadPromises = Array.from(images).map(async (element) => {
|
|
308
311
|
const src = element.getAttribute("src");
|
|
309
312
|
if (!src) return null;
|
|
313
|
+
if (isWechatImageUrl(src)) {
|
|
314
|
+
return { media_id: src, url: src };
|
|
315
|
+
}
|
|
310
316
|
try {
|
|
311
317
|
const result = await this.uploadImage(src, relativePath);
|
|
312
318
|
element.setAttribute("src", result.url);
|
|
@@ -382,6 +388,10 @@ class ImageProcessor {
|
|
|
382
388
|
});
|
|
383
389
|
if (coverPath) {
|
|
384
390
|
try {
|
|
391
|
+
if (isWechatImageUrl(coverPath)) {
|
|
392
|
+
this.logger.info("使用微信图片作为封面", { coverPath });
|
|
393
|
+
return coverPath;
|
|
394
|
+
}
|
|
385
395
|
const result = await this.uploadImage(coverPath, relativePath);
|
|
386
396
|
this.logger.info("封面上传成功(显式指定)", { media_id: result.media_id });
|
|
387
397
|
return result.media_id;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sources":["../src/infrastructure/cache/CacheStore.ts","../src/infrastructure/cache/TokenCache.ts","../src/infrastructure/cache/ImageCache.ts","../src/infrastructure/cache/ThemeCache.ts","../src/infrastructure/http/HttpClient.ts","../src/infrastructure/database/DatabaseManager.ts","../src/utils/image.ts","../src/utils/crypto.ts","../src/utils/file.ts","../src/core/renderer/ImageProcessor.ts","../src/services/AccountService.ts","../src/services/ThemeService.ts","../src/services/RenderService.ts","../src/services/DraftService.ts","../src/services/PublishService.ts","../src/services/WrapperService.ts","../src/container.ts","../src/cli/commands/account.ts","../src/cli/commands/theme.ts","../src/cli/commands/draft.ts","../src/cli/commands/publish.ts","../src/cli/commands/wrapper.ts","../src/cli/index.ts"],"sourcesContent":["export interface CacheEntry<T> {\n value: T;\n expireAt: number;\n}\n\nexport class CacheStore<T = any> {\n private cache: Map<string, CacheEntry<T>> = new Map();\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n }\n\n async get(key: string): Promise<T | null> {\n const entry = this.cache.get(key);\n \n if (!entry) {\n return null;\n }\n\n if (Date.now() > entry.expireAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.value;\n }\n\n async set(key: string, value: T, ttl: number = 3600): Promise<void> {\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, {\n value,\n expireAt: Date.now() + ttl * 1000,\n });\n }\n\n async has(key: string): Promise<boolean> {\n const value = await this.get(key);\n return value !== null;\n }\n\n async delete(key: string): Promise<void> {\n this.cache.delete(key);\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n }\n\n async size(): Promise<number> {\n return this.cache.size;\n }\n}\n","import { CacheStore } from './CacheStore';\n\nexport interface TokenCacheEntry {\n access_token: string;\n expires_in: number;\n}\n\nexport class TokenCache extends CacheStore<TokenCacheEntry> {\n constructor() {\n super(10);\n }\n\n async getToken(appId: string): Promise<string | null> {\n const entry = await this.get(appId);\n return entry ? entry.access_token : null;\n }\n\n async setToken(appId: string, accessToken: string, expiresIn: number): Promise<void> {\n await this.set(\n appId,\n {\n access_token: accessToken,\n expires_in: expiresIn,\n },\n expiresIn - 200\n );\n }\n}\n","import { CacheStore } from './CacheStore';\n\nexport interface ImageCacheEntry {\n media_id: string;\n url: string;\n}\n\nexport class ImageCache extends CacheStore<ImageCacheEntry> {\n constructor() {\n super(500);\n }\n\n async getMediaId(md5: string): Promise<string | null> {\n const entry = await this.get(md5);\n return entry ? entry.media_id : null;\n }\n\n async setImage(md5: string, mediaId: string, url: string, ttl: number = 86400): Promise<void> {\n await this.set(\n md5,\n {\n media_id: mediaId,\n url,\n },\n ttl\n );\n }\n}\n","import { CacheStore } from './CacheStore';\n\nexport class ThemeCache extends CacheStore<string> {\n constructor() {\n super(50);\n }\n\n async getThemeCSS(themeId: string): Promise<string | null> {\n return await this.get(themeId);\n }\n\n async setThemeCSS(themeId: string, css: string, ttl: number = 3600): Promise<void> {\n await this.set(themeId, css, ttl);\n }\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { Logger } from '../logger/Logger';\n\nexport class HttpClient {\n private client: AxiosInstance;\n\n constructor(private logger: Logger) {\n this.client = axios.create({\n timeout: 30000,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n this.client.interceptors.request.use(\n (config) => {\n this.logger.debug('HTTP Request', {\n method: config.method,\n url: config.url,\n });\n return config;\n },\n (error) => {\n this.logger.error('HTTP Request Error', { error: error.message });\n return Promise.reject(error);\n }\n );\n\n this.client.interceptors.response.use(\n (response) => {\n this.logger.debug('HTTP Response', {\n status: response.status,\n url: response.config.url,\n });\n return response;\n },\n (error) => {\n this.logger.error('HTTP Response Error', {\n status: error.response?.status,\n message: error.message,\n });\n return Promise.reject(error);\n }\n );\n }\n\n async get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.get<T>(url, config);\n }\n\n async post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.post<T>(url, data, config);\n }\n\n async put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.put<T>(url, data, config);\n }\n\n async delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.delete<T>(url, config);\n }\n}\n","import initSqlJs, { Database } from 'sql.js';\nimport { Logger } from '../logger/Logger';\nimport { resolve } from 'path';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\n\nexport class DatabaseManager {\n private db!: Database;\n private logger: Logger;\n private dbPath!: string;\n\n constructor(logger: Logger) {\n this.logger = logger;\n }\n\n async initialize(dbPath?: string): Promise<void> {\n const dataDir = resolve(process.cwd(), 'data');\n \n // 确保 data 目录存在\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n\n this.dbPath = dbPath || resolve(dataDir, 'wmp.db');\n this.logger.info('初始化数据库', { path: this.dbPath });\n\n // 初始化 SQL.js\n const SQL = await initSqlJs();\n\n // 加载已存在的数据库或创建新的\n if (existsSync(this.dbPath)) {\n const fileBuffer = readFileSync(this.dbPath);\n this.db = new SQL.Database(fileBuffer);\n } else {\n this.db = new SQL.Database();\n }\n \n this.initTables();\n this.save();\n }\n\n private initTables(): void {\n // Wrapper 版本表\n this.db.run(`\n CREATE TABLE IF NOT EXISTS wrapper_versions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n version INTEGER NOT NULL,\n enabled INTEGER DEFAULT 0,\n header TEXT,\n footer TEXT,\n author TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // 发布的文章记录表\n this.db.run(`\n CREATE TABLE IF NOT EXISTS published_articles (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n url TEXT,\n author TEXT,\n published_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n article_id TEXT,\n media_id TEXT\n )\n `);\n\n // 配置表\n this.db.run(`\n CREATE TABLE IF NOT EXISTS config (\n key TEXT PRIMARY KEY,\n value TEXT\n )\n `);\n\n this.logger.info('数据库表初始化完成');\n }\n\n save(): void {\n const data = this.db.export();\n const buffer = Buffer.from(data);\n writeFileSync(this.dbPath, buffer);\n }\n\n getDatabase(): Database {\n return this.db;\n }\n\n close(): void {\n if (this.db) {\n this.save();\n this.db.close();\n }\n }\n}\n","import { readFile } from 'fs/promises';\nimport axios from 'axios';\n\nexport async function downloadImage(url: string): Promise<Buffer> {\n try {\n const response = await axios.get(url, {\n responseType: 'arraybuffer',\n timeout: 30000,\n });\n \n if (!response.data || response.data.byteLength === 0) {\n throw new Error('下载的图片大小为 0');\n }\n \n return Buffer.from(response.data);\n } catch (error) {\n throw new Error(`下载图片失败: ${url}`);\n }\n}\n\nexport async function readImageFile(filePath: string): Promise<Buffer> {\n try {\n const buffer = await readFile(filePath);\n \n if (buffer.length === 0) {\n throw new Error('图片文件大小为 0');\n }\n \n return buffer;\n } catch (error) {\n throw new Error(`读取图片文件失败: ${filePath}`);\n }\n}\n\nexport function isRemoteUrl(url: string): boolean {\n return url.startsWith('http://') || url.startsWith('https://');\n}\n\nexport function isWechatImageUrl(url: string): boolean {\n return url.startsWith('https://mmbiz.qpic.cn');\n}\n\nexport function getImageFilename(url: string): string {\n const urlWithoutQuery = url.split('?')[0];\n const parts = urlWithoutQuery.split('/');\n const filename = parts[parts.length - 1];\n \n const ext = filename.match(/\\.(jpg|jpeg|png|gif|webp|bmp)$/i);\n if (!ext) {\n return `${filename}.jpg`;\n }\n \n return filename;\n}\n","import { createHash } from 'crypto';\nimport { readFile } from 'fs/promises';\n\nexport function md5FromBuffer(buffer: Buffer): string {\n return createHash('md5').update(buffer).digest('hex');\n}\n\nexport function md5FromString(str: string): string {\n return createHash('md5').update(str).digest('hex');\n}\n\nexport async function md5FromFile(filePath: string): Promise<string> {\n const buffer = await readFile(filePath);\n return md5FromBuffer(buffer);\n}\n\nexport function generateId(prefix: string = ''): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return prefix ? `${prefix}_${timestamp}_${random}` : `${timestamp}_${random}`;\n}\n","import { readFile, writeFile, access, mkdir } from 'fs/promises';\nimport { dirname, resolve, isAbsolute } from 'path';\nimport { constants } from 'fs';\n\nexport async function readFileContent(filePath: string): Promise<string> {\n try {\n return await readFile(filePath, 'utf-8');\n } catch (error) {\n throw new Error(`无法读取文件: ${filePath}`);\n }\n}\n\nexport async function writeFileContent(filePath: string, content: string): Promise<void> {\n try {\n const dir = dirname(filePath);\n await mkdir(dir, { recursive: true });\n await writeFile(filePath, content, 'utf-8');\n } catch (error) {\n throw new Error(`无法写入文件: ${filePath}`);\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function resolvePath(filePath: string, basePath?: string): string {\n if (isAbsolute(filePath)) {\n return filePath;\n }\n \n if (basePath) {\n return resolve(basePath, filePath);\n }\n \n return resolve(process.cwd(), filePath);\n}\n\nexport function getFileExtension(filePath: string): string {\n const match = filePath.match(/\\.([^.]+)$/);\n return match ? match[1].toLowerCase() : '';\n}\n\nexport function isImageFile(filePath: string): boolean {\n const ext = getFileExtension(filePath);\n return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'].includes(ext);\n}\n","import { JSDOM } from 'jsdom';\nimport { MaterialAPI } from '../wechat/api/MaterialAPI';\nimport { ImageCache } from '../../infrastructure/cache/ImageCache';\nimport { Logger } from '../../infrastructure/logger/Logger';\nimport { downloadImage, readImageFile, isRemoteUrl, getImageFilename } from '../../utils/image';\nimport { md5FromBuffer } from '../../utils/crypto';\nimport { resolvePath } from '../../utils/file';\n\nexport interface ProcessImagesResult {\n content: string;\n firstImageMediaId: string;\n firstImageUrl: string;\n}\n\nexport class ImageProcessor {\n constructor(\n private materialAPI: MaterialAPI,\n private imageCache: ImageCache,\n private logger: Logger\n ) {}\n\n async processImages(content: string, relativePath?: string): Promise<ProcessImagesResult> {\n if (!content.includes('<img')) {\n return { content, firstImageMediaId: '', firstImageUrl: '' };\n }\n\n const dom = new JSDOM(content);\n const images = dom.window.document.querySelectorAll('img');\n \n const uploadPromises = Array.from(images).map(async (element: any) => {\n const src = element.getAttribute('src');\n if (!src) return null;\n\n try {\n const result = await this.uploadImage(src, relativePath);\n element.setAttribute('src', result.url);\n return result;\n } catch (error) {\n this.logger.warn('图片上传失败', { src, error });\n return null;\n }\n });\n\n const results = (await Promise.all(uploadPromises)).filter(Boolean) as { media_id: string; url: string }[];\n \n const firstImage = results[0];\n const firstImageMediaId = firstImage?.media_id || '';\n const firstImageUrl = firstImage?.url || '';\n\n return {\n content: dom.serialize(),\n firstImageMediaId,\n firstImageUrl,\n };\n }\n\n /**\n * 从 HTML 内容中提取第一张图片\n */\n extractFirstImageFromContent(content: string): string | null {\n if (!content || !content.includes('<img')) {\n return null;\n }\n\n try {\n const dom = new JSDOM(content);\n const firstImg = dom.window.document.querySelector('img');\n return firstImg?.getAttribute('src') || null;\n } catch (error) {\n this.logger.warn('提取第一张图片失败', { error });\n return null;\n }\n }\n\n async uploadImage(imagePath: string, relativePath?: string): Promise<{ media_id: string; url: string }> {\n let buffer: Buffer;\n let filename: string;\n\n if (isRemoteUrl(imagePath)) {\n this.logger.info('下载远程图片', { url: imagePath });\n buffer = await downloadImage(imagePath);\n filename = getImageFilename(imagePath);\n } else {\n const resolvedPath = resolvePath(imagePath, relativePath);\n this.logger.info('读取本地图片', { path: resolvedPath });\n buffer = await readImageFile(resolvedPath);\n filename = getImageFilename(resolvedPath);\n }\n\n const md5 = md5FromBuffer(buffer);\n const cached = await this.imageCache.getMediaId(md5);\n if (cached) {\n this.logger.debug('使用缓存的图片', { md5 });\n const cachedEntry = await this.imageCache.get(md5);\n return { media_id: cached, url: cachedEntry!.url };\n }\n\n const result = await this.materialAPI.uploadImage(buffer, filename);\n await this.imageCache.setImage(md5, result.media_id, result.url);\n\n this.logger.info('图片上传成功', { media_id: result.media_id });\n return result;\n }\n\n /**\n * 上传封面图\n * 优先级:\n * 1. coverPath(显式指定的封面)\n * 2. fallbackMediaId(从正文第一张图片传来的 media_id)\n * 3. 从 content 中提取第一张图片并上传\n */\n async uploadCover(\n coverPath: string | undefined, \n relativePath: string | undefined, \n fallbackMediaId: string | undefined,\n content?: string\n ): Promise<string> {\n this.logger.debug('开始处理封面', { \n hasCoverPath: !!coverPath, \n hasFallbackMediaId: !!fallbackMediaId,\n hasContent: !!content \n });\n\n // 优先级 1: 显式指定的封面\n if (coverPath) {\n try {\n const result = await this.uploadImage(coverPath, relativePath);\n this.logger.info('封面上传成功(显式指定)', { media_id: result.media_id });\n return result.media_id;\n } catch (error) {\n this.logger.warn('显式封面图上传失败,继续尝试 fallback', { coverPath, error });\n }\n }\n\n // 优先级 2: fallback media_id(正文第一张图片)\n if (fallbackMediaId) {\n this.logger.info('使用正文第一张图片作为封面', { media_id: fallbackMediaId });\n return fallbackMediaId;\n }\n\n // 优先级 3: 从 content 中提取第一张图片\n if (content) {\n const firstImageSrc = this.extractFirstImageFromContent(content);\n if (firstImageSrc) {\n try {\n this.logger.info('尝试从正文提取第一张图片作为封面', { src: firstImageSrc });\n const result = await this.uploadImage(firstImageSrc, relativePath);\n this.logger.info('封面上传成功(从正文提取)', { media_id: result.media_id });\n return result.media_id;\n } catch (error) {\n this.logger.warn('从正文提取封面上传失败', { src: firstImageSrc, error });\n }\n }\n }\n\n // 所有尝试都失败\n throw new Error('无法获取封面图:请在 Markdown 中添加 cover: 图片路径,或确保正文中包含图片');\n }\n}\n","import { ConfigStore } from '../infrastructure/config/ConfigStore';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { Account, AccountCreateOptions } from '../types/account';\nimport { generateId } from '../utils/crypto';\n\nexport class AccountService {\n constructor(\n private configStore: ConfigStore,\n private logger: Logger\n ) {}\n\n async addAccount(options: AccountCreateOptions): Promise<Account> {\n this.logger.info('添加账号', { name: options.name });\n\n const accounts = await this.listAccounts();\n \n const existingAccount = accounts.find(a => a.appId === options.appId);\n if (existingAccount) {\n throw new Error(`账号已存在: ${existingAccount.name}`);\n }\n\n const account: Account = {\n id: generateId('acc'),\n name: options.name,\n appId: options.appId,\n appSecret: options.appSecret,\n isDefault: options.isDefault || accounts.length === 0,\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n\n if (account.isDefault) {\n accounts.forEach(a => a.isDefault = false);\n }\n\n accounts.push(account);\n this.configStore.set('accounts', accounts);\n\n this.logger.info('账号添加成功', { id: account.id, name: account.name });\n return account;\n }\n\n async listAccounts(): Promise<Account[]> {\n return this.configStore.get('accounts', []);\n }\n\n async getAccount(id: string): Promise<Account | null> {\n const accounts = await this.listAccounts();\n return accounts.find(a => a.id === id) || null;\n }\n\n async getCurrentAccount(): Promise<Account> {\n const accounts = await this.listAccounts();\n \n if (accounts.length === 0) {\n throw new Error('未配置账号,请先使用 account add 命令添加账号');\n }\n\n const defaultAccount = accounts.find(a => a.isDefault);\n if (defaultAccount) {\n return defaultAccount;\n }\n\n return accounts[0];\n }\n\n async setDefaultAccount(id: string): Promise<void> {\n this.logger.info('设置默认账号', { id });\n\n const accounts = await this.listAccounts();\n const account = accounts.find(a => a.id === id);\n\n if (!account) {\n throw new Error(`账号不存在: ${id}`);\n }\n\n accounts.forEach(a => {\n a.isDefault = a.id === id;\n if (a.id === id) {\n a.updatedAt = new Date();\n }\n });\n\n this.configStore.set('accounts', accounts);\n this.logger.info('默认账号设置成功', { name: account.name });\n }\n\n async removeAccount(id: string): Promise<void> {\n this.logger.info('删除账号', { id });\n\n const accounts = await this.listAccounts();\n const account = accounts.find(a => a.id === id);\n\n if (!account) {\n throw new Error(`账号不存在: ${id}`);\n }\n\n const filtered = accounts.filter(a => a.id !== id);\n\n if (account.isDefault && filtered.length > 0) {\n filtered[0].isDefault = true;\n }\n\n this.configStore.set('accounts', filtered);\n this.logger.info('账号删除成功', { name: account.name });\n }\n\n async updateAccount(id: string, updates: Partial<Account>): Promise<Account> {\n this.logger.info('更新账号', { id });\n\n const accounts = await this.listAccounts();\n const account = accounts.find(a => a.id === id);\n\n if (!account) {\n throw new Error(`账号不存在: ${id}`);\n }\n\n Object.assign(account, updates, { updatedAt: new Date() });\n this.configStore.set('accounts', accounts);\n\n this.logger.info('账号更新成功', { name: account.name });\n return account;\n }\n}\n","import { ThemeEngine } from '../core/theme/ThemeEngine';\nimport { ConfigStore } from '../infrastructure/config/ConfigStore';\nimport { ThemeCache } from '../infrastructure/cache/ThemeCache';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { ThemeSource } from '../types/theme';\n\nexport class ThemeService {\n constructor(\n private themeEngine: ThemeEngine,\n private configStore: ConfigStore,\n private themeCache: ThemeCache,\n private logger: Logger\n ) {}\n\n async initialize(): Promise<void> {\n this.logger.info('初始化主题系统');\n\n await this.themeEngine.loadBuiltinThemes();\n\n const config = this.configStore.get('themes');\n if (!config) {\n return;\n }\n\n if (config.local) {\n for (const theme of config.local) {\n try {\n await this.themeEngine.addLocalTheme(theme.name, theme.path);\n } catch (error) {\n this.logger.warn('加载本地主题失败', { name: theme.name, error });\n }\n }\n }\n\n if (config.remote) {\n for (const remote of config.remote) {\n if (remote.enabled) {\n try {\n await this.themeEngine.addRemoteAPI(remote.name, remote.apiUrl, remote.apiKey);\n } catch (error) {\n this.logger.warn('添加远程主题 API 失败', { name: remote.name, error });\n }\n }\n }\n }\n\n this.logger.info('主题系统初始化完成');\n }\n\n async listThemes(): Promise<ThemeSource[]> {\n return await this.themeEngine.listThemes();\n }\n\n async getThemeCSS(themeId: string): Promise<string> {\n const cached = await this.themeCache.getThemeCSS(themeId);\n if (cached) {\n this.logger.debug('使用缓存的主题', { themeId });\n return cached;\n }\n\n const css = await this.themeEngine.getThemeCSS(themeId);\n await this.themeCache.setThemeCSS(themeId, css);\n\n return css;\n }\n\n async addLocalTheme(name: string, path: string): Promise<void> {\n this.logger.info('添加本地主题', { name, path });\n\n await this.themeEngine.addLocalTheme(name, path);\n\n const config = this.configStore.get('themes') || {};\n if (!config.local) {\n config.local = [];\n }\n\n const existing = config.local.find(t => t.name === name);\n if (existing) {\n existing.path = path;\n } else {\n config.local.push({ name, path });\n }\n\n this.configStore.set('themes', config);\n this.logger.info('本地主题添加成功');\n }\n\n async addRemoteAPI(name: string, apiUrl: string, apiKey: string): Promise<void> {\n this.logger.info('添加远程主题 API', { name, apiUrl });\n\n await this.themeEngine.addRemoteAPI(name, apiUrl, apiKey);\n\n const config = this.configStore.get('themes') || {};\n if (!config.remote) {\n config.remote = [];\n }\n\n const existing = config.remote.find(r => r.name === name);\n if (existing) {\n existing.apiUrl = apiUrl;\n existing.apiKey = apiKey;\n existing.enabled = true;\n } else {\n config.remote.push({ name, apiUrl, apiKey, enabled: true });\n }\n\n this.configStore.set('themes', config);\n this.logger.info('远程主题 API 添加成功');\n }\n\n async removeTheme(themeId: string): Promise<void> {\n this.logger.info('删除主题', { themeId });\n\n await this.themeEngine.removeTheme(themeId);\n await this.themeCache.delete(themeId);\n\n const config = this.configStore.get('themes') || {};\n if (config.local) {\n config.local = config.local.filter(t => t.name !== themeId);\n }\n\n this.configStore.set('themes', config);\n this.logger.info('主题删除成功');\n }\n}\n","import { MarkdownRenderer, RenderResult } from '../core/renderer/MarkdownRenderer';\nimport { ThemeService } from './ThemeService';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport { readFileContent } from '../utils/file';\n\nexport interface RenderOptions {\n markdown?: string;\n file?: string;\n theme?: string;\n}\n\nexport class RenderService {\n constructor(\n private renderer: MarkdownRenderer,\n private themeService: ThemeService,\n private logger: Logger\n ) {}\n\n async initialize(): Promise<void> {\n await this.renderer.initialize();\n }\n\n async render(options: RenderOptions): Promise<RenderResult> {\n let markdown: string;\n\n if (options.file) {\n this.logger.info('读取 Markdown 文件', { file: options.file });\n markdown = await readFileContent(options.file);\n } else if (options.markdown) {\n markdown = options.markdown;\n } else {\n throw new Error('必须提供 markdown 内容或 file 路径');\n }\n\n let themeCss: string | undefined;\n if (options.theme) {\n this.logger.info('加载主题', { theme: options.theme });\n themeCss = await this.themeService.getThemeCSS(options.theme);\n }\n\n this.logger.info('开始渲染 Markdown');\n const result = await this.renderer.render(markdown, themeCss);\n this.logger.info('Markdown 渲染完成', { title: result.title });\n\n return result;\n }\n}\n","import { WechatClient } from '../core/wechat/WechatClient';\nimport { RenderService } from './RenderService';\nimport { ImageProcessor } from '../core/renderer/ImageProcessor';\nimport { WrapperService } from './WrapperService';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { DraftCreateOptions, Draft, DraftList } from '../types/draft';\nimport { dirname } from 'path';\n\nexport class DraftService {\n constructor(\n private wechatClient: WechatClient,\n private renderService: RenderService,\n private imageProcessor: ImageProcessor,\n private wrapperService: WrapperService,\n private logger: Logger\n ) {}\n\n async create(options: DraftCreateOptions): Promise<{ media_id: string }> {\n this.logger.info('开始创建草稿', { file: options.file });\n\n const rendered = await this.renderService.render({\n markdown: options.markdown,\n file: options.file,\n theme: options.theme,\n });\n\n // 使用 Wrapper 包装内容\n let content = this.wrapperService.wrapContent(rendered.content);\n\n const relativePath = options.relativePath || (options.file ? dirname(options.file) : undefined);\n\n const { content: processedContent, firstImageMediaId } = await this.imageProcessor.processImages(\n content,\n relativePath\n );\n\n const thumbMediaId = await this.imageProcessor.uploadCover(\n rendered.cover,\n relativePath,\n firstImageMediaId,\n processedContent\n );\n\n const result = await this.wechatClient.draft.create({\n title: rendered.title,\n content: processedContent,\n thumb_media_id: thumbMediaId,\n });\n\n this.logger.info('草稿创建成功', { media_id: result.media_id });\n return result;\n }\n\n async list(page: number = 1, pageSize: number = 20): Promise<DraftList> {\n const offset = (page - 1) * pageSize;\n return await this.wechatClient.draft.list(offset, pageSize);\n }\n\n async get(mediaId: string): Promise<Draft> {\n return await this.wechatClient.draft.get(mediaId);\n }\n\n async delete(mediaId: string): Promise<void> {\n this.logger.info('删除草稿', { media_id: mediaId });\n await this.wechatClient.draft.delete(mediaId);\n this.logger.info('草稿删除成功');\n }\n\n async batchDelete(mediaIds: string[]): Promise<void> {\n this.logger.info('批量删除草稿', { count: mediaIds.length });\n\n const results = await Promise.allSettled(\n mediaIds.map(id => this.delete(id))\n );\n\n const failed = results.filter(r => r.status === 'rejected');\n if (failed.length > 0) {\n this.logger.warn('部分草稿删除失败', {\n failed: failed.length,\n total: mediaIds.length,\n });\n }\n }\n\n async count(): Promise<number> {\n return await this.wechatClient.draft.count();\n }\n}\n","import { WechatClient } from '../core/wechat/WechatClient';\nimport { DraftService } from './DraftService';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { PublishResult, PublishedArticle, PublishList, PublishStatus } from '../types/publish';\nimport type { DraftCreateOptions } from '../types/draft';\n\nexport class PublishService {\n constructor(\n private wechatClient: WechatClient,\n private draftService: DraftService,\n private logger: Logger\n ) {}\n\n async submit(mediaId: string): Promise<PublishResult> {\n this.logger.info('发布草稿', { media_id: mediaId });\n const result = await this.wechatClient.publish.submit(mediaId);\n this.logger.info('发布任务提交成功', { publish_id: result.publish_id });\n return result;\n }\n\n async createAndPublish(options: DraftCreateOptions): Promise<PublishResult> {\n this.logger.info('创建并发布文章');\n\n const { media_id } = await this.draftService.create(options);\n const result = await this.submit(media_id);\n\n return result;\n }\n\n async list(page: number = 1, pageSize: number = 20): Promise<PublishList> {\n const offset = (page - 1) * pageSize;\n return await this.wechatClient.publish.list(offset, pageSize);\n }\n\n async get(articleId: string): Promise<PublishedArticle> {\n return await this.wechatClient.publish.get(articleId);\n }\n\n async delete(articleId: string, index: number = 0): Promise<void> {\n this.logger.info('删除已发布文章', { article_id: articleId, index });\n await this.wechatClient.publish.delete(articleId, index);\n this.logger.info('已发布文章删除成功');\n }\n\n async getStatus(publishId: string): Promise<PublishStatus> {\n return await this.wechatClient.publish.getStatus(publishId);\n }\n}\n","import { DatabaseManager } from '../infrastructure/database/DatabaseManager';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface WrapperConfig {\n enabled: boolean;\n header: string;\n footer: string;\n version: number;\n}\n\nexport interface WrapperVersion {\n id: number;\n version: number;\n enabled: number;\n header: string;\n footer: string;\n author: string;\n created_at: string;\n}\n\nexport class WrapperService {\n private dbManager: DatabaseManager;\n private logger: Logger;\n\n constructor(dbManager: DatabaseManager, logger: Logger) {\n this.dbManager = dbManager;\n this.logger = logger;\n }\n\n /**\n * 加载默认配置\n */\n private loadDefaultConfig(): { enabled: boolean; header: string; footer: string } | null {\n try {\n // __dirname 在打包后是 dist/services,需要计算正确路径\n // 全局安装时: /usr/local/lib/node_modules/wechat-md-publisher/dist/services\n // 相对路径到 config: ../config/default-wrapper.json\n const distServicesDir = __dirname;\n const possiblePaths = [\n // 全局安装: node_modules/wechat-md-publisher/dist/services -> node_modules/wechat-md-publisher/config/\n resolve(distServicesDir, '../config/default-wrapper.json'),\n // 本地开发/项目内: 项目根目录/config/\n resolve(process.cwd(), 'config/default-wrapper.json'),\n ];\n \n for (const configPath of possiblePaths) {\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content);\n this.logger.debug('成功加载默认配置', { \n configPath,\n headerLength: config.header?.length || 0,\n footerLength: config.footer?.length || 0\n });\n return config;\n }\n }\n \n this.logger.warn('默认配置文件不存在', { \n triedPaths: possiblePaths,\n __dirname: distServicesDir\n });\n } catch (error) {\n this.logger.warn('无法加载默认 wrapper 配置', { error });\n }\n return null;\n }\n\n /**\n * 初始化默认内容(如果数据库为空)\n * 注意:首次使用时会自动插入默认配置(默认为关闭状态)\n */\n private initializeDefaultIfNeeded(): void {\n const db = this.dbManager.getDatabase();\n const result = db.exec('SELECT COUNT(*) as count FROM wrapper_versions');\n \n if (result.length > 0 && result[0].values[0][0] === 0) {\n // 数据库为空,加载默认配置(默认为关闭状态)\n const defaultConfig = this.loadDefaultConfig();\n if (!defaultConfig) {\n throw new Error('无法加载默认 wrapper 配置文件,请确保 config/default-wrapper.json 存在');\n }\n \n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (1, 0, ?, ?, 'system')\n `, [\n defaultConfig.header,\n defaultConfig.footer\n ]);\n this.dbManager.save();\n this.logger.info('已初始化默认 wrapper 配置(关闭状态)', {\n headerLength: defaultConfig.header.length,\n footerLength: defaultConfig.footer.length\n });\n }\n }\n\n /**\n * 获取当前 Wrapper 配置\n */\n get(): WrapperConfig {\n this.initializeDefaultIfNeeded();\n const db = this.dbManager.getDatabase();\n const result = db.exec(`\n SELECT version, enabled, header, footer \n FROM wrapper_versions \n ORDER BY version DESC \n LIMIT 1\n `);\n\n if (!result.length || !result[0].values.length) {\n return {\n enabled: false,\n header: '',\n footer: '',\n version: 0\n };\n }\n\n const row = result[0].values[0];\n return {\n enabled: row[1] === 1,\n header: row[2] || '',\n footer: row[3] || '',\n version: row[0] as number\n };\n }\n\n /**\n * 开启 Wrapper\n */\n enable(): void {\n const config = this.get();\n if (config.enabled) {\n this.logger.info('Wrapper 已经开启');\n return;\n }\n\n const db = this.dbManager.getDatabase();\n // 直接更新状态为 enabled(get() 已经确保数据存在)\n if (config.version > 0) {\n db.run(`\n UPDATE wrapper_versions \n SET enabled = 1 \n WHERE version = ?\n `, [config.version]);\n } else {\n // 理论上不应该走到这里,因为 get() 会调用 initializeDefaultIfNeeded()\n throw new Error('无法开启 Wrapper:数据库未初始化');\n }\n\n this.dbManager.save();\n this.logger.info('Wrapper 已开启');\n }\n\n /**\n * 关闭 Wrapper\n */\n disable(): void {\n const config = this.get();\n if (!config.enabled) {\n this.logger.info('Wrapper 已经关闭');\n return;\n }\n\n const db = this.dbManager.getDatabase();\n db.run(`\n UPDATE wrapper_versions \n SET enabled = 0 \n WHERE version = ?\n `, [config.version]);\n\n this.dbManager.save();\n this.logger.info('Wrapper 已关闭');\n }\n\n /**\n * 更新 Wrapper 内容(创建新版本)\n */\n update(header: string, footer: string, author: string = 'system'): void {\n const db = this.dbManager.getDatabase();\n const current = this.get();\n const newVersion = current.version + 1;\n\n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (?, ?, ?, ?, ?)\n `, [newVersion, current.enabled ? 1 : 0, header, footer, author]);\n\n this.dbManager.save();\n this.logger.info('Wrapper 内容已更新', { version: newVersion });\n }\n\n /**\n * 获取历史版本\n */\n history(): WrapperVersion[] {\n const db = this.dbManager.getDatabase();\n const result = db.exec(`\n SELECT * FROM wrapper_versions \n ORDER BY version DESC\n `);\n\n if (!result.length || !result[0].values.length) {\n return [];\n }\n\n return result[0].values.map(row => ({\n id: row[0] as number,\n version: row[1] as number,\n enabled: row[2] as number,\n header: row[3] as string,\n footer: row[4] as string,\n author: row[5] as string,\n created_at: row[6] as string\n }));\n }\n\n /**\n * 回滚到指定版本\n */\n rollback(targetVersion: number, author: string = 'system'): void {\n const db = this.dbManager.getDatabase();\n const current = this.get();\n \n const result = db.exec(`\n SELECT * FROM wrapper_versions WHERE version = ?\n `, [targetVersion]);\n\n if (!result.length || !result[0].values.length) {\n throw new Error(`版本 ${targetVersion} 不存在`);\n }\n\n const target = result[0].values[0];\n const newVersion = current.version + 1;\n\n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (?, ?, ?, ?, ?)\n `, [newVersion, target[2], target[3], target[4], author]);\n\n this.dbManager.save();\n this.logger.info('已回滚到指定版本', { \n from: current.version, \n to: targetVersion,\n newVersion \n });\n }\n\n /**\n * 将内容包装到文章中\n */\n wrapContent(content: string): string {\n const config = this.get();\n \n if (!config.enabled) {\n return content;\n }\n\n let result = content;\n\n // 插入头部\n if (config.header) {\n result = config.header + '\\n' + result;\n }\n\n // 插入尾部\n if (config.footer) {\n result = result + '\\n' + config.footer;\n }\n\n return result;\n }\n}\n","import { ConfigStore } from './infrastructure/config/ConfigStore';\nimport { TokenCache } from './infrastructure/cache/TokenCache';\nimport { ImageCache } from './infrastructure/cache/ImageCache';\nimport { ThemeCache } from './infrastructure/cache/ThemeCache';\nimport { Logger } from './infrastructure/logger/Logger';\nimport { HttpClient } from './infrastructure/http/HttpClient';\nimport { DatabaseManager } from './infrastructure/database/DatabaseManager';\nimport { WechatClient } from './core/wechat/WechatClient';\nimport { ThemeEngine } from './core/theme/ThemeEngine';\nimport { MarkdownRenderer } from './core/renderer/MarkdownRenderer';\nimport { ImageProcessor } from './core/renderer/ImageProcessor';\nimport { AccountService } from './services/AccountService';\nimport { ThemeService } from './services/ThemeService';\nimport { RenderService } from './services/RenderService';\nimport { DraftService } from './services/DraftService';\nimport { PublishService } from './services/PublishService';\nimport { WrapperService } from './services/WrapperService';\n\nclass Container {\n\n private configStore!: ConfigStore;\n private logger!: Logger;\n private httpClient!: HttpClient;\n private dbManager!: DatabaseManager;\n private tokenCache!: TokenCache;\n private imageCache!: ImageCache;\n private themeCache!: ThemeCache;\n private themeEngine!: ThemeEngine;\n private renderer!: MarkdownRenderer;\n private accountService!: AccountService;\n private themeService!: ThemeService;\n private renderService!: RenderService;\n private wrapperService!: WrapperService;\n\n async initialize(): Promise<void> {\n this.configStore = new ConfigStore();\n this.logger = new Logger();\n this.httpClient = new HttpClient(this.logger);\n this.dbManager = new DatabaseManager(this.logger);\n await this.dbManager.initialize();\n this.tokenCache = new TokenCache();\n this.imageCache = new ImageCache();\n this.themeCache = new ThemeCache();\n this.themeEngine = new ThemeEngine();\n this.renderer = new MarkdownRenderer();\n \n this.accountService = new AccountService(this.configStore, this.logger);\n this.themeService = new ThemeService(\n this.themeEngine,\n this.configStore,\n this.themeCache,\n this.logger\n );\n this.renderService = new RenderService(\n this.renderer,\n this.themeService,\n this.logger\n );\n this.wrapperService = new WrapperService(this.dbManager, this.logger);\n\n await this.themeService.initialize();\n await this.renderService.initialize();\n }\n\n getAccountService(): AccountService {\n return this.accountService;\n }\n\n getThemeService(): ThemeService {\n return this.themeService;\n }\n\n getRenderService(): RenderService {\n return this.renderService;\n }\n\n getWrapperService(): WrapperService {\n return this.wrapperService;\n }\n\n getDatabaseManager(): DatabaseManager {\n return this.dbManager;\n }\n\n async getDraftService(): Promise<DraftService> {\n const account = await this.accountService.getCurrentAccount();\n const wechatClient = new WechatClient(\n account.appId,\n account.appSecret,\n this.httpClient,\n this.tokenCache,\n this.logger\n );\n\n const imageProcessor = new ImageProcessor(\n wechatClient.material,\n this.imageCache,\n this.logger\n );\n\n return new DraftService(\n wechatClient,\n this.renderService,\n imageProcessor,\n this.wrapperService,\n this.logger\n );\n }\n\n async getPublishService(): Promise<PublishService> {\n const draftService = await this.getDraftService();\n const account = await this.accountService.getCurrentAccount();\n const wechatClient = new WechatClient(\n account.appId,\n account.appSecret,\n this.httpClient,\n this.tokenCache,\n this.logger\n );\n\n return new PublishService(\n wechatClient,\n draftService,\n this.logger\n );\n }\n}\n\nexport const container = new Container();\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function createAccountCommand(): Command {\n const cmd = new Command('account')\n .description('账号管理');\n\n cmd.command('add')\n .description('添加微信公众号账号')\n .requiredOption('--name <name>', '账号名称')\n .requiredOption('--app-id <appId>', '微信公众号 AppID')\n .requiredOption('--app-secret <appSecret>', '微信公众号 AppSecret')\n .option('--default', '设为默认账号')\n .action(async (options) => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n\n const account = await accountService.addAccount({\n name: options.name,\n appId: options.appId,\n appSecret: options.appSecret,\n isDefault: options.default,\n });\n\n console.log(chalk.green('✓ 账号添加成功'));\n console.log(` ID: ${account.id}`);\n console.log(` 名称: ${account.name}`);\n console.log(` AppID: ${account.appId}`);\n console.log(` 默认账号: ${account.isDefault ? '是' : '否'}`);\n } catch (error: any) {\n console.error(chalk.red('✗ 添加账号失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('list')\n .description('列出所有账号')\n .action(async () => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n const accounts = await accountService.listAccounts();\n\n if (accounts.length === 0) {\n console.log(chalk.yellow('未配置账号'));\n console.log('使用 account add 命令添加账号');\n return;\n }\n\n const table = new Table({\n head: ['ID', '名称', 'AppID', '默认'],\n colWidths: [25, 20, 20, 8],\n });\n\n accounts.forEach(account => {\n table.push([\n account.id,\n account.name,\n account.appId,\n account.isDefault ? chalk.green('是') : '否',\n ]);\n });\n\n console.log(table.toString());\n } catch (error: any) {\n console.error(chalk.red('✗ 获取账号列表失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('switch <id>')\n .description('切换默认账号')\n .action(async (id) => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n await accountService.setDefaultAccount(id);\n console.log(chalk.green('✓ 默认账号切换成功'));\n } catch (error: any) {\n console.error(chalk.red('✗ 切换账号失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('remove <id>')\n .description('删除账号')\n .action(async (id) => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n await accountService.removeAccount(id);\n console.log(chalk.green('✓ 账号删除成功'));\n } catch (error: any) {\n console.error(chalk.red('✗ 删除账号失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function createThemeCommand(): Command {\n const cmd = new Command('theme')\n .description('主题管理');\n\n cmd.command('list')\n .description('列出所有可用主题')\n .action(async () => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n const themes = await themeService.listThemes();\n\n if (themes.length === 0) {\n console.log(chalk.yellow('未找到主题'));\n return;\n }\n\n const table = new Table({\n head: ['ID', '名称', '类型', '描述'],\n colWidths: [20, 25, 12, 40],\n });\n\n themes.forEach(theme => {\n const typeColor = theme.type === 'builtin' ? chalk.green :\n theme.type === 'local' ? chalk.blue :\n theme.type === 'remote' ? chalk.magenta : chalk.gray;\n \n table.push([\n theme.id,\n theme.name,\n typeColor(theme.type),\n theme.description || '-',\n ]);\n });\n\n console.log(table.toString());\n console.log(`\\n总计: ${themes.length} 个主题`);\n } catch (error: any) {\n console.error(chalk.red('✗ 获取主题列表失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('add-local')\n .description('添加本地主题')\n .requiredOption('--name <name>', '主题名称')\n .requiredOption('--path <path>', '主题 CSS 文件路径')\n .action(async (options) => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n \n await themeService.addLocalTheme(options.name, options.path);\n \n console.log(chalk.green('✓ 本地主题添加成功'));\n console.log(` 名称: ${options.name}`);\n console.log(` 路径: ${options.path}`);\n } catch (error: any) {\n console.error(chalk.red('✗ 添加本地主题失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('add-remote')\n .description('添加远程主题 API')\n .requiredOption('--name <name>', 'API 名称')\n .requiredOption('--url <url>', 'API URL')\n .requiredOption('--key <key>', 'API Key')\n .action(async (options) => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n \n await themeService.addRemoteAPI(options.name, options.url, options.key);\n \n console.log(chalk.green('✓ 远程主题 API 添加成功'));\n console.log(` 名称: ${options.name}`);\n console.log(` URL: ${options.url}`);\n } catch (error: any) {\n console.error(chalk.red('✗ 添加远程主题 API 失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('remove <theme-id>')\n .description('删除主题')\n .action(async (themeId) => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n \n await themeService.removeTheme(themeId);\n \n console.log(chalk.green('✓ 主题删除成功'));\n } catch (error: any) {\n console.error(chalk.red('✗ 删除主题失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport ora from 'ora';\n\nexport function createDraftCommand(): Command {\n const cmd = new Command('draft')\n .description('草稿管理');\n\n cmd.command('create')\n .description('创建草稿')\n .requiredOption('-f, --file <file>', 'Markdown 文件路径')\n .option('-t, --theme <theme>', '主题 ID')\n .action(async (options) => {\n const spinner = ora('正在创建草稿...').start();\n \n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n const result = await draftService.create({\n file: options.file,\n theme: options.theme,\n });\n \n spinner.succeed('草稿创建成功');\n console.log(chalk.green(` Media ID: ${result.media_id}`));\n console.log(chalk.gray(' 提示: 使用 publish 命令发布此草稿'));\n } catch (error: any) {\n spinner.fail('创建草稿失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('list')\n .description('列出草稿')\n .option('-p, --page <page>', '页码', '1')\n .option('-s, --size <size>', '每页数量', '20')\n .action(async (options) => {\n const spinner = ora('正在获取草稿列表...').start();\n \n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n const page = parseInt(options.page);\n const size = parseInt(options.size);\n const result = await draftService.list(page, size);\n \n spinner.stop();\n \n if (!result.item || result.item.length === 0) {\n console.log(chalk.yellow('暂无草稿'));\n return;\n }\n\n const table = new Table({\n head: ['Media ID', '标题', '更新时间'],\n colWidths: [35, 40, 20],\n });\n\n result.item.forEach(draft => {\n const article = draft.content.news_item[0];\n const updateTime = new Date(draft.update_time * 1000).toLocaleString('zh-CN');\n \n table.push([\n draft.media_id,\n article.title || '-',\n updateTime,\n ]);\n });\n\n console.log(table.toString());\n console.log(`\\n总计: ${result.total_count} 个草稿 (第 ${page} 页)`);\n } catch (error: any) {\n spinner.fail('获取草稿列表失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('delete <media-id>')\n .description('删除草稿')\n .action(async (mediaId) => {\n const spinner = ora('正在删除草稿...').start();\n \n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n await draftService.delete(mediaId);\n \n spinner.succeed('草稿删除成功');\n } catch (error: any) {\n spinner.fail('删除草稿失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('count')\n .description('获取草稿总数')\n .action(async () => {\n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n const count = await draftService.count();\n \n console.log(chalk.green(`草稿总数: ${count}`));\n } catch (error: any) {\n console.error(chalk.red('✗ 获取草稿总数失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport ora from 'ora';\n\nexport function createPublishCommand(): Command {\n const cmd = new Command('publish')\n .description('发布管理');\n\n cmd.command('submit <media-id>')\n .description('发布草稿')\n .action(async (mediaId) => {\n const spinner = ora('正在发布草稿...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const result = await publishService.submit(mediaId);\n \n spinner.succeed('发布任务提交成功');\n console.log(chalk.green(` Publish ID: ${result.publish_id}`));\n console.log(chalk.gray(' 提示: 使用 publish status 命令查看发布状态'));\n } catch (error: any) {\n spinner.fail('发布失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('create')\n .description('创建并发布文章')\n .requiredOption('-f, --file <file>', 'Markdown 文件路径')\n .option('-t, --theme <theme>', '主题 ID')\n .action(async (options) => {\n const spinner = ora('正在创建并发布文章...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const result = await publishService.createAndPublish({\n file: options.file,\n theme: options.theme,\n });\n \n spinner.succeed('文章创建并发布成功');\n console.log(chalk.green(` Publish ID: ${result.publish_id}`));\n } catch (error: any) {\n spinner.fail('创建并发布失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('list')\n .description('列出已发布文章')\n .option('-p, --page <page>', '页码', '1')\n .option('-s, --size <size>', '每页数量', '20')\n .action(async (options) => {\n const spinner = ora('正在获取已发布文章列表...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const page = parseInt(options.page);\n const size = parseInt(options.size);\n const result = await publishService.list(page, size);\n \n spinner.stop();\n \n if (!result.item || result.item.length === 0) {\n console.log(chalk.yellow('暂无已发布文章'));\n return;\n }\n\n const table = new Table({\n head: ['Article ID', '标题', '更新时间'],\n colWidths: [35, 40, 20],\n });\n\n result.item.forEach(article => {\n const newsItem = article.content.news_item[0];\n const updateTime = new Date(article.update_time * 1000).toLocaleString('zh-CN');\n \n table.push([\n article.article_id,\n newsItem.title || '-',\n updateTime,\n ]);\n });\n\n console.log(table.toString());\n console.log(`\\n总计: ${result.total_count} 篇文章 (第 ${page} 页)`);\n } catch (error: any) {\n spinner.fail('获取已发布文章列表失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('delete <article-id>')\n .description('删除已发布文章')\n .option('-i, --index <index>', '文章索引', '0')\n .action(async (articleId, options) => {\n const spinner = ora('正在删除已发布文章...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const index = parseInt(options.index);\n await publishService.delete(articleId, index);\n \n spinner.succeed('已发布文章删除成功');\n } catch (error: any) {\n spinner.fail('删除已发布文章失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('status <publish-id>')\n .description('查询发布状态')\n .action(async (publishId) => {\n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const status = await publishService.getStatus(publishId);\n \n console.log(chalk.green('发布状态:'));\n console.log(` Publish ID: ${status.publish_id}`);\n console.log(` 状态: ${status.publish_status === 0 ? '成功' : '失败'}`);\n \n if (status.article_id) {\n console.log(` Article ID: ${status.article_id}`);\n }\n \n if (status.article_detail) {\n console.log(` 文章数量: ${status.article_detail.count}`);\n }\n } catch (error: any) {\n console.error(chalk.red('✗ 查询发布状态失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function createWrapperCommand(): Command {\n const cmd = new Command('wrapper')\n .description('文章包装功能管理(开头/结尾固定图文)');\n\n // 获取当前状态\n cmd.command('status')\n .description('查看当前 Wrapper 状态')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n const config = wrapperService.get();\n\n console.log(chalk.green('当前状态:'));\n console.log(` 开关: ${config.enabled ? chalk.green('开启') : chalk.red('关闭')}`);\n console.log(` 版本: ${config.version}`);\n \n if (config.header) {\n console.log(chalk.cyan('\\n 头部内容:'));\n console.log(chalk.gray(' ' + config.header.substring(0, 100) + (config.header.length > 100 ? '...' : '')));\n }\n \n if (config.footer) {\n console.log(chalk.cyan('\\n 尾部内容:'));\n console.log(chalk.gray(' ' + config.footer.substring(0, 100) + (config.footer.length > 100 ? '...' : '')));\n }\n } catch (error: any) {\n console.error(chalk.red('✗ 获取状态失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 开启\n cmd.command('on')\n .description('开启 Wrapper 功能')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n wrapperService.enable();\n console.log(chalk.green('✓ Wrapper 已开启'));\n } catch (error: any) {\n console.error(chalk.red('✗ 开启失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 关闭\n cmd.command('off')\n .description('关闭 Wrapper 功能')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n wrapperService.disable();\n console.log(chalk.green('✓ Wrapper 已关闭'));\n } catch (error: any) {\n console.error(chalk.red('✗ 关闭失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 设置内容\n cmd.command('set')\n .description('更新 Wrapper 内容')\n .option('-h, --header <text>', '头部 HTML 内容')\n .option('-f, --footer <text>', '尾部 HTML 内容')\n .option('-a, --author <name>', '作者名称', 'system')\n .action(async (options) => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n \n wrapperService.update(\n options.header || '', \n options.footer || '',\n options.author\n );\n \n console.log(chalk.green('✓ Wrapper 内容已更新(创建新版本)'));\n } catch (error: any) {\n console.error(chalk.red('✗ 更新失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 查看历史\n cmd.command('history')\n .description('查看历史版本')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n const versions = wrapperService.history();\n\n if (versions.length === 0) {\n console.log(chalk.yellow('暂无历史版本'));\n return;\n }\n\n const table = new Table({\n head: ['版本', '状态', '作者', '创建时间'],\n colWidths: [10, 10, 15, 20],\n });\n\n versions.forEach(v => {\n table.push([\n `v${v.version}`,\n v.enabled ? chalk.green('开启') : chalk.red('关闭'),\n v.author,\n new Date(v.created_at).toLocaleString('zh-CN'),\n ]);\n });\n\n console.log(table.toString());\n } catch (error: any) {\n console.error(chalk.red('✗ 获取历史失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 回滚\n cmd.command('rollback <version>')\n .description('回滚到指定版本')\n .option('-a, --author <name>', '作者名称', 'system')\n .action(async (versionStr, options) => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n \n const version = parseInt(versionStr);\n wrapperService.rollback(version, options.author);\n \n console.log(chalk.green(`✓ 已回滚到 v${version}`));\n } catch (error: any) {\n console.error(chalk.red('✗ 回滚失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createAccountCommand } from './commands/account';\nimport { createThemeCommand } from './commands/theme';\nimport { createDraftCommand } from './commands/draft';\nimport { createPublishCommand } from './commands/publish';\nimport { createWrapperCommand } from './commands/wrapper';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\nconst program = new Command();\n\nprogram\n .name('wechat-pub')\n .description('全功能微信公众号 Markdown 发布工具')\n .version(packageJson.version);\n\nprogram.addCommand(createAccountCommand());\nprogram.addCommand(createThemeCommand());\nprogram.addCommand(createDraftCommand());\nprogram.addCommand(createPublishCommand());\nprogram.addCommand(createWrapperCommand());\n\nprogram.parse();\n"],"names":["__filename","__dirname"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/infrastructure/cache/CacheStore.ts","../src/infrastructure/cache/TokenCache.ts","../src/infrastructure/cache/ImageCache.ts","../src/infrastructure/cache/ThemeCache.ts","../src/infrastructure/http/HttpClient.ts","../src/infrastructure/database/DatabaseManager.ts","../src/utils/image.ts","../src/utils/crypto.ts","../src/utils/file.ts","../src/core/renderer/ImageProcessor.ts","../src/services/AccountService.ts","../src/services/ThemeService.ts","../src/services/RenderService.ts","../src/services/DraftService.ts","../src/services/PublishService.ts","../src/services/WrapperService.ts","../src/container.ts","../src/cli/commands/account.ts","../src/cli/commands/theme.ts","../src/cli/commands/draft.ts","../src/cli/commands/publish.ts","../src/cli/commands/wrapper.ts","../src/cli/index.ts"],"sourcesContent":["export interface CacheEntry<T> {\n value: T;\n expireAt: number;\n}\n\nexport class CacheStore<T = any> {\n private cache: Map<string, CacheEntry<T>> = new Map();\n private maxSize: number;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n }\n\n async get(key: string): Promise<T | null> {\n const entry = this.cache.get(key);\n \n if (!entry) {\n return null;\n }\n\n if (Date.now() > entry.expireAt) {\n this.cache.delete(key);\n return null;\n }\n\n return entry.value;\n }\n\n async set(key: string, value: T, ttl: number = 3600): Promise<void> {\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, {\n value,\n expireAt: Date.now() + ttl * 1000,\n });\n }\n\n async has(key: string): Promise<boolean> {\n const value = await this.get(key);\n return value !== null;\n }\n\n async delete(key: string): Promise<void> {\n this.cache.delete(key);\n }\n\n async clear(): Promise<void> {\n this.cache.clear();\n }\n\n async size(): Promise<number> {\n return this.cache.size;\n }\n}\n","import { CacheStore } from './CacheStore';\n\nexport interface TokenCacheEntry {\n access_token: string;\n expires_in: number;\n}\n\nexport class TokenCache extends CacheStore<TokenCacheEntry> {\n constructor() {\n super(10);\n }\n\n async getToken(appId: string): Promise<string | null> {\n const entry = await this.get(appId);\n return entry ? entry.access_token : null;\n }\n\n async setToken(appId: string, accessToken: string, expiresIn: number): Promise<void> {\n await this.set(\n appId,\n {\n access_token: accessToken,\n expires_in: expiresIn,\n },\n expiresIn - 200\n );\n }\n}\n","import { CacheStore } from './CacheStore';\n\nexport interface ImageCacheEntry {\n media_id: string;\n url: string;\n}\n\nexport class ImageCache extends CacheStore<ImageCacheEntry> {\n constructor() {\n super(500);\n }\n\n async getMediaId(md5: string): Promise<string | null> {\n const entry = await this.get(md5);\n return entry ? entry.media_id : null;\n }\n\n async setImage(md5: string, mediaId: string, url: string, ttl: number = 86400): Promise<void> {\n await this.set(\n md5,\n {\n media_id: mediaId,\n url,\n },\n ttl\n );\n }\n}\n","import { CacheStore } from './CacheStore';\n\nexport class ThemeCache extends CacheStore<string> {\n constructor() {\n super(50);\n }\n\n async getThemeCSS(themeId: string): Promise<string | null> {\n return await this.get(themeId);\n }\n\n async setThemeCSS(themeId: string, css: string, ttl: number = 3600): Promise<void> {\n await this.set(themeId, css, ttl);\n }\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { Logger } from '../logger/Logger';\n\nexport class HttpClient {\n private client: AxiosInstance;\n\n constructor(private logger: Logger) {\n this.client = axios.create({\n timeout: 30000,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n this.setupInterceptors();\n }\n\n private setupInterceptors(): void {\n this.client.interceptors.request.use(\n (config) => {\n this.logger.debug('HTTP Request', {\n method: config.method,\n url: config.url,\n });\n return config;\n },\n (error) => {\n this.logger.error('HTTP Request Error', { error: error.message });\n return Promise.reject(error);\n }\n );\n\n this.client.interceptors.response.use(\n (response) => {\n this.logger.debug('HTTP Response', {\n status: response.status,\n url: response.config.url,\n });\n return response;\n },\n (error) => {\n this.logger.error('HTTP Response Error', {\n status: error.response?.status,\n message: error.message,\n });\n return Promise.reject(error);\n }\n );\n }\n\n async get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.get<T>(url, config);\n }\n\n async post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.post<T>(url, data, config);\n }\n\n async put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.put<T>(url, data, config);\n }\n\n async delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> {\n return this.client.delete<T>(url, config);\n }\n}\n","import initSqlJs, { Database } from 'sql.js';\nimport { Logger } from '../logger/Logger';\nimport { resolve } from 'path';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\n\nexport class DatabaseManager {\n private db!: Database;\n private logger: Logger;\n private dbPath!: string;\n\n constructor(logger: Logger) {\n this.logger = logger;\n }\n\n async initialize(dbPath?: string): Promise<void> {\n const dataDir = resolve(process.cwd(), 'data');\n \n // 确保 data 目录存在\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n\n this.dbPath = dbPath || resolve(dataDir, 'wmp.db');\n this.logger.info('初始化数据库', { path: this.dbPath });\n\n // 初始化 SQL.js\n const SQL = await initSqlJs();\n\n // 加载已存在的数据库或创建新的\n if (existsSync(this.dbPath)) {\n const fileBuffer = readFileSync(this.dbPath);\n this.db = new SQL.Database(fileBuffer);\n } else {\n this.db = new SQL.Database();\n }\n \n this.initTables();\n this.save();\n }\n\n private initTables(): void {\n // Wrapper 版本表\n this.db.run(`\n CREATE TABLE IF NOT EXISTS wrapper_versions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n version INTEGER NOT NULL,\n enabled INTEGER DEFAULT 0,\n header TEXT,\n footer TEXT,\n author TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )\n `);\n\n // 发布的文章记录表\n this.db.run(`\n CREATE TABLE IF NOT EXISTS published_articles (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n title TEXT NOT NULL,\n url TEXT,\n author TEXT,\n published_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n article_id TEXT,\n media_id TEXT\n )\n `);\n\n // 配置表\n this.db.run(`\n CREATE TABLE IF NOT EXISTS config (\n key TEXT PRIMARY KEY,\n value TEXT\n )\n `);\n\n this.logger.info('数据库表初始化完成');\n }\n\n save(): void {\n const data = this.db.export();\n const buffer = Buffer.from(data);\n writeFileSync(this.dbPath, buffer);\n }\n\n getDatabase(): Database {\n return this.db;\n }\n\n close(): void {\n if (this.db) {\n this.save();\n this.db.close();\n }\n }\n}\n","import { readFile } from 'fs/promises';\nimport axios from 'axios';\n\nexport async function downloadImage(url: string): Promise<Buffer> {\n try {\n const response = await axios.get(url, {\n responseType: 'arraybuffer',\n timeout: 30000,\n });\n \n if (!response.data || response.data.byteLength === 0) {\n throw new Error('下载的图片大小为 0');\n }\n \n return Buffer.from(response.data);\n } catch (error) {\n throw new Error(`下载图片失败: ${url}`);\n }\n}\n\nexport async function readImageFile(filePath: string): Promise<Buffer> {\n try {\n const buffer = await readFile(filePath);\n \n if (buffer.length === 0) {\n throw new Error('图片文件大小为 0');\n }\n \n return buffer;\n } catch (error) {\n throw new Error(`读取图片文件失败: ${filePath}`);\n }\n}\n\nexport function isRemoteUrl(url: string): boolean {\n return url.startsWith('http://') || url.startsWith('https://');\n}\n\nexport function isWechatImageUrl(url: string): boolean {\n return url.startsWith('https://mmbiz.qpic.cn');\n}\n\nexport function getImageFilename(url: string): string {\n const urlWithoutQuery = url.split('?')[0];\n const parts = urlWithoutQuery.split('/');\n const filename = parts[parts.length - 1];\n \n const ext = filename.match(/\\.(jpg|jpeg|png|gif|webp|bmp)$/i);\n if (!ext) {\n return `${filename}.jpg`;\n }\n \n return filename;\n}\n","import { createHash } from 'crypto';\nimport { readFile } from 'fs/promises';\n\nexport function md5FromBuffer(buffer: Buffer): string {\n return createHash('md5').update(buffer).digest('hex');\n}\n\nexport function md5FromString(str: string): string {\n return createHash('md5').update(str).digest('hex');\n}\n\nexport async function md5FromFile(filePath: string): Promise<string> {\n const buffer = await readFile(filePath);\n return md5FromBuffer(buffer);\n}\n\nexport function generateId(prefix: string = ''): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return prefix ? `${prefix}_${timestamp}_${random}` : `${timestamp}_${random}`;\n}\n","import { readFile, writeFile, access, mkdir } from 'fs/promises';\nimport { dirname, resolve, isAbsolute } from 'path';\nimport { constants } from 'fs';\n\nexport async function readFileContent(filePath: string): Promise<string> {\n try {\n return await readFile(filePath, 'utf-8');\n } catch (error) {\n throw new Error(`无法读取文件: ${filePath}`);\n }\n}\n\nexport async function writeFileContent(filePath: string, content: string): Promise<void> {\n try {\n const dir = dirname(filePath);\n await mkdir(dir, { recursive: true });\n await writeFile(filePath, content, 'utf-8');\n } catch (error) {\n throw new Error(`无法写入文件: ${filePath}`);\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function resolvePath(filePath: string, basePath?: string): string {\n if (isAbsolute(filePath)) {\n return filePath;\n }\n \n if (basePath) {\n return resolve(basePath, filePath);\n }\n \n return resolve(process.cwd(), filePath);\n}\n\nexport function getFileExtension(filePath: string): string {\n const match = filePath.match(/\\.([^.]+)$/);\n return match ? match[1].toLowerCase() : '';\n}\n\nexport function isImageFile(filePath: string): boolean {\n const ext = getFileExtension(filePath);\n return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'].includes(ext);\n}\n","import { JSDOM } from 'jsdom';\nimport { MaterialAPI } from '../wechat/api/MaterialAPI';\nimport { ImageCache } from '../../infrastructure/cache/ImageCache';\nimport { Logger } from '../../infrastructure/logger/Logger';\nimport { downloadImage, readImageFile, isRemoteUrl, isWechatImageUrl, getImageFilename } from '../../utils/image';\nimport { md5FromBuffer } from '../../utils/crypto';\nimport { resolvePath } from '../../utils/file';\n\nexport interface ProcessImagesResult {\n content: string;\n firstImageMediaId: string;\n firstImageUrl: string;\n}\n\nexport class ImageProcessor {\n constructor(\n private materialAPI: MaterialAPI,\n private imageCache: ImageCache,\n private logger: Logger\n ) {}\n\n async processImages(content: string, relativePath?: string): Promise<ProcessImagesResult> {\n if (!content.includes('<img')) {\n return { content, firstImageMediaId: '', firstImageUrl: '' };\n }\n\n const dom = new JSDOM(content);\n const images = dom.window.document.querySelectorAll('img');\n \n const uploadPromises = Array.from(images).map(async (element: any) => {\n const src = element.getAttribute('src');\n if (!src) return null;\n\n if (isWechatImageUrl(src)) {\n return { media_id: src, url: src };\n }\n\n try {\n const result = await this.uploadImage(src, relativePath);\n element.setAttribute('src', result.url);\n return result;\n } catch (error) {\n this.logger.warn('图片上传失败', { src, error });\n return null;\n }\n });\n\n const results = (await Promise.all(uploadPromises)).filter(Boolean) as { media_id: string; url: string }[];\n \n const firstImage = results[0];\n const firstImageMediaId = firstImage?.media_id || '';\n const firstImageUrl = firstImage?.url || '';\n\n return {\n content: dom.serialize(),\n firstImageMediaId,\n firstImageUrl,\n };\n }\n\n /**\n * 从 HTML 内容中提取第一张图片\n */\n extractFirstImageFromContent(content: string): string | null {\n if (!content || !content.includes('<img')) {\n return null;\n }\n\n try {\n const dom = new JSDOM(content);\n const firstImg = dom.window.document.querySelector('img');\n return firstImg?.getAttribute('src') || null;\n } catch (error) {\n this.logger.warn('提取第一张图片失败', { error });\n return null;\n }\n }\n\n async uploadImage(imagePath: string, relativePath?: string): Promise<{ media_id: string; url: string }> {\n let buffer: Buffer;\n let filename: string;\n\n if (isRemoteUrl(imagePath)) {\n this.logger.info('下载远程图片', { url: imagePath });\n buffer = await downloadImage(imagePath);\n filename = getImageFilename(imagePath);\n } else {\n const resolvedPath = resolvePath(imagePath, relativePath);\n this.logger.info('读取本地图片', { path: resolvedPath });\n buffer = await readImageFile(resolvedPath);\n filename = getImageFilename(resolvedPath);\n }\n\n const md5 = md5FromBuffer(buffer);\n const cached = await this.imageCache.getMediaId(md5);\n if (cached) {\n this.logger.debug('使用缓存的图片', { md5 });\n const cachedEntry = await this.imageCache.get(md5);\n return { media_id: cached, url: cachedEntry!.url };\n }\n\n const result = await this.materialAPI.uploadImage(buffer, filename);\n await this.imageCache.setImage(md5, result.media_id, result.url);\n\n this.logger.info('图片上传成功', { media_id: result.media_id });\n return result;\n }\n\n /**\n * 上传封面图\n * 优先级:\n * 1. coverPath(显式指定的封面)\n * 2. fallbackMediaId(从正文第一张图片传来的 media_id)\n * 3. 从 content 中提取第一张图片并上传\n */\n async uploadCover(\n coverPath: string | undefined, \n relativePath: string | undefined, \n fallbackMediaId: string | undefined,\n content?: string\n ): Promise<string> {\n this.logger.debug('开始处理封面', { \n hasCoverPath: !!coverPath, \n hasFallbackMediaId: !!fallbackMediaId,\n hasContent: !!content \n });\n\n // 优先级 1: 显式指定的封面\n if (coverPath) {\n try {\n if (isWechatImageUrl(coverPath)) {\n // 微信图片直接返回\n this.logger.info('使用微信图片作为封面', { coverPath });\n return coverPath;\n }\n\n const result = await this.uploadImage(coverPath, relativePath);\n this.logger.info('封面上传成功(显式指定)', { media_id: result.media_id });\n return result.media_id;\n } catch (error) {\n this.logger.warn('显式封面图上传失败,继续尝试 fallback', { coverPath, error });\n }\n }\n\n // 优先级 2: fallback media_id(正文第一张图片)\n if (fallbackMediaId) {\n this.logger.info('使用正文第一张图片作为封面', { media_id: fallbackMediaId });\n return fallbackMediaId;\n }\n\n // 优先级 3: 从 content 中提取第一张图片\n if (content) {\n const firstImageSrc = this.extractFirstImageFromContent(content);\n if (firstImageSrc) {\n try {\n this.logger.info('尝试从正文提取第一张图片作为封面', { src: firstImageSrc });\n const result = await this.uploadImage(firstImageSrc, relativePath);\n this.logger.info('封面上传成功(从正文提取)', { media_id: result.media_id });\n return result.media_id;\n } catch (error) {\n this.logger.warn('从正文提取封面上传失败', { src: firstImageSrc, error });\n }\n }\n }\n\n // 所有尝试都失败\n throw new Error('无法获取封面图:请在 Markdown 中添加 cover: 图片路径,或确保正文中包含图片');\n }\n}\n","import { ConfigStore } from '../infrastructure/config/ConfigStore';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { Account, AccountCreateOptions } from '../types/account';\nimport { generateId } from '../utils/crypto';\n\nexport class AccountService {\n constructor(\n private configStore: ConfigStore,\n private logger: Logger\n ) {}\n\n async addAccount(options: AccountCreateOptions): Promise<Account> {\n this.logger.info('添加账号', { name: options.name });\n\n const accounts = await this.listAccounts();\n \n const existingAccount = accounts.find(a => a.appId === options.appId);\n if (existingAccount) {\n throw new Error(`账号已存在: ${existingAccount.name}`);\n }\n\n const account: Account = {\n id: generateId('acc'),\n name: options.name,\n appId: options.appId,\n appSecret: options.appSecret,\n isDefault: options.isDefault || accounts.length === 0,\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n\n if (account.isDefault) {\n accounts.forEach(a => a.isDefault = false);\n }\n\n accounts.push(account);\n this.configStore.set('accounts', accounts);\n\n this.logger.info('账号添加成功', { id: account.id, name: account.name });\n return account;\n }\n\n async listAccounts(): Promise<Account[]> {\n return this.configStore.get('accounts', []);\n }\n\n async getAccount(id: string): Promise<Account | null> {\n const accounts = await this.listAccounts();\n return accounts.find(a => a.id === id) || null;\n }\n\n async getCurrentAccount(): Promise<Account> {\n const accounts = await this.listAccounts();\n \n if (accounts.length === 0) {\n throw new Error('未配置账号,请先使用 account add 命令添加账号');\n }\n\n const defaultAccount = accounts.find(a => a.isDefault);\n if (defaultAccount) {\n return defaultAccount;\n }\n\n return accounts[0];\n }\n\n async setDefaultAccount(id: string): Promise<void> {\n this.logger.info('设置默认账号', { id });\n\n const accounts = await this.listAccounts();\n const account = accounts.find(a => a.id === id);\n\n if (!account) {\n throw new Error(`账号不存在: ${id}`);\n }\n\n accounts.forEach(a => {\n a.isDefault = a.id === id;\n if (a.id === id) {\n a.updatedAt = new Date();\n }\n });\n\n this.configStore.set('accounts', accounts);\n this.logger.info('默认账号设置成功', { name: account.name });\n }\n\n async removeAccount(id: string): Promise<void> {\n this.logger.info('删除账号', { id });\n\n const accounts = await this.listAccounts();\n const account = accounts.find(a => a.id === id);\n\n if (!account) {\n throw new Error(`账号不存在: ${id}`);\n }\n\n const filtered = accounts.filter(a => a.id !== id);\n\n if (account.isDefault && filtered.length > 0) {\n filtered[0].isDefault = true;\n }\n\n this.configStore.set('accounts', filtered);\n this.logger.info('账号删除成功', { name: account.name });\n }\n\n async updateAccount(id: string, updates: Partial<Account>): Promise<Account> {\n this.logger.info('更新账号', { id });\n\n const accounts = await this.listAccounts();\n const account = accounts.find(a => a.id === id);\n\n if (!account) {\n throw new Error(`账号不存在: ${id}`);\n }\n\n Object.assign(account, updates, { updatedAt: new Date() });\n this.configStore.set('accounts', accounts);\n\n this.logger.info('账号更新成功', { name: account.name });\n return account;\n }\n}\n","import { ThemeEngine } from '../core/theme/ThemeEngine';\nimport { ConfigStore } from '../infrastructure/config/ConfigStore';\nimport { ThemeCache } from '../infrastructure/cache/ThemeCache';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { ThemeSource } from '../types/theme';\n\nexport class ThemeService {\n constructor(\n private themeEngine: ThemeEngine,\n private configStore: ConfigStore,\n private themeCache: ThemeCache,\n private logger: Logger\n ) {}\n\n async initialize(): Promise<void> {\n this.logger.info('初始化主题系统');\n\n await this.themeEngine.loadBuiltinThemes();\n\n const config = this.configStore.get('themes');\n if (!config) {\n return;\n }\n\n if (config.local) {\n for (const theme of config.local) {\n try {\n await this.themeEngine.addLocalTheme(theme.name, theme.path);\n } catch (error) {\n this.logger.warn('加载本地主题失败', { name: theme.name, error });\n }\n }\n }\n\n if (config.remote) {\n for (const remote of config.remote) {\n if (remote.enabled) {\n try {\n await this.themeEngine.addRemoteAPI(remote.name, remote.apiUrl, remote.apiKey);\n } catch (error) {\n this.logger.warn('添加远程主题 API 失败', { name: remote.name, error });\n }\n }\n }\n }\n\n this.logger.info('主题系统初始化完成');\n }\n\n async listThemes(): Promise<ThemeSource[]> {\n return await this.themeEngine.listThemes();\n }\n\n async getThemeCSS(themeId: string): Promise<string> {\n const cached = await this.themeCache.getThemeCSS(themeId);\n if (cached) {\n this.logger.debug('使用缓存的主题', { themeId });\n return cached;\n }\n\n const css = await this.themeEngine.getThemeCSS(themeId);\n await this.themeCache.setThemeCSS(themeId, css);\n\n return css;\n }\n\n async addLocalTheme(name: string, path: string): Promise<void> {\n this.logger.info('添加本地主题', { name, path });\n\n await this.themeEngine.addLocalTheme(name, path);\n\n const config = this.configStore.get('themes') || {};\n if (!config.local) {\n config.local = [];\n }\n\n const existing = config.local.find(t => t.name === name);\n if (existing) {\n existing.path = path;\n } else {\n config.local.push({ name, path });\n }\n\n this.configStore.set('themes', config);\n this.logger.info('本地主题添加成功');\n }\n\n async addRemoteAPI(name: string, apiUrl: string, apiKey: string): Promise<void> {\n this.logger.info('添加远程主题 API', { name, apiUrl });\n\n await this.themeEngine.addRemoteAPI(name, apiUrl, apiKey);\n\n const config = this.configStore.get('themes') || {};\n if (!config.remote) {\n config.remote = [];\n }\n\n const existing = config.remote.find(r => r.name === name);\n if (existing) {\n existing.apiUrl = apiUrl;\n existing.apiKey = apiKey;\n existing.enabled = true;\n } else {\n config.remote.push({ name, apiUrl, apiKey, enabled: true });\n }\n\n this.configStore.set('themes', config);\n this.logger.info('远程主题 API 添加成功');\n }\n\n async removeTheme(themeId: string): Promise<void> {\n this.logger.info('删除主题', { themeId });\n\n await this.themeEngine.removeTheme(themeId);\n await this.themeCache.delete(themeId);\n\n const config = this.configStore.get('themes') || {};\n if (config.local) {\n config.local = config.local.filter(t => t.name !== themeId);\n }\n\n this.configStore.set('themes', config);\n this.logger.info('主题删除成功');\n }\n}\n","import { MarkdownRenderer, RenderResult } from '../core/renderer/MarkdownRenderer';\nimport { ThemeService } from './ThemeService';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport { readFileContent } from '../utils/file';\n\nexport interface RenderOptions {\n markdown?: string;\n file?: string;\n theme?: string;\n}\n\nexport class RenderService {\n constructor(\n private renderer: MarkdownRenderer,\n private themeService: ThemeService,\n private logger: Logger\n ) {}\n\n async initialize(): Promise<void> {\n await this.renderer.initialize();\n }\n\n async render(options: RenderOptions): Promise<RenderResult> {\n let markdown: string;\n\n if (options.file) {\n this.logger.info('读取 Markdown 文件', { file: options.file });\n markdown = await readFileContent(options.file);\n } else if (options.markdown) {\n markdown = options.markdown;\n } else {\n throw new Error('必须提供 markdown 内容或 file 路径');\n }\n\n let themeCss: string | undefined;\n if (options.theme) {\n this.logger.info('加载主题', { theme: options.theme });\n themeCss = await this.themeService.getThemeCSS(options.theme);\n }\n\n this.logger.info('开始渲染 Markdown');\n const result = await this.renderer.render(markdown, themeCss);\n this.logger.info('Markdown 渲染完成', { title: result.title });\n\n return result;\n }\n}\n","import { WechatClient } from '../core/wechat/WechatClient';\nimport { RenderService } from './RenderService';\nimport { ImageProcessor } from '../core/renderer/ImageProcessor';\nimport { WrapperService } from './WrapperService';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { DraftCreateOptions, Draft, DraftList } from '../types/draft';\nimport { dirname } from 'path';\n\nexport class DraftService {\n constructor(\n private wechatClient: WechatClient,\n private renderService: RenderService,\n private imageProcessor: ImageProcessor,\n private wrapperService: WrapperService,\n private logger: Logger\n ) {}\n\n async create(options: DraftCreateOptions): Promise<{ media_id: string }> {\n this.logger.info('开始创建草稿', { file: options.file });\n\n const rendered = await this.renderService.render({\n markdown: options.markdown,\n file: options.file,\n theme: options.theme,\n });\n\n // 使用 Wrapper 包装内容\n let content = this.wrapperService.wrapContent(rendered.content);\n\n const relativePath = options.relativePath || (options.file ? dirname(options.file) : undefined);\n\n const { content: processedContent, firstImageMediaId } = await this.imageProcessor.processImages(\n content,\n relativePath\n );\n\n const thumbMediaId = await this.imageProcessor.uploadCover(\n rendered.cover,\n relativePath,\n firstImageMediaId,\n processedContent\n );\n\n const result = await this.wechatClient.draft.create({\n title: rendered.title,\n content: processedContent,\n thumb_media_id: thumbMediaId,\n });\n\n this.logger.info('草稿创建成功', { media_id: result.media_id });\n return result;\n }\n\n async list(page: number = 1, pageSize: number = 20): Promise<DraftList> {\n const offset = (page - 1) * pageSize;\n return await this.wechatClient.draft.list(offset, pageSize);\n }\n\n async get(mediaId: string): Promise<Draft> {\n return await this.wechatClient.draft.get(mediaId);\n }\n\n async delete(mediaId: string): Promise<void> {\n this.logger.info('删除草稿', { media_id: mediaId });\n await this.wechatClient.draft.delete(mediaId);\n this.logger.info('草稿删除成功');\n }\n\n async batchDelete(mediaIds: string[]): Promise<void> {\n this.logger.info('批量删除草稿', { count: mediaIds.length });\n\n const results = await Promise.allSettled(\n mediaIds.map(id => this.delete(id))\n );\n\n const failed = results.filter(r => r.status === 'rejected');\n if (failed.length > 0) {\n this.logger.warn('部分草稿删除失败', {\n failed: failed.length,\n total: mediaIds.length,\n });\n }\n }\n\n async count(): Promise<number> {\n return await this.wechatClient.draft.count();\n }\n}\n","import { WechatClient } from '../core/wechat/WechatClient';\nimport { DraftService } from './DraftService';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport type { PublishResult, PublishedArticle, PublishList, PublishStatus } from '../types/publish';\nimport type { DraftCreateOptions } from '../types/draft';\n\nexport class PublishService {\n constructor(\n private wechatClient: WechatClient,\n private draftService: DraftService,\n private logger: Logger\n ) {}\n\n async submit(mediaId: string): Promise<PublishResult> {\n this.logger.info('发布草稿', { media_id: mediaId });\n const result = await this.wechatClient.publish.submit(mediaId);\n this.logger.info('发布任务提交成功', { publish_id: result.publish_id });\n return result;\n }\n\n async createAndPublish(options: DraftCreateOptions): Promise<PublishResult> {\n this.logger.info('创建并发布文章');\n\n const { media_id } = await this.draftService.create(options);\n const result = await this.submit(media_id);\n\n return result;\n }\n\n async list(page: number = 1, pageSize: number = 20): Promise<PublishList> {\n const offset = (page - 1) * pageSize;\n return await this.wechatClient.publish.list(offset, pageSize);\n }\n\n async get(articleId: string): Promise<PublishedArticle> {\n return await this.wechatClient.publish.get(articleId);\n }\n\n async delete(articleId: string, index: number = 0): Promise<void> {\n this.logger.info('删除已发布文章', { article_id: articleId, index });\n await this.wechatClient.publish.delete(articleId, index);\n this.logger.info('已发布文章删除成功');\n }\n\n async getStatus(publishId: string): Promise<PublishStatus> {\n return await this.wechatClient.publish.getStatus(publishId);\n }\n}\n","import { DatabaseManager } from '../infrastructure/database/DatabaseManager';\nimport { Logger } from '../infrastructure/logger/Logger';\nimport { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport interface WrapperConfig {\n enabled: boolean;\n header: string;\n footer: string;\n version: number;\n}\n\nexport interface WrapperVersion {\n id: number;\n version: number;\n enabled: number;\n header: string;\n footer: string;\n author: string;\n created_at: string;\n}\n\nexport class WrapperService {\n private dbManager: DatabaseManager;\n private logger: Logger;\n\n constructor(dbManager: DatabaseManager, logger: Logger) {\n this.dbManager = dbManager;\n this.logger = logger;\n }\n\n /**\n * 加载默认配置\n */\n private loadDefaultConfig(): { enabled: boolean; header: string; footer: string } | null {\n try {\n // __dirname 在打包后是 dist/services,需要计算正确路径\n // 全局安装时: /usr/local/lib/node_modules/wechat-md-publisher/dist/services\n // 相对路径到 config: ../config/default-wrapper.json\n const distServicesDir = __dirname;\n const possiblePaths = [\n // 全局安装: node_modules/wechat-md-publisher/dist/services -> node_modules/wechat-md-publisher/config/\n resolve(distServicesDir, '../config/default-wrapper.json'),\n // 本地开发/项目内: 项目根目录/config/\n resolve(process.cwd(), 'config/default-wrapper.json'),\n ];\n \n for (const configPath of possiblePaths) {\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(content);\n this.logger.debug('成功加载默认配置', { \n configPath,\n headerLength: config.header?.length || 0,\n footerLength: config.footer?.length || 0\n });\n return config;\n }\n }\n \n this.logger.warn('默认配置文件不存在', { \n triedPaths: possiblePaths,\n __dirname: distServicesDir\n });\n } catch (error) {\n this.logger.warn('无法加载默认 wrapper 配置', { error });\n }\n return null;\n }\n\n /**\n * 初始化默认内容(如果数据库为空)\n * 注意:首次使用时会自动插入默认配置(默认为关闭状态)\n */\n private initializeDefaultIfNeeded(): void {\n const db = this.dbManager.getDatabase();\n const result = db.exec('SELECT COUNT(*) as count FROM wrapper_versions');\n \n if (result.length > 0 && result[0].values[0][0] === 0) {\n // 数据库为空,加载默认配置(默认为关闭状态)\n const defaultConfig = this.loadDefaultConfig();\n if (!defaultConfig) {\n throw new Error('无法加载默认 wrapper 配置文件,请确保 config/default-wrapper.json 存在');\n }\n \n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (1, 0, ?, ?, 'system')\n `, [\n defaultConfig.header,\n defaultConfig.footer\n ]);\n this.dbManager.save();\n this.logger.info('已初始化默认 wrapper 配置(关闭状态)', {\n headerLength: defaultConfig.header.length,\n footerLength: defaultConfig.footer.length\n });\n }\n }\n\n /**\n * 获取当前 Wrapper 配置\n */\n get(): WrapperConfig {\n this.initializeDefaultIfNeeded();\n const db = this.dbManager.getDatabase();\n const result = db.exec(`\n SELECT version, enabled, header, footer \n FROM wrapper_versions \n ORDER BY version DESC \n LIMIT 1\n `);\n\n if (!result.length || !result[0].values.length) {\n return {\n enabled: false,\n header: '',\n footer: '',\n version: 0\n };\n }\n\n const row = result[0].values[0];\n return {\n enabled: row[1] === 1,\n header: row[2] || '',\n footer: row[3] || '',\n version: row[0] as number\n };\n }\n\n /**\n * 开启 Wrapper\n */\n enable(): void {\n const config = this.get();\n if (config.enabled) {\n this.logger.info('Wrapper 已经开启');\n return;\n }\n\n const db = this.dbManager.getDatabase();\n // 直接更新状态为 enabled(get() 已经确保数据存在)\n if (config.version > 0) {\n db.run(`\n UPDATE wrapper_versions \n SET enabled = 1 \n WHERE version = ?\n `, [config.version]);\n } else {\n // 理论上不应该走到这里,因为 get() 会调用 initializeDefaultIfNeeded()\n throw new Error('无法开启 Wrapper:数据库未初始化');\n }\n\n this.dbManager.save();\n this.logger.info('Wrapper 已开启');\n }\n\n /**\n * 关闭 Wrapper\n */\n disable(): void {\n const config = this.get();\n if (!config.enabled) {\n this.logger.info('Wrapper 已经关闭');\n return;\n }\n\n const db = this.dbManager.getDatabase();\n db.run(`\n UPDATE wrapper_versions \n SET enabled = 0 \n WHERE version = ?\n `, [config.version]);\n\n this.dbManager.save();\n this.logger.info('Wrapper 已关闭');\n }\n\n /**\n * 更新 Wrapper 内容(创建新版本)\n */\n update(header: string, footer: string, author: string = 'system'): void {\n const db = this.dbManager.getDatabase();\n const current = this.get();\n const newVersion = current.version + 1;\n\n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (?, ?, ?, ?, ?)\n `, [newVersion, current.enabled ? 1 : 0, header, footer, author]);\n\n this.dbManager.save();\n this.logger.info('Wrapper 内容已更新', { version: newVersion });\n }\n\n /**\n * 获取历史版本\n */\n history(): WrapperVersion[] {\n const db = this.dbManager.getDatabase();\n const result = db.exec(`\n SELECT * FROM wrapper_versions \n ORDER BY version DESC\n `);\n\n if (!result.length || !result[0].values.length) {\n return [];\n }\n\n return result[0].values.map(row => ({\n id: row[0] as number,\n version: row[1] as number,\n enabled: row[2] as number,\n header: row[3] as string,\n footer: row[4] as string,\n author: row[5] as string,\n created_at: row[6] as string\n }));\n }\n\n /**\n * 回滚到指定版本\n */\n rollback(targetVersion: number, author: string = 'system'): void {\n const db = this.dbManager.getDatabase();\n const current = this.get();\n \n const result = db.exec(`\n SELECT * FROM wrapper_versions WHERE version = ?\n `, [targetVersion]);\n\n if (!result.length || !result[0].values.length) {\n throw new Error(`版本 ${targetVersion} 不存在`);\n }\n\n const target = result[0].values[0];\n const newVersion = current.version + 1;\n\n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (?, ?, ?, ?, ?)\n `, [newVersion, target[2], target[3], target[4], author]);\n\n this.dbManager.save();\n this.logger.info('已回滚到指定版本', { \n from: current.version, \n to: targetVersion,\n newVersion \n });\n }\n\n /**\n * 将内容包装到文章中\n */\n wrapContent(content: string): string {\n const config = this.get();\n \n if (!config.enabled) {\n return content;\n }\n\n let result = content;\n\n // 插入头部\n if (config.header) {\n result = config.header + '\\n' + result;\n }\n\n // 插入尾部\n if (config.footer) {\n result = result + '\\n' + config.footer;\n }\n\n return result;\n }\n}\n","import { ConfigStore } from './infrastructure/config/ConfigStore';\nimport { TokenCache } from './infrastructure/cache/TokenCache';\nimport { ImageCache } from './infrastructure/cache/ImageCache';\nimport { ThemeCache } from './infrastructure/cache/ThemeCache';\nimport { Logger } from './infrastructure/logger/Logger';\nimport { HttpClient } from './infrastructure/http/HttpClient';\nimport { DatabaseManager } from './infrastructure/database/DatabaseManager';\nimport { WechatClient } from './core/wechat/WechatClient';\nimport { ThemeEngine } from './core/theme/ThemeEngine';\nimport { MarkdownRenderer } from './core/renderer/MarkdownRenderer';\nimport { ImageProcessor } from './core/renderer/ImageProcessor';\nimport { AccountService } from './services/AccountService';\nimport { ThemeService } from './services/ThemeService';\nimport { RenderService } from './services/RenderService';\nimport { DraftService } from './services/DraftService';\nimport { PublishService } from './services/PublishService';\nimport { WrapperService } from './services/WrapperService';\n\nclass Container {\n\n private configStore!: ConfigStore;\n private logger!: Logger;\n private httpClient!: HttpClient;\n private dbManager!: DatabaseManager;\n private tokenCache!: TokenCache;\n private imageCache!: ImageCache;\n private themeCache!: ThemeCache;\n private themeEngine!: ThemeEngine;\n private renderer!: MarkdownRenderer;\n private accountService!: AccountService;\n private themeService!: ThemeService;\n private renderService!: RenderService;\n private wrapperService!: WrapperService;\n\n async initialize(): Promise<void> {\n this.configStore = new ConfigStore();\n this.logger = new Logger();\n this.httpClient = new HttpClient(this.logger);\n this.dbManager = new DatabaseManager(this.logger);\n await this.dbManager.initialize();\n this.tokenCache = new TokenCache();\n this.imageCache = new ImageCache();\n this.themeCache = new ThemeCache();\n this.themeEngine = new ThemeEngine();\n this.renderer = new MarkdownRenderer();\n \n this.accountService = new AccountService(this.configStore, this.logger);\n this.themeService = new ThemeService(\n this.themeEngine,\n this.configStore,\n this.themeCache,\n this.logger\n );\n this.renderService = new RenderService(\n this.renderer,\n this.themeService,\n this.logger\n );\n this.wrapperService = new WrapperService(this.dbManager, this.logger);\n\n await this.themeService.initialize();\n await this.renderService.initialize();\n }\n\n getAccountService(): AccountService {\n return this.accountService;\n }\n\n getThemeService(): ThemeService {\n return this.themeService;\n }\n\n getRenderService(): RenderService {\n return this.renderService;\n }\n\n getWrapperService(): WrapperService {\n return this.wrapperService;\n }\n\n getDatabaseManager(): DatabaseManager {\n return this.dbManager;\n }\n\n async getDraftService(): Promise<DraftService> {\n const account = await this.accountService.getCurrentAccount();\n const wechatClient = new WechatClient(\n account.appId,\n account.appSecret,\n this.httpClient,\n this.tokenCache,\n this.logger\n );\n\n const imageProcessor = new ImageProcessor(\n wechatClient.material,\n this.imageCache,\n this.logger\n );\n\n return new DraftService(\n wechatClient,\n this.renderService,\n imageProcessor,\n this.wrapperService,\n this.logger\n );\n }\n\n async getPublishService(): Promise<PublishService> {\n const draftService = await this.getDraftService();\n const account = await this.accountService.getCurrentAccount();\n const wechatClient = new WechatClient(\n account.appId,\n account.appSecret,\n this.httpClient,\n this.tokenCache,\n this.logger\n );\n\n return new PublishService(\n wechatClient,\n draftService,\n this.logger\n );\n }\n}\n\nexport const container = new Container();\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function createAccountCommand(): Command {\n const cmd = new Command('account')\n .description('账号管理');\n\n cmd.command('add')\n .description('添加微信公众号账号')\n .requiredOption('--name <name>', '账号名称')\n .requiredOption('--app-id <appId>', '微信公众号 AppID')\n .requiredOption('--app-secret <appSecret>', '微信公众号 AppSecret')\n .option('--default', '设为默认账号')\n .action(async (options) => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n\n const account = await accountService.addAccount({\n name: options.name,\n appId: options.appId,\n appSecret: options.appSecret,\n isDefault: options.default,\n });\n\n console.log(chalk.green('✓ 账号添加成功'));\n console.log(` ID: ${account.id}`);\n console.log(` 名称: ${account.name}`);\n console.log(` AppID: ${account.appId}`);\n console.log(` 默认账号: ${account.isDefault ? '是' : '否'}`);\n } catch (error: any) {\n console.error(chalk.red('✗ 添加账号失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('list')\n .description('列出所有账号')\n .action(async () => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n const accounts = await accountService.listAccounts();\n\n if (accounts.length === 0) {\n console.log(chalk.yellow('未配置账号'));\n console.log('使用 account add 命令添加账号');\n return;\n }\n\n const table = new Table({\n head: ['ID', '名称', 'AppID', '默认'],\n colWidths: [25, 20, 20, 8],\n });\n\n accounts.forEach(account => {\n table.push([\n account.id,\n account.name,\n account.appId,\n account.isDefault ? chalk.green('是') : '否',\n ]);\n });\n\n console.log(table.toString());\n } catch (error: any) {\n console.error(chalk.red('✗ 获取账号列表失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('switch <id>')\n .description('切换默认账号')\n .action(async (id) => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n await accountService.setDefaultAccount(id);\n console.log(chalk.green('✓ 默认账号切换成功'));\n } catch (error: any) {\n console.error(chalk.red('✗ 切换账号失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('remove <id>')\n .description('删除账号')\n .action(async (id) => {\n try {\n await container.initialize();\n const accountService = container.getAccountService();\n await accountService.removeAccount(id);\n console.log(chalk.green('✓ 账号删除成功'));\n } catch (error: any) {\n console.error(chalk.red('✗ 删除账号失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function createThemeCommand(): Command {\n const cmd = new Command('theme')\n .description('主题管理');\n\n cmd.command('list')\n .description('列出所有可用主题')\n .action(async () => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n const themes = await themeService.listThemes();\n\n if (themes.length === 0) {\n console.log(chalk.yellow('未找到主题'));\n return;\n }\n\n const table = new Table({\n head: ['ID', '名称', '类型', '描述'],\n colWidths: [20, 25, 12, 40],\n });\n\n themes.forEach(theme => {\n const typeColor = theme.type === 'builtin' ? chalk.green :\n theme.type === 'local' ? chalk.blue :\n theme.type === 'remote' ? chalk.magenta : chalk.gray;\n \n table.push([\n theme.id,\n theme.name,\n typeColor(theme.type),\n theme.description || '-',\n ]);\n });\n\n console.log(table.toString());\n console.log(`\\n总计: ${themes.length} 个主题`);\n } catch (error: any) {\n console.error(chalk.red('✗ 获取主题列表失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('add-local')\n .description('添加本地主题')\n .requiredOption('--name <name>', '主题名称')\n .requiredOption('--path <path>', '主题 CSS 文件路径')\n .action(async (options) => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n \n await themeService.addLocalTheme(options.name, options.path);\n \n console.log(chalk.green('✓ 本地主题添加成功'));\n console.log(` 名称: ${options.name}`);\n console.log(` 路径: ${options.path}`);\n } catch (error: any) {\n console.error(chalk.red('✗ 添加本地主题失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('add-remote')\n .description('添加远程主题 API')\n .requiredOption('--name <name>', 'API 名称')\n .requiredOption('--url <url>', 'API URL')\n .requiredOption('--key <key>', 'API Key')\n .action(async (options) => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n \n await themeService.addRemoteAPI(options.name, options.url, options.key);\n \n console.log(chalk.green('✓ 远程主题 API 添加成功'));\n console.log(` 名称: ${options.name}`);\n console.log(` URL: ${options.url}`);\n } catch (error: any) {\n console.error(chalk.red('✗ 添加远程主题 API 失败:'), error.message);\n process.exit(1);\n }\n });\n\n cmd.command('remove <theme-id>')\n .description('删除主题')\n .action(async (themeId) => {\n try {\n await container.initialize();\n const themeService = container.getThemeService();\n \n await themeService.removeTheme(themeId);\n \n console.log(chalk.green('✓ 主题删除成功'));\n } catch (error: any) {\n console.error(chalk.red('✗ 删除主题失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport ora from 'ora';\n\nexport function createDraftCommand(): Command {\n const cmd = new Command('draft')\n .description('草稿管理');\n\n cmd.command('create')\n .description('创建草稿')\n .requiredOption('-f, --file <file>', 'Markdown 文件路径')\n .option('-t, --theme <theme>', '主题 ID')\n .action(async (options) => {\n const spinner = ora('正在创建草稿...').start();\n \n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n const result = await draftService.create({\n file: options.file,\n theme: options.theme,\n });\n \n spinner.succeed('草稿创建成功');\n console.log(chalk.green(` Media ID: ${result.media_id}`));\n console.log(chalk.gray(' 提示: 使用 publish 命令发布此草稿'));\n } catch (error: any) {\n spinner.fail('创建草稿失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('list')\n .description('列出草稿')\n .option('-p, --page <page>', '页码', '1')\n .option('-s, --size <size>', '每页数量', '20')\n .action(async (options) => {\n const spinner = ora('正在获取草稿列表...').start();\n \n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n const page = parseInt(options.page);\n const size = parseInt(options.size);\n const result = await draftService.list(page, size);\n \n spinner.stop();\n \n if (!result.item || result.item.length === 0) {\n console.log(chalk.yellow('暂无草稿'));\n return;\n }\n\n const table = new Table({\n head: ['Media ID', '标题', '更新时间'],\n colWidths: [35, 40, 20],\n });\n\n result.item.forEach(draft => {\n const article = draft.content.news_item[0];\n const updateTime = new Date(draft.update_time * 1000).toLocaleString('zh-CN');\n \n table.push([\n draft.media_id,\n article.title || '-',\n updateTime,\n ]);\n });\n\n console.log(table.toString());\n console.log(`\\n总计: ${result.total_count} 个草稿 (第 ${page} 页)`);\n } catch (error: any) {\n spinner.fail('获取草稿列表失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('delete <media-id>')\n .description('删除草稿')\n .action(async (mediaId) => {\n const spinner = ora('正在删除草稿...').start();\n \n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n await draftService.delete(mediaId);\n \n spinner.succeed('草稿删除成功');\n } catch (error: any) {\n spinner.fail('删除草稿失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('count')\n .description('获取草稿总数')\n .action(async () => {\n try {\n await container.initialize();\n const draftService = await container.getDraftService();\n \n const count = await draftService.count();\n \n console.log(chalk.green(`草稿总数: ${count}`));\n } catch (error: any) {\n console.error(chalk.red('✗ 获取草稿总数失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\nimport ora from 'ora';\n\nexport function createPublishCommand(): Command {\n const cmd = new Command('publish')\n .description('发布管理');\n\n cmd.command('submit <media-id>')\n .description('发布草稿')\n .action(async (mediaId) => {\n const spinner = ora('正在发布草稿...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const result = await publishService.submit(mediaId);\n \n spinner.succeed('发布任务提交成功');\n console.log(chalk.green(` Publish ID: ${result.publish_id}`));\n console.log(chalk.gray(' 提示: 使用 publish status 命令查看发布状态'));\n } catch (error: any) {\n spinner.fail('发布失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('create')\n .description('创建并发布文章')\n .requiredOption('-f, --file <file>', 'Markdown 文件路径')\n .option('-t, --theme <theme>', '主题 ID')\n .action(async (options) => {\n const spinner = ora('正在创建并发布文章...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const result = await publishService.createAndPublish({\n file: options.file,\n theme: options.theme,\n });\n \n spinner.succeed('文章创建并发布成功');\n console.log(chalk.green(` Publish ID: ${result.publish_id}`));\n } catch (error: any) {\n spinner.fail('创建并发布失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('list')\n .description('列出已发布文章')\n .option('-p, --page <page>', '页码', '1')\n .option('-s, --size <size>', '每页数量', '20')\n .action(async (options) => {\n const spinner = ora('正在获取已发布文章列表...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const page = parseInt(options.page);\n const size = parseInt(options.size);\n const result = await publishService.list(page, size);\n \n spinner.stop();\n \n if (!result.item || result.item.length === 0) {\n console.log(chalk.yellow('暂无已发布文章'));\n return;\n }\n\n const table = new Table({\n head: ['Article ID', '标题', '更新时间'],\n colWidths: [35, 40, 20],\n });\n\n result.item.forEach(article => {\n const newsItem = article.content.news_item[0];\n const updateTime = new Date(article.update_time * 1000).toLocaleString('zh-CN');\n \n table.push([\n article.article_id,\n newsItem.title || '-',\n updateTime,\n ]);\n });\n\n console.log(table.toString());\n console.log(`\\n总计: ${result.total_count} 篇文章 (第 ${page} 页)`);\n } catch (error: any) {\n spinner.fail('获取已发布文章列表失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('delete <article-id>')\n .description('删除已发布文章')\n .option('-i, --index <index>', '文章索引', '0')\n .action(async (articleId, options) => {\n const spinner = ora('正在删除已发布文章...').start();\n \n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const index = parseInt(options.index);\n await publishService.delete(articleId, index);\n \n spinner.succeed('已发布文章删除成功');\n } catch (error: any) {\n spinner.fail('删除已发布文章失败');\n console.error(chalk.red(error.message));\n process.exit(1);\n }\n });\n\n cmd.command('status <publish-id>')\n .description('查询发布状态')\n .action(async (publishId) => {\n try {\n await container.initialize();\n const publishService = await container.getPublishService();\n \n const status = await publishService.getStatus(publishId);\n \n console.log(chalk.green('发布状态:'));\n console.log(` Publish ID: ${status.publish_id}`);\n console.log(` 状态: ${status.publish_status === 0 ? '成功' : '失败'}`);\n \n if (status.article_id) {\n console.log(` Article ID: ${status.article_id}`);\n }\n \n if (status.article_detail) {\n console.log(` 文章数量: ${status.article_detail.count}`);\n }\n } catch (error: any) {\n console.error(chalk.red('✗ 查询发布状态失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","import { Command } from 'commander';\nimport { container } from '../../container';\nimport chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function createWrapperCommand(): Command {\n const cmd = new Command('wrapper')\n .description('文章包装功能管理(开头/结尾固定图文)');\n\n // 获取当前状态\n cmd.command('status')\n .description('查看当前 Wrapper 状态')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n const config = wrapperService.get();\n\n console.log(chalk.green('当前状态:'));\n console.log(` 开关: ${config.enabled ? chalk.green('开启') : chalk.red('关闭')}`);\n console.log(` 版本: ${config.version}`);\n \n if (config.header) {\n console.log(chalk.cyan('\\n 头部内容:'));\n console.log(chalk.gray(' ' + config.header.substring(0, 100) + (config.header.length > 100 ? '...' : '')));\n }\n \n if (config.footer) {\n console.log(chalk.cyan('\\n 尾部内容:'));\n console.log(chalk.gray(' ' + config.footer.substring(0, 100) + (config.footer.length > 100 ? '...' : '')));\n }\n } catch (error: any) {\n console.error(chalk.red('✗ 获取状态失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 开启\n cmd.command('on')\n .description('开启 Wrapper 功能')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n wrapperService.enable();\n console.log(chalk.green('✓ Wrapper 已开启'));\n } catch (error: any) {\n console.error(chalk.red('✗ 开启失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 关闭\n cmd.command('off')\n .description('关闭 Wrapper 功能')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n wrapperService.disable();\n console.log(chalk.green('✓ Wrapper 已关闭'));\n } catch (error: any) {\n console.error(chalk.red('✗ 关闭失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 设置内容\n cmd.command('set')\n .description('更新 Wrapper 内容')\n .option('-h, --header <text>', '头部 HTML 内容')\n .option('-f, --footer <text>', '尾部 HTML 内容')\n .option('-a, --author <name>', '作者名称', 'system')\n .action(async (options) => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n \n wrapperService.update(\n options.header || '', \n options.footer || '',\n options.author\n );\n \n console.log(chalk.green('✓ Wrapper 内容已更新(创建新版本)'));\n } catch (error: any) {\n console.error(chalk.red('✗ 更新失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 查看历史\n cmd.command('history')\n .description('查看历史版本')\n .action(async () => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n const versions = wrapperService.history();\n\n if (versions.length === 0) {\n console.log(chalk.yellow('暂无历史版本'));\n return;\n }\n\n const table = new Table({\n head: ['版本', '状态', '作者', '创建时间'],\n colWidths: [10, 10, 15, 20],\n });\n\n versions.forEach(v => {\n table.push([\n `v${v.version}`,\n v.enabled ? chalk.green('开启') : chalk.red('关闭'),\n v.author,\n new Date(v.created_at).toLocaleString('zh-CN'),\n ]);\n });\n\n console.log(table.toString());\n } catch (error: any) {\n console.error(chalk.red('✗ 获取历史失败:'), error.message);\n process.exit(1);\n }\n });\n\n // 回滚\n cmd.command('rollback <version>')\n .description('回滚到指定版本')\n .option('-a, --author <name>', '作者名称', 'system')\n .action(async (versionStr, options) => {\n try {\n await container.initialize();\n const wrapperService = await container.getWrapperService();\n \n const version = parseInt(versionStr);\n wrapperService.rollback(version, options.author);\n \n console.log(chalk.green(`✓ 已回滚到 v${version}`));\n } catch (error: any) {\n console.error(chalk.red('✗ 回滚失败:'), error.message);\n process.exit(1);\n }\n });\n\n return cmd;\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createAccountCommand } from './commands/account';\nimport { createThemeCommand } from './commands/theme';\nimport { createDraftCommand } from './commands/draft';\nimport { createPublishCommand } from './commands/publish';\nimport { createWrapperCommand } from './commands/wrapper';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst packageJson = JSON.parse(\n readFileSync(join(__dirname, '../package.json'), 'utf-8')\n);\n\nconst program = new Command();\n\nprogram\n .name('wechat-pub')\n .description('全功能微信公众号 Markdown 发布工具')\n .version(packageJson.version);\n\nprogram.addCommand(createAccountCommand());\nprogram.addCommand(createThemeCommand());\nprogram.addCommand(createDraftCommand());\nprogram.addCommand(createPublishCommand());\nprogram.addCommand(createWrapperCommand());\n\nprogram.parse();\n"],"names":["__filename","__dirname"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageProcessor.d.ts","sourceRoot":"","sources":["../../../src/core/renderer/ImageProcessor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAK5D,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,cAAc;IAEnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;gBAFN,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM;IAGpB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageProcessor.d.ts","sourceRoot":"","sources":["../../../src/core/renderer/ImageProcessor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAK5D,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,cAAc;IAEnB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;gBAFN,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM;IAGpB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAuCzF;;OAEG;IACH,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAetD,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IA8BvG;;;;;;OAMG;IACG,WAAW,CACb,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,OAAO,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;CAgDrB"}
|