wechat-md-publisher 0.3.5 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Logger-CXtK4XH3.js → Logger-DtWQXK5s.js} +11 -2
- package/dist/{Logger-CXtK4XH3.js.map → Logger-DtWQXK5s.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/core/renderer/MarkdownRenderer.d.ts.map +1 -1
- package/dist/core/renderer/MarkdownRenderer.js +11 -1
- package/dist/core/renderer/MarkdownRenderer.js.map +1 -1
- package/package.json +13 -11
- package/themes/builtin/lapis.css +0 -0
- package/themes/builtin/maize.css +0 -0
- package/themes/builtin/phycat.css +0 -0
- package/themes/builtin/pie.css +0 -0
- package/themes/builtin/purple.css +0 -0
- package/themes/builtin/rainbow.css +0 -0
- package/themes/builtin/sport.css +55 -69
|
@@ -620,9 +620,18 @@ class MarkdownRenderer {
|
|
|
620
620
|
};
|
|
621
621
|
await this.wenyan.applyStylesWithTheme(wenyanElement, options);
|
|
622
622
|
const styledHtml = wenyanElement.innerHTML;
|
|
623
|
+
const postDom = new JSDOM(styledHtml);
|
|
624
|
+
const postDoc = postDom.window.document;
|
|
625
|
+
const emptyPTags = postDoc.querySelectorAll("p");
|
|
626
|
+
for (const p of emptyPTags) {
|
|
627
|
+
if (!p.textContent.trim()) {
|
|
628
|
+
p.remove();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
const filteredHtml = postDoc.body.innerHTML;
|
|
623
632
|
return {
|
|
624
633
|
title: attributes.title || "",
|
|
625
|
-
content:
|
|
634
|
+
content: filteredHtml,
|
|
626
635
|
cover: attributes.cover
|
|
627
636
|
};
|
|
628
637
|
}
|
|
@@ -718,4 +727,4 @@ export {
|
|
|
718
727
|
WechatError as e,
|
|
719
728
|
WechatRateLimitError as f
|
|
720
729
|
};
|
|
721
|
-
//# sourceMappingURL=Logger-
|
|
730
|
+
//# sourceMappingURL=Logger-DtWQXK5s.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Logger-CXtK4XH3.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 } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\nimport type { Theme } from '../../../types/theme';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst BUILTIN_THEMES = [\n { id: 'default', name: '默认主题', description: '简洁清爽的默认样式,适合各类文章' },\n { id: 'lapis', name: 'Lapis', description: 'A minimal and refreshing theme in cool blue tones.' },\n { id: 'maize', name: 'Maize', description: 'A crisp, light theme with a soft maize palette.' },\n { id: 'orangeheart', name: 'Orange Heart', description: 'A vibrant and elegant theme in warm orange tones.' },\n { id: 'phycat', name: '物理猫-薄荷', description: 'A mint-green theme with clear structure and hierarchy.' },\n { id: 'pie', name: 'Pie', description: 'Inspired by sspai.com and Misty — modern, sharp, and stylish.' },\n { id: 'purple', name: 'Purple', description: 'Clean and minimalist, with a subtle purple accent.' },\n { id: 'rainbow', name: 'Rainbow', description: 'A colorful, lively theme with a clean layout.' },\n { id: 'sport', name: '运动风', description: '活力 · 动感 · 渐变色,适合体育和科技内容' },\n];\n\nexport class BuiltinLoader {\n async loadAll(): Promise<Theme[]> {\n const themes: Theme[] = [];\n\n for (const themeInfo of BUILTIN_THEMES) {\n try {\n const themePath = join(__dirname, '../../../..', '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 if (themes.length === 0) {\n console.error('[BuiltinLoader] No builtin themes were loaded. Check if themes directory exists.');\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 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 const { createWenyanCore } = await import('@wenyan-md/core');\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 { body, attributes } = await this.wenyan.handleFrontMatter(markdown);\n const html = await this.wenyan.renderMarkdown(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 await this.wenyan.applyStylesWithTheme(wenyanElement, options);\n const styledHtml = wenyanElement.innerHTML;\n\n return {\n title: attributes.title || '',\n content: styledHtml,\n cover: attributes.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":["__filename","__dirname"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Logger-DtWQXK5s.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 } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\nimport type { Theme } from '../../../types/theme';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst BUILTIN_THEMES = [\n { id: 'default', name: '默认主题', description: '简洁清爽的默认样式,适合各类文章' },\n { id: 'lapis', name: 'Lapis', description: 'A minimal and refreshing theme in cool blue tones.' },\n { id: 'maize', name: 'Maize', description: 'A crisp, light theme with a soft maize palette.' },\n { id: 'orangeheart', name: 'Orange Heart', description: 'A vibrant and elegant theme in warm orange tones.' },\n { id: 'phycat', name: '物理猫-薄荷', description: 'A mint-green theme with clear structure and hierarchy.' },\n { id: 'pie', name: 'Pie', description: 'Inspired by sspai.com and Misty — modern, sharp, and stylish.' },\n { id: 'purple', name: 'Purple', description: 'Clean and minimalist, with a subtle purple accent.' },\n { id: 'rainbow', name: 'Rainbow', description: 'A colorful, lively theme with a clean layout.' },\n { id: 'sport', name: '运动风', description: '活力 · 动感 · 渐变色,适合体育和科技内容' },\n];\n\nexport class BuiltinLoader {\n async loadAll(): Promise<Theme[]> {\n const themes: Theme[] = [];\n\n for (const themeInfo of BUILTIN_THEMES) {\n try {\n const themePath = join(__dirname, '../../../..', '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 if (themes.length === 0) {\n console.error('[BuiltinLoader] No builtin themes were loaded. Check if themes directory exists.');\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 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 const { createWenyanCore } = await import('@wenyan-md/core');\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 { body, attributes } = await this.wenyan.handleFrontMatter(markdown);\n const html = await this.wenyan.renderMarkdown(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 await this.wenyan.applyStylesWithTheme(wenyanElement, options);\n const styledHtml = wenyanElement.innerHTML;\n\n // 过滤空 <p> 标签\n const postDom = new JSDOM(styledHtml);\n const postDoc = postDom.window.document;\n const emptyPTags = postDoc.querySelectorAll('p');\n for (const p of emptyPTags) {\n if (!p.textContent.trim()) {\n p.remove();\n }\n }\n const filteredHtml = postDoc.body.innerHTML;\n\n return {\n title: attributes.title || '',\n content: filteredHtml,\n cover: attributes.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":["__filename","__dirname"],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from "commander";
|
|
|
3
3
|
import { readFileSync } from "fs";
|
|
4
4
|
import { isAbsolute, resolve, dirname, join } from "path";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
|
-
import { C as ConfigStore, L as Logger, T as ThemeEngine, M as MarkdownRenderer, d as WechatClient } from "./Logger-
|
|
6
|
+
import { C as ConfigStore, L as Logger, T as ThemeEngine, M as MarkdownRenderer, d as WechatClient } from "./Logger-DtWQXK5s.js";
|
|
7
7
|
import axios from "axios";
|
|
8
8
|
import { JSDOM } from "jsdom";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../src/core/renderer/MarkdownRenderer.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAM;IAEd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../src/core/renderer/MarkdownRenderer.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAM;IAEd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAwC3E"}
|
|
@@ -26,9 +26,19 @@ export class MarkdownRenderer {
|
|
|
26
26
|
};
|
|
27
27
|
await this.wenyan.applyStylesWithTheme(wenyanElement, options);
|
|
28
28
|
const styledHtml = wenyanElement.innerHTML;
|
|
29
|
+
// 过滤空 <p> 标签
|
|
30
|
+
const postDom = new JSDOM(styledHtml);
|
|
31
|
+
const postDoc = postDom.window.document;
|
|
32
|
+
const emptyPTags = postDoc.querySelectorAll('p');
|
|
33
|
+
for (const p of emptyPTags) {
|
|
34
|
+
if (!p.textContent.trim()) {
|
|
35
|
+
p.remove();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const filteredHtml = postDoc.body.innerHTML;
|
|
29
39
|
return {
|
|
30
40
|
title: attributes.title || '',
|
|
31
|
-
content:
|
|
41
|
+
content: filteredHtml,
|
|
32
42
|
cover: attributes.cover,
|
|
33
43
|
};
|
|
34
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../src/core/renderer/MarkdownRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAQ9B,MAAM,OAAO,gBAAgB;IACjB,MAAM,CAAM;IAEpB,KAAK,CAAC,UAAU;QACZ,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACjC,gBAAgB,EAAE,IAAI;YACtB,QAAQ,EAAE,IAAI;SACjB,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,QAAiB;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;QACrC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpD,aAAa,CAAC,EAAE,GAAG,QAAQ,CAAC;QAC5B,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC;QAE/B,MAAM,OAAO,GAAuB;YAChC,QAAQ;YACR,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,KAAK;SACvB,CAAC;QAEF,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC;QAE3C,OAAO;YACH,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,EAAE;YAC7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../src/core/renderer/MarkdownRenderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAQ9B,MAAM,OAAO,gBAAgB;IACjB,MAAM,CAAM;IAEpB,KAAK,CAAC,UAAU;QACZ,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACjC,gBAAgB,EAAE,IAAI;YACtB,QAAQ,EAAE,IAAI;SACjB,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,QAAiB;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;QACrC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACpD,aAAa,CAAC,EAAE,GAAG,QAAQ,CAAC;QAC5B,aAAa,CAAC,SAAS,GAAG,IAAI,CAAC;QAE/B,MAAM,OAAO,GAAuB;YAChC,QAAQ;YACR,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,KAAK;SACvB,CAAC;QAEF,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC;QAE3C,aAAa;QACb,MAAM,OAAO,GAAG,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QACxC,MAAM,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC;gBACxB,CAAC,CAAC,MAAM,EAAE,CAAC;YACf,CAAC;QACL,CAAC;QACD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAE5C,OAAO;YACH,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,EAAE;YAC7B,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,UAAU,CAAC,KAAK;SAC1B,CAAC;IACN,CAAC;CACJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wechat-md-publisher",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "全功能微信公众号 Markdown 发布工具 - 支持草稿、发布、删除和多主题",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,6 +15,16 @@
|
|
|
15
15
|
"README.md",
|
|
16
16
|
"LICENSE"
|
|
17
17
|
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "vite build --watch",
|
|
20
|
+
"build": "vite build && tsc",
|
|
21
|
+
"test": "vitest",
|
|
22
|
+
"test:unit": "vitest run tests/unit",
|
|
23
|
+
"test:integration": "vitest run tests/integration",
|
|
24
|
+
"lint": "eslint src --ext .ts",
|
|
25
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
26
|
+
"prepublishOnly": "pnpm build"
|
|
27
|
+
},
|
|
18
28
|
"keywords": [
|
|
19
29
|
"wechat",
|
|
20
30
|
"weixin",
|
|
@@ -35,6 +45,7 @@
|
|
|
35
45
|
"url": "https://github.com/sipingme/wechat-md-publisher/issues"
|
|
36
46
|
},
|
|
37
47
|
"homepage": "https://github.com/sipingme/wechat-md-publisher#readme",
|
|
48
|
+
"packageManager": "pnpm@10.7.1",
|
|
38
49
|
"dependencies": {
|
|
39
50
|
"@wenyan-md/core": "^2.0.8",
|
|
40
51
|
"commander": "^12.1.0",
|
|
@@ -65,14 +76,5 @@
|
|
|
65
76
|
"jsdom": "^27.4.0",
|
|
66
77
|
"form-data-encoder": "^4.1.0",
|
|
67
78
|
"formdata-node": "^6.0.3"
|
|
68
|
-
},
|
|
69
|
-
"scripts": {
|
|
70
|
-
"dev": "vite build --watch",
|
|
71
|
-
"build": "vite build && tsc",
|
|
72
|
-
"test": "vitest",
|
|
73
|
-
"test:unit": "vitest run tests/unit",
|
|
74
|
-
"test:integration": "vitest run tests/integration",
|
|
75
|
-
"lint": "eslint src --ext .ts",
|
|
76
|
-
"format": "prettier --write \"src/**/*.ts\""
|
|
77
79
|
}
|
|
78
|
-
}
|
|
80
|
+
}
|
package/themes/builtin/lapis.css
CHANGED
|
File without changes
|
package/themes/builtin/maize.css
CHANGED
|
File without changes
|
|
File without changes
|
package/themes/builtin/pie.css
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/themes/builtin/sport.css
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
/* Sports Theme -
|
|
2
|
-
*
|
|
1
|
+
/* Sports Theme - WeChat Compatible Version
|
|
2
|
+
* 运动风主题 - 微信公众号兼容版
|
|
3
|
+
* 特点:活力 · 动感 · 简洁
|
|
3
4
|
* 主色调:#00A968 (翠绿色)
|
|
5
|
+
*
|
|
6
|
+
* 说明:
|
|
7
|
+
* 1. 移除了所有渐变效果,改用纯色
|
|
8
|
+
* 2. 移除了阴影效果
|
|
9
|
+
* 3. 简化了圆角效果
|
|
10
|
+
* 4. 移除了伪元素,列表样式需在 HTML 层面处理
|
|
11
|
+
* 5. 移除了交互效果(hover、transition)
|
|
12
|
+
* 6. 所有样式需转换为内联样式(inline style)才能在微信中生效
|
|
4
13
|
*/
|
|
5
14
|
|
|
6
15
|
#wenyan {
|
|
@@ -14,7 +23,7 @@
|
|
|
14
23
|
letter-spacing: 0.02em;
|
|
15
24
|
}
|
|
16
25
|
|
|
17
|
-
/* 一级标题 -
|
|
26
|
+
/* 一级标题 - 纯色背景替代渐变 */
|
|
18
27
|
#wenyan h1 {
|
|
19
28
|
padding: 0.6em 1.5em;
|
|
20
29
|
margin: 2.2em 0 1.2em;
|
|
@@ -24,13 +33,11 @@
|
|
|
24
33
|
text-align: center;
|
|
25
34
|
letter-spacing: 0.12em;
|
|
26
35
|
line-height: 1.4;
|
|
27
|
-
background:
|
|
28
|
-
border-radius:
|
|
29
|
-
box-shadow: 0 8px 20px rgba(0, 169, 104, 0.3);
|
|
30
|
-
text-transform: uppercase;
|
|
36
|
+
background-color: #00A968;
|
|
37
|
+
border-radius: 8px;
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
/* 二级标题 -
|
|
40
|
+
/* 二级标题 - 左边框样式 */
|
|
34
41
|
#wenyan h2 {
|
|
35
42
|
padding: 0.4em 1em 0.5em 1em;
|
|
36
43
|
margin: 1.6em 0 0.8em;
|
|
@@ -40,11 +47,9 @@
|
|
|
40
47
|
letter-spacing: 0.06em;
|
|
41
48
|
line-height: 1.4;
|
|
42
49
|
color: #00A968;
|
|
43
|
-
background:
|
|
50
|
+
background-color: #f0faf5;
|
|
44
51
|
border-left: 4px solid #00A968;
|
|
45
|
-
border-radius: 0
|
|
46
|
-
box-shadow: 0 3px 8px rgba(0, 169, 104, 0.12);
|
|
47
|
-
text-transform: uppercase;
|
|
52
|
+
border-radius: 0 8px 8px 0;
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
/* 三级标题 - 简化版二级标题 */
|
|
@@ -57,24 +62,21 @@
|
|
|
57
62
|
text-align: left;
|
|
58
63
|
letter-spacing: 0.08em;
|
|
59
64
|
border-left: 4px solid #00A968;
|
|
60
|
-
background:
|
|
61
|
-
border-radius: 0
|
|
65
|
+
background-color: #f8f8f8;
|
|
66
|
+
border-radius: 0 8px 8px 0;
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
/* 段落 */
|
|
65
70
|
#wenyan p {
|
|
66
|
-
margin: 0 !important;
|
|
71
|
+
margin: 0.8em 0 !important;
|
|
67
72
|
text-align: left !important;
|
|
68
73
|
line-height: 1.8 !important;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
/* 加粗 -
|
|
76
|
+
/* 加粗 - 使用纯色替代渐变 */
|
|
72
77
|
#wenyan strong {
|
|
73
78
|
font-weight: 700;
|
|
74
|
-
|
|
75
|
-
-webkit-background-clip: text;
|
|
76
|
-
-webkit-text-fill-color: transparent;
|
|
77
|
-
background-clip: text;
|
|
79
|
+
color: #00A968;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
/* 斜体 */
|
|
@@ -88,10 +90,10 @@
|
|
|
88
90
|
#wenyan code {
|
|
89
91
|
font-size: 90%;
|
|
90
92
|
color: #00A968;
|
|
91
|
-
background:
|
|
93
|
+
background-color: #f0faf5;
|
|
92
94
|
padding: 3px 6px;
|
|
93
95
|
border-radius: 4px;
|
|
94
|
-
font-family:
|
|
96
|
+
font-family: Menlo, Consolas, monospace;
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
/* 代码块 */
|
|
@@ -102,14 +104,17 @@
|
|
|
102
104
|
padding: 1.2em;
|
|
103
105
|
line-height: 1.6;
|
|
104
106
|
margin: 1.5em 0;
|
|
105
|
-
background:
|
|
106
|
-
|
|
107
|
+
background-color: #f8f8f8;
|
|
108
|
+
border-top: 3px solid #00A968;
|
|
109
|
+
border-left: 1px solid #e0e0e0;
|
|
110
|
+
border-right: 1px solid #e0e0e0;
|
|
111
|
+
border-bottom: 1px solid #e0e0e0;
|
|
107
112
|
}
|
|
108
113
|
|
|
109
114
|
#wenyan pre code {
|
|
110
|
-
background:
|
|
115
|
+
background-color: transparent;
|
|
111
116
|
padding: 0;
|
|
112
|
-
font-family:
|
|
117
|
+
font-family: Menlo, Consolas, monospace;
|
|
113
118
|
font-size: 14px;
|
|
114
119
|
color: #2c2c2c;
|
|
115
120
|
line-height: 1.6;
|
|
@@ -121,7 +126,7 @@
|
|
|
121
126
|
padding: 1.2em 1.5em;
|
|
122
127
|
border-left: 5px solid #00A968;
|
|
123
128
|
color: #3c3c3e;
|
|
124
|
-
background: #f8f8f8;
|
|
129
|
+
background-color: #f8f8f8;
|
|
125
130
|
border-radius: 0 8px 8px 0;
|
|
126
131
|
margin: 1.8em 0;
|
|
127
132
|
}
|
|
@@ -132,59 +137,44 @@
|
|
|
132
137
|
line-height: 1.8;
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
/* 无序列表
|
|
140
|
+
/* 无序列表
|
|
141
|
+
* 注意:微信不支持 ::before 伪元素
|
|
142
|
+
* 建议在 HTML 生成时直接添加 "• " 符号
|
|
143
|
+
*/
|
|
136
144
|
#wenyan ul {
|
|
137
|
-
list-style: none;
|
|
138
|
-
padding: 0;
|
|
145
|
+
list-style-type: none;
|
|
146
|
+
padding-left: 0;
|
|
139
147
|
margin: 1.5em 0;
|
|
140
148
|
}
|
|
141
149
|
|
|
142
150
|
#wenyan ul li {
|
|
143
151
|
margin: 0.6em 0;
|
|
144
|
-
padding:
|
|
152
|
+
padding-left: 1.5em;
|
|
145
153
|
line-height: 1.8;
|
|
146
154
|
}
|
|
147
155
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
margin-right: 0.5em;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/* 有序列表 */
|
|
156
|
+
/* 有序列表
|
|
157
|
+
* 注意:微信不支持 counter-reset 和 ::before
|
|
158
|
+
* 建议使用默认列表样式或在 HTML 生成时添加序号
|
|
159
|
+
*/
|
|
156
160
|
#wenyan ol {
|
|
157
|
-
list-style:
|
|
158
|
-
|
|
161
|
+
list-style-type: decimal;
|
|
162
|
+
list-style-position: outside;
|
|
163
|
+
padding-left: 2em;
|
|
159
164
|
margin: 1.5em 0;
|
|
160
|
-
counter-reset: list-counter;
|
|
161
165
|
}
|
|
162
166
|
|
|
163
167
|
#wenyan ol li {
|
|
164
168
|
margin: 0.6em 0;
|
|
165
|
-
padding: 0;
|
|
169
|
+
padding-left: 0.5em;
|
|
166
170
|
line-height: 1.8;
|
|
167
|
-
counter-increment: list-counter;
|
|
168
171
|
}
|
|
169
172
|
|
|
170
|
-
|
|
171
|
-
content: counter(list-counter) ". ";
|
|
172
|
-
color: #00A968;
|
|
173
|
-
font-weight: bold;
|
|
174
|
-
margin-right: 0.5em;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/* 链接 */
|
|
173
|
+
/* 链接 - 移除 hover 效果 */
|
|
178
174
|
#wenyan a {
|
|
179
175
|
color: #00A968;
|
|
180
176
|
text-decoration: none;
|
|
181
177
|
border-bottom: 1px solid #00A968;
|
|
182
|
-
transition: all 0.3s ease;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
#wenyan a:hover {
|
|
186
|
-
color: #008A56;
|
|
187
|
-
border-bottom-color: #008A56;
|
|
188
178
|
}
|
|
189
179
|
|
|
190
180
|
/* 图片 */
|
|
@@ -193,7 +183,7 @@
|
|
|
193
183
|
height: auto;
|
|
194
184
|
border-radius: 8px;
|
|
195
185
|
margin: 1.5em 0;
|
|
196
|
-
|
|
186
|
+
border: 1px solid #e0e0e0;
|
|
197
187
|
}
|
|
198
188
|
|
|
199
189
|
/* 表格 */
|
|
@@ -201,26 +191,22 @@
|
|
|
201
191
|
width: 100%;
|
|
202
192
|
border-collapse: collapse;
|
|
203
193
|
margin: 1.8em 0;
|
|
204
|
-
border
|
|
205
|
-
overflow: hidden;
|
|
206
|
-
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
207
|
-
border: 2px solid transparent;
|
|
194
|
+
border: 1px solid #e0e0e0;
|
|
208
195
|
}
|
|
209
196
|
|
|
210
197
|
#wenyan table th {
|
|
211
198
|
padding: 12px 16px;
|
|
212
199
|
text-align: left;
|
|
213
200
|
font-weight: 700;
|
|
214
|
-
background:
|
|
201
|
+
background-color: #f0faf5;
|
|
215
202
|
color: #00A968;
|
|
216
|
-
border-bottom: 2px solid
|
|
217
|
-
text-transform: uppercase;
|
|
203
|
+
border-bottom: 2px solid #00A968;
|
|
218
204
|
letter-spacing: 0.04em;
|
|
219
205
|
}
|
|
220
206
|
|
|
221
207
|
#wenyan table td {
|
|
222
208
|
padding: 10px 16px;
|
|
223
|
-
border-bottom: 1px solid
|
|
209
|
+
border-bottom: 1px solid #e0e0e0;
|
|
224
210
|
color: #2c2c2c;
|
|
225
211
|
}
|
|
226
212
|
|
|
@@ -228,10 +214,10 @@
|
|
|
228
214
|
border-bottom: none;
|
|
229
215
|
}
|
|
230
216
|
|
|
231
|
-
/* 分割线 */
|
|
217
|
+
/* 分割线 - 使用纯色替代渐变 */
|
|
232
218
|
#wenyan hr {
|
|
233
219
|
height: 3px;
|
|
234
220
|
border: none;
|
|
235
221
|
margin: 3em 0;
|
|
236
|
-
background-
|
|
222
|
+
background-color: #00A968;
|
|
237
223
|
}
|