@skrillex1224/chrome-article-publish-extension 1.0.6 → 1.0.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.
@@ -579,6 +579,7 @@ declare class DouyinAdapter extends CodeAdapter {
579
579
  };
580
580
  private userInfo;
581
581
  private cachedImageXToken;
582
+ private activePublishOptions;
582
583
  private readonly HEADER_RULES;
583
584
  checkAuth(): Promise<AuthResult>;
584
585
  publish(article: Article, options?: PublishOptions): Promise<SyncResult>;
@@ -586,11 +587,14 @@ declare class DouyinAdapter extends CodeAdapter {
586
587
  private createPublishContext;
587
588
  private publishVideo;
588
589
  getStatus(statusRef: PublishStatusRef): Promise<PublishStatusResult>;
590
+ private queryItemStatus;
591
+ private isTransientStatusError;
589
592
  private resolveStatusId;
590
593
  private getStatusUserId;
591
594
  private resolveCurrentUserId;
592
595
  private fetchItemDetail;
593
596
  private fetchItemMget;
597
+ private getCreatorJsonWithFetchFallback;
594
598
  private extractDetailStatusItem;
595
599
  private extractMgetStatusItem;
596
600
  private toStatusItem;
@@ -620,6 +624,7 @@ declare class DouyinAdapter extends CodeAdapter {
620
624
  private extractBodyText;
621
625
  private normalizeText;
622
626
  private buildPublishItem;
627
+ private resolveDouyinHashtag;
623
628
  private uploadDouyinVideo;
624
629
  private waitForVideoTransend;
625
630
  private buildVideoPublishPayload;
@@ -633,6 +638,8 @@ declare class DouyinAdapter extends CodeAdapter {
633
638
  private assertPublishSuccess;
634
639
  private extractPublishPostId;
635
640
  private looksLikeSecondVerify;
641
+ private throwSecondVerify;
642
+ private notifySecondVerify;
636
643
  private detectImageSize;
637
644
  private parseJsonText;
638
645
  private pickString;
@@ -15,7 +15,7 @@ import {
15
15
  createLogger,
16
16
  htmlToMarkdown,
17
17
  parseMarkdownImages
18
- } from "../chunk-HHDGQYVN.js";
18
+ } from "../chunk-NERXWCKG.js";
19
19
 
20
20
  // src/adapters/types.ts
21
21
  var DEFAULT_PREPROCESS_CONFIG = {
@@ -198,14 +198,23 @@ var ExtensionRuntime = class {
198
198
  chrome.tabs.onUpdated.removeListener(listener);
199
199
  reject(new Error("Tab load timeout"));
200
200
  }, timeout);
201
+ const finish = () => {
202
+ clearTimeout(timeoutId);
203
+ chrome.tabs.onUpdated.removeListener(listener);
204
+ setTimeout(resolve, 1e3);
205
+ };
201
206
  const listener = (updatedTabId, info) => {
202
207
  if (updatedTabId === tabId && info.status === "complete") {
203
- clearTimeout(timeoutId);
204
- chrome.tabs.onUpdated.removeListener(listener);
205
- setTimeout(resolve, 1e3);
208
+ finish();
206
209
  }
207
210
  };
208
211
  chrome.tabs.onUpdated.addListener(listener);
212
+ chrome.tabs.get(tabId, (tab) => {
213
+ if (chrome.runtime.lastError) return;
214
+ if (tab?.status === "complete") {
215
+ finish();
216
+ }
217
+ });
209
218
  });
210
219
  },
211
220
  withManagedTab: async (options, callback) => {
@@ -299,4 +308,4 @@ export {
299
308
  ExtensionRuntime,
300
309
  createExtensionRuntime
301
310
  };
302
- //# sourceMappingURL=chunk-DTCVBBPG.js.map
311
+ //# sourceMappingURL=chunk-AR6FTEUE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/chrome-extension.ts"],"sourcesContent":["import type { ManagedTabHandle, ManagedTabOptions, RuntimeInterface, RuntimeConfig } from './interface'\nimport type { Cookie, HeaderRule } from '../types'\n\n/**\n * Chrome 扩展运行时实现\n */\n// 默认请求超时:30 秒\nconst DEFAULT_FETCH_TIMEOUT = 30 * 1000\nconst RUNTIME_TAB_GROUP_TITLE = 'Article Publish Runtime'\n\nexport class ExtensionRuntime implements RuntimeInterface {\n readonly type = 'extension' as const\n // 使用时间戳+随机数避免规则 ID 冲突(扩展重载或并发场景)\n private ruleIdBase = Date.now() % 100000\n private ruleIdCounter = 0\n private runtimeTabGroupId: number | null = null\n\n constructor(private config?: RuntimeConfig) {}\n\n /**\n * HTTP 请求 - 自动携带 cookies,带超时保护\n */\n async fetch(url: string, options?: RequestInit): Promise<Response> {\n const timeout = this.config?.timeout ?? DEFAULT_FETCH_TIMEOUT\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n try {\n const response = await fetch(url, {\n ...options,\n credentials: 'include',\n signal: controller.signal,\n })\n return response\n } catch (error) {\n if ((error as Error).name === 'AbortError') {\n throw new Error(`请求超时(${timeout / 1000}秒): ${url}`)\n }\n const message = error instanceof Error ? error.message : String(error)\n throw new Error(`${message}: ${url}`)\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n /**\n * Cookie 管理\n */\n cookies = {\n async get(domain: string): Promise<Cookie[]> {\n const cookies = await chrome.cookies.getAll({ domain })\n return cookies.map(c => ({\n name: c.name,\n value: c.value,\n domain: c.domain,\n path: c.path,\n secure: c.secure,\n httpOnly: c.httpOnly,\n expirationDate: c.expirationDate,\n }))\n },\n\n async set(cookie: Cookie): Promise<void> {\n await chrome.cookies.set({\n url: `https://${cookie.domain}${cookie.path || '/'}`,\n name: cookie.name,\n value: cookie.value,\n domain: cookie.domain,\n path: cookie.path,\n secure: cookie.secure,\n httpOnly: cookie.httpOnly,\n expirationDate: cookie.expirationDate,\n })\n },\n\n async remove(name: string, domain: string): Promise<void> {\n await chrome.cookies.remove({\n url: `https://${domain}`,\n name,\n })\n },\n }\n\n /**\n * 获取单个 Cookie 值(便捷方法)\n */\n async getCookie(domain: string, name: string): Promise<string | null> {\n const cookies = await chrome.cookies.getAll({ domain, name })\n return cookies.length > 0 ? cookies[0].value : null\n }\n\n /**\n * 持久化存储\n */\n storage = {\n async get<T>(key: string): Promise<T | null> {\n const result = await chrome.storage.local.get(key)\n return (result[key] as T) ?? null\n },\n\n async set<T>(key: string, value: T): Promise<void> {\n await chrome.storage.local.set({ [key]: value })\n },\n\n async remove(key: string): Promise<void> {\n await chrome.storage.local.remove(key)\n },\n }\n\n /**\n * 会话存储\n */\n session = {\n async get<T>(key: string): Promise<T | null> {\n const result = await chrome.storage.session.get(key)\n return (result[key] as T) ?? null\n },\n\n async set<T>(key: string, value: T): Promise<void> {\n await chrome.storage.session.set({ [key]: value })\n },\n }\n\n /**\n * Header 规则管理 (declarativeNetRequest)\n * 规则只对扩展自身发起的请求生效,不影响其他网页\n */\n headerRules = {\n add: async (rule: HeaderRule): Promise<string> => {\n // 组合 base + counter 生成唯一 ID,避免冲突\n const ruleId = this.ruleIdBase + this.ruleIdCounter++\n const id = `rule_${ruleId}`\n\n await chrome.declarativeNetRequest.updateDynamicRules({\n removeRuleIds: [ruleId],\n })\n\n await chrome.declarativeNetRequest.updateDynamicRules({\n addRules: [\n {\n id: ruleId,\n priority: 1,\n action: {\n type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS,\n requestHeaders: Object.entries(rule.headers).map(\n ([header, value]) => ({\n header,\n operation: chrome.declarativeNetRequest.HeaderOperation.SET,\n value,\n })\n ),\n },\n condition: {\n urlFilter: rule.urlFilter,\n // 只对扩展自身发起的请求生效,不影响其他网页\n initiatorDomains: [chrome.runtime.id],\n resourceTypes: (rule.resourceTypes || [\n 'xmlhttprequest',\n ]) as chrome.declarativeNetRequest.ResourceType[],\n },\n },\n ],\n })\n\n return id\n },\n\n remove: async (ruleId: string): Promise<void> => {\n const id = parseInt(ruleId.replace('rule_', ''), 10)\n await chrome.declarativeNetRequest.updateDynamicRules({\n removeRuleIds: [id],\n })\n },\n\n clear: async (): Promise<void> => {\n const rules = await chrome.declarativeNetRequest.getDynamicRules()\n await chrome.declarativeNetRequest.updateDynamicRules({\n removeRuleIds: rules.map(r => r.id),\n })\n },\n }\n\n /**\n * 文件下载\n * Service Worker 中不支持 URL.createObjectURL,使用 data URL 替代\n */\n downloads = {\n async download(blob: Blob, filename: string, saveAs = true): Promise<number> {\n // 将 Blob 转换为 data URL\n const buffer = await blob.arrayBuffer()\n const base64 = btoa(\n new Uint8Array(buffer).reduce((data, byte) => data + String.fromCharCode(byte), '')\n )\n const mimeType = blob.type || 'application/octet-stream'\n const dataUrl = `data:${mimeType};base64,${base64}`\n\n const downloadId = await chrome.downloads.download({\n url: dataUrl,\n filename,\n saveAs,\n })\n return downloadId\n },\n }\n\n /**\n * Tab 管理\n */\n tabs = {\n async query(urlPattern: string): Promise<Array<{ id: number; url?: string }>> {\n const tabs = await chrome.tabs.query({ url: urlPattern })\n return tabs.filter(t => t.id !== undefined).map(t => ({ id: t.id!, url: t.url }))\n },\n\n create: async (url: string, active = false): Promise<{ id: number }> => {\n const tab = await chrome.tabs.create({ url, active })\n await this.addToRuntimeTabGroup(tab.id!)\n return { id: tab.id! }\n },\n\n close: async (tabId: number): Promise<void> => {\n await chrome.tabs.remove(tabId)\n },\n\n async waitForLoad(tabId: number, timeout = 30000): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n chrome.tabs.onUpdated.removeListener(listener)\n reject(new Error('Tab load timeout'))\n }, timeout)\n\n const finish = () => {\n clearTimeout(timeoutId)\n chrome.tabs.onUpdated.removeListener(listener)\n // 额外等待让页面 JS 初始化\n setTimeout(resolve, 1000)\n }\n\n const listener = (updatedTabId: number, info: chrome.tabs.TabChangeInfo) => {\n if (updatedTabId === tabId && info.status === 'complete') {\n finish()\n }\n }\n chrome.tabs.onUpdated.addListener(listener)\n\n chrome.tabs.get(tabId, tab => {\n if (chrome.runtime.lastError) return\n if (tab?.status === 'complete') {\n finish()\n }\n })\n })\n },\n\n withManagedTab: async <T>(\n options: ManagedTabOptions,\n callback: (tab: ManagedTabHandle) => Promise<T> | T\n ): Promise<T> => {\n const patterns = Array.isArray(options.urlPattern)\n ? options.urlPattern\n : [options.urlPattern]\n\n for (const pattern of patterns) {\n const tabs = await this.tabs.query(pattern)\n const existing = tabs.find(tab =>\n typeof tab.id === 'number'\n && (!options.match || options.match(tab))\n )\n if (existing) {\n return callback({\n id: existing.id,\n url: existing.url,\n owned: false,\n })\n }\n }\n\n const tab = await this.tabs.create(options.createUrl, options.active ?? false)\n const ownedTab: ManagedTabHandle = {\n id: tab.id,\n owned: true,\n }\n\n if (options.waitForLoad !== false) {\n await this.tabs.waitForLoad(tab.id, options.loadTimeout ?? 30000)\n }\n\n try {\n return await callback(ownedTab)\n } finally {\n if (options.closeWhenDone !== false) {\n await this.tabs.close(tab.id)\n }\n }\n },\n\n async executeScript<T, A extends unknown[]>(\n tabId: number,\n func: (...args: A) => T | Promise<T>,\n args: A\n ): Promise<T> {\n const results = await chrome.scripting.executeScript({\n target: { tabId },\n world: 'MAIN',\n func: func as (...args: unknown[]) => unknown,\n args: args as unknown[],\n })\n\n const result = results[0]?.result as T\n return result\n },\n }\n\n private async addToRuntimeTabGroup(tabId: number): Promise<void> {\n if (!chrome.tabs.group || !chrome.tabGroups?.update) return\n\n try {\n const groupId = await chrome.tabs.group({\n tabIds: [tabId],\n ...(this.runtimeTabGroupId === null ? {} : { groupId: this.runtimeTabGroupId }),\n })\n if (this.runtimeTabGroupId === null) {\n this.runtimeTabGroupId = groupId\n await chrome.tabGroups.update(groupId, {\n title: RUNTIME_TAB_GROUP_TITLE,\n color: 'grey',\n collapsed: true,\n })\n }\n } catch (error) {\n console.warn('Failed to group Article Publish runtime tab:', error)\n }\n }\n\n /**\n * DOM 操作 - 通过 Offscreen Document 实现\n */\n dom = {\n parseHTML: async (html: string): Promise<Document> => {\n const parser = new DOMParser()\n return parser.parseFromString(html, 'text/html')\n },\n\n querySelector: (doc: Document, selector: string): Element | null => {\n return doc.querySelector(selector)\n },\n\n querySelectorAll: (doc: Document, selector: string): Element[] => {\n return Array.from(doc.querySelectorAll(selector))\n },\n\n getTextContent: (element: Element): string => {\n return element.textContent || ''\n },\n\n getInnerHTML: (element: Element): string => {\n return element.innerHTML\n },\n }\n}\n\n/**\n * 创建扩展运行时实例\n */\nexport function createExtensionRuntime(config?: RuntimeConfig): ExtensionRuntime {\n return new ExtensionRuntime(config)\n}\n"],"mappings":"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","names":["tab"]}