@sohu-bpd/wechat
Advanced tools
+3
-7
@@ -18,4 +18,2 @@ /** | ||
| interface GlobalConfig { | ||
| /** 微信 JS-SDK 的 URL 地址 */ | ||
| sdkUrl: string; | ||
| /** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */ | ||
@@ -106,9 +104,6 @@ getSignature: (url: string) => Promise<SignatureResult>; | ||
| /** | ||
| * 加载 SDK(仅加载一次) | ||
| */ | ||
| declare function loadSDK(): Promise<void>; | ||
| /** | ||
| * 初始化 SDK(获取签名并调用 wx.config) | ||
| * SPA 模式下,URL 变化时会重新初始化(Android) | ||
| * iOS 微信始终使用首次进入的 URL 进行签名 | ||
| * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用 | ||
| */ | ||
@@ -142,2 +137,3 @@ declare function initSDK(jsApiList: string[]): Promise<void>; | ||
| * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise | ||
| * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用 | ||
| * @param config - 微信 JS-SDK 配置参数 | ||
@@ -148,2 +144,2 @@ * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息 | ||
| export { type GlobalConfig, type Config as InitConfig, type ShareOptions, type SignatureResult, config, getConfig, getWx, init, initSDK, isConfigured, loadSDK, resetSDK, share }; | ||
| export { type GlobalConfig, type Config as InitConfig, type ShareOptions, type SignatureResult, config, getConfig, getWx, init, initSDK, isConfigured, resetSDK, share }; |
+3
-7
@@ -18,4 +18,2 @@ /** | ||
| interface GlobalConfig { | ||
| /** 微信 JS-SDK 的 URL 地址 */ | ||
| sdkUrl: string; | ||
| /** 获取签名参数的函数,接收当前页面 URL,返回签名参数 */ | ||
@@ -106,9 +104,6 @@ getSignature: (url: string) => Promise<SignatureResult>; | ||
| /** | ||
| * 加载 SDK(仅加载一次) | ||
| */ | ||
| declare function loadSDK(): Promise<void>; | ||
| /** | ||
| * 初始化 SDK(获取签名并调用 wx.config) | ||
| * SPA 模式下,URL 变化时会重新初始化(Android) | ||
| * iOS 微信始终使用首次进入的 URL 进行签名 | ||
| * 注意:需要使用者在全局引入微信 JS-SDK,确保 window.wx 可用 | ||
| */ | ||
@@ -142,2 +137,3 @@ declare function initSDK(jsApiList: string[]): Promise<void>; | ||
| * 初始化微信 JS-SDK,调用 wx.config 并返回 Promise | ||
| * 注意:使用此函数前,需要在 HTML 中提前引入微信 JS-SDK 脚本,确保 window.wx 可用 | ||
| * @param config - 微信 JS-SDK 配置参数 | ||
@@ -148,2 +144,2 @@ * @returns Promise,ready 时 resolve,error 时 reject 并携带错误信息 | ||
| export { type GlobalConfig, type Config as InitConfig, type ShareOptions, type SignatureResult, config, getConfig, getWx, init, initSDK, isConfigured, loadSDK, resetSDK, share }; | ||
| export { type GlobalConfig, type Config as InitConfig, type ShareOptions, type SignatureResult, config, getConfig, getWx, init, initSDK, isConfigured, resetSDK, share }; |
+0
-29
@@ -20,3 +20,2 @@ var SohuWechat = (function (exports) { | ||
| // src/sdk.ts | ||
| var sdkLoadPromise = null; | ||
| var sdkInitPromise = null; | ||
@@ -41,15 +40,2 @@ var currentInitUrl = null; | ||
| } | ||
| function loadScript(url) { | ||
| return new Promise((resolve, reject) => { | ||
| if (typeof document === "undefined") { | ||
| reject(new Error("document is not defined")); | ||
| return; | ||
| } | ||
| const script = document.createElement("script"); | ||
| script.src = url; | ||
| script.onload = () => resolve(); | ||
| script.onerror = () => reject(new Error(`Failed to load script: ${url}`)); | ||
| document.head.appendChild(script); | ||
| }); | ||
| } | ||
| function getWx() { | ||
@@ -65,14 +51,2 @@ if (typeof window === "undefined") { | ||
| } | ||
| async function loadSDK() { | ||
| if (sdkLoadPromise) { | ||
| return sdkLoadPromise; | ||
| } | ||
| const config2 = getConfig(); | ||
| if (typeof window !== "undefined" && window.wx) { | ||
| sdkLoadPromise = Promise.resolve(); | ||
| return sdkLoadPromise; | ||
| } | ||
| sdkLoadPromise = loadScript(config2.sdkUrl); | ||
| return sdkLoadPromise; | ||
| } | ||
| async function initSDK(jsApiList) { | ||
@@ -87,3 +61,2 @@ const cfg = getConfig(); | ||
| sdkInitPromise = (async () => { | ||
| await loadSDK(); | ||
| const signatureResult = await cfg.getSignature(signatureUrl); | ||
@@ -113,3 +86,2 @@ const wx = getWx(); | ||
| function resetSDK() { | ||
| sdkLoadPromise = null; | ||
| sdkInitPromise = null; | ||
@@ -186,3 +158,2 @@ currentInitUrl = null; | ||
| exports.isConfigured = isConfigured; | ||
| exports.loadSDK = loadSDK; | ||
| exports.resetSDK = resetSDK; | ||
@@ -189,0 +160,0 @@ exports.share = share; |
@@ -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 /** 微信 JS-SDK 的 URL 地址 */\n sdkUrl: string\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 sdkLoadPromise: Promise<void> | null = null\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 * 加载微信 JS-SDK 脚本\n */\nfunction loadScript(url: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') {\n reject(new Error('document is not defined'))\n return\n }\n\n const script = document.createElement('script')\n script.src = url\n script.onload = () => resolve()\n script.onerror = () => reject(new Error(`Failed to load script: ${url}`))\n document.head.appendChild(script)\n })\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(仅加载一次)\n */\nexport async function loadSDK(): Promise<void> {\n if (sdkLoadPromise) {\n return sdkLoadPromise\n }\n\n const config = getConfig()\n\n // 检查是否已经加载\n if (typeof window !== 'undefined' && (window as unknown as Record<string, unknown>).wx) {\n sdkLoadPromise = Promise.resolve()\n return sdkLoadPromise\n }\n\n sdkLoadPromise = loadScript(config.sdkUrl)\n return sdkLoadPromise\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\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 // 先确保 SDK 已加载\n await loadSDK()\n\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 sdkLoadPromise = null\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 * @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 */\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"]} |
+0
-29
@@ -19,3 +19,2 @@ 'use strict'; | ||
| // src/sdk.ts | ||
| var sdkLoadPromise = null; | ||
| var sdkInitPromise = null; | ||
@@ -40,15 +39,2 @@ var currentInitUrl = null; | ||
| } | ||
| function loadScript(url) { | ||
| return new Promise((resolve, reject) => { | ||
| if (typeof document === "undefined") { | ||
| reject(new Error("document is not defined")); | ||
| return; | ||
| } | ||
| const script = document.createElement("script"); | ||
| script.src = url; | ||
| script.onload = () => resolve(); | ||
| script.onerror = () => reject(new Error(`Failed to load script: ${url}`)); | ||
| document.head.appendChild(script); | ||
| }); | ||
| } | ||
| function getWx() { | ||
@@ -64,14 +50,2 @@ if (typeof window === "undefined") { | ||
| } | ||
| async function loadSDK() { | ||
| if (sdkLoadPromise) { | ||
| return sdkLoadPromise; | ||
| } | ||
| const config2 = getConfig(); | ||
| if (typeof window !== "undefined" && window.wx) { | ||
| sdkLoadPromise = Promise.resolve(); | ||
| return sdkLoadPromise; | ||
| } | ||
| sdkLoadPromise = loadScript(config2.sdkUrl); | ||
| return sdkLoadPromise; | ||
| } | ||
| async function initSDK(jsApiList) { | ||
@@ -86,3 +60,2 @@ const cfg = getConfig(); | ||
| sdkInitPromise = (async () => { | ||
| await loadSDK(); | ||
| const signatureResult = await cfg.getSignature(signatureUrl); | ||
@@ -112,3 +85,2 @@ const wx = getWx(); | ||
| function resetSDK() { | ||
| sdkLoadPromise = null; | ||
| sdkInitPromise = null; | ||
@@ -185,3 +157,2 @@ currentInitUrl = null; | ||
| exports.isConfigured = isConfigured; | ||
| exports.loadSDK = loadSDK; | ||
| exports.resetSDK = resetSDK; | ||
@@ -188,0 +159,0 @@ exports.share = share; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/config.ts","../src/sdk.ts","../src/share.ts","../src/init.ts"],"names":["config"],"mappings":";;;AAgCA,IAAI,YAAA,GAAoC,IAAA;AAMjC,SAAS,OAAO,OAAA,EAA6B;AAClD,EAAA,YAAA,GAAe,OAAA;AACjB;AAMO,SAAS,SAAA,GAA0B;AACxC,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,MAAM,IAAI,MAAM,4DAAoB,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,YAAA;AACT;AAKO,SAAS,YAAA,GAAwB;AACtC,EAAA,OAAO,YAAA,KAAiB,IAAA;AAC1B;;;AC3BA,IAAI,cAAA,GAAuC,IAAA;AAC3C,IAAI,cAAA,GAAuC,IAAA;AAC3C,IAAI,cAAA,GAAgC,IAAA;AACpC,IAAI,QAAA,GAA0B,IAAA;AAK9B,SAAS,WAAA,GAAuB;AAC9B,EAAA,IAAI,OAAO,SAAA,KAAc,WAAA,EAAa,OAAO,KAAA;AAC7C,EAAA,MAAM,EAAA,GAAK,SAAA,CAAU,SAAA,CAAU,WAAA,EAAY;AAC3C,EAAA,OAAO,mBAAmB,IAAA,CAAK,EAAE,CAAA,IAAK,gBAAA,CAAiB,KAAK,EAAE,CAAA;AAChE;AAMA,SAAS,eAAA,GAA0B;AACjC,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,EAAA;AAE1C,EAAA,MAAM,aAAa,MAAA,CAAO,QAAA,CAAS,KAAK,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAEpD,EAAA,IAAI,aAAY,EAAG;AAEjB,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,QAAA,GAAW,UAAA;AAAA,IACb;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAGA,EAAA,OAAO,UAAA;AACT;AAKA,SAAS,WAAW,GAAA,EAA4B;AAC9C,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,yBAAyB,CAAC,CAAA;AAC3C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,GAAM,GAAA;AACb,IAAA,MAAA,CAAO,MAAA,GAAS,MAAM,OAAA,EAAQ;AAC9B,IAAA,MAAA,CAAO,OAAA,GAAU,MAAM,MAAA,CAAO,IAAI,MAAM,CAAA,uBAAA,EAA0B,GAAG,EAAE,CAAC,CAAA;AACxE,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,MAAM,CAAA;AAAA,EAClC,CAAC,CAAA;AACH;AAKO,SAAS,KAAA,GAAe;AAC7B,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,KAAM,MAAA,CAA8C,EAAA;AAC1D,EAAA,IAAI,CAAC,EAAA,EAAI;AACP,IAAA,MAAM,IAAI,MAAM,mBAAmB,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,EAAA;AACT;AAKA,eAAsB,OAAA,GAAyB;AAC7C,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,OAAO,cAAA;AAAA,EACT;AAEA,EAAA,MAAMA,UAAS,SAAA,EAAU;AAGzB,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAgB,MAAA,CAA8C,EAAA,EAAI;AACtF,IAAA,cAAA,GAAiB,QAAQ,OAAA,EAAQ;AACjC,IAAA,OAAO,cAAA;AAAA,EACT;AAEA,EAAA,cAAA,GAAiB,UAAA,CAAWA,QAAO,MAAM,CAAA;AACzC,EAAA,OAAO,cAAA;AACT;AAOA,eAAsB,QAAQ,SAAA,EAAoC;AAChE,EAAA,MAAM,MAAM,SAAA,EAAU;AACtB,EAAA,MAAM,eAAe,eAAA,EAAgB;AACrC,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,KAAQ,KAAA;AAG1B,EAAA,IAAI,cAAA,KAAmB,CAAC,KAAA,IAAS,cAAA,KAAmB,YAAA,CAAA,EAAe;AACjE,IAAA,OAAO,cAAA;AAAA,EACT;AAGA,EAAA,cAAA,GAAiB,YAAA;AAEjB,EAAA,cAAA,GAAA,CAAkB,YAAY;AAE5B,IAAA,MAAM,OAAA,EAAQ;AAGd,IAAA,MAAM,eAAA,GAAkB,MAAM,GAAA,CAAI,YAAA,CAAa,YAAY,CAAA;AAG3D,IAAA,MAAM,KAAK,KAAA,EAAM;AAEjB,IAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC5C,MAAA,EAAA,CAAG,MAAA,CAAO;AAAA,QACR,KAAA,EAAO,IAAI,KAAA,IAAS,KAAA;AAAA,QACpB,OAAO,eAAA,CAAgB,KAAA;AAAA,QACvB,WAAW,eAAA,CAAgB,SAAA;AAAA,QAC3B,UAAU,eAAA,CAAgB,QAAA;AAAA,QAC1B,WAAW,eAAA,CAAgB,SAAA;AAAA,QAC3B;AAAA,OACD,CAAA;AAED,MAAA,EAAA,CAAG,MAAM,MAAM;AACb,QAAA,OAAA,EAAQ;AAAA,MACV,CAAC,CAAA;AAED,MAAA,EAAA,CAAG,KAAA,CAAM,CAAC,GAAA,KAA4B;AAEpC,QAAA,cAAA,GAAiB,IAAA;AACjB,QAAA,cAAA,GAAiB,IAAA;AACjB,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,GAAA,CAAI,MAAM,EAAE,CAAC,CAAA;AAAA,MACrD,CAAC,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH,CAAA,GAAG;AAEH,EAAA,OAAO,cAAA;AACT;AAKO,SAAS,QAAA,GAAiB;AAC/B,EAAA,cAAA,GAAiB,IAAA;AACjB,EAAA,cAAA,GAAiB,IAAA;AACjB,EAAA,cAAA,GAAiB,IAAA;AACjB,EAAA,QAAA,GAAW,IAAA;AACb;;;ACpKA,IAAM,iBAAA,GAAoB;AAAA,EACxB,2BAAA;AAAA,EACA;AACF,CAAA;AAOA,eAAsB,MAAM,OAAA,EAAsC;AAEhE,EAAA,MAAM,QAAQ,iBAAiB,CAAA;AAE/B,EAAA,MAAM,KAAK,KAAA,EAAM;AACjB,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,KAAS,OAAO,WAAW,WAAA,GAAc,MAAA,CAAO,SAAS,IAAA,GAAO,EAAA,CAAA;AAGrF,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC3C,IAAA,EAAA,CAAG,yBAAA,CAA0B;AAAA,MAC3B,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,IAAA,EAAM,QAAQ,IAAA,IAAQ,EAAA;AAAA,MACtB,IAAA;AAAA,MACA,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,MACvB,IAAA,EAAM,CAAC,GAAA,KAAQ,MAAA,CAAO,IAAI,MAAM,CAAA,kCAAA,EAAqC,GAAA,CAAI,MAAM,CAAA,CAAE,CAAC;AAAA,KACnF,CAAA;AAED,IAAA,UAAA,CAAW,SAAS,GAAG,CAAA;AAAA,EACzB,CAAC,CAAA;AAGD,EAAA,MAAM,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC3C,IAAA,EAAA,CAAG,uBAAA,CAAwB;AAAA,MACzB,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,IAAA;AAAA,MACA,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,MACvB,IAAA,EAAM,CAAC,GAAA,KAAQ,MAAA,CAAO,IAAI,MAAM,CAAA,gCAAA,EAAmC,GAAA,CAAI,MAAM,CAAA,CAAE,CAAC;AAAA,KACjF,CAAA;AAED,IAAA,UAAA,CAAW,SAAS,GAAG,CAAA;AAAA,EACzB,CAAC,CAAA;AACH;;;ACpBO,SAAS,KAAKA,OAAAA,EAA+B;AAClD,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,6BAA6B,CAAC,CAAA;AAAA,EAChE;AAEA,EAAA,MAAM,KAAM,MAAA,CAA8C,EAAA;AAC1D,EAAA,IAAI,CAAC,EAAA,EAAI;AACP,IAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,0DAA0D,CAAC,CAAA;AAAA,EAC7F;AAEA,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAA,KAAW;AAC5C,IAAA,EAAA,CAAG,MAAA,CAAO;AAAA,MACR,KAAA,EAAOA,QAAO,KAAA,IAAS,KAAA;AAAA,MACvB,OAAOA,OAAAA,CAAO,KAAA;AAAA,MACd,WAAWA,OAAAA,CAAO,SAAA;AAAA,MAClB,UAAUA,OAAAA,CAAO,QAAA;AAAA,MACjB,WAAWA,OAAAA,CAAO,SAAA;AAAA,MAClB,WAAWA,OAAAA,CAAO,SAAA;AAAA,MAClB,aAAaA,OAAAA,CAAO;AAAA,KACrB,CAAA;AAED,IAAA,EAAA,CAAG,MAAM,MAAM;AACb,MAAA,OAAA,EAAQ;AAAA,IACV,CAAC,CAAA;AAED,IAAA,EAAA,CAAG,KAAA,CAAM,CAAC,GAAA,KAA4B;AACpC,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,MAAA,EAAS,GAAA,CAAI,MAAM,EAAE,CAAC,CAAA;AAAA,IACzC,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH","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 /** 微信 JS-SDK 的 URL 地址 */\n sdkUrl: string\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 sdkLoadPromise: Promise<void> | null = null\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 * 加载微信 JS-SDK 脚本\n */\nfunction loadScript(url: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') {\n reject(new Error('document is not defined'))\n return\n }\n\n const script = document.createElement('script')\n script.src = url\n script.onload = () => resolve()\n script.onerror = () => reject(new Error(`Failed to load script: ${url}`))\n document.head.appendChild(script)\n })\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(仅加载一次)\n */\nexport async function loadSDK(): Promise<void> {\n if (sdkLoadPromise) {\n return sdkLoadPromise\n }\n\n const config = getConfig()\n\n // 检查是否已经加载\n if (typeof window !== 'undefined' && (window as unknown as Record<string, unknown>).wx) {\n sdkLoadPromise = Promise.resolve()\n return sdkLoadPromise\n }\n\n sdkLoadPromise = loadScript(config.sdkUrl)\n return sdkLoadPromise\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\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 // 先确保 SDK 已加载\n await loadSDK()\n\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 sdkLoadPromise = null\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 * @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 */\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"]} |
+1
-29
@@ -17,3 +17,2 @@ // src/config.ts | ||
| // src/sdk.ts | ||
| var sdkLoadPromise = null; | ||
| var sdkInitPromise = null; | ||
@@ -38,15 +37,2 @@ var currentInitUrl = null; | ||
| } | ||
| function loadScript(url) { | ||
| return new Promise((resolve, reject) => { | ||
| if (typeof document === "undefined") { | ||
| reject(new Error("document is not defined")); | ||
| return; | ||
| } | ||
| const script = document.createElement("script"); | ||
| script.src = url; | ||
| script.onload = () => resolve(); | ||
| script.onerror = () => reject(new Error(`Failed to load script: ${url}`)); | ||
| document.head.appendChild(script); | ||
| }); | ||
| } | ||
| function getWx() { | ||
@@ -62,14 +48,2 @@ if (typeof window === "undefined") { | ||
| } | ||
| async function loadSDK() { | ||
| if (sdkLoadPromise) { | ||
| return sdkLoadPromise; | ||
| } | ||
| const config2 = getConfig(); | ||
| if (typeof window !== "undefined" && window.wx) { | ||
| sdkLoadPromise = Promise.resolve(); | ||
| return sdkLoadPromise; | ||
| } | ||
| sdkLoadPromise = loadScript(config2.sdkUrl); | ||
| return sdkLoadPromise; | ||
| } | ||
| async function initSDK(jsApiList) { | ||
@@ -84,3 +58,2 @@ const cfg = getConfig(); | ||
| sdkInitPromise = (async () => { | ||
| await loadSDK(); | ||
| const signatureResult = await cfg.getSignature(signatureUrl); | ||
@@ -110,3 +83,2 @@ const wx = getWx(); | ||
| function resetSDK() { | ||
| sdkLoadPromise = null; | ||
| sdkInitPromise = null; | ||
@@ -177,4 +149,4 @@ currentInitUrl = null; | ||
| export { config, getConfig, getWx, init, initSDK, isConfigured, loadSDK, resetSDK, share }; | ||
| export { config, getConfig, getWx, init, initSDK, isConfigured, resetSDK, share }; | ||
| //# sourceMappingURL=index.mjs.map | ||
| //# sourceMappingURL=index.mjs.map |
@@ -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 /** 微信 JS-SDK 的 URL 地址 */\n sdkUrl: string\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 sdkLoadPromise: Promise<void> | null = null\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 * 加载微信 JS-SDK 脚本\n */\nfunction loadScript(url: string): Promise<void> {\n return new Promise((resolve, reject) => {\n if (typeof document === 'undefined') {\n reject(new Error('document is not defined'))\n return\n }\n\n const script = document.createElement('script')\n script.src = url\n script.onload = () => resolve()\n script.onerror = () => reject(new Error(`Failed to load script: ${url}`))\n document.head.appendChild(script)\n })\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(仅加载一次)\n */\nexport async function loadSDK(): Promise<void> {\n if (sdkLoadPromise) {\n return sdkLoadPromise\n }\n\n const config = getConfig()\n\n // 检查是否已经加载\n if (typeof window !== 'undefined' && (window as unknown as Record<string, unknown>).wx) {\n sdkLoadPromise = Promise.resolve()\n return sdkLoadPromise\n }\n\n sdkLoadPromise = loadScript(config.sdkUrl)\n return sdkLoadPromise\n}\n\n/**\n * 初始化 SDK(获取签名并调用 wx.config)\n * SPA 模式下,URL 变化时会重新初始化(Android)\n * iOS 微信始终使用首次进入的 URL 进行签名\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 // 先确保 SDK 已加载\n await loadSDK()\n\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 sdkLoadPromise = null\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 * @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 */\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"]} |
+2
-1
| { | ||
| "name": "@sohu-bpd/wechat", | ||
| "version": "0.0.3", | ||
| "version": "0.0.4", | ||
| "description": "WeChat JS-SDK utility library", | ||
@@ -8,2 +8,3 @@ "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "unpkg": "./dist/index.global.js", | ||
| "exports": { | ||
@@ -10,0 +11,0 @@ ".": { |
+29
-18
| # @sohu-bpd/wechat | ||
| WeChat JS-SDK utility library with automatic SDK loading, initialization, and SPA support. | ||
| WeChat JS-SDK utility library with initialization helpers and SPA support. | ||
| ## Features | ||
| - 🚀 **Auto SDK Loading** - Automatically loads WeChat JS-SDK from CDN | ||
| - 🔄 **SPA Support** - Auto re-initialization on URL changes for single-page apps | ||
@@ -26,4 +25,12 @@ - 📱 **iOS Compatible** - Handles iOS WeChat signature URL quirks automatically | ||
| ### 1. Configure Once | ||
| ### 1. Load WeChat JS-SDK | ||
| First, include the WeChat JS-SDK script in your HTML: | ||
| ```html | ||
| <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> | ||
| ``` | ||
| ### 2. Configure Once | ||
| ```typescript | ||
@@ -33,3 +40,2 @@ import { config } from '@sohu-bpd/wechat' | ||
| config({ | ||
| sdkUrl: 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js', | ||
| getSignature: async (url) => { | ||
@@ -45,3 +51,3 @@ // Fetch signature from your backend | ||
| ### 2. Use Anywhere | ||
| ### 3. Use Anywhere | ||
@@ -74,2 +80,5 @@ ```typescript | ||
| ```html | ||
| <!-- Load WeChat JS-SDK first --> | ||
| <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> | ||
| <!-- Then load this library --> | ||
| <script src="https://unpkg.com/@sohu-bpd/wechat/dist/index.global.js"></script> | ||
@@ -80,3 +89,2 @@ <script> | ||
| config({ | ||
| sdkUrl: 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js', | ||
| getSignature: async (url) => { | ||
@@ -104,6 +112,6 @@ const res = await fetch('/api/wechat/signature?url=' + encodeURIComponent(url)) | ||
| **Note:** You must load the WeChat JS-SDK script in your HTML before using this library. | ||
| ```typescript | ||
| interface GlobalConfig { | ||
| /** WeChat JS-SDK URL */ | ||
| sdkUrl: string | ||
| /** Function to fetch signature, receives current URL */ | ||
@@ -124,3 +132,2 @@ getSignature: (url: string) => Promise<SignatureResult> | ||
| config({ | ||
| sdkUrl: 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js', | ||
| getSignature: async (url) => { | ||
@@ -185,10 +192,2 @@ const res = await fetch(`/api/wechat/signature?url=${encodeURIComponent(url)}`) | ||
| #### loadSDK() | ||
| Load WeChat JS-SDK script (automatically called by high-level APIs). | ||
| ```typescript | ||
| function loadSDK(sdkUrl: string): Promise<void> | ||
| ``` | ||
| #### initSDK(jsApiList) | ||
@@ -198,2 +197,4 @@ | ||
| **Note:** Requires WeChat JS-SDK to be loaded globally first. | ||
| ```typescript | ||
@@ -221,4 +222,6 @@ function initSDK(jsApiList: string[]): Promise<void> | ||
| For use cases that don't need global configuration: | ||
| For use cases that don't need global configuration. | ||
| **Note:** Requires WeChat JS-SDK to be loaded globally first. | ||
| ```typescript | ||
@@ -319,2 +322,10 @@ interface InitConfig { | ||
| ### 0.0.3 (2026-01-29) | ||
| - **Breaking Change:** Removed automatic SDK loading functionality | ||
| - Users must now manually include the WeChat JS-SDK script in their HTML | ||
| - Removed `sdkUrl` configuration option from `GlobalConfig` | ||
| - Removed `loadSDK()` export from public API | ||
| - Updated documentation with instructions for manual SDK inclusion | ||
| ### 0.0.2 (2026-01-29) | ||
@@ -321,0 +332,0 @@ |
334
3.41%67989
-10%579
-13.45%