🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@sohu-bpd/wechat

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sohu-bpd/wechat - npm Package Compare versions

Comparing version
0.0.4
to
0.0.5
+10
-5
dist/index.d.mts

@@ -18,4 +18,9 @@ /**

interface GlobalConfig {
/** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */
getSignature: (url: string) => Promise<SignatureResult>;
/**
* 获取签名参数的函数,接收当前页面 URL,返回签名参数
* - 在 https://act.go.sohu.com 或 https://test.r.ads.sohu.com 域名下,此参数可选
* - 未提供时将自动使用内置签名获取函数(请求 /wechat/ticket)
* - 在其他域名下,此参数必填
*/
getSignature?: (url: string) => Promise<SignatureResult>;
/** 是否开启调试模式,默认 false */

@@ -34,8 +39,8 @@ debug?: boolean;

*/
declare function config(options: GlobalConfig): void;
declare function config(options?: GlobalConfig): void;
/**
* 获取全局配置
* @returns 全局配置,如果未配置则抛出错误
* @returns 全局配置,如果未配置则尝试自动初始化(仅在支持的域名下)
*/
declare function getConfig(): GlobalConfig;
declare function getConfig(): Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig;
/**

@@ -42,0 +47,0 @@ * 检查是否已配置

@@ -18,4 +18,9 @@ /**

interface GlobalConfig {
/** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */
getSignature: (url: string) => Promise<SignatureResult>;
/**
* 获取签名参数的函数,接收当前页面 URL,返回签名参数
* - 在 https://act.go.sohu.com 或 https://test.r.ads.sohu.com 域名下,此参数可选
* - 未提供时将自动使用内置签名获取函数(请求 /wechat/ticket)
* - 在其他域名下,此参数必填
*/
getSignature?: (url: string) => Promise<SignatureResult>;
/** 是否开启调试模式,默认 false */

@@ -34,8 +39,8 @@ debug?: boolean;

*/
declare function config(options: GlobalConfig): void;
declare function config(options?: GlobalConfig): void;
/**
* 获取全局配置
* @returns 全局配置,如果未配置则抛出错误
* @returns 全局配置,如果未配置则尝试自动初始化(仅在支持的域名下)
*/
declare function getConfig(): GlobalConfig;
declare function getConfig(): Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig;
/**

@@ -42,0 +47,0 @@ * 检查是否已配置

@@ -5,4 +5,70 @@ var SohuWechat = (function (exports) {

// src/config.ts
var BUILT_IN_SIGNATURE_DOMAINS = [
"https://act.go.sohu.com",
"https://test.r.ads.sohu.com"
];
function isBuiltInSignatureDomain() {
if (typeof window === "undefined") return false;
const origin = window.location.origin;
return BUILT_IN_SIGNATURE_DOMAINS.includes(origin);
}
async function httpGet(url) {
if (typeof fetch !== "undefined") {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch signature: ${response.status} ${response.statusText}`);
}
return await response.json();
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const result = JSON.parse(xhr.responseText);
resolve(result);
} catch (error) {
reject(new Error(`Failed to parse response: ${error}`));
}
} else {
reject(new Error(`Failed to fetch signature: ${xhr.status} ${xhr.statusText}`));
}
};
xhr.onerror = () => {
reject(new Error("Network error occurred"));
};
xhr.send();
});
}
async function builtInGetSignature(url) {
const apiUrl = `/wechat/ticket?url=${encodeURIComponent(url)}`;
const result = await httpGet(apiUrl);
if (result.code !== 0) {
throw new Error(`Signature API error: ${result.message}`);
}
return {
appId: result.data.app_id,
timestamp: result.data.timestamp,
nonceStr: result.data.nonce_str,
signature: result.data.signature
};
}
var globalConfig = null;
function config(options) {
function config(options = {}) {
if (!options.getSignature) {
if (isBuiltInSignatureDomain()) {
options.getSignature = builtInGetSignature;
if (options.debug === void 0) {
options.debug = false;
}
if (options.spa === void 0) {
options.spa = true;
}
} else {
throw new Error(
"\u5F53\u524D\u57DF\u540D\u4E0D\u652F\u6301\u5185\u7F6E\u7B7E\u540D\uFF0C\u8BF7\u63D0\u4F9B getSignature \u51FD\u6570\u3002\u5185\u7F6E\u7B7E\u540D\u4EC5\u5728\u4EE5\u4E0B\u57DF\u540D\u4E0B\u53EF\u7528\uFF1A" + BUILT_IN_SIGNATURE_DOMAINS.join(", ")
);
}
}
globalConfig = options;

@@ -12,3 +78,9 @@ }

if (!globalConfig) {
throw new Error("\u8BF7\u5148\u8C03\u7528 config() \u8FDB\u884C\u914D\u7F6E");
if (isBuiltInSignatureDomain()) {
config({});
} else {
throw new Error(
"\u8BF7\u5148\u8C03\u7528 config() \u8FDB\u884C\u914D\u7F6E\u3002\u5728 " + BUILT_IN_SIGNATURE_DOMAINS.join(", ") + " \u57DF\u540D\u4E0B\u53EF\u4EE5\u81EA\u52A8\u4F7F\u7528\u5185\u7F6E\u914D\u7F6E\u3002"
);
}
}

@@ -15,0 +87,0 @@ return globalConfig;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":"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","file":"index.global.js","sourcesContent":["/**\n * 微信 JS-SDK 签名参数\n */\nexport interface SignatureResult {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n}\n\n/**\n * 全局配置选项\n */\nexport interface GlobalConfig {\n /** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */\n getSignature: (url: string) => Promise<SignatureResult>\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /**\n * 是否为 SPA 单页应用模式,默认 true\n * - true: 每次调用 API 时检测 URL 变化,变化则重新初始化\n * - false: 仅初始化一次\n */\n spa?: boolean\n}\n\nlet globalConfig: GlobalConfig | null = null\n\n/**\n * 设置全局配置\n * @param options - 配置选项\n */\nexport function config(options: GlobalConfig): void {\n globalConfig = options\n}\n\n/**\n * 获取全局配置\n * @returns 全局配置,如果未配置则抛出错误\n */\nexport function getConfig(): GlobalConfig {\n if (!globalConfig) {\n throw new Error('请先调用 config() 进行配置')\n }\n return globalConfig\n}\n\n/**\n * 检查是否已配置\n */\nexport function isConfigured(): boolean {\n return globalConfig !== null\n}\n","import { getConfig } from './config'\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n updateAppMessageShareData: (options: {\n title: string\n desc: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n updateTimelineShareData: (options: {\n title: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n}\n\nlet sdkInitPromise: Promise<void> | null = null\nlet currentInitUrl: string | null = null\nlet entryUrl: string | null = null // iOS 微信需要用首次进入的 URL\n\n/**\n * 检测是否为 iOS 微信浏览器\n */\nfunction isIOSWechat(): boolean {\n if (typeof navigator === 'undefined') return false\n const ua = navigator.userAgent.toLowerCase()\n return /iphone|ipad|ipod/.test(ua) && /micromessenger/.test(ua)\n}\n\n/**\n * 获取用于签名的 URL\n * iOS 微信需要用首次进入页面的 URL,Android 用当前 URL\n */\nfunction getSignatureUrl(): string {\n if (typeof window === 'undefined') return ''\n\n const currentUrl = window.location.href.split('#')[0]\n\n if (isIOSWechat()) {\n // iOS 微信:用首次进入的 URL\n if (!entryUrl) {\n entryUrl = currentUrl\n }\n return entryUrl\n }\n\n // Android 或其他:用当前 URL\n return currentUrl\n}\n\n/**\n * 获取 wx 对象\n */\nexport function getWx(): WxSDK {\n if (typeof window === 'undefined') {\n throw new Error('window is not defined')\n }\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n throw new Error('wx is not defined')\n }\n return wx\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\n * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用\n */\nexport async function initSDK(jsApiList: string[]): Promise<void> {\n const cfg = getConfig()\n const signatureUrl = getSignatureUrl()\n const isSpa = cfg.spa !== false // 默认为 true\n\n // 非 SPA 模式或 URL 没有变化,且已经初始化过,直接返回\n if (sdkInitPromise && (!isSpa || currentInitUrl === signatureUrl)) {\n return sdkInitPromise\n }\n\n // URL 变化或首次初始化\n currentInitUrl = signatureUrl\n\n sdkInitPromise = (async () => {\n // 获取签名\n const signatureResult = await cfg.getSignature(signatureUrl)\n\n // 调用 wx.config\n const wx = getWx()\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: cfg.debug ?? false,\n appId: signatureResult.appId,\n timestamp: signatureResult.timestamp,\n nonceStr: signatureResult.nonceStr,\n signature: signatureResult.signature,\n jsApiList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n // 初始化失败,清除缓存以便下次重试\n sdkInitPromise = null\n currentInitUrl = null\n reject(new Error(`wx.config failed: ${res.errMsg}`))\n })\n })\n })()\n\n return sdkInitPromise\n}\n\n/**\n * 重置 SDK 状态(用于测试或强制重新初始化)\n */\nexport function resetSDK(): void {\n sdkInitPromise = null\n currentInitUrl = null\n entryUrl = null\n}\n","import { initSDK, getWx } from './sdk'\n\n/**\n * 分享参数\n */\nexport interface ShareOptions {\n /** 分享标题 */\n title: string\n /** 分享描述(分享给朋友时显示) */\n desc?: string\n /** 分享链接,默认为当前页面 URL */\n link?: string\n /** 分享图标 URL */\n imgUrl: string\n}\n\nconst SHARE_JS_API_LIST = [\n 'updateAppMessageShareData',\n 'updateTimelineShareData',\n]\n\n/**\n * 设置微信分享内容\n * 会自动加载 SDK 并初始化,然后设置分享内容\n * @param options - 分享参数\n */\nexport async function share(options: ShareOptions): Promise<void> {\n // 确保 SDK 已初始化\n await initSDK(SHARE_JS_API_LIST)\n\n const wx = getWx()\n const link = options.link ?? (typeof window !== 'undefined' ? window.location.href : '')\n\n // 设置分享给朋友\n await new Promise<void>((resolve, reject) => {\n wx.updateAppMessageShareData({\n title: options.title,\n desc: options.desc ?? '',\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateAppMessageShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n\n // 设置分享到朋友圈\n await new Promise<void>((resolve, reject) => {\n wx.updateTimelineShareData({\n title: options.title,\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateTimelineShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n}\n","/**\n * 微信 JS-SDK wx.config 所需的配置参数\n */\nexport interface Config {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n /** 需要使用的 JS 接口列表 */\n jsApiList: string[]\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /** 需要使用的开放标签列表 */\n openTagList?: string[]\n}\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n}\n\n/**\n * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise\n * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用\n * @param config - 微信 JS-SDK 配置参数\n * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息\n */\nexport function init(config: Config): Promise<void> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('init: window is not defined'))\n }\n\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n return Promise.reject(new Error('init: wx is not defined, please load WeChat JS-SDK first'))\n }\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: config.debug ?? false,\n appId: config.appId,\n timestamp: config.timestamp,\n nonceStr: config.nonceStr,\n signature: config.signature,\n jsApiList: config.jsApiList,\n openTagList: config.openTagList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n reject(new Error(`init: ${res.errMsg}`))\n })\n })\n}\n"]}
{"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":"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","file":"index.global.js","sourcesContent":["/**\n * 微信 JS-SDK 签名参数\n */\nexport interface SignatureResult {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n}\n\n/**\n * 内置签名接口返回值\n */\ninterface BuiltInSignatureResponse {\n code: number\n data: {\n app_id: string\n timestamp: number\n nonce_str: string\n signature: string\n }\n message: string\n}\n\n/**\n * 支持内置签名的域名列表\n */\nconst BUILT_IN_SIGNATURE_DOMAINS = [\n 'https://act.go.sohu.com',\n 'https://test.r.ads.sohu.com',\n]\n\n/**\n * 检查当前域名是否支持内置签名\n */\nfunction isBuiltInSignatureDomain(): boolean {\n if (typeof window === 'undefined') return false\n const origin = window.location.origin\n return BUILT_IN_SIGNATURE_DOMAINS.includes(origin)\n}\n\n/**\n * 发起 HTTP GET 请求,支持 fetch 和 XMLHttpRequest 回退\n */\nasync function httpGet(url: string): Promise<BuiltInSignatureResponse> {\n // 优先使用 fetch API\n if (typeof fetch !== 'undefined') {\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(`Failed to fetch signature: ${response.status} ${response.statusText}`)\n }\n\n return await response.json()\n }\n\n // 回退到 XMLHttpRequest\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', url, true)\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const result = JSON.parse(xhr.responseText)\n resolve(result)\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`))\n }\n } else {\n reject(new Error(`Failed to fetch signature: ${xhr.status} ${xhr.statusText}`))\n }\n }\n\n xhr.onerror = () => {\n reject(new Error('Network error occurred'))\n }\n\n xhr.send()\n })\n}\n\n/**\n * 内置的签名获取函数(仅在特定域名下可用)\n */\nasync function builtInGetSignature(url: string): Promise<SignatureResult> {\n const apiUrl = `/wechat/ticket?url=${encodeURIComponent(url)}`\n const result = await httpGet(apiUrl)\n\n if (result.code !== 0) {\n throw new Error(`Signature API error: ${result.message}`)\n }\n\n return {\n appId: result.data.app_id,\n timestamp: result.data.timestamp,\n nonceStr: result.data.nonce_str,\n signature: result.data.signature,\n }\n}\n\n/**\n * 全局配置选项\n */\nexport interface GlobalConfig {\n /**\n * 获取签名参数的函数,接收当前页面 URL,返回签名参数\n * - 在 https://act.go.sohu.com 或 https://test.r.ads.sohu.com 域名下,此参数可选\n * - 未提供时将自动使用内置签名获取函数(请求 /wechat/ticket)\n * - 在其他域名下,此参数必填\n */\n getSignature?: (url: string) => Promise<SignatureResult>\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /**\n * 是否为 SPA 单页应用模式,默认 true\n * - true: 每次调用 API 时检测 URL 变化,变化则重新初始化\n * - false: 仅初始化一次\n */\n spa?: boolean\n}\n\nlet globalConfig: GlobalConfig | null = null\n\n/**\n * 设置全局配置\n * @param options - 配置选项\n */\nexport function config(options: GlobalConfig = {}): void {\n // 如果未提供 getSignature,尝试使用内置签名函数\n if (!options.getSignature) {\n if (isBuiltInSignatureDomain()) {\n options.getSignature = builtInGetSignature\n // 设置默认值,确保未初始化时也有合理的默认配置\n if (options.debug === undefined) {\n options.debug = false\n }\n if (options.spa === undefined) {\n options.spa = true\n }\n } else {\n throw new Error(\n '当前域名不支持内置签名,请提供 getSignature 函数。' +\n '内置签名仅在以下域名下可用:' +\n BUILT_IN_SIGNATURE_DOMAINS.join(', ')\n )\n }\n }\n\n globalConfig = options as Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig\n}\n\n/**\n * 获取全局配置\n * @returns 全局配置,如果未配置则尝试自动初始化(仅在支持的域名下)\n */\nexport function getConfig(): Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig {\n if (!globalConfig) {\n // 在支持的域名下,自动初始化默认配置\n if (isBuiltInSignatureDomain()) {\n config({})\n } else {\n throw new Error(\n '请先调用 config() 进行配置。' +\n '在 ' +\n BUILT_IN_SIGNATURE_DOMAINS.join(', ') +\n ' 域名下可以自动使用内置配置。'\n )\n }\n }\n return globalConfig as Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig\n}\n\n/**\n * 检查是否已配置\n */\nexport function isConfigured(): boolean {\n return globalConfig !== null\n}\n\n/**\n * 重置配置(仅用于测试)\n * @internal\n */\nexport function resetConfig(): void {\n globalConfig = null\n}\n","import { getConfig } from './config'\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n updateAppMessageShareData: (options: {\n title: string\n desc: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n updateTimelineShareData: (options: {\n title: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n}\n\nlet sdkInitPromise: Promise<void> | null = null\nlet currentInitUrl: string | null = null\nlet entryUrl: string | null = null // iOS 微信需要用首次进入的 URL\n\n/**\n * 检测是否为 iOS 微信浏览器\n */\nfunction isIOSWechat(): boolean {\n if (typeof navigator === 'undefined') return false\n const ua = navigator.userAgent.toLowerCase()\n return /iphone|ipad|ipod/.test(ua) && /micromessenger/.test(ua)\n}\n\n/**\n * 获取用于签名的 URL\n * iOS 微信需要用首次进入页面的 URL,Android 用当前 URL\n */\nfunction getSignatureUrl(): string {\n if (typeof window === 'undefined') return ''\n\n const currentUrl = window.location.href.split('#')[0]\n\n if (isIOSWechat()) {\n // iOS 微信:用首次进入的 URL\n if (!entryUrl) {\n entryUrl = currentUrl\n }\n return entryUrl\n }\n\n // Android 或其他:用当前 URL\n return currentUrl\n}\n\n/**\n * 获取 wx 对象\n */\nexport function getWx(): WxSDK {\n if (typeof window === 'undefined') {\n throw new Error('window is not defined')\n }\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n throw new Error('wx is not defined')\n }\n return wx\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\n * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用\n */\nexport async function initSDK(jsApiList: string[]): Promise<void> {\n const cfg = getConfig()\n const signatureUrl = getSignatureUrl()\n const isSpa = cfg.spa !== false // 默认为 true\n\n // 非 SPA 模式或 URL 没有变化,且已经初始化过,直接返回\n if (sdkInitPromise && (!isSpa || currentInitUrl === signatureUrl)) {\n return sdkInitPromise\n }\n\n // URL 变化或首次初始化\n currentInitUrl = signatureUrl\n\n sdkInitPromise = (async () => {\n // 获取签名\n const signatureResult = await cfg.getSignature(signatureUrl)\n\n // 调用 wx.config\n const wx = getWx()\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: cfg.debug ?? false,\n appId: signatureResult.appId,\n timestamp: signatureResult.timestamp,\n nonceStr: signatureResult.nonceStr,\n signature: signatureResult.signature,\n jsApiList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n // 初始化失败,清除缓存以便下次重试\n sdkInitPromise = null\n currentInitUrl = null\n reject(new Error(`wx.config failed: ${res.errMsg}`))\n })\n })\n })()\n\n return sdkInitPromise\n}\n\n/**\n * 重置 SDK 状态(用于测试或强制重新初始化)\n */\nexport function resetSDK(): void {\n sdkInitPromise = null\n currentInitUrl = null\n entryUrl = null\n}\n","import { initSDK, getWx } from './sdk'\n\n/**\n * 分享参数\n */\nexport interface ShareOptions {\n /** 分享标题 */\n title: string\n /** 分享描述(分享给朋友时显示) */\n desc?: string\n /** 分享链接,默认为当前页面 URL */\n link?: string\n /** 分享图标 URL */\n imgUrl: string\n}\n\nconst SHARE_JS_API_LIST = [\n 'updateAppMessageShareData',\n 'updateTimelineShareData',\n]\n\n/**\n * 设置微信分享内容\n * 会自动加载 SDK 并初始化,然后设置分享内容\n * @param options - 分享参数\n */\nexport async function share(options: ShareOptions): Promise<void> {\n // 确保 SDK 已初始化\n await initSDK(SHARE_JS_API_LIST)\n\n const wx = getWx()\n const link = options.link ?? (typeof window !== 'undefined' ? window.location.href : '')\n\n // 设置分享给朋友\n await new Promise<void>((resolve, reject) => {\n wx.updateAppMessageShareData({\n title: options.title,\n desc: options.desc ?? '',\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateAppMessageShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n\n // 设置分享到朋友圈\n await new Promise<void>((resolve, reject) => {\n wx.updateTimelineShareData({\n title: options.title,\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateTimelineShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n}\n","/**\n * 微信 JS-SDK wx.config 所需的配置参数\n */\nexport interface Config {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n /** 需要使用的 JS 接口列表 */\n jsApiList: string[]\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /** 需要使用的开放标签列表 */\n openTagList?: string[]\n}\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n}\n\n/**\n * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise\n * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用\n * @param config - 微信 JS-SDK 配置参数\n * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息\n */\nexport function init(config: Config): Promise<void> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('init: window is not defined'))\n }\n\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n return Promise.reject(new Error('init: wx is not defined, please load WeChat JS-SDK first'))\n }\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: config.debug ?? false,\n appId: config.appId,\n timestamp: config.timestamp,\n nonceStr: config.nonceStr,\n signature: config.signature,\n jsApiList: config.jsApiList,\n openTagList: config.openTagList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n reject(new Error(`init: ${res.errMsg}`))\n })\n })\n}\n"]}
'use strict';
// src/config.ts
var BUILT_IN_SIGNATURE_DOMAINS = [
"https://act.go.sohu.com",
"https://test.r.ads.sohu.com"
];
function isBuiltInSignatureDomain() {
if (typeof window === "undefined") return false;
const origin = window.location.origin;
return BUILT_IN_SIGNATURE_DOMAINS.includes(origin);
}
async function httpGet(url) {
if (typeof fetch !== "undefined") {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch signature: ${response.status} ${response.statusText}`);
}
return await response.json();
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const result = JSON.parse(xhr.responseText);
resolve(result);
} catch (error) {
reject(new Error(`Failed to parse response: ${error}`));
}
} else {
reject(new Error(`Failed to fetch signature: ${xhr.status} ${xhr.statusText}`));
}
};
xhr.onerror = () => {
reject(new Error("Network error occurred"));
};
xhr.send();
});
}
async function builtInGetSignature(url) {
const apiUrl = `/wechat/ticket?url=${encodeURIComponent(url)}`;
const result = await httpGet(apiUrl);
if (result.code !== 0) {
throw new Error(`Signature API error: ${result.message}`);
}
return {
appId: result.data.app_id,
timestamp: result.data.timestamp,
nonceStr: result.data.nonce_str,
signature: result.data.signature
};
}
var globalConfig = null;
function config(options) {
function config(options = {}) {
if (!options.getSignature) {
if (isBuiltInSignatureDomain()) {
options.getSignature = builtInGetSignature;
if (options.debug === void 0) {
options.debug = false;
}
if (options.spa === void 0) {
options.spa = true;
}
} else {
throw new Error(
"\u5F53\u524D\u57DF\u540D\u4E0D\u652F\u6301\u5185\u7F6E\u7B7E\u540D\uFF0C\u8BF7\u63D0\u4F9B getSignature \u51FD\u6570\u3002\u5185\u7F6E\u7B7E\u540D\u4EC5\u5728\u4EE5\u4E0B\u57DF\u540D\u4E0B\u53EF\u7528\uFF1A" + BUILT_IN_SIGNATURE_DOMAINS.join(", ")
);
}
}
globalConfig = options;

@@ -10,3 +76,9 @@ }

if (!globalConfig) {
throw new Error("\u8BF7\u5148\u8C03\u7528 config() \u8FDB\u884C\u914D\u7F6E");
if (isBuiltInSignatureDomain()) {
config({});
} else {
throw new Error(
"\u8BF7\u5148\u8C03\u7528 config() \u8FDB\u884C\u914D\u7F6E\u3002\u5728 " + BUILT_IN_SIGNATURE_DOMAINS.join(", ") + " \u57DF\u540D\u4E0B\u53EF\u4EE5\u81EA\u52A8\u4F7F\u7528\u5185\u7F6E\u914D\u7F6E\u3002"
);
}
}

@@ -13,0 +85,0 @@ return globalConfig;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 微信 JS-SDK 签名参数\n */\nexport interface SignatureResult {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n}\n\n/**\n * 全局配置选项\n */\nexport interface GlobalConfig {\n /** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */\n getSignature: (url: string) => Promise<SignatureResult>\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /**\n * 是否为 SPA 单页应用模式,默认 true\n * - true: 每次调用 API 时检测 URL 变化,变化则重新初始化\n * - false: 仅初始化一次\n */\n spa?: boolean\n}\n\nlet globalConfig: GlobalConfig | null = null\n\n/**\n * 设置全局配置\n * @param options - 配置选项\n */\nexport function config(options: GlobalConfig): void {\n globalConfig = options\n}\n\n/**\n * 获取全局配置\n * @returns 全局配置,如果未配置则抛出错误\n */\nexport function getConfig(): GlobalConfig {\n if (!globalConfig) {\n throw new Error('请先调用 config() 进行配置')\n }\n return globalConfig\n}\n\n/**\n * 检查是否已配置\n */\nexport function isConfigured(): boolean {\n return globalConfig !== null\n}\n","import { getConfig } from './config'\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n updateAppMessageShareData: (options: {\n title: string\n desc: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n updateTimelineShareData: (options: {\n title: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n}\n\nlet sdkInitPromise: Promise<void> | null = null\nlet currentInitUrl: string | null = null\nlet entryUrl: string | null = null // iOS 微信需要用首次进入的 URL\n\n/**\n * 检测是否为 iOS 微信浏览器\n */\nfunction isIOSWechat(): boolean {\n if (typeof navigator === 'undefined') return false\n const ua = navigator.userAgent.toLowerCase()\n return /iphone|ipad|ipod/.test(ua) && /micromessenger/.test(ua)\n}\n\n/**\n * 获取用于签名的 URL\n * iOS 微信需要用首次进入页面的 URL,Android 用当前 URL\n */\nfunction getSignatureUrl(): string {\n if (typeof window === 'undefined') return ''\n\n const currentUrl = window.location.href.split('#')[0]\n\n if (isIOSWechat()) {\n // iOS 微信:用首次进入的 URL\n if (!entryUrl) {\n entryUrl = currentUrl\n }\n return entryUrl\n }\n\n // Android 或其他:用当前 URL\n return currentUrl\n}\n\n/**\n * 获取 wx 对象\n */\nexport function getWx(): WxSDK {\n if (typeof window === 'undefined') {\n throw new Error('window is not defined')\n }\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n throw new Error('wx is not defined')\n }\n return wx\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\n * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用\n */\nexport async function initSDK(jsApiList: string[]): Promise<void> {\n const cfg = getConfig()\n const signatureUrl = getSignatureUrl()\n const isSpa = cfg.spa !== false // 默认为 true\n\n // 非 SPA 模式或 URL 没有变化,且已经初始化过,直接返回\n if (sdkInitPromise && (!isSpa || currentInitUrl === signatureUrl)) {\n return sdkInitPromise\n }\n\n // URL 变化或首次初始化\n currentInitUrl = signatureUrl\n\n sdkInitPromise = (async () => {\n // 获取签名\n const signatureResult = await cfg.getSignature(signatureUrl)\n\n // 调用 wx.config\n const wx = getWx()\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: cfg.debug ?? false,\n appId: signatureResult.appId,\n timestamp: signatureResult.timestamp,\n nonceStr: signatureResult.nonceStr,\n signature: signatureResult.signature,\n jsApiList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n // 初始化失败,清除缓存以便下次重试\n sdkInitPromise = null\n currentInitUrl = null\n reject(new Error(`wx.config failed: ${res.errMsg}`))\n })\n })\n })()\n\n return sdkInitPromise\n}\n\n/**\n * 重置 SDK 状态(用于测试或强制重新初始化)\n */\nexport function resetSDK(): void {\n sdkInitPromise = null\n currentInitUrl = null\n entryUrl = null\n}\n","import { initSDK, getWx } from './sdk'\n\n/**\n * 分享参数\n */\nexport interface ShareOptions {\n /** 分享标题 */\n title: string\n /** 分享描述(分享给朋友时显示) */\n desc?: string\n /** 分享链接,默认为当前页面 URL */\n link?: string\n /** 分享图标 URL */\n imgUrl: string\n}\n\nconst SHARE_JS_API_LIST = [\n 'updateAppMessageShareData',\n 'updateTimelineShareData',\n]\n\n/**\n * 设置微信分享内容\n * 会自动加载 SDK 并初始化,然后设置分享内容\n * @param options - 分享参数\n */\nexport async function share(options: ShareOptions): Promise<void> {\n // 确保 SDK 已初始化\n await initSDK(SHARE_JS_API_LIST)\n\n const wx = getWx()\n const link = options.link ?? (typeof window !== 'undefined' ? window.location.href : '')\n\n // 设置分享给朋友\n await new Promise<void>((resolve, reject) => {\n wx.updateAppMessageShareData({\n title: options.title,\n desc: options.desc ?? '',\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateAppMessageShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n\n // 设置分享到朋友圈\n await new Promise<void>((resolve, reject) => {\n wx.updateTimelineShareData({\n title: options.title,\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateTimelineShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n}\n","/**\n * 微信 JS-SDK wx.config 所需的配置参数\n */\nexport interface Config {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n /** 需要使用的 JS 接口列表 */\n jsApiList: string[]\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /** 需要使用的开放标签列表 */\n openTagList?: string[]\n}\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n}\n\n/**\n * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise\n * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用\n * @param config - 微信 JS-SDK 配置参数\n * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息\n */\nexport function init(config: Config): Promise<void> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('init: window is not defined'))\n }\n\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n return Promise.reject(new Error('init: wx is not defined, please load WeChat JS-SDK first'))\n }\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: config.debug ?? false,\n appId: config.appId,\n timestamp: config.timestamp,\n nonceStr: config.nonceStr,\n signature: config.signature,\n jsApiList: config.jsApiList,\n openTagList: config.openTagList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n reject(new Error(`init: ${res.errMsg}`))\n })\n })\n}\n"]}
{"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 微信 JS-SDK 签名参数\n */\nexport interface SignatureResult {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n}\n\n/**\n * 内置签名接口返回值\n */\ninterface BuiltInSignatureResponse {\n code: number\n data: {\n app_id: string\n timestamp: number\n nonce_str: string\n signature: string\n }\n message: string\n}\n\n/**\n * 支持内置签名的域名列表\n */\nconst BUILT_IN_SIGNATURE_DOMAINS = [\n 'https://act.go.sohu.com',\n 'https://test.r.ads.sohu.com',\n]\n\n/**\n * 检查当前域名是否支持内置签名\n */\nfunction isBuiltInSignatureDomain(): boolean {\n if (typeof window === 'undefined') return false\n const origin = window.location.origin\n return BUILT_IN_SIGNATURE_DOMAINS.includes(origin)\n}\n\n/**\n * 发起 HTTP GET 请求,支持 fetch 和 XMLHttpRequest 回退\n */\nasync function httpGet(url: string): Promise<BuiltInSignatureResponse> {\n // 优先使用 fetch API\n if (typeof fetch !== 'undefined') {\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(`Failed to fetch signature: ${response.status} ${response.statusText}`)\n }\n\n return await response.json()\n }\n\n // 回退到 XMLHttpRequest\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', url, true)\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const result = JSON.parse(xhr.responseText)\n resolve(result)\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`))\n }\n } else {\n reject(new Error(`Failed to fetch signature: ${xhr.status} ${xhr.statusText}`))\n }\n }\n\n xhr.onerror = () => {\n reject(new Error('Network error occurred'))\n }\n\n xhr.send()\n })\n}\n\n/**\n * 内置的签名获取函数(仅在特定域名下可用)\n */\nasync function builtInGetSignature(url: string): Promise<SignatureResult> {\n const apiUrl = `/wechat/ticket?url=${encodeURIComponent(url)}`\n const result = await httpGet(apiUrl)\n\n if (result.code !== 0) {\n throw new Error(`Signature API error: ${result.message}`)\n }\n\n return {\n appId: result.data.app_id,\n timestamp: result.data.timestamp,\n nonceStr: result.data.nonce_str,\n signature: result.data.signature,\n }\n}\n\n/**\n * 全局配置选项\n */\nexport interface GlobalConfig {\n /**\n * 获取签名参数的函数,接收当前页面 URL,返回签名参数\n * - 在 https://act.go.sohu.com 或 https://test.r.ads.sohu.com 域名下,此参数可选\n * - 未提供时将自动使用内置签名获取函数(请求 /wechat/ticket)\n * - 在其他域名下,此参数必填\n */\n getSignature?: (url: string) => Promise<SignatureResult>\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /**\n * 是否为 SPA 单页应用模式,默认 true\n * - true: 每次调用 API 时检测 URL 变化,变化则重新初始化\n * - false: 仅初始化一次\n */\n spa?: boolean\n}\n\nlet globalConfig: GlobalConfig | null = null\n\n/**\n * 设置全局配置\n * @param options - 配置选项\n */\nexport function config(options: GlobalConfig = {}): void {\n // 如果未提供 getSignature,尝试使用内置签名函数\n if (!options.getSignature) {\n if (isBuiltInSignatureDomain()) {\n options.getSignature = builtInGetSignature\n // 设置默认值,确保未初始化时也有合理的默认配置\n if (options.debug === undefined) {\n options.debug = false\n }\n if (options.spa === undefined) {\n options.spa = true\n }\n } else {\n throw new Error(\n '当前域名不支持内置签名,请提供 getSignature 函数。' +\n '内置签名仅在以下域名下可用:' +\n BUILT_IN_SIGNATURE_DOMAINS.join(', ')\n )\n }\n }\n\n globalConfig = options as Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig\n}\n\n/**\n * 获取全局配置\n * @returns 全局配置,如果未配置则尝试自动初始化(仅在支持的域名下)\n */\nexport function getConfig(): Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig {\n if (!globalConfig) {\n // 在支持的域名下,自动初始化默认配置\n if (isBuiltInSignatureDomain()) {\n config({})\n } else {\n throw new Error(\n '请先调用 config() 进行配置。' +\n '在 ' +\n BUILT_IN_SIGNATURE_DOMAINS.join(', ') +\n ' 域名下可以自动使用内置配置。'\n )\n }\n }\n return globalConfig as Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig\n}\n\n/**\n * 检查是否已配置\n */\nexport function isConfigured(): boolean {\n return globalConfig !== null\n}\n\n/**\n * 重置配置(仅用于测试)\n * @internal\n */\nexport function resetConfig(): void {\n globalConfig = null\n}\n","import { getConfig } from './config'\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n updateAppMessageShareData: (options: {\n title: string\n desc: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n updateTimelineShareData: (options: {\n title: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n}\n\nlet sdkInitPromise: Promise<void> | null = null\nlet currentInitUrl: string | null = null\nlet entryUrl: string | null = null // iOS 微信需要用首次进入的 URL\n\n/**\n * 检测是否为 iOS 微信浏览器\n */\nfunction isIOSWechat(): boolean {\n if (typeof navigator === 'undefined') return false\n const ua = navigator.userAgent.toLowerCase()\n return /iphone|ipad|ipod/.test(ua) && /micromessenger/.test(ua)\n}\n\n/**\n * 获取用于签名的 URL\n * iOS 微信需要用首次进入页面的 URL,Android 用当前 URL\n */\nfunction getSignatureUrl(): string {\n if (typeof window === 'undefined') return ''\n\n const currentUrl = window.location.href.split('#')[0]\n\n if (isIOSWechat()) {\n // iOS 微信:用首次进入的 URL\n if (!entryUrl) {\n entryUrl = currentUrl\n }\n return entryUrl\n }\n\n // Android 或其他:用当前 URL\n return currentUrl\n}\n\n/**\n * 获取 wx 对象\n */\nexport function getWx(): WxSDK {\n if (typeof window === 'undefined') {\n throw new Error('window is not defined')\n }\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n throw new Error('wx is not defined')\n }\n return wx\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\n * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用\n */\nexport async function initSDK(jsApiList: string[]): Promise<void> {\n const cfg = getConfig()\n const signatureUrl = getSignatureUrl()\n const isSpa = cfg.spa !== false // 默认为 true\n\n // 非 SPA 模式或 URL 没有变化,且已经初始化过,直接返回\n if (sdkInitPromise && (!isSpa || currentInitUrl === signatureUrl)) {\n return sdkInitPromise\n }\n\n // URL 变化或首次初始化\n currentInitUrl = signatureUrl\n\n sdkInitPromise = (async () => {\n // 获取签名\n const signatureResult = await cfg.getSignature(signatureUrl)\n\n // 调用 wx.config\n const wx = getWx()\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: cfg.debug ?? false,\n appId: signatureResult.appId,\n timestamp: signatureResult.timestamp,\n nonceStr: signatureResult.nonceStr,\n signature: signatureResult.signature,\n jsApiList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n // 初始化失败,清除缓存以便下次重试\n sdkInitPromise = null\n currentInitUrl = null\n reject(new Error(`wx.config failed: ${res.errMsg}`))\n })\n })\n })()\n\n return sdkInitPromise\n}\n\n/**\n * 重置 SDK 状态(用于测试或强制重新初始化)\n */\nexport function resetSDK(): void {\n sdkInitPromise = null\n currentInitUrl = null\n entryUrl = null\n}\n","import { initSDK, getWx } from './sdk'\n\n/**\n * 分享参数\n */\nexport interface ShareOptions {\n /** 分享标题 */\n title: string\n /** 分享描述(分享给朋友时显示) */\n desc?: string\n /** 分享链接,默认为当前页面 URL */\n link?: string\n /** 分享图标 URL */\n imgUrl: string\n}\n\nconst SHARE_JS_API_LIST = [\n 'updateAppMessageShareData',\n 'updateTimelineShareData',\n]\n\n/**\n * 设置微信分享内容\n * 会自动加载 SDK 并初始化,然后设置分享内容\n * @param options - 分享参数\n */\nexport async function share(options: ShareOptions): Promise<void> {\n // 确保 SDK 已初始化\n await initSDK(SHARE_JS_API_LIST)\n\n const wx = getWx()\n const link = options.link ?? (typeof window !== 'undefined' ? window.location.href : '')\n\n // 设置分享给朋友\n await new Promise<void>((resolve, reject) => {\n wx.updateAppMessageShareData({\n title: options.title,\n desc: options.desc ?? '',\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateAppMessageShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n\n // 设置分享到朋友圈\n await new Promise<void>((resolve, reject) => {\n wx.updateTimelineShareData({\n title: options.title,\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateTimelineShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n}\n","/**\n * 微信 JS-SDK wx.config 所需的配置参数\n */\nexport interface Config {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n /** 需要使用的 JS 接口列表 */\n jsApiList: string[]\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /** 需要使用的开放标签列表 */\n openTagList?: string[]\n}\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n}\n\n/**\n * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise\n * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用\n * @param config - 微信 JS-SDK 配置参数\n * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息\n */\nexport function init(config: Config): Promise<void> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('init: window is not defined'))\n }\n\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n return Promise.reject(new Error('init: wx is not defined, please load WeChat JS-SDK first'))\n }\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: config.debug ?? false,\n appId: config.appId,\n timestamp: config.timestamp,\n nonceStr: config.nonceStr,\n signature: config.signature,\n jsApiList: config.jsApiList,\n openTagList: config.openTagList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n reject(new Error(`init: ${res.errMsg}`))\n })\n })\n}\n"]}
// src/config.ts
var BUILT_IN_SIGNATURE_DOMAINS = [
"https://act.go.sohu.com",
"https://test.r.ads.sohu.com"
];
function isBuiltInSignatureDomain() {
if (typeof window === "undefined") return false;
const origin = window.location.origin;
return BUILT_IN_SIGNATURE_DOMAINS.includes(origin);
}
async function httpGet(url) {
if (typeof fetch !== "undefined") {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch signature: ${response.status} ${response.statusText}`);
}
return await response.json();
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
const result = JSON.parse(xhr.responseText);
resolve(result);
} catch (error) {
reject(new Error(`Failed to parse response: ${error}`));
}
} else {
reject(new Error(`Failed to fetch signature: ${xhr.status} ${xhr.statusText}`));
}
};
xhr.onerror = () => {
reject(new Error("Network error occurred"));
};
xhr.send();
});
}
async function builtInGetSignature(url) {
const apiUrl = `/wechat/ticket?url=${encodeURIComponent(url)}`;
const result = await httpGet(apiUrl);
if (result.code !== 0) {
throw new Error(`Signature API error: ${result.message}`);
}
return {
appId: result.data.app_id,
timestamp: result.data.timestamp,
nonceStr: result.data.nonce_str,
signature: result.data.signature
};
}
var globalConfig = null;
function config(options) {
function config(options = {}) {
if (!options.getSignature) {
if (isBuiltInSignatureDomain()) {
options.getSignature = builtInGetSignature;
if (options.debug === void 0) {
options.debug = false;
}
if (options.spa === void 0) {
options.spa = true;
}
} else {
throw new Error(
"\u5F53\u524D\u57DF\u540D\u4E0D\u652F\u6301\u5185\u7F6E\u7B7E\u540D\uFF0C\u8BF7\u63D0\u4F9B getSignature \u51FD\u6570\u3002\u5185\u7F6E\u7B7E\u540D\u4EC5\u5728\u4EE5\u4E0B\u57DF\u540D\u4E0B\u53EF\u7528\uFF1A" + BUILT_IN_SIGNATURE_DOMAINS.join(", ")
);
}
}
globalConfig = options;

@@ -8,3 +74,9 @@ }

if (!globalConfig) {
throw new Error("\u8BF7\u5148\u8C03\u7528 config() \u8FDB\u884C\u914D\u7F6E");
if (isBuiltInSignatureDomain()) {
config({});
} else {
throw new Error(
"\u8BF7\u5148\u8C03\u7528 config() \u8FDB\u884C\u914D\u7F6E\u3002\u5728 " + BUILT_IN_SIGNATURE_DOMAINS.join(", ") + " \u57DF\u540D\u4E0B\u53EF\u4EE5\u81EA\u52A8\u4F7F\u7528\u5185\u7F6E\u914D\u7F6E\u3002"
);
}
}

@@ -11,0 +83,0 @@ return globalConfig;

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * 微信 JS-SDK 签名参数\n */\nexport interface SignatureResult {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n}\n\n/**\n * 全局配置选项\n */\nexport interface GlobalConfig {\n /** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */\n getSignature: (url: string) => Promise<SignatureResult>\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /**\n * 是否为 SPA 单页应用模式,默认 true\n * - true: 每次调用 API 时检测 URL 变化,变化则重新初始化\n * - false: 仅初始化一次\n */\n spa?: boolean\n}\n\nlet globalConfig: GlobalConfig | null = null\n\n/**\n * 设置全局配置\n * @param options - 配置选项\n */\nexport function config(options: GlobalConfig): void {\n globalConfig = options\n}\n\n/**\n * 获取全局配置\n * @returns 全局配置,如果未配置则抛出错误\n */\nexport function getConfig(): GlobalConfig {\n if (!globalConfig) {\n throw new Error('请先调用 config() 进行配置')\n }\n return globalConfig\n}\n\n/**\n * 检查是否已配置\n */\nexport function isConfigured(): boolean {\n return globalConfig !== null\n}\n","import { getConfig } from './config'\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n updateAppMessageShareData: (options: {\n title: string\n desc: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n updateTimelineShareData: (options: {\n title: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n}\n\nlet sdkInitPromise: Promise<void> | null = null\nlet currentInitUrl: string | null = null\nlet entryUrl: string | null = null // iOS 微信需要用首次进入的 URL\n\n/**\n * 检测是否为 iOS 微信浏览器\n */\nfunction isIOSWechat(): boolean {\n if (typeof navigator === 'undefined') return false\n const ua = navigator.userAgent.toLowerCase()\n return /iphone|ipad|ipod/.test(ua) && /micromessenger/.test(ua)\n}\n\n/**\n * 获取用于签名的 URL\n * iOS 微信需要用首次进入页面的 URL,Android 用当前 URL\n */\nfunction getSignatureUrl(): string {\n if (typeof window === 'undefined') return ''\n\n const currentUrl = window.location.href.split('#')[0]\n\n if (isIOSWechat()) {\n // iOS 微信:用首次进入的 URL\n if (!entryUrl) {\n entryUrl = currentUrl\n }\n return entryUrl\n }\n\n // Android 或其他:用当前 URL\n return currentUrl\n}\n\n/**\n * 获取 wx 对象\n */\nexport function getWx(): WxSDK {\n if (typeof window === 'undefined') {\n throw new Error('window is not defined')\n }\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n throw new Error('wx is not defined')\n }\n return wx\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\n * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用\n */\nexport async function initSDK(jsApiList: string[]): Promise<void> {\n const cfg = getConfig()\n const signatureUrl = getSignatureUrl()\n const isSpa = cfg.spa !== false // 默认为 true\n\n // 非 SPA 模式或 URL 没有变化,且已经初始化过,直接返回\n if (sdkInitPromise && (!isSpa || currentInitUrl === signatureUrl)) {\n return sdkInitPromise\n }\n\n // URL 变化或首次初始化\n currentInitUrl = signatureUrl\n\n sdkInitPromise = (async () => {\n // 获取签名\n const signatureResult = await cfg.getSignature(signatureUrl)\n\n // 调用 wx.config\n const wx = getWx()\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: cfg.debug ?? false,\n appId: signatureResult.appId,\n timestamp: signatureResult.timestamp,\n nonceStr: signatureResult.nonceStr,\n signature: signatureResult.signature,\n jsApiList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n // 初始化失败,清除缓存以便下次重试\n sdkInitPromise = null\n currentInitUrl = null\n reject(new Error(`wx.config failed: ${res.errMsg}`))\n })\n })\n })()\n\n return sdkInitPromise\n}\n\n/**\n * 重置 SDK 状态(用于测试或强制重新初始化)\n */\nexport function resetSDK(): void {\n sdkInitPromise = null\n currentInitUrl = null\n entryUrl = null\n}\n","import { initSDK, getWx } from './sdk'\n\n/**\n * 分享参数\n */\nexport interface ShareOptions {\n /** 分享标题 */\n title: string\n /** 分享描述(分享给朋友时显示) */\n desc?: string\n /** 分享链接,默认为当前页面 URL */\n link?: string\n /** 分享图标 URL */\n imgUrl: string\n}\n\nconst SHARE_JS_API_LIST = [\n 'updateAppMessageShareData',\n 'updateTimelineShareData',\n]\n\n/**\n * 设置微信分享内容\n * 会自动加载 SDK 并初始化,然后设置分享内容\n * @param options - 分享参数\n */\nexport async function share(options: ShareOptions): Promise<void> {\n // 确保 SDK 已初始化\n await initSDK(SHARE_JS_API_LIST)\n\n const wx = getWx()\n const link = options.link ?? (typeof window !== 'undefined' ? window.location.href : '')\n\n // 设置分享给朋友\n await new Promise<void>((resolve, reject) => {\n wx.updateAppMessageShareData({\n title: options.title,\n desc: options.desc ?? '',\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateAppMessageShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n\n // 设置分享到朋友圈\n await new Promise<void>((resolve, reject) => {\n wx.updateTimelineShareData({\n title: options.title,\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateTimelineShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n}\n","/**\n * 微信 JS-SDK wx.config 所需的配置参数\n */\nexport interface Config {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n /** 需要使用的 JS 接口列表 */\n jsApiList: string[]\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /** 需要使用的开放标签列表 */\n openTagList?: string[]\n}\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n}\n\n/**\n * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise\n * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用\n * @param config - 微信 JS-SDK 配置参数\n * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息\n */\nexport function init(config: Config): Promise<void> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('init: window is not defined'))\n }\n\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n return Promise.reject(new Error('init: wx is not defined, please load WeChat JS-SDK first'))\n }\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: config.debug ?? false,\n appId: config.appId,\n timestamp: config.timestamp,\n nonceStr: config.nonceStr,\n signature: config.signature,\n jsApiList: config.jsApiList,\n openTagList: config.openTagList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n reject(new Error(`init: ${res.errMsg}`))\n })\n })\n}\n"]}
{"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * 微信 JS-SDK 签名参数\n */\nexport interface SignatureResult {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n}\n\n/**\n * 内置签名接口返回值\n */\ninterface BuiltInSignatureResponse {\n code: number\n data: {\n app_id: string\n timestamp: number\n nonce_str: string\n signature: string\n }\n message: string\n}\n\n/**\n * 支持内置签名的域名列表\n */\nconst BUILT_IN_SIGNATURE_DOMAINS = [\n 'https://act.go.sohu.com',\n 'https://test.r.ads.sohu.com',\n]\n\n/**\n * 检查当前域名是否支持内置签名\n */\nfunction isBuiltInSignatureDomain(): boolean {\n if (typeof window === 'undefined') return false\n const origin = window.location.origin\n return BUILT_IN_SIGNATURE_DOMAINS.includes(origin)\n}\n\n/**\n * 发起 HTTP GET 请求,支持 fetch 和 XMLHttpRequest 回退\n */\nasync function httpGet(url: string): Promise<BuiltInSignatureResponse> {\n // 优先使用 fetch API\n if (typeof fetch !== 'undefined') {\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(`Failed to fetch signature: ${response.status} ${response.statusText}`)\n }\n\n return await response.json()\n }\n\n // 回退到 XMLHttpRequest\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest()\n xhr.open('GET', url, true)\n\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n try {\n const result = JSON.parse(xhr.responseText)\n resolve(result)\n } catch (error) {\n reject(new Error(`Failed to parse response: ${error}`))\n }\n } else {\n reject(new Error(`Failed to fetch signature: ${xhr.status} ${xhr.statusText}`))\n }\n }\n\n xhr.onerror = () => {\n reject(new Error('Network error occurred'))\n }\n\n xhr.send()\n })\n}\n\n/**\n * 内置的签名获取函数(仅在特定域名下可用)\n */\nasync function builtInGetSignature(url: string): Promise<SignatureResult> {\n const apiUrl = `/wechat/ticket?url=${encodeURIComponent(url)}`\n const result = await httpGet(apiUrl)\n\n if (result.code !== 0) {\n throw new Error(`Signature API error: ${result.message}`)\n }\n\n return {\n appId: result.data.app_id,\n timestamp: result.data.timestamp,\n nonceStr: result.data.nonce_str,\n signature: result.data.signature,\n }\n}\n\n/**\n * 全局配置选项\n */\nexport interface GlobalConfig {\n /**\n * 获取签名参数的函数,接收当前页面 URL,返回签名参数\n * - 在 https://act.go.sohu.com 或 https://test.r.ads.sohu.com 域名下,此参数可选\n * - 未提供时将自动使用内置签名获取函数(请求 /wechat/ticket)\n * - 在其他域名下,此参数必填\n */\n getSignature?: (url: string) => Promise<SignatureResult>\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /**\n * 是否为 SPA 单页应用模式,默认 true\n * - true: 每次调用 API 时检测 URL 变化,变化则重新初始化\n * - false: 仅初始化一次\n */\n spa?: boolean\n}\n\nlet globalConfig: GlobalConfig | null = null\n\n/**\n * 设置全局配置\n * @param options - 配置选项\n */\nexport function config(options: GlobalConfig = {}): void {\n // 如果未提供 getSignature,尝试使用内置签名函数\n if (!options.getSignature) {\n if (isBuiltInSignatureDomain()) {\n options.getSignature = builtInGetSignature\n // 设置默认值,确保未初始化时也有合理的默认配置\n if (options.debug === undefined) {\n options.debug = false\n }\n if (options.spa === undefined) {\n options.spa = true\n }\n } else {\n throw new Error(\n '当前域名不支持内置签名,请提供 getSignature 函数。' +\n '内置签名仅在以下域名下可用:' +\n BUILT_IN_SIGNATURE_DOMAINS.join(', ')\n )\n }\n }\n\n globalConfig = options as Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig\n}\n\n/**\n * 获取全局配置\n * @returns 全局配置,如果未配置则尝试自动初始化(仅在支持的域名下)\n */\nexport function getConfig(): Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig {\n if (!globalConfig) {\n // 在支持的域名下,自动初始化默认配置\n if (isBuiltInSignatureDomain()) {\n config({})\n } else {\n throw new Error(\n '请先调用 config() 进行配置。' +\n '在 ' +\n BUILT_IN_SIGNATURE_DOMAINS.join(', ') +\n ' 域名下可以自动使用内置配置。'\n )\n }\n }\n return globalConfig as Required<Pick<GlobalConfig, 'getSignature'>> & GlobalConfig\n}\n\n/**\n * 检查是否已配置\n */\nexport function isConfigured(): boolean {\n return globalConfig !== null\n}\n\n/**\n * 重置配置(仅用于测试)\n * @internal\n */\nexport function resetConfig(): void {\n globalConfig = null\n}\n","import { getConfig } from './config'\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n updateAppMessageShareData: (options: {\n title: string\n desc: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n updateTimelineShareData: (options: {\n title: string\n link: string\n imgUrl: string\n success?: () => void\n fail?: (err: { errMsg: string }) => void\n }) => void\n}\n\nlet sdkInitPromise: Promise<void> | null = null\nlet currentInitUrl: string | null = null\nlet entryUrl: string | null = null // iOS 微信需要用首次进入的 URL\n\n/**\n * 检测是否为 iOS 微信浏览器\n */\nfunction isIOSWechat(): boolean {\n if (typeof navigator === 'undefined') return false\n const ua = navigator.userAgent.toLowerCase()\n return /iphone|ipad|ipod/.test(ua) && /micromessenger/.test(ua)\n}\n\n/**\n * 获取用于签名的 URL\n * iOS 微信需要用首次进入页面的 URL,Android 用当前 URL\n */\nfunction getSignatureUrl(): string {\n if (typeof window === 'undefined') return ''\n\n const currentUrl = window.location.href.split('#')[0]\n\n if (isIOSWechat()) {\n // iOS 微信:用首次进入的 URL\n if (!entryUrl) {\n entryUrl = currentUrl\n }\n return entryUrl\n }\n\n // Android 或其他:用当前 URL\n return currentUrl\n}\n\n/**\n * 获取 wx 对象\n */\nexport function getWx(): WxSDK {\n if (typeof window === 'undefined') {\n throw new Error('window is not defined')\n }\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n throw new Error('wx is not defined')\n }\n return wx\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\n * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用\n */\nexport async function initSDK(jsApiList: string[]): Promise<void> {\n const cfg = getConfig()\n const signatureUrl = getSignatureUrl()\n const isSpa = cfg.spa !== false // 默认为 true\n\n // 非 SPA 模式或 URL 没有变化,且已经初始化过,直接返回\n if (sdkInitPromise && (!isSpa || currentInitUrl === signatureUrl)) {\n return sdkInitPromise\n }\n\n // URL 变化或首次初始化\n currentInitUrl = signatureUrl\n\n sdkInitPromise = (async () => {\n // 获取签名\n const signatureResult = await cfg.getSignature(signatureUrl)\n\n // 调用 wx.config\n const wx = getWx()\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: cfg.debug ?? false,\n appId: signatureResult.appId,\n timestamp: signatureResult.timestamp,\n nonceStr: signatureResult.nonceStr,\n signature: signatureResult.signature,\n jsApiList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n // 初始化失败,清除缓存以便下次重试\n sdkInitPromise = null\n currentInitUrl = null\n reject(new Error(`wx.config failed: ${res.errMsg}`))\n })\n })\n })()\n\n return sdkInitPromise\n}\n\n/**\n * 重置 SDK 状态(用于测试或强制重新初始化)\n */\nexport function resetSDK(): void {\n sdkInitPromise = null\n currentInitUrl = null\n entryUrl = null\n}\n","import { initSDK, getWx } from './sdk'\n\n/**\n * 分享参数\n */\nexport interface ShareOptions {\n /** 分享标题 */\n title: string\n /** 分享描述(分享给朋友时显示) */\n desc?: string\n /** 分享链接,默认为当前页面 URL */\n link?: string\n /** 分享图标 URL */\n imgUrl: string\n}\n\nconst SHARE_JS_API_LIST = [\n 'updateAppMessageShareData',\n 'updateTimelineShareData',\n]\n\n/**\n * 设置微信分享内容\n * 会自动加载 SDK 并初始化,然后设置分享内容\n * @param options - 分享参数\n */\nexport async function share(options: ShareOptions): Promise<void> {\n // 确保 SDK 已初始化\n await initSDK(SHARE_JS_API_LIST)\n\n const wx = getWx()\n const link = options.link ?? (typeof window !== 'undefined' ? window.location.href : '')\n\n // 设置分享给朋友\n await new Promise<void>((resolve, reject) => {\n wx.updateAppMessageShareData({\n title: options.title,\n desc: options.desc ?? '',\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateAppMessageShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n\n // 设置分享到朋友圈\n await new Promise<void>((resolve, reject) => {\n wx.updateTimelineShareData({\n title: options.title,\n link,\n imgUrl: options.imgUrl,\n success: () => resolve(),\n fail: (err) => reject(new Error(`updateTimelineShareData failed: ${err.errMsg}`)),\n })\n // 微信 SDK 有时不会调用 success/fail,设置超时自动 resolve\n setTimeout(resolve, 500)\n })\n}\n","/**\n * 微信 JS-SDK wx.config 所需的配置参数\n */\nexport interface Config {\n /** 公众号的 appId */\n appId: string\n /** 生成签名的时间戳 */\n timestamp: number | string\n /** 生成签名的随机字符串 */\n nonceStr: string\n /** 签名 */\n signature: string\n /** 需要使用的 JS 接口列表 */\n jsApiList: string[]\n /** 是否开启调试模式,默认 false */\n debug?: boolean\n /** 需要使用的开放标签列表 */\n openTagList?: string[]\n}\n\ninterface WxSDK {\n config: (cfg: {\n debug: boolean\n appId: string\n timestamp: number | string\n nonceStr: string\n signature: string\n jsApiList: string[]\n openTagList?: string[]\n }) => void\n ready: (fn: () => void) => void\n error: (fn: (res: { errMsg: string }) => void) => void\n}\n\n/**\n * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise\n * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用\n * @param config - 微信 JS-SDK 配置参数\n * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息\n */\nexport function init(config: Config): Promise<void> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('init: window is not defined'))\n }\n\n const wx = (window as unknown as Record<string, unknown>).wx as WxSDK | undefined\n if (!wx) {\n return Promise.reject(new Error('init: wx is not defined, please load WeChat JS-SDK first'))\n }\n\n return new Promise<void>((resolve, reject) => {\n wx.config({\n debug: config.debug ?? false,\n appId: config.appId,\n timestamp: config.timestamp,\n nonceStr: config.nonceStr,\n signature: config.signature,\n jsApiList: config.jsApiList,\n openTagList: config.openTagList,\n })\n\n wx.ready(() => {\n resolve()\n })\n\n wx.error((res: { errMsg: string }) => {\n reject(new Error(`init: ${res.errMsg}`))\n })\n })\n}\n"]}
{
"name": "@sohu-bpd/wechat",
"version": "0.0.4",
"version": "0.0.5",
"description": "WeChat JS-SDK utility library",

@@ -5,0 +5,0 @@ "main": "./dist/index.js",

+180
-6

@@ -33,8 +33,41 @@ # @sohu-bpd/wechat

### 2. Configure Once
### 2. Configure (Optional on Sohu Domains)
**Option A: Zero Configuration (Sohu Domains Only)**
If you're on `https://act.go.sohu.com` or `https://test.r.ads.sohu.com`, you can skip configuration entirely:
```typescript
import { share } from '@sohu-bpd/wechat'
// No config needed! Just use it directly
await share({
title: 'My Page Title',
desc: 'Share description',
imgUrl: 'https://example.com/image.jpg',
})
```
**Option B: Custom Configuration (Sohu Domains)**
Or customize settings on supported domains:
```typescript
import { config } from '@sohu-bpd/wechat'
// No need to provide getSignature on supported domains
config({
debug: false,
spa: true, // Enable SPA mode (default)
})
```
**Option C: Custom Signature Function (Other Domains)**
For other domains or custom backends:
```typescript
import { config } from '@sohu-bpd/wechat'
config({
getSignature: async (url) => {

@@ -108,8 +141,15 @@ // Fetch signature from your backend

**Note:** You must load the WeChat JS-SDK script in your HTML before using this library.
**Note:**
- You must load the WeChat JS-SDK script in your HTML before using this library
- **On `https://act.go.sohu.com` or `https://test.r.ads.sohu.com`, calling `config()` is optional** - the library will auto-configure with defaults when you use features like `share()`
```typescript
interface GlobalConfig {
/** Function to fetch signature, receives current URL */
getSignature: (url: string) => Promise<SignatureResult>
/**
* Function to fetch signature, receives current URL
* - Optional on https://act.go.sohu.com or https://test.r.ads.sohu.com
* - Will auto-use built-in signature (requests /wechat/ticket) if not provided
* - Required on other domains
*/
getSignature?: (url: string) => Promise<SignatureResult>
/** Enable debug mode, default false */

@@ -121,8 +161,21 @@ debug?: boolean

function config(options: GlobalConfig): void
function config(options?: GlobalConfig): void
```
**Example:**
**Example - No configuration needed (Sohu domains):**
```typescript
import { share } from '@sohu-bpd/wechat'
// Just use it directly!
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
```
**Example - Custom signature function:**
```typescript
config({

@@ -138,2 +191,12 @@ getSignature: async (url) => {

**Example - Custom settings with built-in signature (Sohu domains):**
```typescript
// On https://act.go.sohu.com or https://test.r.ads.sohu.com
config({
debug: true,
spa: true,
})
```
#### share(options)

@@ -257,2 +320,104 @@

## Built-in Signature Support
On specific Sohu domains, the library provides built-in signature functionality:
### Supported Domains
- `https://act.go.sohu.com`
- `https://test.r.ads.sohu.com`
### How It Works
When you call `config()` without providing `getSignature` on a supported domain:
1. The library automatically detects the current domain
2. Uses the built-in signature function that requests `/wechat/ticket`
3. Converts the API response to the standard `SignatureResult` format
### API Request Format
The built-in signature function sends a GET request to:
```
/wechat/ticket?url={encoded_current_url}
```
**Parameters:**
- `url` (query parameter): The current page URL (URL-encoded)
**Example Request:**
```
GET /wechat/ticket?url=https%3A%2F%2Fact.go.sohu.com%2Fpage%3Fid%3D123
```
### API Response Format
The built-in signature endpoint `/wechat/ticket` should return:
```typescript
{
code: number // 0 for success
data: {
app_id: string // Converted to appId
timestamp: number // Kept as timestamp
nonce_str: string // Converted to nonceStr
signature: string // Kept as signature
}
message: string // Error message if code !== 0
}
```
**Notes:**
- Uses `fetch` API if available (modern browsers)
- Automatically falls back to `XMLHttpRequest` in older environments
- Response format is automatically converted to match `SignatureResult` interface
### Usage
**Zero Configuration (Recommended):**
```typescript
import { share } from '@sohu-bpd/wechat'
// No config() needed on supported domains!
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
```
**With Custom Settings:**
```typescript
import { config, share } from '@sohu-bpd/wechat'
// Optional: customize settings
config({
debug: true,
spa: true,
})
// Then use normally
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
```
### Fallback to Custom Function
Even on supported domains, you can provide your own `getSignature` function:
```typescript
config({
getSignature: async (url) => {
// Your custom implementation
return await fetchSignatureFromCustomAPI(url)
},
})
```
## iOS WeChat Quirk

@@ -317,2 +482,11 @@

### 0.0.4 (TBD)
- **New Feature:** Built-in signature support for Sohu domains
- **Zero Configuration Mode:** On `https://act.go.sohu.com` and `https://test.r.ads.sohu.com`, you can now use the library without calling `config()` at all
- `getSignature` is now optional on supported domains
- Automatic signature fetching from `/wechat/ticket?url={current_url}` endpoint on supported domains
- Built-in request uses `fetch` API with automatic fallback to `XMLHttpRequest` for older browsers
- Added comprehensive tests for built-in signature functionality, xhr fallback, and auto-initialization
### 0.0.3 (2026-01-29)

@@ -319,0 +493,0 @@