@skrillex1224/chrome-article-publish-extension 1.0.0
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/README.md +226 -0
- package/dist/adapters/index.d.ts +1125 -0
- package/dist/adapters/index.js +1900 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/chunk-7Q3KKWUB.js +602 -0
- package/dist/chunk-7Q3KKWUB.js.map +1 -0
- package/dist/chunk-IUAZAMKF.js +123 -0
- package/dist/chunk-IUAZAMKF.js.map +1 -0
- package/dist/chunk-QM2T4VGM.js +6688 -0
- package/dist/chunk-QM2T4VGM.js.map +1 -0
- package/dist/chunk-UO6CDRC5.js +322 -0
- package/dist/chunk-UO6CDRC5.js.map +1 -0
- package/dist/converter/index.d.ts +2 -0
- package/dist/converter/index.html +10 -0
- package/dist/converter/index.js +432 -0
- package/dist/converter/index.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +192 -0
- package/dist/index.js.map +1 -0
- package/dist/interface-BlLeWXzS.d.ts +265 -0
- package/dist/preprocessor/index.html +10 -0
- package/dist/runtime/index.d.ts +90 -0
- package/dist/runtime/index.js +9 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/types-BAnNlLpy.d.ts +140 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createExtensionRuntime
|
|
3
|
+
} from "./chunk-UO6CDRC5.js";
|
|
4
|
+
import {
|
|
5
|
+
BaijiahaoAdapter,
|
|
6
|
+
BilibiliAdapter,
|
|
7
|
+
CSDNAdapter,
|
|
8
|
+
CnblogsAdapter,
|
|
9
|
+
Cto51Adapter,
|
|
10
|
+
DouyinAdapter,
|
|
11
|
+
JuejinAdapter,
|
|
12
|
+
NeteaseAdapter,
|
|
13
|
+
SohuAdapter,
|
|
14
|
+
TencentAdapter,
|
|
15
|
+
ToutiaoAdapter,
|
|
16
|
+
WeixinAdapter
|
|
17
|
+
} from "./chunk-QM2T4VGM.js";
|
|
18
|
+
import "./chunk-7Q3KKWUB.js";
|
|
19
|
+
|
|
20
|
+
// src/publish.ts
|
|
21
|
+
var ADAPTERS = {
|
|
22
|
+
baijiahao: BaijiahaoAdapter,
|
|
23
|
+
bilibili: BilibiliAdapter,
|
|
24
|
+
cnblogs: CnblogsAdapter,
|
|
25
|
+
csdn: CSDNAdapter,
|
|
26
|
+
"51cto": Cto51Adapter,
|
|
27
|
+
douyin: DouyinAdapter,
|
|
28
|
+
juejin: JuejinAdapter,
|
|
29
|
+
netease: NeteaseAdapter,
|
|
30
|
+
sohu: SohuAdapter,
|
|
31
|
+
tencent: TencentAdapter,
|
|
32
|
+
toutiao: ToutiaoAdapter,
|
|
33
|
+
weixin: WeixinAdapter
|
|
34
|
+
};
|
|
35
|
+
function createAdapter(platform) {
|
|
36
|
+
const Adapter = ADAPTERS[platform];
|
|
37
|
+
return Adapter ? new Adapter() : null;
|
|
38
|
+
}
|
|
39
|
+
async function publish(request) {
|
|
40
|
+
const adapter = createAdapter(request.platform);
|
|
41
|
+
if (!adapter) {
|
|
42
|
+
return {
|
|
43
|
+
platform: request.platform,
|
|
44
|
+
state: "failed",
|
|
45
|
+
error: { message: "Platform not found", code: "unsupported" },
|
|
46
|
+
timestamp: Date.now()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
await adapter.init(request.runtime);
|
|
51
|
+
const result = await adapter.publish(normalizeArticle(request.article), {
|
|
52
|
+
...request.options,
|
|
53
|
+
onEvent: request.onEvent
|
|
54
|
+
});
|
|
55
|
+
return toPublishResult(request.platform, result);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return failedResult(request.platform, error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function checkAuth(request) {
|
|
61
|
+
const adapter = createAdapter(request.platform);
|
|
62
|
+
if (!adapter) {
|
|
63
|
+
return { isAuthenticated: false, error: "Platform not found" };
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
await adapter.init(request.runtime);
|
|
67
|
+
const auth = await adapter.checkAuth();
|
|
68
|
+
if (!auth.isAuthenticated && !auth.error) {
|
|
69
|
+
return { ...auth, error: "Not authenticated" };
|
|
70
|
+
}
|
|
71
|
+
return auth;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return { isAuthenticated: false, error: error instanceof Error ? error.message : String(error) };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function getStatus(request) {
|
|
77
|
+
const platform = request.platform;
|
|
78
|
+
const adapter = createAdapter(platform);
|
|
79
|
+
if (!adapter) {
|
|
80
|
+
return {
|
|
81
|
+
platform,
|
|
82
|
+
state: "unknown",
|
|
83
|
+
message: "Platform not found",
|
|
84
|
+
checkedAt: Date.now()
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (request.statusRef.platform !== platform) {
|
|
88
|
+
return {
|
|
89
|
+
platform,
|
|
90
|
+
state: "unknown",
|
|
91
|
+
message: `statusRef belongs to ${request.statusRef.platform}`,
|
|
92
|
+
checkedAt: Date.now()
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
await adapter.init(request.runtime);
|
|
97
|
+
if (!adapter.getStatus) {
|
|
98
|
+
return {
|
|
99
|
+
platform,
|
|
100
|
+
state: "unknown",
|
|
101
|
+
message: "Adapter status query is not implemented",
|
|
102
|
+
checkedAt: Date.now()
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return await adapter.getStatus(request.statusRef);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
return {
|
|
108
|
+
platform,
|
|
109
|
+
state: "unknown",
|
|
110
|
+
message: error instanceof Error ? error.message : String(error),
|
|
111
|
+
checkedAt: Date.now()
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function normalizeArticle(article) {
|
|
116
|
+
const input = article;
|
|
117
|
+
const markdown = input.markdown ?? input.body ?? input.content ?? "";
|
|
118
|
+
return {
|
|
119
|
+
title: input.title,
|
|
120
|
+
markdown,
|
|
121
|
+
html: input.html,
|
|
122
|
+
summary: input.summary ?? input.description,
|
|
123
|
+
cover: input.cover,
|
|
124
|
+
tags: input.tags,
|
|
125
|
+
category: input.category,
|
|
126
|
+
source: input.source
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function toPublishResult(platform, result) {
|
|
130
|
+
if (!result.success) {
|
|
131
|
+
return {
|
|
132
|
+
platform,
|
|
133
|
+
state: "failed",
|
|
134
|
+
error: { message: result.error || result.message || "Publish failed" },
|
|
135
|
+
timestamp: result.timestamp || Date.now()
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
const statusRef = createStatusRef(platform, result);
|
|
139
|
+
if (!statusRef.id && !statusRef.url) {
|
|
140
|
+
return {
|
|
141
|
+
platform,
|
|
142
|
+
state: "failed",
|
|
143
|
+
error: { message: "Publish succeeded but adapter did not return a statusRef source", code: "missing_status_ref" },
|
|
144
|
+
timestamp: result.timestamp || Date.now()
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
platform,
|
|
149
|
+
state: "succeeded",
|
|
150
|
+
statusRef,
|
|
151
|
+
postId: result.postId,
|
|
152
|
+
postUrl: result.postUrl,
|
|
153
|
+
timestamp: result.timestamp || Date.now()
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function createStatusRef(platform, result) {
|
|
157
|
+
return {
|
|
158
|
+
platform,
|
|
159
|
+
kind: getStatusKind(platform),
|
|
160
|
+
id: result.postId,
|
|
161
|
+
url: result.postUrl,
|
|
162
|
+
data: result.statusData
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function getStatusKind(platform) {
|
|
166
|
+
const kinds = {
|
|
167
|
+
bilibili: "opus",
|
|
168
|
+
cnblogs: "article",
|
|
169
|
+
douyin: "note",
|
|
170
|
+
weixin: "appmsg"
|
|
171
|
+
};
|
|
172
|
+
return kinds[platform] || "article";
|
|
173
|
+
}
|
|
174
|
+
function failedResult(platform, error) {
|
|
175
|
+
return {
|
|
176
|
+
platform,
|
|
177
|
+
state: "failed",
|
|
178
|
+
error: { message: error instanceof Error ? error.message : String(error) },
|
|
179
|
+
timestamp: Date.now()
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/index.ts
|
|
184
|
+
var VERSION = "1.0.0";
|
|
185
|
+
export {
|
|
186
|
+
VERSION,
|
|
187
|
+
checkAuth,
|
|
188
|
+
createExtensionRuntime,
|
|
189
|
+
getStatus,
|
|
190
|
+
publish
|
|
191
|
+
};
|
|
192
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/publish.ts","../src/index.ts"],"sourcesContent":["import type {\n Article,\n AuthResult,\n PublishEventHandler,\n PublishResult,\n PublishStatusRef,\n PublishStatusResult,\n SyncResult,\n} from './types'\nimport type { RuntimeInterface } from './runtime'\nimport type { ImageProgressCallback, PlatformAdapter } from './adapters/types'\nimport { BaijiahaoAdapter } from './adapters/platforms/baijiahao'\nimport { BilibiliAdapter } from './adapters/platforms/bilibili'\nimport { CnblogsAdapter } from './adapters/platforms/cnblogs'\nimport { CSDNAdapter } from './adapters/platforms/csdn'\nimport { Cto51Adapter } from './adapters/platforms/cto51'\nimport { DouyinAdapter } from './adapters/platforms/douyin'\nimport { JuejinAdapter } from './adapters/platforms/juejin'\nimport { NeteaseAdapter } from './adapters/platforms/netease'\nimport { SohuAdapter } from './adapters/platforms/sohu'\nimport { TencentAdapter } from './adapters/platforms/tencent'\nimport { ToutiaoAdapter } from './adapters/platforms/toutiao'\nimport { WeixinAdapter } from './adapters/platforms/weixin'\n\ntype AdapterConstructor = new () => PlatformAdapter\n\nconst ADAPTERS: Record<string, AdapterConstructor> = {\n baijiahao: BaijiahaoAdapter,\n bilibili: BilibiliAdapter,\n cnblogs: CnblogsAdapter,\n csdn: CSDNAdapter,\n '51cto': Cto51Adapter,\n douyin: DouyinAdapter,\n juejin: JuejinAdapter,\n netease: NeteaseAdapter,\n sohu: SohuAdapter,\n tencent: TencentAdapter,\n toutiao: ToutiaoAdapter,\n weixin: WeixinAdapter,\n}\n\nexport interface PublishArticleInput {\n title: string\n description?: string\n body?: string\n content?: string\n markdown?: string\n html?: string\n cover?: string\n tags?: string[]\n category?: string\n source?: Article['source']\n}\n\nexport interface PublishRequestOptions {\n onImageProgress?: ImageProgressCallback\n}\n\nexport interface PublishRequest {\n platform: string\n article: Article | PublishArticleInput\n runtime: RuntimeInterface\n onEvent?: PublishEventHandler\n options?: PublishRequestOptions\n}\n\nexport interface GetStatusRequest {\n platform: string\n runtime: RuntimeInterface\n statusRef: PublishStatusRef\n}\n\nexport interface CheckAuthRequest {\n platform: string\n runtime: RuntimeInterface\n}\n\nexport function getSupportedPlatforms(): string[] {\n return Object.keys(ADAPTERS)\n}\n\nexport function createAdapter(platform: string): PlatformAdapter | null {\n const Adapter = ADAPTERS[platform]\n return Adapter ? new Adapter() : null\n}\n\nexport async function publish(request: PublishRequest): Promise<PublishResult> {\n const adapter = createAdapter(request.platform)\n if (!adapter) {\n return {\n platform: request.platform,\n state: 'failed',\n error: { message: 'Platform not found', code: 'unsupported' },\n timestamp: Date.now(),\n }\n }\n\n try {\n await adapter.init(request.runtime)\n const result = await adapter.publish(normalizeArticle(request.article), {\n ...request.options,\n onEvent: request.onEvent,\n })\n return toPublishResult(request.platform, result)\n } catch (error) {\n return failedResult(request.platform, error)\n }\n}\n\nexport async function checkAuth(request: CheckAuthRequest): Promise<AuthResult> {\n const adapter = createAdapter(request.platform)\n if (!adapter) {\n return { isAuthenticated: false, error: 'Platform not found' }\n }\n\n try {\n await adapter.init(request.runtime)\n const auth = await adapter.checkAuth()\n if (!auth.isAuthenticated && !auth.error) {\n return { ...auth, error: 'Not authenticated' }\n }\n return auth\n } catch (error) {\n return { isAuthenticated: false, error: error instanceof Error ? error.message : String(error) }\n }\n}\n\nexport async function getStatus(request: GetStatusRequest): Promise<PublishStatusResult> {\n const platform = request.platform\n const adapter = createAdapter(platform)\n if (!adapter) {\n return {\n platform,\n state: 'unknown',\n message: 'Platform not found',\n checkedAt: Date.now(),\n }\n }\n\n if (request.statusRef.platform !== platform) {\n return {\n platform,\n state: 'unknown',\n message: `statusRef belongs to ${request.statusRef.platform}`,\n checkedAt: Date.now(),\n }\n }\n\n try {\n await adapter.init(request.runtime)\n if (!adapter.getStatus) {\n return {\n platform,\n state: 'unknown',\n message: 'Adapter status query is not implemented',\n checkedAt: Date.now(),\n }\n }\n return await adapter.getStatus(request.statusRef)\n } catch (error) {\n return {\n platform,\n state: 'unknown',\n message: error instanceof Error ? error.message : String(error),\n checkedAt: Date.now(),\n }\n }\n}\n\nfunction normalizeArticle(article: Article | PublishArticleInput): Article {\n const input = article as PublishArticleInput & Partial<Article>\n const markdown = input.markdown ?? input.body ?? input.content ?? ''\n\n return {\n title: input.title,\n markdown,\n html: input.html,\n summary: input.summary ?? input.description,\n cover: input.cover,\n tags: input.tags,\n category: input.category,\n source: input.source,\n }\n}\n\nfunction toPublishResult(platform: string, result: SyncResult): PublishResult {\n if (!result.success) {\n return {\n platform,\n state: 'failed',\n error: { message: result.error || result.message || 'Publish failed' },\n timestamp: result.timestamp || Date.now(),\n }\n }\n\n const statusRef = createStatusRef(platform, result)\n if (!statusRef.id && !statusRef.url) {\n return {\n platform,\n state: 'failed',\n error: { message: 'Publish succeeded but adapter did not return a statusRef source', code: 'missing_status_ref' },\n timestamp: result.timestamp || Date.now(),\n }\n }\n\n return {\n platform,\n state: 'succeeded',\n statusRef,\n postId: result.postId,\n postUrl: result.postUrl,\n timestamp: result.timestamp || Date.now(),\n }\n}\n\nfunction createStatusRef(platform: string, result: SyncResult): PublishStatusRef {\n return {\n platform,\n kind: getStatusKind(platform),\n id: result.postId,\n url: result.postUrl,\n data: result.statusData,\n }\n}\n\nfunction getStatusKind(platform: string): string {\n const kinds: Record<string, string> = {\n bilibili: 'opus',\n cnblogs: 'article',\n douyin: 'note',\n weixin: 'appmsg',\n }\n return kinds[platform] || 'article'\n}\n\nfunction failedResult(platform: string, error: unknown): PublishResult {\n return {\n platform,\n state: 'failed',\n error: { message: error instanceof Error ? error.message : String(error) },\n timestamp: Date.now(),\n }\n}\n","export { checkAuth, getStatus, publish } from './publish'\nexport { createExtensionRuntime } from './runtime'\nexport type {\n CheckAuthRequest,\n GetStatusRequest,\n PublishArticleInput,\n PublishRequest,\n PublishRequestOptions,\n} from './publish'\nexport type {\n Article,\n AuthResult,\n PublishError,\n PublishEvent,\n PublishEventHandler,\n PublishResult,\n PublishState,\n PublishStatusRef,\n PublishStatusResult,\n PublishStatusState,\n} from './types'\nexport type {\n MarkdownImageRenderOptions,\n MarkdownImageRenderResult,\n RuntimeConfig,\n RuntimeInterface,\n} from './runtime/interface'\n\n// Version\nexport const VERSION = '1.0.0'\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 文章内容
|
|
3
|
+
*
|
|
4
|
+
* 内容格式说明:
|
|
5
|
+
* - markdown: 主要内容格式,由 content script 使用 Turndown + 原生 DOM 转换
|
|
6
|
+
* - html: 可选的原始 HTML,某些平台可能需要
|
|
7
|
+
*/
|
|
8
|
+
interface Article {
|
|
9
|
+
title: string;
|
|
10
|
+
markdown: string;
|
|
11
|
+
html?: string;
|
|
12
|
+
summary?: string;
|
|
13
|
+
cover?: string;
|
|
14
|
+
tags?: string[];
|
|
15
|
+
category?: string;
|
|
16
|
+
source?: {
|
|
17
|
+
url: string;
|
|
18
|
+
platform: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 同步结果
|
|
23
|
+
*/
|
|
24
|
+
interface SyncResult {
|
|
25
|
+
platform: string;
|
|
26
|
+
success: boolean;
|
|
27
|
+
postId?: string;
|
|
28
|
+
postUrl?: string;
|
|
29
|
+
statusData?: Record<string, string | number | boolean | null>;
|
|
30
|
+
error?: string;
|
|
31
|
+
message?: string;
|
|
32
|
+
timestamp: number;
|
|
33
|
+
}
|
|
34
|
+
type PublishState = 'succeeded' | 'failed';
|
|
35
|
+
type PublishStatusState = 'published' | 'reviewing' | 'rejected' | 'not_found' | 'unknown';
|
|
36
|
+
type SecurityCheckMethod = 'qrcode' | 'captcha' | 'manual';
|
|
37
|
+
interface PublishStatusRef {
|
|
38
|
+
platform: string;
|
|
39
|
+
kind: string;
|
|
40
|
+
id?: string;
|
|
41
|
+
url?: string;
|
|
42
|
+
data?: Record<string, string | number | boolean | null>;
|
|
43
|
+
}
|
|
44
|
+
interface PublishEvent {
|
|
45
|
+
type: 'progress' | 'security_check';
|
|
46
|
+
platform: string;
|
|
47
|
+
message: string;
|
|
48
|
+
expiresAt: number;
|
|
49
|
+
url?: string;
|
|
50
|
+
method?: SecurityCheckMethod;
|
|
51
|
+
}
|
|
52
|
+
type PublishEventHandler = (event: PublishEvent) => void | Promise<void>;
|
|
53
|
+
interface PublishError {
|
|
54
|
+
message: string;
|
|
55
|
+
code?: string;
|
|
56
|
+
}
|
|
57
|
+
type PublishResult = {
|
|
58
|
+
platform: string;
|
|
59
|
+
state: 'succeeded';
|
|
60
|
+
statusRef: PublishStatusRef;
|
|
61
|
+
postId?: string;
|
|
62
|
+
postUrl?: string;
|
|
63
|
+
timestamp: number;
|
|
64
|
+
} | {
|
|
65
|
+
platform: string;
|
|
66
|
+
state: 'failed';
|
|
67
|
+
error: PublishError;
|
|
68
|
+
timestamp: number;
|
|
69
|
+
};
|
|
70
|
+
interface PublishStatusResult {
|
|
71
|
+
platform: string;
|
|
72
|
+
state: PublishStatusState;
|
|
73
|
+
message?: string;
|
|
74
|
+
postUrl?: string;
|
|
75
|
+
checkedAt: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 认证状态
|
|
79
|
+
*/
|
|
80
|
+
interface AuthResult {
|
|
81
|
+
isAuthenticated: boolean;
|
|
82
|
+
username?: string;
|
|
83
|
+
userId?: string;
|
|
84
|
+
avatar?: string;
|
|
85
|
+
error?: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 平台能力
|
|
89
|
+
*/
|
|
90
|
+
type PlatformCapability = 'article' | 'draft' | 'image_upload' | 'categories' | 'tags' | 'cover' | 'schedule';
|
|
91
|
+
/**
|
|
92
|
+
* 平台元信息
|
|
93
|
+
*/
|
|
94
|
+
interface PlatformMeta {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
icon: string;
|
|
98
|
+
homepage: string;
|
|
99
|
+
capabilities: PlatformCapability[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Cookie
|
|
103
|
+
*/
|
|
104
|
+
interface Cookie {
|
|
105
|
+
name: string;
|
|
106
|
+
value: string;
|
|
107
|
+
domain: string;
|
|
108
|
+
path?: string;
|
|
109
|
+
secure?: boolean;
|
|
110
|
+
httpOnly?: boolean;
|
|
111
|
+
expirationDate?: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Header 规则
|
|
115
|
+
*/
|
|
116
|
+
interface HeaderRule {
|
|
117
|
+
id?: string;
|
|
118
|
+
urlFilter: string;
|
|
119
|
+
headers: Record<string, string>;
|
|
120
|
+
resourceTypes?: string[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface MarkdownImageRenderOptions {
|
|
124
|
+
title?: string;
|
|
125
|
+
theme?: string;
|
|
126
|
+
width?: number;
|
|
127
|
+
height?: number;
|
|
128
|
+
scale?: number;
|
|
129
|
+
maxPages?: number;
|
|
130
|
+
}
|
|
131
|
+
interface MarkdownImageRenderResult {
|
|
132
|
+
src: string;
|
|
133
|
+
width: number;
|
|
134
|
+
height: number;
|
|
135
|
+
index: number;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 运行时接口抽象
|
|
139
|
+
* 支持在浏览器扩展和 Node.js 环境中复用核心逻辑
|
|
140
|
+
*/
|
|
141
|
+
interface RuntimeInterface {
|
|
142
|
+
/** 运行时类型标识 */
|
|
143
|
+
readonly type: 'extension' | 'node';
|
|
144
|
+
/**
|
|
145
|
+
* HTTP 请求
|
|
146
|
+
* 在扩展环境自动携带 cookies,Node 环境需手动管理
|
|
147
|
+
*/
|
|
148
|
+
fetch(url: string, options?: RequestInit): Promise<Response>;
|
|
149
|
+
/**
|
|
150
|
+
* Cookie 管理
|
|
151
|
+
*/
|
|
152
|
+
cookies: {
|
|
153
|
+
get(domain: string): Promise<Cookie[]>;
|
|
154
|
+
set(cookie: Cookie): Promise<void>;
|
|
155
|
+
remove(name: string, domain: string): Promise<void>;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* 获取单个 Cookie 值(便捷方法)
|
|
159
|
+
* @param domain Cookie 域名
|
|
160
|
+
* @param name Cookie 名称
|
|
161
|
+
* @returns Cookie 值,不存在返回 null
|
|
162
|
+
*/
|
|
163
|
+
getCookie?(domain: string, name: string): Promise<string | null>;
|
|
164
|
+
/**
|
|
165
|
+
* 持久化存储
|
|
166
|
+
*/
|
|
167
|
+
storage: {
|
|
168
|
+
get<T>(key: string): Promise<T | null>;
|
|
169
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
170
|
+
remove(key: string): Promise<void>;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* 会话存储 (扩展重启后清空)
|
|
174
|
+
*/
|
|
175
|
+
session: {
|
|
176
|
+
get<T>(key: string): Promise<T | null>;
|
|
177
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Header 规则管理 (用于请求拦截)
|
|
181
|
+
* 仅扩展环境支持
|
|
182
|
+
*/
|
|
183
|
+
headerRules?: {
|
|
184
|
+
add(rule: HeaderRule): Promise<string>;
|
|
185
|
+
remove(ruleId: string): Promise<void>;
|
|
186
|
+
clear(): Promise<void>;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* 文件下载(仅扩展环境支持)
|
|
190
|
+
*/
|
|
191
|
+
downloads?: {
|
|
192
|
+
/**
|
|
193
|
+
* 下载文件
|
|
194
|
+
* @param blob 文件内容
|
|
195
|
+
* @param filename 文件名
|
|
196
|
+
* @param saveAs 是否弹出保存对话框
|
|
197
|
+
* @returns 下载 ID
|
|
198
|
+
*/
|
|
199
|
+
download(blob: Blob, filename: string, saveAs?: boolean): Promise<number>;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* Markdown 转图片
|
|
203
|
+
* Service Worker 通过扩展页面渲染,Node 环境可选择不实现
|
|
204
|
+
*/
|
|
205
|
+
renderMarkdownToImages?(markdown: string, options?: MarkdownImageRenderOptions): Promise<MarkdownImageRenderResult[]>;
|
|
206
|
+
/**
|
|
207
|
+
* Tab 管理(仅扩展环境支持)
|
|
208
|
+
*/
|
|
209
|
+
tabs?: {
|
|
210
|
+
/**
|
|
211
|
+
* 查找匹配 URL 的 tab
|
|
212
|
+
*/
|
|
213
|
+
query(urlPattern: string): Promise<Array<{
|
|
214
|
+
id: number;
|
|
215
|
+
url?: string;
|
|
216
|
+
}>>;
|
|
217
|
+
/**
|
|
218
|
+
* 创建新 tab
|
|
219
|
+
*/
|
|
220
|
+
create(url: string, active?: boolean): Promise<{
|
|
221
|
+
id: number;
|
|
222
|
+
}>;
|
|
223
|
+
/**
|
|
224
|
+
* 等待 tab 加载完成
|
|
225
|
+
*/
|
|
226
|
+
waitForLoad(tabId: number, timeout?: number): Promise<void>;
|
|
227
|
+
/**
|
|
228
|
+
* 在 tab 的页面上下文中执行函数
|
|
229
|
+
* @param tabId Tab ID
|
|
230
|
+
* @param func 要执行的函数
|
|
231
|
+
* @param args 函数参数
|
|
232
|
+
* @returns 函数执行结果
|
|
233
|
+
*/
|
|
234
|
+
executeScript<T, A extends unknown[]>(tabId: number, func: (...args: A) => T | Promise<T>, args: A): Promise<T>;
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* DOM 操作
|
|
238
|
+
* 扩展环境通过 Offscreen Document 实现
|
|
239
|
+
* Node 环境使用 jsdom 或类似库
|
|
240
|
+
*/
|
|
241
|
+
dom: {
|
|
242
|
+
parseHTML(html: string): Promise<Document>;
|
|
243
|
+
querySelector(doc: Document, selector: string): Element | null;
|
|
244
|
+
querySelectorAll(doc: Document, selector: string): Element[];
|
|
245
|
+
getTextContent(element: Element): string;
|
|
246
|
+
getInnerHTML(element: Element): string;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* 创建运行时的工厂函数类型
|
|
251
|
+
*/
|
|
252
|
+
type RuntimeFactory = (config?: RuntimeConfig) => RuntimeInterface;
|
|
253
|
+
/**
|
|
254
|
+
* 运行时配置
|
|
255
|
+
*/
|
|
256
|
+
interface RuntimeConfig {
|
|
257
|
+
/** Node 环境:预加载的 cookies */
|
|
258
|
+
cookies?: Record<string, Cookie[]>;
|
|
259
|
+
/** 请求超时时间 (ms) */
|
|
260
|
+
timeout?: number;
|
|
261
|
+
/** 用户代理 */
|
|
262
|
+
userAgent?: string;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export type { AuthResult as A, Cookie as C, HeaderRule as H, MarkdownImageRenderOptions as M, PlatformMeta as P, RuntimeInterface as R, SyncResult as S, Article as a, PublishEventHandler as b, PublishStatusRef as c, PublishStatusResult as d, PublishResult as e, MarkdownImageRenderResult as f, PublishError as g, PublishEvent as h, PublishState as i, PublishStatusState as j, RuntimeConfig as k, RuntimeFactory as l };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { k as RuntimeConfig, R as RuntimeInterface, C as Cookie, H as HeaderRule, M as MarkdownImageRenderOptions, f as MarkdownImageRenderResult } from '../interface-BlLeWXzS.js';
|
|
2
|
+
export { l as RuntimeFactory } from '../interface-BlLeWXzS.js';
|
|
3
|
+
|
|
4
|
+
declare class ExtensionRuntime implements RuntimeInterface {
|
|
5
|
+
private config?;
|
|
6
|
+
readonly type: "extension";
|
|
7
|
+
private ruleIdBase;
|
|
8
|
+
private ruleIdCounter;
|
|
9
|
+
constructor(config?: RuntimeConfig | undefined);
|
|
10
|
+
/**
|
|
11
|
+
* HTTP 请求 - 自动携带 cookies,带超时保护
|
|
12
|
+
*/
|
|
13
|
+
fetch(url: string, options?: RequestInit): Promise<Response>;
|
|
14
|
+
/**
|
|
15
|
+
* Cookie 管理
|
|
16
|
+
*/
|
|
17
|
+
cookies: {
|
|
18
|
+
get(domain: string): Promise<Cookie[]>;
|
|
19
|
+
set(cookie: Cookie): Promise<void>;
|
|
20
|
+
remove(name: string, domain: string): Promise<void>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* 获取单个 Cookie 值(便捷方法)
|
|
24
|
+
*/
|
|
25
|
+
getCookie(domain: string, name: string): Promise<string | null>;
|
|
26
|
+
/**
|
|
27
|
+
* 持久化存储
|
|
28
|
+
*/
|
|
29
|
+
storage: {
|
|
30
|
+
get<T>(key: string): Promise<T | null>;
|
|
31
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
32
|
+
remove(key: string): Promise<void>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* 会话存储
|
|
36
|
+
*/
|
|
37
|
+
session: {
|
|
38
|
+
get<T>(key: string): Promise<T | null>;
|
|
39
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Header 规则管理 (declarativeNetRequest)
|
|
43
|
+
* 规则只对扩展自身发起的请求生效,不影响其他网页
|
|
44
|
+
*/
|
|
45
|
+
headerRules: {
|
|
46
|
+
add: (rule: HeaderRule) => Promise<string>;
|
|
47
|
+
remove: (ruleId: string) => Promise<void>;
|
|
48
|
+
clear: () => Promise<void>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* 文件下载
|
|
52
|
+
* Service Worker 中不支持 URL.createObjectURL,使用 data URL 替代
|
|
53
|
+
*/
|
|
54
|
+
downloads: {
|
|
55
|
+
download(blob: Blob, filename: string, saveAs?: boolean): Promise<number>;
|
|
56
|
+
};
|
|
57
|
+
renderMarkdownToImages(markdown: string, options?: MarkdownImageRenderOptions): Promise<MarkdownImageRenderResult[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Tab 管理
|
|
60
|
+
*/
|
|
61
|
+
tabs: {
|
|
62
|
+
query(urlPattern: string): Promise<Array<{
|
|
63
|
+
id: number;
|
|
64
|
+
url?: string;
|
|
65
|
+
}>>;
|
|
66
|
+
create(url: string, active?: boolean): Promise<{
|
|
67
|
+
id: number;
|
|
68
|
+
}>;
|
|
69
|
+
waitForLoad(tabId: number, timeout?: number): Promise<void>;
|
|
70
|
+
executeScript<T, A extends unknown[]>(tabId: number, func: (...args: A) => T | Promise<T>, args: A): Promise<T>;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* DOM 操作 - 通过 Offscreen Document 实现
|
|
74
|
+
*/
|
|
75
|
+
dom: {
|
|
76
|
+
parseHTML: (html: string) => Promise<Document>;
|
|
77
|
+
querySelector: (doc: Document, selector: string) => Element | null;
|
|
78
|
+
querySelectorAll: (doc: Document, selector: string) => Element[];
|
|
79
|
+
getTextContent: (element: Element) => string;
|
|
80
|
+
getInnerHTML: (element: Element) => string;
|
|
81
|
+
};
|
|
82
|
+
private waitForTabComplete;
|
|
83
|
+
private sendRuntimeMessageWithTimeout;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 创建扩展运行时实例
|
|
87
|
+
*/
|
|
88
|
+
declare function createExtensionRuntime(config?: RuntimeConfig): ExtensionRuntime;
|
|
89
|
+
|
|
90
|
+
export { ExtensionRuntime, MarkdownImageRenderOptions, MarkdownImageRenderResult, RuntimeConfig, RuntimeInterface, createExtensionRuntime };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|