wechat-md-publisher 0.7.1 → 0.7.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.
@@ -1,3 +1,6 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1
4
  import { readFile } from "fs/promises";
2
5
  import axios from "axios";
3
6
  import { dirname, join } from "path";
@@ -346,6 +349,10 @@ class MaterialAPI {
346
349
  }
347
350
  class WechatClient {
348
351
  constructor(appId, appSecret, httpClient, tokenCache, logger) {
352
+ __publicField(this, "token");
353
+ __publicField(this, "draft");
354
+ __publicField(this, "publish");
355
+ __publicField(this, "material");
349
356
  this.appId = appId;
350
357
  this.token = new TokenAPI(appId, appSecret, httpClient, tokenCache, logger);
351
358
  const getAccessToken = () => this.token.getAccessToken();
@@ -353,10 +360,6 @@ class WechatClient {
353
360
  this.publish = new PublishAPI(getAccessToken, httpClient, logger);
354
361
  this.material = new MaterialAPI(getAccessToken, httpClient, logger);
355
362
  }
356
- token;
357
- draft;
358
- publish;
359
- material;
360
363
  async getAccessToken() {
361
364
  return await this.token.getAccessToken();
362
365
  }
@@ -399,7 +402,9 @@ class LocalLoader {
399
402
  }
400
403
  }
401
404
  class RemoteLoader {
402
- configs = /* @__PURE__ */ new Map();
405
+ constructor() {
406
+ __publicField(this, "configs", /* @__PURE__ */ new Map());
407
+ }
403
408
  async addAPI(name, apiUrl, apiKey) {
404
409
  this.configs.set(name, {
405
410
  name,
@@ -510,7 +515,9 @@ class BuiltinLoader {
510
515
  }
511
516
  }
512
517
  class ThemeRegistry {
513
- themes = /* @__PURE__ */ new Map();
518
+ constructor() {
519
+ __publicField(this, "themes", /* @__PURE__ */ new Map());
520
+ }
514
521
  register(theme) {
515
522
  this.themes.set(theme.id, theme);
516
523
  }
@@ -539,11 +546,11 @@ class ThemeRegistry {
539
546
  }
540
547
  }
541
548
  class ThemeEngine {
542
- registry;
543
- localLoader;
544
- remoteLoader;
545
- builtinLoader;
546
549
  constructor() {
550
+ __publicField(this, "registry");
551
+ __publicField(this, "localLoader");
552
+ __publicField(this, "remoteLoader");
553
+ __publicField(this, "builtinLoader");
547
554
  this.registry = new ThemeRegistry();
548
555
  this.localLoader = new LocalLoader();
549
556
  this.remoteLoader = new RemoteLoader();
@@ -590,7 +597,9 @@ class ThemeEngine {
590
597
  }
591
598
  }
592
599
  class MarkdownRenderer {
593
- wenyan;
600
+ constructor() {
601
+ __publicField(this, "wenyan");
602
+ }
594
603
  async initialize() {
595
604
  this.wenyan = await createWenyanCore({
596
605
  isConvertMathJax: true,
@@ -634,8 +643,8 @@ const AccountSchema = z.object({
634
643
  updatedAt: z.date().optional()
635
644
  });
636
645
  class ConfigStore {
637
- store;
638
646
  constructor() {
647
+ __publicField(this, "store");
639
648
  this.store = new Conf({
640
649
  projectName: "wechat-md-publisher"
641
650
  });
@@ -666,8 +675,8 @@ class ConfigStore {
666
675
  }
667
676
  }
668
677
  class Logger {
669
- logger;
670
678
  constructor() {
679
+ __publicField(this, "logger");
671
680
  this.logger = winston.createLogger({
672
681
  level: process.env.LOG_LEVEL || "info",
673
682
  format: winston.format.combine(
@@ -715,4 +724,4 @@ export {
715
724
  WechatError as e,
716
725
  WechatRateLimitError as f
717
726
  };
718
- //# sourceMappingURL=Logger-CRPQmRrm.js.map
727
+ //# sourceMappingURL=Logger-mgxqCI3-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Logger-CRPQmRrm.js","sources":["../src/errors/BaseError.ts","../src/errors/WechatError.ts","../src/core/wechat/constants.ts","../src/core/wechat/api/TokenAPI.ts","../src/core/wechat/api/DraftAPI.ts","../src/core/wechat/api/PublishAPI.ts","../src/core/wechat/api/MaterialAPI.ts","../src/core/wechat/WechatClient.ts","../src/errors/ThemeError.ts","../src/core/theme/loaders/LocalLoader.ts","../src/core/theme/loaders/RemoteLoader.ts","../src/core/theme/loaders/BuiltinLoader.ts","../src/core/theme/registry.ts","../src/core/theme/ThemeEngine.ts","../src/core/renderer/MarkdownRenderer.ts","../src/infrastructure/config/ConfigStore.ts","../src/infrastructure/logger/Logger.ts"],"sourcesContent":["export class BaseError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: any\n ) {\n super(message);\n this.name = this.constructor.name;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n details: this.details,\n };\n }\n}\n","import { BaseError } from './BaseError';\n\nexport class WechatError extends BaseError {\n constructor(\n message: string,\n public errcode: number,\n public errmsg: string\n ) {\n super(message, 'WECHAT_API_ERROR', 500, { errcode, errmsg });\n }\n\n static fromResponse(data: { errcode: number; errmsg: string }): WechatError {\n return new WechatError(\n `微信 API 错误: ${data.errmsg} (${data.errcode})`,\n data.errcode,\n data.errmsg\n );\n }\n}\n\nexport class WechatAuthError extends BaseError {\n constructor(message: string) {\n super(message, 'WECHAT_AUTH_ERROR', 401);\n }\n}\n\nexport class WechatRateLimitError extends BaseError {\n constructor(message: string) {\n super(message, 'WECHAT_RATE_LIMIT_ERROR', 429);\n }\n}\n","export const WECHAT_API_BASE = 'https://api.weixin.qq.com';\n\nexport const WECHAT_API_ENDPOINTS = {\n TOKEN: '/cgi-bin/token',\n DRAFT_ADD: '/cgi-bin/draft/add',\n DRAFT_GET: '/cgi-bin/draft/get',\n DRAFT_DELETE: '/cgi-bin/draft/delete',\n DRAFT_UPDATE: '/cgi-bin/draft/update',\n DRAFT_BATCH_GET: '/cgi-bin/draft/batchget',\n DRAFT_COUNT: '/cgi-bin/draft/count',\n PUBLISH_SUBMIT: '/cgi-bin/freepublish/submit',\n PUBLISH_GET: '/cgi-bin/freepublish/get',\n PUBLISH_DELETE: '/cgi-bin/freepublish/delete',\n PUBLISH_BATCH_GET: '/cgi-bin/freepublish/batchget',\n PUBLISH_GET_STATUS: '/cgi-bin/freepublish/get',\n MATERIAL_ADD: '/cgi-bin/material/add_material',\n MATERIAL_GET: '/cgi-bin/material/get_material',\n MATERIAL_DELETE: '/cgi-bin/material/del_material',\n MATERIAL_BATCH_GET: '/cgi-bin/material/batchget_material',\n MATERIAL_COUNT: '/cgi-bin/material/get_materialcount',\n} as const;\n\nexport const WECHAT_ERROR_CODES = {\n SUCCESS: 0,\n INVALID_CREDENTIAL: 40001,\n ACCESS_TOKEN_EXPIRED: 42001,\n RATE_LIMIT_EXCEEDED: 45009,\n API_UNAUTHORIZED: 48001,\n} as const;\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { TokenCache } from '../../../infrastructure/cache/TokenCache';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\n\nexport class TokenAPI {\n constructor(\n private appId: string,\n private appSecret: string,\n private httpClient: HttpClient,\n private tokenCache: TokenCache,\n private logger: Logger\n ) {}\n\n async getAccessToken(): Promise<string> {\n const cached = await this.tokenCache.getToken(this.appId);\n if (cached) {\n this.logger.debug('使用缓存的 Access Token', { appId: this.appId });\n return cached;\n }\n\n return await this.refreshAccessToken();\n }\n\n async refreshAccessToken(): Promise<string> {\n this.logger.info('刷新 Access Token', { appId: this.appId });\n\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.TOKEN}`;\n const response = await this.httpClient.get(url, {\n params: {\n grant_type: 'client_credential',\n appid: this.appId,\n secret: this.appSecret,\n },\n });\n\n const data = response.data;\n\n if (data.errcode) {\n throw WechatError.fromResponse(data);\n }\n\n await this.tokenCache.setToken(\n this.appId,\n data.access_token,\n data.expires_in\n );\n\n this.logger.info('Access Token 刷新成功', {\n appId: this.appId,\n expiresIn: data.expires_in,\n });\n\n return data.access_token;\n }\n}\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\nimport type { Draft, DraftList, DraftArticle } from '../../../types/draft';\n\nexport class DraftAPI {\n constructor(\n private getAccessToken: () => Promise<string>,\n private httpClient: HttpClient,\n private logger: Logger\n ) {}\n\n async create(article: DraftArticle): Promise<{ media_id: string }> {\n this.logger.info('创建草稿', { title: article.title });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_ADD}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n articles: [article],\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('草稿创建成功', { media_id: data.media_id });\n return { media_id: data.media_id };\n }\n\n async get(mediaId: string): Promise<Draft> {\n this.logger.info('获取草稿详情', { media_id: mediaId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async list(offset: number = 0, count: number = 20): Promise<DraftList> {\n this.logger.info('获取草稿列表', { offset, count });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_BATCH_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n offset,\n count,\n no_content: 0,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async delete(mediaId: string): Promise<void> {\n this.logger.info('删除草稿', { media_id: mediaId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_DELETE}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('草稿删除成功');\n }\n\n async update(mediaId: string, article: DraftArticle, index: number = 0): Promise<void> {\n this.logger.info('更新草稿', { media_id: mediaId, index });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_UPDATE}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n index,\n articles: article,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('草稿更新成功');\n }\n\n async count(): Promise<number> {\n this.logger.info('获取草稿总数');\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_COUNT}?access_token=${accessToken}`;\n\n const response = await this.httpClient.get(url);\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data.total_count || 0;\n }\n}\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\nimport type { PublishResult, PublishedArticle, PublishList, PublishStatus } from '../../../types/publish';\n\nexport class PublishAPI {\n constructor(\n private getAccessToken: () => Promise<string>,\n private httpClient: HttpClient,\n private logger: Logger\n ) {}\n\n async submit(mediaId: string): Promise<PublishResult> {\n this.logger.info('发布草稿', { media_id: mediaId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_SUBMIT}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('发布任务提交成功', { publish_id: data.publish_id });\n return {\n publish_id: data.publish_id,\n msg_data_id: data.msg_data_id,\n };\n }\n\n async get(articleId: string): Promise<PublishedArticle> {\n this.logger.info('获取已发布文章详情', { article_id: articleId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n article_id: articleId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async list(offset: number = 0, count: number = 20): Promise<PublishList> {\n this.logger.info('获取已发布文章列表', { offset, count });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_BATCH_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n offset,\n count,\n no_content: 0,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async delete(articleId: string, index: number = 0): Promise<void> {\n this.logger.info('删除已发布文章', { article_id: articleId, index });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_DELETE}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n article_id: articleId,\n index,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('已发布文章删除成功');\n }\n\n async getStatus(publishId: string): Promise<PublishStatus> {\n this.logger.info('获取发布状态', { publish_id: publishId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_GET_STATUS}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n publish_id: publishId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n}\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\n\nexport interface UploadResult {\n media_id: string;\n url: string;\n}\n\nexport class MaterialAPI {\n constructor(\n private getAccessToken: () => Promise<string>,\n private httpClient: HttpClient,\n private logger: Logger\n ) {}\n\n async uploadImage(file: Buffer, filename: string): Promise<UploadResult> {\n this.logger.info('上传图片', { filename });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.MATERIAL_ADD}?access_token=${accessToken}&type=image`;\n\n const formData = new FormData();\n const blob = new Blob([file]);\n formData.append('media', blob, filename);\n\n const response = await this.httpClient.post(url, formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n if (data.url && data.url.startsWith('http://')) {\n data.url = data.url.replace(/^http:\\/\\//i, 'https://');\n }\n\n this.logger.info('图片上传成功', { media_id: data.media_id });\n return {\n media_id: data.media_id,\n url: data.url,\n };\n }\n\n async uploadThumb(file: Buffer, filename: string): Promise<UploadResult> {\n this.logger.info('上传封面图', { filename });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.MATERIAL_ADD}?access_token=${accessToken}&type=thumb`;\n\n const formData = new FormData();\n const blob = new Blob([file]);\n formData.append('media', blob, filename);\n\n const response = await this.httpClient.post(url, formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n if (data.url && data.url.startsWith('http://')) {\n data.url = data.url.replace(/^http:\\/\\//i, 'https://');\n }\n\n this.logger.info('封面图上传成功', { media_id: data.media_id });\n return {\n media_id: data.media_id,\n url: data.url,\n };\n }\n\n async getMaterialCount(): Promise<{ voice_count: number; video_count: number; image_count: number; news_count: number }> {\n this.logger.info('获取素材总数');\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.MATERIAL_COUNT}?access_token=${accessToken}`;\n\n const response = await this.httpClient.get(url);\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n}\n","import { TokenAPI } from './api/TokenAPI';\nimport { DraftAPI } from './api/DraftAPI';\nimport { PublishAPI } from './api/PublishAPI';\nimport { MaterialAPI } from './api/MaterialAPI';\nimport { HttpClient } from '../../infrastructure/http/HttpClient';\nimport { TokenCache } from '../../infrastructure/cache/TokenCache';\nimport { Logger } from '../../infrastructure/logger/Logger';\n\nexport class WechatClient {\n public readonly token: TokenAPI;\n public readonly draft: DraftAPI;\n public readonly publish: PublishAPI;\n public readonly material: MaterialAPI;\n\n constructor(\n private appId: string,\n appSecret: string,\n httpClient: HttpClient,\n tokenCache: TokenCache,\n logger: Logger\n ) {\n this.token = new TokenAPI(appId, appSecret, httpClient, tokenCache, logger);\n \n const getAccessToken = () => this.token.getAccessToken();\n \n this.draft = new DraftAPI(getAccessToken, httpClient, logger);\n this.publish = new PublishAPI(getAccessToken, httpClient, logger);\n this.material = new MaterialAPI(getAccessToken, httpClient, logger);\n }\n\n async getAccessToken(): Promise<string> {\n return await this.token.getAccessToken();\n }\n\n async refreshAccessToken(): Promise<string> {\n return await this.token.refreshAccessToken();\n }\n\n getAppId(): string {\n return this.appId;\n }\n}\n","import { BaseError } from './BaseError';\n\nexport class ThemeError extends BaseError {\n constructor(message: string, details?: any) {\n super(message, 'THEME_ERROR', 500, details);\n }\n}\n\nexport class ThemeNotFoundError extends BaseError {\n constructor(themeId: string) {\n super(`主题不存在: ${themeId}`, 'THEME_NOT_FOUND', 404, { themeId });\n }\n}\n\nexport class ThemeLoadError extends BaseError {\n constructor(themeId: string, reason: string) {\n super(`主题加载失败: ${themeId} - ${reason}`, 'THEME_LOAD_ERROR', 500, { themeId, reason });\n }\n}\n","import { readFile } from 'fs/promises';\nimport type { Theme } from '../../../types/theme';\nimport { ThemeLoadError } from '../../../errors/ThemeError';\n\nexport class LocalLoader {\n async load(name: string, path: string): Promise<Theme> {\n try {\n const css = await readFile(path, 'utf-8');\n \n return {\n id: name,\n name,\n type: 'local',\n description: `本地主题: ${path}`,\n getCss: async () => css,\n };\n } catch (error) {\n throw new ThemeLoadError(name, `无法读取文件: ${path}`);\n }\n }\n}\n","import axios from 'axios';\nimport type { Theme, ThemeSource, RemoteThemeConfig } from '../../../types/theme';\nimport { ThemeLoadError } from '../../../errors/ThemeError';\n\nexport class RemoteLoader {\n private configs: Map<string, RemoteThemeConfig> = new Map();\n\n async addAPI(name: string, apiUrl: string, apiKey: string): Promise<void> {\n this.configs.set(name, {\n name,\n apiUrl,\n apiKey,\n enabled: true,\n });\n }\n\n async load(themeId: string): Promise<Theme | null> {\n for (const [name, config] of this.configs) {\n if (!config.enabled) continue;\n\n try {\n const css = await this.fetchThemeCSS(config.apiUrl, config.apiKey, themeId);\n if (css) {\n return {\n id: themeId,\n name: `${name}:${themeId}`,\n type: 'remote',\n description: `远程主题来自 ${name}`,\n getCss: async () => css,\n };\n }\n } catch (error) {\n continue;\n }\n }\n\n return null;\n }\n\n async list(): Promise<ThemeSource[]> {\n const themes: ThemeSource[] = [];\n\n for (const [name, config] of this.configs) {\n if (!config.enabled) continue;\n\n try {\n const themeList = await this.fetchThemeList(config.apiUrl, config.apiKey);\n for (const themeId of themeList) {\n themes.push({\n type: 'remote',\n id: themeId,\n name: `${name}:${themeId}`,\n description: `远程主题来自 ${name}`,\n });\n }\n } catch (error) {\n continue;\n }\n }\n\n return themes;\n }\n\n getConfig(): RemoteThemeConfig[] {\n return Array.from(this.configs.values());\n }\n\n private async fetchThemeList(apiUrl: string, apiKey: string): Promise<string[]> {\n try {\n const response = await axios.get(`${apiUrl}/themes`, {\n headers: {\n 'X-API-Key': apiKey,\n },\n });\n return response.data.themes || [];\n } catch (error) {\n throw new ThemeLoadError('remote', '无法获取远程主题列表');\n }\n }\n\n private async fetchThemeCSS(apiUrl: string, apiKey: string, themeId: string): Promise<string | null> {\n try {\n const response = await axios.get(`${apiUrl}/themes/${themeId}`, {\n headers: {\n 'X-API-Key': apiKey,\n },\n });\n return response.data.css || null;\n } catch (error) {\n return null;\n }\n }\n}\n","import { readFile } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { createRequire } from 'module';\nimport type { Theme } from '../../../types/theme';\n\n// Use require to get the package's directory at runtime\nconst require = createRequire(import.meta.url);\n// require.resolve points to dist/index.js, so we need to go up to package root\nconst packageRoot = dirname(dirname(require.resolve('wechat-md-publisher')));\n\nconsole.log('[BuiltinLoader] packageRoot:', packageRoot);\n\n// Only use the 6 themes in themes/builtin/ folder\nconst LOCAL_THEMES = [\n { id: 'default', name: '默认主题', description: '简洁清爽的默认样式,适合各类文章' },\n { id: 'orangesun', name: 'Orange Sun', description: 'A warm and bright theme with orange sunshine vibes.' },\n { id: 'redruby', name: 'Red Ruby', description: 'An elegant theme with bold ruby red accents.' },\n { id: 'greenmint', name: 'Green Mint', description: 'A fresh and calming mint green theme.' },\n { id: 'purplerain', name: 'Purple Rain', description: 'A dreamy purple theme with soft gradients.' },\n { id: 'blackink', name: 'Black Ink', description: 'A dark mode theme with indigo accents for night reading.' },\n];\n\nexport class BuiltinLoader {\n async loadAll(): Promise<Theme[]> {\n const themes: Theme[] = [];\n\n // FIXED: Only load LOCAL_THEMES that have matching CSS files\n for (const themeInfo of LOCAL_THEMES) {\n try {\n const themePath = join(packageRoot, 'themes', 'builtin', `${themeInfo.id}.css`);\n const css = await readFile(themePath, 'utf-8');\n\n themes.push({\n id: themeInfo.id,\n name: themeInfo.name,\n type: 'builtin',\n description: themeInfo.description,\n getCss: async () => css,\n });\n } catch (error) {\n console.warn(`[BuiltinLoader] Failed to load theme \"${themeInfo.id}\":`, error instanceof Error ? error.message : error);\n continue;\n }\n }\n\n return themes;\n }\n}\n","import type { Theme, ThemeSource } from '../../types/theme';\n\nexport class ThemeRegistry {\n private themes: Map<string, Theme> = new Map();\n\n register(theme: Theme): void {\n this.themes.set(theme.id, theme);\n }\n\n get(id: string): Theme | undefined {\n return this.themes.get(id);\n }\n\n has(id: string): boolean {\n return this.themes.has(id);\n }\n\n remove(id: string): void {\n this.themes.delete(id);\n }\n\n list(): ThemeSource[] {\n return Array.from(this.themes.values()).map(theme => ({\n type: theme.type,\n id: theme.id,\n name: theme.name,\n description: theme.description,\n }));\n }\n\n getLocalThemes(): ThemeSource[] {\n return this.list().filter(t => t.type === 'local');\n }\n\n clear(): void {\n this.themes.clear();\n }\n}\n","import { LocalLoader } from './loaders/LocalLoader';\nimport { RemoteLoader } from './loaders/RemoteLoader';\nimport { BuiltinLoader } from './loaders/BuiltinLoader';\nimport { ThemeRegistry } from './registry';\nimport { ThemeNotFoundError } from '../../errors/ThemeError';\nimport type { ThemeSource } from '../../types/theme';\n\nexport class ThemeEngine {\n private registry: ThemeRegistry;\n private localLoader: LocalLoader;\n private remoteLoader: RemoteLoader;\n private builtinLoader: BuiltinLoader;\n\n constructor() {\n this.registry = new ThemeRegistry();\n this.localLoader = new LocalLoader();\n this.remoteLoader = new RemoteLoader();\n this.builtinLoader = new BuiltinLoader();\n }\n\n async loadBuiltinThemes(): Promise<void> {\n const themes = await this.builtinLoader.loadAll();\n for (const theme of themes) {\n this.registry.register(theme);\n }\n }\n\n async addLocalTheme(name: string, path: string): Promise<void> {\n const theme = await this.localLoader.load(name, path);\n this.registry.register(theme);\n }\n\n async addRemoteAPI(name: string, apiUrl: string, apiKey: string): Promise<void> {\n await this.remoteLoader.addAPI(name, apiUrl, apiKey);\n }\n\n async getThemeCSS(themeId: string): Promise<string> {\n const theme = this.registry.get(themeId);\n if (theme) {\n return await theme.getCss();\n }\n\n const remoteTheme = await this.remoteLoader.load(themeId);\n if (remoteTheme) {\n return await remoteTheme.getCss();\n }\n\n throw new ThemeNotFoundError(themeId);\n }\n\n async listThemes(): Promise<ThemeSource[]> {\n const themes: ThemeSource[] = [];\n \n themes.push(...this.registry.list());\n \n themes.push(...await this.remoteLoader.list());\n\n return themes;\n }\n\n async removeTheme(themeId: string): Promise<void> {\n this.registry.remove(themeId);\n }\n\n async getConfig(): Promise<any> {\n return {\n local: this.registry.getLocalThemes(),\n remote: this.remoteLoader.getConfig(),\n };\n }\n}\n","import { createWenyanCore } from '@wenyan-md/core';\nimport type { ApplyStylesOptions } from '@wenyan-md/core';\nimport { JSDOM } from 'jsdom';\n\nexport interface RenderResult {\n title: string;\n content: string;\n cover?: string;\n}\n\nexport class MarkdownRenderer {\n private wenyan: any;\n\n async initialize(): Promise<void> {\n this.wenyan = await createWenyanCore({\n isConvertMathJax: true,\n isWechat: true,\n });\n }\n\n async render(markdown: string, themeCss?: string): Promise<RenderResult> {\n if (!this.wenyan) {\n await this.initialize();\n }\n\n const result = await this.wenyan.handleFrontMatter(markdown);\n \n if (!result || !result.body) {\n throw new Error('Invalid markdown: handleFrontMatter returned empty data');\n }\n \n const html = await this.wenyan.renderMarkdown(result.body);\n\n const dom = new JSDOM(html);\n const document = dom.window.document;\n const wenyanElement = document.createElement('div');\n wenyanElement.id = 'wenyan';\n wenyanElement.innerHTML = html;\n\n const options: ApplyStylesOptions = {\n themeCss,\n isMacStyle: true,\n isAddFootnote: false,\n };\n\n const styledHtml = await this.wenyan.applyStylesWithTheme(wenyanElement, options);\n\n return {\n title: result.title || '',\n content: styledHtml,\n cover: result.cover,\n };\n }\n}\n","import Conf from 'conf';\nimport { z } from 'zod';\nimport type { Config } from '../../types/config';\n\nconst AccountSchema = z.object({\n id: z.string(),\n name: z.string(),\n appId: z.string().regex(/^wx[a-zA-Z0-9]{16}$/, '无效的 AppID 格式'),\n appSecret: z.string().min(32, 'AppSecret 长度不足'),\n isDefault: z.boolean().optional(),\n createdAt: z.date().optional(),\n updatedAt: z.date().optional(),\n});\n\nexport class ConfigStore {\n private store: Conf<Config>;\n\n constructor() {\n this.store = new Conf<Config>({\n projectName: 'wechat-md-publisher',\n });\n }\n\n get<K extends keyof Config>(key: K): Config[K] | undefined;\n get<K extends keyof Config>(key: K, defaultValue: Config[K]): Config[K];\n get<K extends keyof Config>(key: K, defaultValue?: Config[K]): Config[K] | undefined {\n return this.store.get(key, defaultValue as any);\n }\n\n set<K extends keyof Config>(key: K, value: Config[K]): void {\n if (key === 'accounts') {\n z.array(AccountSchema).parse(value);\n }\n this.store.set(key, value);\n }\n\n has(key: keyof Config): boolean {\n return this.store.has(key);\n }\n\n delete(key: keyof Config): void {\n this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n\n getAll(): Config {\n return this.store.store;\n }\n\n getPath(): string {\n return this.store.path;\n }\n}\n","import winston from 'winston';\n\nexport class Logger {\n private logger: winston.Logger;\n\n constructor() {\n this.logger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json()\n ),\n transports: [\n new winston.transports.Console({\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.printf(({ level, message, timestamp, ...meta }) => {\n const metaStr = Object.keys(meta).length ? JSON.stringify(meta) : '';\n return `${timestamp} [${level}]: ${message} ${metaStr}`;\n })\n ),\n }),\n ],\n });\n }\n\n debug(message: string, meta?: any): void {\n this.logger.debug(message, meta);\n }\n\n info(message: string, meta?: any): void {\n this.logger.info(message, meta);\n }\n\n warn(message: string, meta?: any): void {\n this.logger.warn(message, meta);\n }\n\n error(message: string, meta?: any): void {\n this.logger.error(message, meta);\n }\n}\n"],"names":["require"],"mappings":"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"}
1
+ {"version":3,"file":"Logger-mgxqCI3-.js","sources":["../src/errors/BaseError.ts","../src/errors/WechatError.ts","../src/core/wechat/constants.ts","../src/core/wechat/api/TokenAPI.ts","../src/core/wechat/api/DraftAPI.ts","../src/core/wechat/api/PublishAPI.ts","../src/core/wechat/api/MaterialAPI.ts","../src/core/wechat/WechatClient.ts","../src/errors/ThemeError.ts","../src/core/theme/loaders/LocalLoader.ts","../src/core/theme/loaders/RemoteLoader.ts","../src/core/theme/loaders/BuiltinLoader.ts","../src/core/theme/registry.ts","../src/core/theme/ThemeEngine.ts","../src/core/renderer/MarkdownRenderer.ts","../src/infrastructure/config/ConfigStore.ts","../src/infrastructure/logger/Logger.ts"],"sourcesContent":["export class BaseError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode: number = 500,\n public details?: any\n ) {\n super(message);\n this.name = this.constructor.name;\n Error.captureStackTrace(this, this.constructor);\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n details: this.details,\n };\n }\n}\n","import { BaseError } from './BaseError';\n\nexport class WechatError extends BaseError {\n constructor(\n message: string,\n public errcode: number,\n public errmsg: string\n ) {\n super(message, 'WECHAT_API_ERROR', 500, { errcode, errmsg });\n }\n\n static fromResponse(data: { errcode: number; errmsg: string }): WechatError {\n return new WechatError(\n `微信 API 错误: ${data.errmsg} (${data.errcode})`,\n data.errcode,\n data.errmsg\n );\n }\n}\n\nexport class WechatAuthError extends BaseError {\n constructor(message: string) {\n super(message, 'WECHAT_AUTH_ERROR', 401);\n }\n}\n\nexport class WechatRateLimitError extends BaseError {\n constructor(message: string) {\n super(message, 'WECHAT_RATE_LIMIT_ERROR', 429);\n }\n}\n","export const WECHAT_API_BASE = 'https://api.weixin.qq.com';\n\nexport const WECHAT_API_ENDPOINTS = {\n TOKEN: '/cgi-bin/token',\n DRAFT_ADD: '/cgi-bin/draft/add',\n DRAFT_GET: '/cgi-bin/draft/get',\n DRAFT_DELETE: '/cgi-bin/draft/delete',\n DRAFT_UPDATE: '/cgi-bin/draft/update',\n DRAFT_BATCH_GET: '/cgi-bin/draft/batchget',\n DRAFT_COUNT: '/cgi-bin/draft/count',\n PUBLISH_SUBMIT: '/cgi-bin/freepublish/submit',\n PUBLISH_GET: '/cgi-bin/freepublish/get',\n PUBLISH_DELETE: '/cgi-bin/freepublish/delete',\n PUBLISH_BATCH_GET: '/cgi-bin/freepublish/batchget',\n PUBLISH_GET_STATUS: '/cgi-bin/freepublish/get',\n MATERIAL_ADD: '/cgi-bin/material/add_material',\n MATERIAL_GET: '/cgi-bin/material/get_material',\n MATERIAL_DELETE: '/cgi-bin/material/del_material',\n MATERIAL_BATCH_GET: '/cgi-bin/material/batchget_material',\n MATERIAL_COUNT: '/cgi-bin/material/get_materialcount',\n} as const;\n\nexport const WECHAT_ERROR_CODES = {\n SUCCESS: 0,\n INVALID_CREDENTIAL: 40001,\n ACCESS_TOKEN_EXPIRED: 42001,\n RATE_LIMIT_EXCEEDED: 45009,\n API_UNAUTHORIZED: 48001,\n} as const;\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { TokenCache } from '../../../infrastructure/cache/TokenCache';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\n\nexport class TokenAPI {\n constructor(\n private appId: string,\n private appSecret: string,\n private httpClient: HttpClient,\n private tokenCache: TokenCache,\n private logger: Logger\n ) {}\n\n async getAccessToken(): Promise<string> {\n const cached = await this.tokenCache.getToken(this.appId);\n if (cached) {\n this.logger.debug('使用缓存的 Access Token', { appId: this.appId });\n return cached;\n }\n\n return await this.refreshAccessToken();\n }\n\n async refreshAccessToken(): Promise<string> {\n this.logger.info('刷新 Access Token', { appId: this.appId });\n\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.TOKEN}`;\n const response = await this.httpClient.get(url, {\n params: {\n grant_type: 'client_credential',\n appid: this.appId,\n secret: this.appSecret,\n },\n });\n\n const data = response.data;\n\n if (data.errcode) {\n throw WechatError.fromResponse(data);\n }\n\n await this.tokenCache.setToken(\n this.appId,\n data.access_token,\n data.expires_in\n );\n\n this.logger.info('Access Token 刷新成功', {\n appId: this.appId,\n expiresIn: data.expires_in,\n });\n\n return data.access_token;\n }\n}\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\nimport type { Draft, DraftList, DraftArticle } from '../../../types/draft';\n\nexport class DraftAPI {\n constructor(\n private getAccessToken: () => Promise<string>,\n private httpClient: HttpClient,\n private logger: Logger\n ) {}\n\n async create(article: DraftArticle): Promise<{ media_id: string }> {\n this.logger.info('创建草稿', { title: article.title });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_ADD}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n articles: [article],\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('草稿创建成功', { media_id: data.media_id });\n return { media_id: data.media_id };\n }\n\n async get(mediaId: string): Promise<Draft> {\n this.logger.info('获取草稿详情', { media_id: mediaId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async list(offset: number = 0, count: number = 20): Promise<DraftList> {\n this.logger.info('获取草稿列表', { offset, count });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_BATCH_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n offset,\n count,\n no_content: 0,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async delete(mediaId: string): Promise<void> {\n this.logger.info('删除草稿', { media_id: mediaId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_DELETE}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('草稿删除成功');\n }\n\n async update(mediaId: string, article: DraftArticle, index: number = 0): Promise<void> {\n this.logger.info('更新草稿', { media_id: mediaId, index });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_UPDATE}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n index,\n articles: article,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('草稿更新成功');\n }\n\n async count(): Promise<number> {\n this.logger.info('获取草稿总数');\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.DRAFT_COUNT}?access_token=${accessToken}`;\n\n const response = await this.httpClient.get(url);\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data.total_count || 0;\n }\n}\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\nimport type { PublishResult, PublishedArticle, PublishList, PublishStatus } from '../../../types/publish';\n\nexport class PublishAPI {\n constructor(\n private getAccessToken: () => Promise<string>,\n private httpClient: HttpClient,\n private logger: Logger\n ) {}\n\n async submit(mediaId: string): Promise<PublishResult> {\n this.logger.info('发布草稿', { media_id: mediaId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_SUBMIT}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n media_id: mediaId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('发布任务提交成功', { publish_id: data.publish_id });\n return {\n publish_id: data.publish_id,\n msg_data_id: data.msg_data_id,\n };\n }\n\n async get(articleId: string): Promise<PublishedArticle> {\n this.logger.info('获取已发布文章详情', { article_id: articleId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n article_id: articleId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async list(offset: number = 0, count: number = 20): Promise<PublishList> {\n this.logger.info('获取已发布文章列表', { offset, count });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_BATCH_GET}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n offset,\n count,\n no_content: 0,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n\n async delete(articleId: string, index: number = 0): Promise<void> {\n this.logger.info('删除已发布文章', { article_id: articleId, index });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_DELETE}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n article_id: articleId,\n index,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n this.logger.info('已发布文章删除成功');\n }\n\n async getStatus(publishId: string): Promise<PublishStatus> {\n this.logger.info('获取发布状态', { publish_id: publishId });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.PUBLISH_GET_STATUS}?access_token=${accessToken}`;\n\n const response = await this.httpClient.post(url, {\n publish_id: publishId,\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n}\n","import { HttpClient } from '../../../infrastructure/http/HttpClient';\nimport { Logger } from '../../../infrastructure/logger/Logger';\nimport { WechatError } from '../../../errors/WechatError';\nimport { WECHAT_API_BASE, WECHAT_API_ENDPOINTS } from '../constants';\n\nexport interface UploadResult {\n media_id: string;\n url: string;\n}\n\nexport class MaterialAPI {\n constructor(\n private getAccessToken: () => Promise<string>,\n private httpClient: HttpClient,\n private logger: Logger\n ) {}\n\n async uploadImage(file: Buffer, filename: string): Promise<UploadResult> {\n this.logger.info('上传图片', { filename });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.MATERIAL_ADD}?access_token=${accessToken}&type=image`;\n\n const formData = new FormData();\n const blob = new Blob([file]);\n formData.append('media', blob, filename);\n\n const response = await this.httpClient.post(url, formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n if (data.url && data.url.startsWith('http://')) {\n data.url = data.url.replace(/^http:\\/\\//i, 'https://');\n }\n\n this.logger.info('图片上传成功', { media_id: data.media_id });\n return {\n media_id: data.media_id,\n url: data.url,\n };\n }\n\n async uploadThumb(file: Buffer, filename: string): Promise<UploadResult> {\n this.logger.info('上传封面图', { filename });\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.MATERIAL_ADD}?access_token=${accessToken}&type=thumb`;\n\n const formData = new FormData();\n const blob = new Blob([file]);\n formData.append('media', blob, filename);\n\n const response = await this.httpClient.post(url, formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n if (data.url && data.url.startsWith('http://')) {\n data.url = data.url.replace(/^http:\\/\\//i, 'https://');\n }\n\n this.logger.info('封面图上传成功', { media_id: data.media_id });\n return {\n media_id: data.media_id,\n url: data.url,\n };\n }\n\n async getMaterialCount(): Promise<{ voice_count: number; video_count: number; image_count: number; news_count: number }> {\n this.logger.info('获取素材总数');\n\n const accessToken = await this.getAccessToken();\n const url = `${WECHAT_API_BASE}${WECHAT_API_ENDPOINTS.MATERIAL_COUNT}?access_token=${accessToken}`;\n\n const response = await this.httpClient.get(url);\n\n const data = response.data;\n\n if (data.errcode && data.errcode !== 0) {\n throw WechatError.fromResponse(data);\n }\n\n return data;\n }\n}\n","import { TokenAPI } from './api/TokenAPI';\nimport { DraftAPI } from './api/DraftAPI';\nimport { PublishAPI } from './api/PublishAPI';\nimport { MaterialAPI } from './api/MaterialAPI';\nimport { HttpClient } from '../../infrastructure/http/HttpClient';\nimport { TokenCache } from '../../infrastructure/cache/TokenCache';\nimport { Logger } from '../../infrastructure/logger/Logger';\n\nexport class WechatClient {\n public readonly token: TokenAPI;\n public readonly draft: DraftAPI;\n public readonly publish: PublishAPI;\n public readonly material: MaterialAPI;\n\n constructor(\n private appId: string,\n appSecret: string,\n httpClient: HttpClient,\n tokenCache: TokenCache,\n logger: Logger\n ) {\n this.token = new TokenAPI(appId, appSecret, httpClient, tokenCache, logger);\n \n const getAccessToken = () => this.token.getAccessToken();\n \n this.draft = new DraftAPI(getAccessToken, httpClient, logger);\n this.publish = new PublishAPI(getAccessToken, httpClient, logger);\n this.material = new MaterialAPI(getAccessToken, httpClient, logger);\n }\n\n async getAccessToken(): Promise<string> {\n return await this.token.getAccessToken();\n }\n\n async refreshAccessToken(): Promise<string> {\n return await this.token.refreshAccessToken();\n }\n\n getAppId(): string {\n return this.appId;\n }\n}\n","import { BaseError } from './BaseError';\n\nexport class ThemeError extends BaseError {\n constructor(message: string, details?: any) {\n super(message, 'THEME_ERROR', 500, details);\n }\n}\n\nexport class ThemeNotFoundError extends BaseError {\n constructor(themeId: string) {\n super(`主题不存在: ${themeId}`, 'THEME_NOT_FOUND', 404, { themeId });\n }\n}\n\nexport class ThemeLoadError extends BaseError {\n constructor(themeId: string, reason: string) {\n super(`主题加载失败: ${themeId} - ${reason}`, 'THEME_LOAD_ERROR', 500, { themeId, reason });\n }\n}\n","import { readFile } from 'fs/promises';\nimport type { Theme } from '../../../types/theme';\nimport { ThemeLoadError } from '../../../errors/ThemeError';\n\nexport class LocalLoader {\n async load(name: string, path: string): Promise<Theme> {\n try {\n const css = await readFile(path, 'utf-8');\n \n return {\n id: name,\n name,\n type: 'local',\n description: `本地主题: ${path}`,\n getCss: async () => css,\n };\n } catch (error) {\n throw new ThemeLoadError(name, `无法读取文件: ${path}`);\n }\n }\n}\n","import axios from 'axios';\nimport type { Theme, ThemeSource, RemoteThemeConfig } from '../../../types/theme';\nimport { ThemeLoadError } from '../../../errors/ThemeError';\n\nexport class RemoteLoader {\n private configs: Map<string, RemoteThemeConfig> = new Map();\n\n async addAPI(name: string, apiUrl: string, apiKey: string): Promise<void> {\n this.configs.set(name, {\n name,\n apiUrl,\n apiKey,\n enabled: true,\n });\n }\n\n async load(themeId: string): Promise<Theme | null> {\n for (const [name, config] of this.configs) {\n if (!config.enabled) continue;\n\n try {\n const css = await this.fetchThemeCSS(config.apiUrl, config.apiKey, themeId);\n if (css) {\n return {\n id: themeId,\n name: `${name}:${themeId}`,\n type: 'remote',\n description: `远程主题来自 ${name}`,\n getCss: async () => css,\n };\n }\n } catch (error) {\n continue;\n }\n }\n\n return null;\n }\n\n async list(): Promise<ThemeSource[]> {\n const themes: ThemeSource[] = [];\n\n for (const [name, config] of this.configs) {\n if (!config.enabled) continue;\n\n try {\n const themeList = await this.fetchThemeList(config.apiUrl, config.apiKey);\n for (const themeId of themeList) {\n themes.push({\n type: 'remote',\n id: themeId,\n name: `${name}:${themeId}`,\n description: `远程主题来自 ${name}`,\n });\n }\n } catch (error) {\n continue;\n }\n }\n\n return themes;\n }\n\n getConfig(): RemoteThemeConfig[] {\n return Array.from(this.configs.values());\n }\n\n private async fetchThemeList(apiUrl: string, apiKey: string): Promise<string[]> {\n try {\n const response = await axios.get(`${apiUrl}/themes`, {\n headers: {\n 'X-API-Key': apiKey,\n },\n });\n return response.data.themes || [];\n } catch (error) {\n throw new ThemeLoadError('remote', '无法获取远程主题列表');\n }\n }\n\n private async fetchThemeCSS(apiUrl: string, apiKey: string, themeId: string): Promise<string | null> {\n try {\n const response = await axios.get(`${apiUrl}/themes/${themeId}`, {\n headers: {\n 'X-API-Key': apiKey,\n },\n });\n return response.data.css || null;\n } catch (error) {\n return null;\n }\n }\n}\n","import { readFile } from 'fs/promises';\nimport { join, dirname } from 'path';\nimport { createRequire } from 'module';\nimport type { Theme } from '../../../types/theme';\n\n// Use require to get the package's directory at runtime\nconst require = createRequire(import.meta.url);\n// require.resolve points to dist/index.js, so we need to go up to package root\nconst packageRoot = dirname(dirname(require.resolve('wechat-md-publisher')));\n\nconsole.log('[BuiltinLoader] packageRoot:', packageRoot);\n\n// Only use the 6 themes in themes/builtin/ folder\nconst LOCAL_THEMES = [\n { id: 'default', name: '默认主题', description: '简洁清爽的默认样式,适合各类文章' },\n { id: 'orangesun', name: 'Orange Sun', description: 'A warm and bright theme with orange sunshine vibes.' },\n { id: 'redruby', name: 'Red Ruby', description: 'An elegant theme with bold ruby red accents.' },\n { id: 'greenmint', name: 'Green Mint', description: 'A fresh and calming mint green theme.' },\n { id: 'purplerain', name: 'Purple Rain', description: 'A dreamy purple theme with soft gradients.' },\n { id: 'blackink', name: 'Black Ink', description: 'A dark mode theme with indigo accents for night reading.' },\n];\n\nexport class BuiltinLoader {\n async loadAll(): Promise<Theme[]> {\n const themes: Theme[] = [];\n\n // FIXED: Only load LOCAL_THEMES that have matching CSS files\n for (const themeInfo of LOCAL_THEMES) {\n try {\n const themePath = join(packageRoot, 'themes', 'builtin', `${themeInfo.id}.css`);\n const css = await readFile(themePath, 'utf-8');\n\n themes.push({\n id: themeInfo.id,\n name: themeInfo.name,\n type: 'builtin',\n description: themeInfo.description,\n getCss: async () => css,\n });\n } catch (error) {\n console.warn(`[BuiltinLoader] Failed to load theme \"${themeInfo.id}\":`, error instanceof Error ? error.message : error);\n continue;\n }\n }\n\n return themes;\n }\n}\n","import type { Theme, ThemeSource } from '../../types/theme';\n\nexport class ThemeRegistry {\n private themes: Map<string, Theme> = new Map();\n\n register(theme: Theme): void {\n this.themes.set(theme.id, theme);\n }\n\n get(id: string): Theme | undefined {\n return this.themes.get(id);\n }\n\n has(id: string): boolean {\n return this.themes.has(id);\n }\n\n remove(id: string): void {\n this.themes.delete(id);\n }\n\n list(): ThemeSource[] {\n return Array.from(this.themes.values()).map(theme => ({\n type: theme.type,\n id: theme.id,\n name: theme.name,\n description: theme.description,\n }));\n }\n\n getLocalThemes(): ThemeSource[] {\n return this.list().filter(t => t.type === 'local');\n }\n\n clear(): void {\n this.themes.clear();\n }\n}\n","import { LocalLoader } from './loaders/LocalLoader';\nimport { RemoteLoader } from './loaders/RemoteLoader';\nimport { BuiltinLoader } from './loaders/BuiltinLoader';\nimport { ThemeRegistry } from './registry';\nimport { ThemeNotFoundError } from '../../errors/ThemeError';\nimport type { ThemeSource } from '../../types/theme';\n\nexport class ThemeEngine {\n private registry: ThemeRegistry;\n private localLoader: LocalLoader;\n private remoteLoader: RemoteLoader;\n private builtinLoader: BuiltinLoader;\n\n constructor() {\n this.registry = new ThemeRegistry();\n this.localLoader = new LocalLoader();\n this.remoteLoader = new RemoteLoader();\n this.builtinLoader = new BuiltinLoader();\n }\n\n async loadBuiltinThemes(): Promise<void> {\n const themes = await this.builtinLoader.loadAll();\n for (const theme of themes) {\n this.registry.register(theme);\n }\n }\n\n async addLocalTheme(name: string, path: string): Promise<void> {\n const theme = await this.localLoader.load(name, path);\n this.registry.register(theme);\n }\n\n async addRemoteAPI(name: string, apiUrl: string, apiKey: string): Promise<void> {\n await this.remoteLoader.addAPI(name, apiUrl, apiKey);\n }\n\n async getThemeCSS(themeId: string): Promise<string> {\n const theme = this.registry.get(themeId);\n if (theme) {\n return await theme.getCss();\n }\n\n const remoteTheme = await this.remoteLoader.load(themeId);\n if (remoteTheme) {\n return await remoteTheme.getCss();\n }\n\n throw new ThemeNotFoundError(themeId);\n }\n\n async listThemes(): Promise<ThemeSource[]> {\n const themes: ThemeSource[] = [];\n \n themes.push(...this.registry.list());\n \n themes.push(...await this.remoteLoader.list());\n\n return themes;\n }\n\n async removeTheme(themeId: string): Promise<void> {\n this.registry.remove(themeId);\n }\n\n async getConfig(): Promise<any> {\n return {\n local: this.registry.getLocalThemes(),\n remote: this.remoteLoader.getConfig(),\n };\n }\n}\n","import { createWenyanCore } from '@wenyan-md/core';\nimport type { ApplyStylesOptions } from '@wenyan-md/core';\nimport { JSDOM } from 'jsdom';\n\nexport interface RenderResult {\n title: string;\n content: string;\n cover?: string;\n}\n\nexport class MarkdownRenderer {\n private wenyan: any;\n\n async initialize(): Promise<void> {\n this.wenyan = await createWenyanCore({\n isConvertMathJax: true,\n isWechat: true,\n });\n }\n\n async render(markdown: string, themeCss?: string): Promise<RenderResult> {\n if (!this.wenyan) {\n await this.initialize();\n }\n\n const result = await this.wenyan.handleFrontMatter(markdown);\n \n if (!result || !result.body) {\n throw new Error('Invalid markdown: handleFrontMatter returned empty data');\n }\n \n const html = await this.wenyan.renderMarkdown(result.body);\n\n const dom = new JSDOM(html);\n const document = dom.window.document;\n const wenyanElement = document.createElement('div');\n wenyanElement.id = 'wenyan';\n wenyanElement.innerHTML = html;\n\n const options: ApplyStylesOptions = {\n themeCss,\n isMacStyle: true,\n isAddFootnote: false,\n };\n\n const styledHtml = await this.wenyan.applyStylesWithTheme(wenyanElement, options);\n\n return {\n title: result.title || '',\n content: styledHtml,\n cover: result.cover,\n };\n }\n}\n","import Conf from 'conf';\nimport { z } from 'zod';\nimport type { Config } from '../../types/config';\n\nconst AccountSchema = z.object({\n id: z.string(),\n name: z.string(),\n appId: z.string().regex(/^wx[a-zA-Z0-9]{16}$/, '无效的 AppID 格式'),\n appSecret: z.string().min(32, 'AppSecret 长度不足'),\n isDefault: z.boolean().optional(),\n createdAt: z.date().optional(),\n updatedAt: z.date().optional(),\n});\n\nexport class ConfigStore {\n private store: Conf<Config>;\n\n constructor() {\n this.store = new Conf<Config>({\n projectName: 'wechat-md-publisher',\n });\n }\n\n get<K extends keyof Config>(key: K): Config[K] | undefined;\n get<K extends keyof Config>(key: K, defaultValue: Config[K]): Config[K];\n get<K extends keyof Config>(key: K, defaultValue?: Config[K]): Config[K] | undefined {\n return this.store.get(key, defaultValue as any);\n }\n\n set<K extends keyof Config>(key: K, value: Config[K]): void {\n if (key === 'accounts') {\n z.array(AccountSchema).parse(value);\n }\n this.store.set(key, value);\n }\n\n has(key: keyof Config): boolean {\n return this.store.has(key);\n }\n\n delete(key: keyof Config): void {\n this.store.delete(key);\n }\n\n clear(): void {\n this.store.clear();\n }\n\n getAll(): Config {\n return this.store.store;\n }\n\n getPath(): string {\n return this.store.path;\n }\n}\n","import winston from 'winston';\n\nexport class Logger {\n private logger: winston.Logger;\n\n constructor() {\n this.logger = winston.createLogger({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json()\n ),\n transports: [\n new winston.transports.Console({\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.printf(({ level, message, timestamp, ...meta }) => {\n const metaStr = Object.keys(meta).length ? JSON.stringify(meta) : '';\n return `${timestamp} [${level}]: ${message} ${metaStr}`;\n })\n ),\n }),\n ],\n });\n }\n\n debug(message: string, meta?: any): void {\n this.logger.debug(message, meta);\n }\n\n info(message: string, meta?: any): void {\n this.logger.info(message, meta);\n }\n\n warn(message: string, meta?: any): void {\n this.logger.warn(message, meta);\n }\n\n error(message: string, meta?: any): void {\n this.logger.error(message, meta);\n }\n}\n"],"names":["require"],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -1,9 +1,12 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2
5
  import { Command } from "commander";
3
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
4
7
  import { resolve, isAbsolute, dirname, join } from "path";
5
8
  import { fileURLToPath } from "url";
6
- import { C as ConfigStore, L as Logger, T as ThemeEngine, M as MarkdownRenderer, d as WechatClient } from "./Logger-CRPQmRrm.js";
9
+ import { C as ConfigStore, L as Logger, T as ThemeEngine, M as MarkdownRenderer, d as WechatClient } from "./Logger-mgxqCI3-.js";
7
10
  import axios from "axios";
8
11
  import initSqlJs from "sql.js";
9
12
  import { JSDOM } from "jsdom";
@@ -13,9 +16,9 @@ import chalk from "chalk";
13
16
  import Table from "cli-table3";
14
17
  import ora from "ora";
15
18
  class CacheStore {
16
- cache = /* @__PURE__ */ new Map();
17
- maxSize;
18
19
  constructor(maxSize = 100) {
20
+ __publicField(this, "cache", /* @__PURE__ */ new Map());
21
+ __publicField(this, "maxSize");
19
22
  this.maxSize = maxSize;
20
23
  }
21
24
  async get(key) {
@@ -106,6 +109,7 @@ class ThemeCache extends CacheStore {
106
109
  }
107
110
  class HttpClient {
108
111
  constructor(logger) {
112
+ __publicField(this, "client");
109
113
  this.logger = logger;
110
114
  this.client = axios.create({
111
115
  timeout: 3e4,
@@ -115,7 +119,6 @@ class HttpClient {
115
119
  });
116
120
  this.setupInterceptors();
117
121
  }
118
- client;
119
122
  setupInterceptors() {
120
123
  this.client.interceptors.request.use(
121
124
  (config) => {
@@ -139,8 +142,9 @@ class HttpClient {
139
142
  return response;
140
143
  },
141
144
  (error) => {
145
+ var _a;
142
146
  this.logger.error("HTTP Response Error", {
143
- status: error.response?.status,
147
+ status: (_a = error.response) == null ? void 0 : _a.status,
144
148
  message: error.message
145
149
  });
146
150
  return Promise.reject(error);
@@ -161,10 +165,10 @@ class HttpClient {
161
165
  }
162
166
  }
163
167
  class DatabaseManager {
164
- db;
165
- logger;
166
- dbPath;
167
168
  constructor(logger) {
169
+ __publicField(this, "db");
170
+ __publicField(this, "logger");
171
+ __publicField(this, "dbPath");
168
172
  this.logger = logger;
169
173
  }
170
174
  async initialize(dbPath) {
@@ -682,9 +686,9 @@ class PublishService {
682
686
  const __filename$2 = fileURLToPath(import.meta.url);
683
687
  const __dirname$2 = dirname(__filename$2);
684
688
  class WrapperService {
685
- dbManager;
686
- logger;
687
689
  constructor(dbManager, logger) {
690
+ __publicField(this, "dbManager");
691
+ __publicField(this, "logger");
688
692
  this.dbManager = dbManager;
689
693
  this.logger = logger;
690
694
  }
@@ -692,12 +696,32 @@ class WrapperService {
692
696
  * 加载默认配置
693
697
  */
694
698
  loadDefaultConfig() {
699
+ var _a, _b;
695
700
  try {
696
- const configPath = resolve(__dirname$2, "../../config/default-wrapper.json");
697
- if (existsSync(configPath)) {
698
- const content = readFileSync(configPath, "utf-8");
699
- return JSON.parse(content);
701
+ const possiblePaths = [
702
+ // 全局安装: node_modules/wechat-md-publisher/config/
703
+ resolve(__dirname$2, "../../config/default-wrapper.json"),
704
+ // 从当前工作目录(项目根目录)查找
705
+ resolve(process.cwd(), "config/default-wrapper.json"),
706
+ // 回退:从模块目录查找
707
+ resolve(__dirname$2, "../../../config/default-wrapper.json")
708
+ ];
709
+ for (const configPath of possiblePaths) {
710
+ if (existsSync(configPath)) {
711
+ const content = readFileSync(configPath, "utf-8");
712
+ const config = JSON.parse(content);
713
+ this.logger.debug("成功加载默认配置", {
714
+ configPath,
715
+ headerLength: ((_a = config.header) == null ? void 0 : _a.length) || 0,
716
+ footerLength: ((_b = config.footer) == null ? void 0 : _b.length) || 0
717
+ });
718
+ return config;
719
+ }
700
720
  }
721
+ this.logger.warn("默认配置文件不存在", {
722
+ triedPaths: possiblePaths,
723
+ __dirname: __dirname$2
724
+ });
701
725
  } catch (error) {
702
726
  this.logger.warn("无法加载默认 wrapper 配置", { error });
703
727
  }
@@ -712,17 +736,21 @@ class WrapperService {
712
736
  const result = db.exec("SELECT COUNT(*) as count FROM wrapper_versions");
713
737
  if (result.length > 0 && result[0].values[0][0] === 0) {
714
738
  const defaultConfig = this.loadDefaultConfig();
715
- if (defaultConfig) {
716
- db.run(`
717
- INSERT INTO wrapper_versions (version, enabled, header, footer, author)
718
- VALUES (1, 0, ?, ?, 'system')
719
- `, [
720
- defaultConfig.header,
721
- defaultConfig.footer
722
- ]);
723
- this.dbManager.save();
724
- this.logger.info("已初始化默认 wrapper 配置(关闭状态)");
739
+ if (!defaultConfig) {
740
+ throw new Error("无法加载默认 wrapper 配置文件,请确保 config/default-wrapper.json 存在");
725
741
  }
742
+ db.run(`
743
+ INSERT INTO wrapper_versions (version, enabled, header, footer, author)
744
+ VALUES (1, 0, ?, ?, 'system')
745
+ `, [
746
+ defaultConfig.header,
747
+ defaultConfig.footer
748
+ ]);
749
+ this.dbManager.save();
750
+ this.logger.info("已初始化默认 wrapper 配置(关闭状态)", {
751
+ headerLength: defaultConfig.header.length,
752
+ footerLength: defaultConfig.footer.length
753
+ });
726
754
  }
727
755
  }
728
756
  /**
@@ -757,7 +785,6 @@ class WrapperService {
757
785
  * 开启 Wrapper
758
786
  */
759
787
  enable() {
760
- this.initializeDefaultIfNeeded();
761
788
  const config = this.get();
762
789
  if (config.enabled) {
763
790
  this.logger.info("Wrapper 已经开启");
@@ -771,18 +798,7 @@ class WrapperService {
771
798
  WHERE version = ?
772
799
  `, [config.version]);
773
800
  } else {
774
- const defaultConfig = this.loadDefaultConfig();
775
- if (defaultConfig) {
776
- db.run(`
777
- INSERT INTO wrapper_versions (version, enabled, header, footer, author)
778
- VALUES (1, 1, ?, ?, 'system')
779
- `, [defaultConfig.header, defaultConfig.footer]);
780
- } else {
781
- db.run(`
782
- INSERT INTO wrapper_versions (version, enabled, header, footer, author)
783
- VALUES (1, 1, '', '', 'system')
784
- `);
785
- }
801
+ throw new Error("无法开启 Wrapper:数据库未初始化");
786
802
  }
787
803
  this.dbManager.save();
788
804
  this.logger.info("Wrapper 已开启");
@@ -885,19 +901,21 @@ class WrapperService {
885
901
  }
886
902
  }
887
903
  class Container {
888
- configStore;
889
- logger;
890
- httpClient;
891
- dbManager;
892
- tokenCache;
893
- imageCache;
894
- themeCache;
895
- themeEngine;
896
- renderer;
897
- accountService;
898
- themeService;
899
- renderService;
900
- wrapperService;
904
+ constructor() {
905
+ __publicField(this, "configStore");
906
+ __publicField(this, "logger");
907
+ __publicField(this, "httpClient");
908
+ __publicField(this, "dbManager");
909
+ __publicField(this, "tokenCache");
910
+ __publicField(this, "imageCache");
911
+ __publicField(this, "themeCache");
912
+ __publicField(this, "themeEngine");
913
+ __publicField(this, "renderer");
914
+ __publicField(this, "accountService");
915
+ __publicField(this, "themeService");
916
+ __publicField(this, "renderService");
917
+ __publicField(this, "wrapperService");
918
+ }
901
919
  async initialize() {
902
920
  this.configStore = new ConfigStore();
903
921
  this.logger = new Logger();
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, 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}\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: '' };\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 src;\n }\n\n const result = await this.uploadImage(src, relativePath);\n element.setAttribute('src', result.url);\n return result.media_id;\n });\n\n const mediaIds = (await Promise.all(uploadPromises)).filter(Boolean) as string[];\n const firstImageMediaId = mediaIds[0] || '';\n\n return {\n content: dom.serialize(),\n firstImageMediaId,\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 async uploadCover(coverPath: string | undefined, relativePath?: string, fallbackMediaId?: string): Promise<string> {\n if (!coverPath) {\n if (fallbackMediaId) {\n return fallbackMediaId;\n }\n throw new Error('必须指定封面图或在正文中至少包含一张图片');\n }\n\n if (isWechatImageUrl(coverPath)) {\n const md5 = md5FromBuffer(Buffer.from(coverPath));\n const cached = await this.imageCache.getMediaId(md5);\n if (cached) {\n return cached;\n }\n }\n\n const result = await this.uploadImage(coverPath, relativePath);\n return result.media_id;\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 );\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 // 从模块安装目录查找配置文件(相对于编译后的 dist/services 目录)\n const configPath = resolve(__dirname, '../../config/default-wrapper.json');\n if (existsSync(configPath)) {\n const content = readFileSync(configPath, 'utf-8');\n return JSON.parse(content);\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 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 }\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 // 确保已初始化默认配置\n this.initializeDefaultIfNeeded();\n \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 if (config.version > 0) {\n // 更新当前版本的状态为 enabled\n db.run(`\n UPDATE wrapper_versions \n SET enabled = 1 \n WHERE version = ?\n `, [config.version]);\n } else {\n // 首次启用,加载默认配置\n const defaultConfig = this.loadDefaultConfig();\n if (defaultConfig) {\n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (1, 1, ?, ?, 'system')\n `, [defaultConfig.header, defaultConfig.footer]);\n } else {\n // 如果没有默认配置文件,插入空内容\n db.run(`\n INSERT INTO wrapper_versions (version, enabled, header, footer, author)\n VALUES (1, 1, '', '', 'system')\n `);\n }\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}\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: '' };\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 src;\n }\n\n const result = await this.uploadImage(src, relativePath);\n element.setAttribute('src', result.url);\n return result.media_id;\n });\n\n const mediaIds = (await Promise.all(uploadPromises)).filter(Boolean) as string[];\n const firstImageMediaId = mediaIds[0] || '';\n\n return {\n content: dom.serialize(),\n firstImageMediaId,\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 async uploadCover(coverPath: string | undefined, relativePath?: string, fallbackMediaId?: string): Promise<string> {\n if (!coverPath) {\n if (fallbackMediaId) {\n return fallbackMediaId;\n }\n throw new Error('必须指定封面图或在正文中至少包含一张图片');\n }\n\n if (isWechatImageUrl(coverPath)) {\n const md5 = md5FromBuffer(Buffer.from(coverPath));\n const cached = await this.imageCache.getMediaId(md5);\n if (cached) {\n return cached;\n }\n }\n\n const result = await this.uploadImage(coverPath, relativePath);\n return result.media_id;\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 );\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 // 方法1: 从 npm 包安装目录查找(全局安装时使用)\n const possiblePaths = [\n // 全局安装: node_modules/wechat-md-publisher/config/\n resolve(__dirname, '../../config/default-wrapper.json'),\n // 从当前工作目录(项目根目录)查找\n resolve(process.cwd(), 'config/default-wrapper.json'),\n // 回退:从模块目录查找\n resolve(__dirname, '../../../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 \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":"WrapperService.d.ts","sourceRoot":"","sources":["../../src/services/WrapperService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAQzD,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM;IAKtD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAqBjC;;OAEG;IACH,GAAG,IAAI,aAAa;IA4BpB;;OAEG;IACH,MAAM,IAAI,IAAI;IAuCd;;OAEG;IACH,OAAO,IAAI,IAAI;IAkBf;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiB,GAAG,IAAI;IAcvE;;OAEG;IACH,OAAO,IAAI,cAAc,EAAE;IAsB3B;;OAEG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiB,GAAG,IAAI;IA4BhE;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAqBvC"}
1
+ {"version":3,"file":"WrapperService.d.ts","sourceRoot":"","sources":["../../src/services/WrapperService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AAQzD,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM;IAKtD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAmCzB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IA0BjC;;OAEG;IACH,GAAG,IAAI,aAAa;IA4BpB;;OAEG;IACH,MAAM,IAAI,IAAI;IAwBd;;OAEG;IACH,OAAO,IAAI,IAAI;IAkBf;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiB,GAAG,IAAI;IAcvE;;OAEG;IACH,OAAO,IAAI,cAAc,EAAE;IAsB3B;;OAEG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,GAAE,MAAiB,GAAG,IAAI;IA4BhE;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAqBvC"}
@@ -15,12 +15,31 @@ export class WrapperService {
15
15
  */
16
16
  loadDefaultConfig() {
17
17
  try {
18
- // 从模块安装目录查找配置文件(相对于编译后的 dist/services 目录)
19
- const configPath = resolve(__dirname, '../../config/default-wrapper.json');
20
- if (existsSync(configPath)) {
21
- const content = readFileSync(configPath, 'utf-8');
22
- return JSON.parse(content);
18
+ // 方法1: npm 包安装目录查找(全局安装时使用)
19
+ const possiblePaths = [
20
+ // 全局安装: node_modules/wechat-md-publisher/config/
21
+ resolve(__dirname, '../../config/default-wrapper.json'),
22
+ // 从当前工作目录(项目根目录)查找
23
+ resolve(process.cwd(), 'config/default-wrapper.json'),
24
+ // 回退:从模块目录查找
25
+ resolve(__dirname, '../../../config/default-wrapper.json'),
26
+ ];
27
+ for (const configPath of possiblePaths) {
28
+ if (existsSync(configPath)) {
29
+ const content = readFileSync(configPath, 'utf-8');
30
+ const config = JSON.parse(content);
31
+ this.logger.debug('成功加载默认配置', {
32
+ configPath,
33
+ headerLength: config.header?.length || 0,
34
+ footerLength: config.footer?.length || 0
35
+ });
36
+ return config;
37
+ }
23
38
  }
39
+ this.logger.warn('默认配置文件不存在', {
40
+ triedPaths: possiblePaths,
41
+ __dirname
42
+ });
24
43
  }
25
44
  catch (error) {
26
45
  this.logger.warn('无法加载默认 wrapper 配置', { error });
@@ -37,17 +56,21 @@ export class WrapperService {
37
56
  if (result.length > 0 && result[0].values[0][0] === 0) {
38
57
  // 数据库为空,加载默认配置(默认为关闭状态)
39
58
  const defaultConfig = this.loadDefaultConfig();
40
- if (defaultConfig) {
41
- db.run(`
42
- INSERT INTO wrapper_versions (version, enabled, header, footer, author)
43
- VALUES (1, 0, ?, ?, 'system')
44
- `, [
45
- defaultConfig.header,
46
- defaultConfig.footer
47
- ]);
48
- this.dbManager.save();
49
- this.logger.info('已初始化默认 wrapper 配置(关闭状态)');
59
+ if (!defaultConfig) {
60
+ throw new Error('无法加载默认 wrapper 配置文件,请确保 config/default-wrapper.json 存在');
50
61
  }
62
+ db.run(`
63
+ INSERT INTO wrapper_versions (version, enabled, header, footer, author)
64
+ VALUES (1, 0, ?, ?, 'system')
65
+ `, [
66
+ defaultConfig.header,
67
+ defaultConfig.footer
68
+ ]);
69
+ this.dbManager.save();
70
+ this.logger.info('已初始化默认 wrapper 配置(关闭状态)', {
71
+ headerLength: defaultConfig.header.length,
72
+ footerLength: defaultConfig.footer.length
73
+ });
51
74
  }
52
75
  }
53
76
  /**
@@ -82,16 +105,14 @@ export class WrapperService {
82
105
  * 开启 Wrapper
83
106
  */
84
107
  enable() {
85
- // 确保已初始化默认配置
86
- this.initializeDefaultIfNeeded();
87
108
  const config = this.get();
88
109
  if (config.enabled) {
89
110
  this.logger.info('Wrapper 已经开启');
90
111
  return;
91
112
  }
92
113
  const db = this.dbManager.getDatabase();
114
+ // 直接更新状态为 enabled(get() 已经确保数据存在)
93
115
  if (config.version > 0) {
94
- // 更新当前版本的状态为 enabled
95
116
  db.run(`
96
117
  UPDATE wrapper_versions
97
118
  SET enabled = 1
@@ -99,21 +120,8 @@ export class WrapperService {
99
120
  `, [config.version]);
100
121
  }
101
122
  else {
102
- // 首次启用,加载默认配置
103
- const defaultConfig = this.loadDefaultConfig();
104
- if (defaultConfig) {
105
- db.run(`
106
- INSERT INTO wrapper_versions (version, enabled, header, footer, author)
107
- VALUES (1, 1, ?, ?, 'system')
108
- `, [defaultConfig.header, defaultConfig.footer]);
109
- }
110
- else {
111
- // 如果没有默认配置文件,插入空内容
112
- db.run(`
113
- INSERT INTO wrapper_versions (version, enabled, header, footer, author)
114
- VALUES (1, 1, '', '', 'system')
115
- `);
116
- }
123
+ // 理论上不应该走到这里,因为 get() 会调用 initializeDefaultIfNeeded()
124
+ throw new Error('无法开启 Wrapper:数据库未初始化');
117
125
  }
118
126
  this.dbManager.save();
119
127
  this.logger.info('Wrapper 已开启');
@@ -1 +1 @@
1
- {"version":3,"file":"WrapperService.js","sourceRoot":"","sources":["../../src/services/WrapperService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WrapperService.js","sourceRoot":"","sources":["../../src/services/WrapperService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wechat-md-publisher",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "全功能微信公众号 Markdown 发布工具 - 支持草稿、发布、删除和多主题",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",